Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,141 @@ Set to 0 to disable, remember to change your client as well.
<formatter>boolean</formatter>
</grid_view>
</field>
<field>
<id>instance.dns_update</id>
<label>DNS update</label>
<type>checkbox</type>
<style>role role_server</style>
<help>
Register client IP address at an external DNS server,
with the X509 client certificate 'CN' field as hostname.
Can be changed to another field in advanced mode.
</help>
</field>
<field>
<id>instance.dns_update_server</id>
<label>DNS update: server name</label>
<type>text</type>
<style>role role_server_dns_update</style>
<help>Hostname / IP address of the external DNS server.</help>
</field>
<field>
<id>instance.dns_update_port</id>
<label>DNS update: server port</label>
<type>text</type>
<style>role role_server_dns_update</style>
<advanced>true</advanced>
<help>
Used port on the external DNS server. &lt;br&gt;
If empty: '53'
</help>
</field>
<field>
<id>instance.dns_update_key_name</id>
<label>DNS update: key name</label>
<type>text</type>
<style>role role_server_dns_update</style>
<help>Name of the key to authenticate at the external DNS server.</help>
</field>
<field>
<id>instance.dns_update_key_secret</id>
<label>DNS update: key secret</label>
<type>text</type>
<style>role role_server_dns_update</style>
<help>Base64 secret of the key to authenticate at the external DNS server.</help>
</field>
<field>
<id>instance.dns_update_key_algorithm</id>
<label>DNS update: key algorithm</label>
<type>dropdown</type>
<style>role role_server_dns_update</style>
<help>Key algorithm used to authenticate at the external DNS server.</help>
</field>
<field>
<id>instance.dns_update_zone_forward</id>
<label>DNS update: forward zone name</label>
<type>text</type>
<style>role role_server_dns_update</style>
<help>
The zone name the hostname will be registered in. &lt;br&gt;
example: 'example.com'
</help>
</field>
<field>
<id>instance.dns_update_zone_reverse_4</id>
<label>DNS update: reverse zone name (IPv4)</label>
<type>text</type>
<style>role role_server_dns_update</style>
<advanced>true</advanced>
<help>
The reverse zone name the hostname will be registered in. &lt;br&gt;
If empty the /24 zone of the client IP will be used. &lt;br&gt;
example: &lt;br&gt;
client IP = '10.20.30.40' &lt;br&gt;
results in zone name = '30.20.10.in-addr.arpa'
</help>
</field>
<field>
<id>instance.dns_update_zone_reverse_6</id>
<label>DNS update: reverse zone name (IPv6)</label>
<type>text</type>
<style>role role_server_dns_update</style>
<advanced>true</advanced>
<help>
The reverse zone name the hostname will be registered in. &lt;br&gt;
If empty the /64 zone of the client IP will be used. &lt;br&gt;
example: &lt;br&gt;
client IP = '2001:0db8:abcd:0012:0000:0000:0000:0042' &lt;br&gt;
results in zone name = '2.1.0.0.d.c.b.a.8.b.d.0.1.0.0.2.ip6.arpa'
</help>
</field>
<field>
<id>instance.dns_update_hostname_field</id>
<label>DNS update: hostname field</label>
<type>text</type>
<advanced>true</advanced>
<style>role role_server_dns_update</style>
<help>
The X509 client certificate field used as hostname. &lt;br&gt;
If empty: 'CN'
</help>
</field>
<field>
<id>instance.dns_update_hostname_prefix</id>
<label>DNS update: hostname prefix</label>
<type>text</type>
<style>role role_server_dns_update</style>
<advanced>true</advanced>
<help>
An optional prefix can be added to the registered hostname.
example: &lt;br&gt;
prefix='vpn-' &lt;br&gt;
hostname='client1' &lt;br&gt;
registered name at DNS is 'vpn-client1'
</help>
</field>
<field>
<id>instance.dns_update_hostname_suffix</id>
<label>DNS update: hostname suffix</label>
<type>text</type>
<style>role role_server_dns_update</style>
<advanced>true</advanced>
<help>
An optional suffix can be added to the registered hostname. &lt;br&gt;
example: &lt;br&gt;
suffix='-vpn' &lt;br&gt;
hostname='client1' &lt;br&gt;
registered name at DNS is 'client1-vpn'
</help>
</field>
<field>
<id>instance.dns_update_ttl</id>
<label>DNS update: TTL</label>
<type>text</type>
<style>role role_server_dns_update</style>
<advanced>true</advanced>
<help>TTL in seconds for the DNS record. If empty: '300'</help>
</field>
<field>
<id>instance.http-proxy</id>
<label>HTTP Proxy</label>
Expand Down
72 changes: 69 additions & 3 deletions src/opnsense/mvc/app/models/OPNsense/OpenVPN/OpenVPN.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,39 @@ public function performValidation($validateFullModel = false)
$key . ".port-share"
));
}

if (!$instance->dns_update->isEmpty()) {
if ($instance->dns_update_server->isEmpty()) {
$messages->appendMessage(new Message(
gettext('The external server is required.'),
$key . ".dns_update_server"
));
}
if ($instance->dns_update_key_name->isEmpty()) {
$messages->appendMessage(new Message(
gettext('The authentication key name is required.'),
$key . ".dns_update_key_name"
));
}
if ($instance->dns_update_key_secret->isEmpty()) {
$messages->appendMessage(new Message(
gettext('The authentication key secret is required.'),
$key . ".dns_update_key_secret"
));
}
if ($instance->dns_update_key_algorithm->isEmpty()) {
$messages->appendMessage(new Message(
gettext('The authentication key algorithm is required.'),
$key . ".dns_update_key_algorithm"
));
}
if ($instance->dns_update_zone_forward->isEmpty()) {
$messages->appendMessage(new Message(
gettext('The forward zone name is required.'),
$key . ".dns_update_zone_forward"
));
}
}
}
if (!$instance->cert->isEmpty()) {
$tmp = Store::getCertificate((string)$instance->cert);
Expand Down Expand Up @@ -643,15 +676,48 @@ public function generateInstanceConfig($uuid = null)
$options['username-as-common-name'] = null;
}
$options['client-config-dir'] = "/var/etc/openvpn-csc/{$node->vpnid}";

if (!$node->dns_update->isEmpty()) {
// add these options as comments, cause these a no generic OpenVPN options
// we parse them in our own dns update script
$options['#dns-update-server'] = "$node->dns_update_server";
if (!$node->dns_update_port->isEmpty()) {
$options['#dns-update-port'] = "$node->dns_update_port";
}
$options['#dns-update-key-name'] = "$node->dns_update_key_name";
$options['#dns-update-key-secret'] = "$node->dns_update_key_secret";
$options['#dns-update-key-algorithm'] = "$node->dns_update_key_algorithm";
$options['#dns-update-zone-forward'] = "$node->dns_update_zone_forward";
if (!$node->dns_update_zone_reverse_4->isEmpty()) {
$options['#dns-update-zone-reverse-4'] = "$node->dns_update_zone_reverse_4";
}
if (!$node->dns_update_zone_reverse_6->isEmpty()) {
$options['#dns-update-zone-reverse-6'] = "$node->dns_update_zone_reverse_6";
}
if (!$node->dns_update_hostname_field->isEmpty()) {
$options['#dns-update-hostname-field'] = "$node->dns_update_hostname_field";
}
if (!$node->dns_update_hostname_prefix->isEmpty()) {
$options['#dns-update-hostname-prefix'] = "$node->dns_update_hostname_prefix";
}
if (!$node->dns_update_hostname_suffix->isEmpty()) {
$options['#dns-update-hostname-suffix'] = "$node->dns_update_hostname_suffix";
}
if (!$node->dns_update_ttl->isEmpty()) {
$options['#dns-update-ttl'] = "$node->dns_update_ttl";
}
$run_dns_update = "--dns_update";
}

// hook event handlers
if (!$node->authmode->isEmpty()) {
$options['auth-user-pass-verify'] = "\"{$event_script} --defer '{$node_uuid}'\" via-env";
$options['learn-address'] = "\"{$event_script} '{$node->vpnid}'\"";
$options['learn-address'] = "\"{$event_script} {$run_dns_update} '{$node->vpnid}'\"";
} else {
// client specific profiles are being deployed using the connect event when no auth is used
$options['client-connect'] = "\"{$event_script} '{$node_uuid}'\"";
$options['client-connect'] = "\"{$event_script} {$run_dns_update} '{$node_uuid}'\"";
}
$options['client-disconnect'] = "\"{$event_script} '{$node_uuid}'\"";
$options['client-disconnect'] = "\"{$event_script} {$run_dns_update} '{$node_uuid}'\"";
$options['tls-verify'] = "\"{$event_script} '{$node_uuid}'\"";

if (!$node->maxclients->isEmpty()) {
Expand Down
42 changes: 42 additions & 0 deletions src/opnsense/mvc/app/models/OPNsense/OpenVPN/OpenVPN.xml
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,48 @@
<description type="DescriptionField"/>
<compress_migrate type="BooleanField"/>
<ifconfig-pool-persist type="BooleanField"/>
<dns_update type="BooleanField"/>
<dns_update_server type="HostnameField">
<WildcardEnabled>N</WildcardEnabled>
</dns_update_server>
<dns_update_port type="IntegerField">
<MinimumValue>1</MinimumValue>
<MaximumValue>65535</MaximumValue>
</dns_update_port>
<dns_update_key_name type="TextField"/>
<dns_update_key_secret type="TextField"/>
<dns_update_key_algorithm type="OptionField">
<Required>Y</Required>
<Multiple>N</Multiple>
<OptionValues>
<hmac-md5>hmac-md5</hmac-md5>
<hmac-sha1>hmac-sha1</hmac-sha1>
<hmac-sha224>hmac-sha224</hmac-sha224>
<hmac-sha256>hmac-sha256</hmac-sha256>
<hmac-sha384>hmac-sha384</hmac-sha384>
<hmac-sha512>hmac-sha512</hmac-sha512>
</OptionValues>
<Default>hmac-sha256</Default>
</dns_update_key_algorithm>
<dns_update_zone_forward type="HostnameField">
<WildcardEnabled>N</WildcardEnabled>
<ValidationMessage>This is not a valid zone name</ValidationMessage>
</dns_update_zone_forward>
<dns_update_zone_reverse_4 type="HostnameField">
<WildcardEnabled>N</WildcardEnabled>
<ValidationMessage>This is not a valid zone name</ValidationMessage>
</dns_update_zone_reverse_4>
<dns_update_zone_reverse_6 type="HostnameField">
<WildcardEnabled>N</WildcardEnabled>
<ValidationMessage>This is not a valid zone name</ValidationMessage>
</dns_update_zone_reverse_6>
<dns_update_hostname_field type="TextField"/>
<dns_update_hostname_prefix type="TextField"/>
<dns_update_hostname_suffix type="TextField"/>
<dns_update_ttl type="IntegerField">
<MinimumValue>1</MinimumValue>
<Default>300</Default>
</dns_update_ttl>
<http-proxy type="IPPortField">
<HostnameAllowed>Y</HostnameAllowed>
</http-proxy>
Expand Down
6 changes: 5 additions & 1 deletion src/opnsense/mvc/app/views/OPNsense/OpenVPN/instances.volt
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,20 @@
del:'/api/openvpn/instances/del_static_key/'
});

$("#instance\\.role, #instance\\.dev_type").change(function(){
$("#instance\\.role, #instance\\.dev_type, #instance\\.dns_update").change(function(){
const show_advanced = $("#show_advanced_formDialogdialog_dialogInstance").hasClass("fa-toggle-on");
const this_role = $("#instance\\.role").val();
const this_dev_type = $("#instance\\.dev_type").val();
const this_dns_update = $("#instance\\.dns_update").is(':checked');
$(".role").each(function(){
const tr = $(this).closest("tr").hide();
if ((tr.data('advanced') === true && show_advanced) || !tr.data('advanced')) {
if ($(this).hasClass('role_' + this_role) || $(this).hasClass('role_' + this_role + '_' + this_dev_type)) {
tr.show();
}
else if (this_dns_update && $(this).hasClass('role_' + this_role + '_dns_update')) {
tr.show();
}
}
});
});
Expand Down
Loading