mirror of
https://github.com/pfsense/pfsense.git
synced 2025-10-26 11:38:35 +00:00
Add back DNS over TLS host verification code. Fixes #8602
Requires Unbound 1.9.0_1 from pfsense/freebsd-ports, which fixes a bug
in Unbound 1.9.0 which did not fully implement OpenSSL 1.0.2 host
validation support. See https://www.nlnetlabs.nl/bugs-script/show_bug.cgi?id=4206#c5
(cherry picked from commit 7e8bfed216)
This commit is contained in:
parent
fdb7f0a547
commit
44fb8aca0d
@ -183,7 +183,7 @@ EOF;
|
||||
}
|
||||
|
||||
// Determine interfaces where unbound will bind
|
||||
$sslport = is_numeric($unboundcfg['sslport']) ? $unboundcfg['sslport'] : "853";
|
||||
$tlsport = is_numeric($unboundcfg['tlsport']) ? $unboundcfg['tlsport'] : "853";
|
||||
$bindintcfg = "";
|
||||
$bindints = array();
|
||||
$active_interfaces = explode(",", $unboundcfg['active_interface']);
|
||||
@ -210,18 +210,19 @@ EOF;
|
||||
foreach ($bindints as $bindint) {
|
||||
$bindintcfg .= "interface: {$bindint}\n";
|
||||
if (isset($unboundcfg['enablessl'])) {
|
||||
$bindintcfg .= "interface: {$bindint}@{$sslport}\n";
|
||||
$bindintcfg .= "interface: {$bindint}@{$tlsport}\n";
|
||||
}
|
||||
}
|
||||
|
||||
// SSL Configuration
|
||||
$sslconfig = "";
|
||||
// TLS Configuration
|
||||
$tlsconfig = "tls-cert-bundle: \"/etc/ssl/cert.pem\"\n";
|
||||
|
||||
if (isset($unboundcfg['enablessl'])) {
|
||||
$sslcert_path = "{$g['unbound_chroot_path']}/sslcert.crt";
|
||||
$sslkey_path = "{$g['unbound_chroot_path']}/sslcert.key";
|
||||
$tlscert_path = "{$g['unbound_chroot_path']}/sslcert.crt";
|
||||
$tlskey_path = "{$g['unbound_chroot_path']}/sslcert.key";
|
||||
|
||||
// Enable SSL on the chosen or default port
|
||||
$sslconfig .= "ssl-port: {$sslport}\n";
|
||||
$tlsconfig .= "tls-port: {$tlsport}\n";
|
||||
|
||||
// Lookup CA and Server Cert
|
||||
$cert = lookup_cert($unboundcfg['sslcertref']);
|
||||
@ -232,14 +233,14 @@ EOF;
|
||||
}
|
||||
|
||||
// Write CA and Server Cert
|
||||
file_put_contents($sslcert_path, $cert_chain);
|
||||
chmod($sslcert_path, 0644);
|
||||
file_put_contents($sslkey_path, base64_decode($cert['prv']));
|
||||
chmod($sslkey_path, 0600);
|
||||
file_put_contents($tlscert_path, $cert_chain);
|
||||
chmod($tlscert_path, 0644);
|
||||
file_put_contents($tlskey_path, base64_decode($cert['prv']));
|
||||
chmod($tlskey_path, 0600);
|
||||
|
||||
// Add config for CA and Server Cert
|
||||
$sslconfig .= "ssl-service-pem: \"{$sslcert_path}\"\n";
|
||||
$sslconfig .= "ssl-service-key: \"{$sslkey_path}\"\n";
|
||||
$tlsconfig .= "tls-service-pem: \"{$tlscert_path}\"\n";
|
||||
$tlsconfig .= "tls-service-key: \"{$tlskey_path}\"\n";
|
||||
}
|
||||
|
||||
// Determine interfaces to run on
|
||||
@ -345,10 +346,29 @@ EOD;
|
||||
if (isset($unboundcfg['forward_tls_upstream'])) {
|
||||
$forward_conf .= "\tforward-tls-upstream: yes\n";
|
||||
}
|
||||
|
||||
/* Build DNS server hostname list. See https://redmine.pfsense.org/issues/8602 */
|
||||
$dns_hostnames = array();
|
||||
$dnshost_counter = 1;
|
||||
while (isset($config["system"]["dns{$dnshost_counter}host"])) {
|
||||
$pconfig_dnshost_counter = $dnshost_counter - 1;
|
||||
if (!empty($config["system"]["dns{$dnshost_counter}host"]) &&
|
||||
isset($config["system"]["dnsserver"][$pconfig_dnshost_counter]))
|
||||
$dns_hostnames[$config["system"]["dnsserver"][$pconfig_dnshost_counter]] = $config["system"]["dns{$dnshost_counter}host"];
|
||||
$dnshost_counter++;
|
||||
}
|
||||
|
||||
foreach ($dnsservers as $dnsserver) {
|
||||
$fwdport = "";
|
||||
$fwdhost = "";
|
||||
if (is_ipaddr($dnsserver) && !ip_in_subnet($dnsserver, "127.0.0.0/8")) {
|
||||
$fwdport = isset($unboundcfg['forward_tls_upstream']) ? "@853" : "";
|
||||
$forward_conf .= "\tforward-addr: {$dnsserver}{$fwdport}\n";
|
||||
if (isset($unboundcfg['forward_tls_upstream'])) {
|
||||
$fwdport = "@853";
|
||||
if (array_key_exists($dnsserver, $dns_hostnames)) {
|
||||
$fwdhost = "#{$dns_hostnames[$dnsserver]}";
|
||||
}
|
||||
}
|
||||
$forward_conf .= "\tforward-addr: {$dnsserver}{$fwdport}{$fwdhost}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -425,8 +445,8 @@ use-caps-for-id: {$use_caps}
|
||||
serve-expired: {$dns_record_cache}
|
||||
# Statistics
|
||||
{$statistics}
|
||||
# SSL Configuration
|
||||
{$sslconfig}
|
||||
# TLS Configuration
|
||||
{$tlsconfig}
|
||||
# Interface IP(s) to bind to
|
||||
{$bindintcfg}
|
||||
{$outgoingints}
|
||||
@ -571,6 +591,7 @@ function unbound_add_domain_overrides($pvt_rev="", $cfgsubdir = "") {
|
||||
$sorted_domains = msort($domains, "domain");
|
||||
$result = array();
|
||||
$tls_domains = array();
|
||||
$tls_hostnames = array();
|
||||
foreach ($sorted_domains as $domain) {
|
||||
$domain_key = current($domain);
|
||||
if (!isset($result[$domain_key])) {
|
||||
@ -580,6 +601,7 @@ function unbound_add_domain_overrides($pvt_rev="", $cfgsubdir = "") {
|
||||
/* If any entry for a domain has TLS set, it will be active for all entries. */
|
||||
if (isset($domain['forward_tls_upstream'])) {
|
||||
$tls_domains[] = $domain_key;
|
||||
$tls_hostnames[$domain['ip']] = $domain['tls_hostname'];
|
||||
}
|
||||
}
|
||||
|
||||
@ -594,20 +616,25 @@ function unbound_add_domain_overrides($pvt_rev="", $cfgsubdir = "") {
|
||||
$domain_entries .= "local-zone: \"$domain\" typetransparent\n";
|
||||
}
|
||||
} else {
|
||||
$use_tls = in_array($domain, $tls_domains);
|
||||
$domain_entries .= "forward-zone:\n";
|
||||
$domain_entries .= "\tname: \"$domain\"\n";
|
||||
$fwdport = "";
|
||||
/* Enable TLS forwarding for this domain if needed. */
|
||||
if (in_array($domain, $tls_domains)) {
|
||||
if ($use_tls) {
|
||||
$domain_entries .= "\tforward-tls-upstream: yes\n";
|
||||
$fwdport = "@853";
|
||||
}
|
||||
foreach ($ips as $ip) {
|
||||
$fwdhost = "";
|
||||
/* If an IP address already contains a port specification, do not add another. */
|
||||
if (strstr($ip, '@') !== false) {
|
||||
$fwdport = "";
|
||||
}
|
||||
$domain_entries .= "\tforward-addr: {$ip}{$fwdport}\n";
|
||||
if ($use_tls && array_key_exists($ip, $tls_hostnames)) {
|
||||
$fwdhost = "#{$tls_hostnames[$ip]}";
|
||||
}
|
||||
$domain_entries .= "\tforward-addr: {$ip}{$fwdport}{$fwdhost}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,6 +42,7 @@ if (isset($id) && $a_domainOverrides[$id]) {
|
||||
$pconfig['domain'] = $a_domainOverrides[$id]['domain'];
|
||||
$pconfig['ip'] = $a_domainOverrides[$id]['ip'];
|
||||
$pconfig['descr'] = $a_domainOverrides[$id]['descr'];
|
||||
$pconfig['tls_hostname'] = $a_domainOverrides[$id]['tls_hostname'];
|
||||
$pconfig['forward_tls_upstream'] = isset($a_domainOverrides[$id]['forward_tls_upstream']);
|
||||
}
|
||||
|
||||
@ -80,11 +81,16 @@ if ($_POST['save']) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_POST['tls_hostname']) && !is_hostname($_POST['tls_hostname'])) {
|
||||
$input_errors[] = gettext("The supplied TLS hostname is not valid.");
|
||||
}
|
||||
|
||||
if (!$input_errors) {
|
||||
$doment = array();
|
||||
$doment['domain'] = $_POST['domain'];
|
||||
$doment['ip'] = $_POST['ip'];
|
||||
$doment['descr'] = $_POST['descr'];
|
||||
$doment['tls_hostname'] = $_POST['tls_hostname'];
|
||||
$doment['forward_tls_upstream'] = isset($_POST['forward_tls_upstream']);
|
||||
|
||||
if (isset($id) && $a_domainOverrides[$id]) {
|
||||
@ -136,6 +142,13 @@ $section->addInput(new Form_Checkbox(
|
||||
$pconfig['forward_tls_upstream']
|
||||
))->setHelp('When set, queries to %1$sall DNS servers for this domain%2$s will be sent using SSL/TLS on the default port of 853.', '<b>', '</b>');
|
||||
|
||||
$section->addInput(new Form_Input(
|
||||
'tls_hostname',
|
||||
'TLS Hostname',
|
||||
'text',
|
||||
$pconfig['tls_hostname']
|
||||
))->setHelp('An optional TLS hostname used to verify the server certificate when performing TLS Queries.');
|
||||
|
||||
$section->addInput(new Form_Input(
|
||||
'descr',
|
||||
'Description',
|
||||
|
||||
@ -52,6 +52,14 @@ if (!isset($config['system']['language'])) {
|
||||
$config['system']['language'] = $g['language'];
|
||||
}
|
||||
|
||||
$dnshost_counter = 1;
|
||||
|
||||
while (isset($config["system"]["dns{$dnshost_counter}host"])) {
|
||||
$pconfig_dnshost_counter = $dnshost_counter - 1;
|
||||
$pconfig["dnshost{$pconfig_dnshost_counter}"] = $config["system"]["dns{$dnshost_counter}host"];
|
||||
$dnshost_counter++;
|
||||
}
|
||||
|
||||
$dnsgw_counter = 1;
|
||||
|
||||
while (isset($config["system"]["dns{$dnsgw_counter}gw"])) {
|
||||
@ -184,11 +192,15 @@ if ($_POST) {
|
||||
|
||||
while (isset($_POST[$dnsname])) {
|
||||
$dnsgwname = "dnsgw{$dnscounter}";
|
||||
$dnshostname = "dnshost{$dnscounter}";
|
||||
$dnslist[] = $_POST[$dnsname];
|
||||
|
||||
if (($_POST[$dnsname] && !is_ipaddr($_POST[$dnsname]))) {
|
||||
$input_errors[] = sprintf(gettext("A valid IP address must be specified for DNS server %s."), $dnscounter+1);
|
||||
} else {
|
||||
if (!empty($_POST[$dnshostname]) && !is_hostname($_POST[$dnshostname])) {
|
||||
$input_errors[] = sprintf(gettext('The hostname provided for DNS server "%1$s" is not valid.'), $_POST[$dnsname]);
|
||||
}
|
||||
if (($_POST[$dnsgwname] <> "") && ($_POST[$dnsgwname] <> "none")) {
|
||||
// A real gateway has been selected.
|
||||
if (is_ipaddr($_POST[$dnsname])) {
|
||||
@ -350,22 +362,29 @@ if ($_POST) {
|
||||
while (isset($_POST[$dnsname])) {
|
||||
// The $_POST array key of the corresponding gateway (starts from 0)
|
||||
$dnsgwname = "dnsgw{$dnscounter}";
|
||||
// The numbering of DNS GW entries in the config starts from 1
|
||||
$dnshostname = "dnshost{$dnscounter}";
|
||||
// The numbering of DNS GW/host entries in the config starts from 1
|
||||
$dnsgwconfigcounter = $dnscounter + 1;
|
||||
$dnshostconfigcounter = $dnscounter + 1;
|
||||
// So this is the array key of the DNS GW entry in $config['system']
|
||||
$dnsgwconfigname = "dns{$dnsgwconfigcounter}gw";
|
||||
$dnshostconfigname = "dns{$dnshostconfigcounter}host";
|
||||
|
||||
$olddnsgwname = $config['system'][$dnsgwconfigname];
|
||||
$olddnshostname = $config['system'][$dnshostconfigname];
|
||||
|
||||
if ($ignore_posted_dnsgw[$dnsgwname]) {
|
||||
$thisdnsgwname = "none";
|
||||
} else {
|
||||
$thisdnsgwname = $pconfig[$dnsgwname];
|
||||
}
|
||||
$thisdnshostname = $pconfig[$dnshostname];
|
||||
|
||||
// "Blank" out the settings for this index, then we set them below using the "outdnscounter" index.
|
||||
$config['system'][$dnsgwconfigname] = "none";
|
||||
$pconfig[$dnsgwname] = "none";
|
||||
$config['system'][$dnshostconfigname] = "";
|
||||
$pconfig[$dnshostname] = "";
|
||||
$pconfig[$dnsname] = "";
|
||||
|
||||
if ($_POST[$dnsname]) {
|
||||
@ -377,19 +396,28 @@ if ($_POST) {
|
||||
$outdnsname = "dns{$outdnscounter}";
|
||||
// The $pconfig array key of the corresponding gateway (starts from 0)
|
||||
$outdnsgwname = "dnsgw{$outdnscounter}";
|
||||
// The numbering of DNS GW entries in the config starts from 1
|
||||
// The $pconfig array key of the corresponding hostname (starts from 0)
|
||||
$outdnshostname = "dnshost{$outdnscounter}";
|
||||
|
||||
// The numbering of DNS GW/host entries in the config starts from 1
|
||||
$outdnsgwconfigcounter = $outdnscounter + 1;
|
||||
$outdnshostconfigcounter = $outdnscounter + 1;
|
||||
// So this is the array key of the output DNS GW entry in $config['system']
|
||||
$outdnsgwconfigname = "dns{$outdnsgwconfigcounter}gw";
|
||||
$outdnshostconfigname = "dns{$outdnshostconfigcounter}host";
|
||||
|
||||
$pconfig[$outdnsname] = $_POST[$dnsname];
|
||||
if ($_POST[$dnsgwname]) {
|
||||
$config['system'][$outdnsgwconfigname] = $thisdnsgwname;
|
||||
$pconfig[$outdnsgwname] = $thisdnsgwname;
|
||||
$config['system'][$outdnshostconfigname] = $thisdnshostname;
|
||||
$pconfig[$outdnshostname] = $thisdnshostname;
|
||||
} else {
|
||||
// Note: when no DNS GW name is chosen, the entry is set to "none", so actually this case never happens.
|
||||
unset($config['system'][$outdnsgwconfigname]);
|
||||
$pconfig[$outdnsgwname] = "";
|
||||
unset($config['system'][$outdnshostconfigname]);
|
||||
$pconfig[$outdnshostname] = "";
|
||||
}
|
||||
$outdnscounter++;
|
||||
}
|
||||
@ -485,6 +513,7 @@ $dnsserver_count = count($pconfig['dnsserver']);
|
||||
$dnsserver_num = 0;
|
||||
$dnsserver_help = gettext("Address") . '<br/>' . gettext("Enter IP addresses to be used by the system for DNS resolution.") . " " .
|
||||
gettext("These are also used for the DHCP service, DNS Forwarder and DNS Resolver when it has DNS Query Forwarding enabled.");
|
||||
$dnshost_help = gettext("Hostname") . '<br/>' . gettext("Enter the DNS Server Hostname for TLS Verification in the DNS Resolver (optional).");
|
||||
$dnsgw_help = gettext("Gateway") . '<br/>'. gettext("Optionally select the gateway for each DNS server.") . " " .
|
||||
gettext("When using multiple WAN connections there should be at least one unique DNS server per gateway.");
|
||||
|
||||
@ -506,6 +535,13 @@ foreach ($pconfig['dnsserver'] as $dnsserver) {
|
||||
$dnsserver
|
||||
))->setHelp(($is_last_dnsserver) ? $dnsserver_help:null);
|
||||
|
||||
$group->add(new Form_Input(
|
||||
'dnshost' . $dnsserver_num,
|
||||
'DNS Hostname',
|
||||
'text',
|
||||
$pconfig['dnshost' . $dnsserver_num]
|
||||
))->setHelp(($is_last_dnsserver) ? $dnshost_help:null);
|
||||
|
||||
if ($multiwan) {
|
||||
$options = array('none' => 'none');
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user