$ips) { if($pvt == true) { $domain_entries .= "private-domain: \"$domain\"\n"; $domain_entries .= "domain-insecure: \"$domain\"\n"; } else { $domain_entries .= "stub-zone:\n"; $domain_entries .= "\tname: \"$domain\"\n"; foreach($ips as $ip) { $domain_entries .= "\tstub-addr: $ip\n"; } $domain_entries .= "\tstub-prime: no\n"; } } if($pvt == true) return $domain_entries; else file_put_contents("{$g['unbound_chroot_path']}/etc/domainoverrides.conf", $domain_entries); } /* Optimize Unbound for environment */ function unbound_optimization() { global $config; $optimization_settings = array(); /* Set the number of threads equal to number of CPUs. * Use 1 to disable threading, if for some reason this sysctl fails. */ $numprocs = intval(trim(`/sbin/sysctl kern.smp.cpus | /usr/bin/cut -d" " -f2`)); if($numprocs > 0) $optimization['number_threads'] = "num-threads: {$numprocs}"; else $optimization['number_threads'] = "num-threads: 1"; /* Slabs to help reduce lock contention. */ if ($numprocs > 4) { $optimization['msg_cache_slabs'] = "msg-cache-slabs: {$numprocs}"; $optimization['rrset_cache_slabs'] = "rrset-cache-slabs: {$numprocs}"; $optimization['infra_cache_slabs'] = "infra-cache-slabs: {$numprocs}"; $optimization['key_cache_slabs'] = "key-cache-slabs: {$numprocs}"; } else { $optimization['msg_cache_slabs'] = "msg-cache-slabs: 4"; $optimization['rrset_cache_slabs'] = "rrset-cache-slabs: 4"; $optimization['infra_cache_slabs'] = "infra-cache-slabs: 4"; $optimization['key_cache_slabs'] = "key-cache-slabs: 4"; } /* Memory usage default of 4MB */ $optimization['msg_cache_size'] = "msg-cache-size: 4m"; $optimization['rrset_cache_size'] = "rrset-cache-size: 8m"; /* More outgoing connections per thread otherwise assign a default of 4096 for a single thread */ if($numprocs > 0) { $or = (1024/$numprocs) - 50; $optimization['outgoing_range'] = "outgoing-range: {$or}"; } else { $optimization['outgoing_range'] = "outgoing-range: {4096}"; } /* Larger socket buffer for busy servers * Check that it is set to 4MB (by default the OS has it configured to 4MB) */ foreach ($config['sysctl']['item'] as $tunable) { if ($tunable['tunable'] == 'kern.ipc.maxsockbuf') { $so = floor(($tunable['value']/1024/1024)-1); // Check to ensure that the number is not a negative if ($so > 0) $optimization['so_rcvbuf'] = "so-rcvbuf: {$so}m"; else unset($optimization['so_rcvbuf']); } } /* Safety check in case kern.ipc.maxsockbuf is not available. */ if(!isset($optimization['so_rcvbuf'])) $optimization['so_rcvbuf'] = "#so-rcvbuf: 4m"; return $optimization; } /* Fetch root name servers hints file */ function unbound_fetch_root_hints_using_dig() { global $g; $hints = "{$g['unbound_chroot_path']}/etc/root.hints"; if (@filesize($hints) == 0) { $returnvar = mwexec("/usr/bin/dig +tcp +nocmd +answer +time=1 +tries=1 +retry=1 @`/usr/bin/dig +nocmd +noall +answer +short +time=1 +tries=1 +retry=1 . NS | /usr/bin/head -1` . NS > {$hints}"); if ($returnvar != 0) { mwexec("/bin/rm -f {$hints}"); return false; } else return true; } else return true; } /* Fetch root name servers hints file */ function unbound_fetch_root_hints() { global $g; $destination_file = "{$g['unbound_chroot_path']}/etc/root.hints"; if (@filesize($destination_file) == 0 ) { $fout = fopen($destination_file, "w"); $url = "ftp://ftp.internic.net/domain/named.cache"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, '5'); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); $data = curl_exec($ch); curl_close($ch); fwrite($fout, $data); fclose($fout); return ($http_code == 200) ? true : $http_code; } else return false; } /* Configure initial anchor to support DNSSEC */ function unbound_anchor_setup() { global $g; $conf = << $dhcpifconf) if(is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable'])) foreach ($dhcpifconf['staticmap'] as $host) if ($host['ipaddr'] && $host['hostname']) { $host_entries .= "local-data-ptr: \"{$host['ipaddr']} {$host['hostname']}.{$syscfg['domain']}\"\n"; $host_entries .= "local-data: \"{$host['hostname']}.{$syscfg['domain']} IN A {$host['ipaddr']}\"\n"; if (!empty($host['descr']) && $unboundcfg['txtsupport'] == 'on') $host_entries .= "local-data: '{$host['hostname']}.{$syscfg['domain']} TXT \"".addslashes($host['descr'])."\"'\n"; } $unbound_entries .= $host_entries; } // Handle DHCPLeases added host entries $dhcplcfg = read_hosts(); $host_entries = ""; if(is_array($dhcplcfg)) { foreach($dhcplcfg as $key=>$host) { $host_entries .= "local-data-ptr: \"{$host['ipaddr']} {$host['fqdn']}\"\n"; $host_entries .= "local-data: \"{$host['fqdn']} IN A {$host['ipaddr']}\"\n"; if (!empty($host['name'])) { $host_entries .= "local-data-ptr: \"{$host['ipaddr']} {$host['name']}\"\n"; $host_entries .= "local-data: \"{$host['name']} IN A {$host['ipaddr']}\"\n"; } } $unbound_entries .= $host_entries; } /* Write out entries */ file_put_contents("{$g['unbound_chroot_path']}/etc/host_entries.conf", $unbound_entries); } /* Read /etc/hosts */ function read_hosts() { /* Open /etc/hosts and extract the only dhcpleases info * XXX - to convert to an unbound C library which reads /etc/hosts automatically */ $etc_hosts = array(); foreach (file('/etc/hosts') as $line) { $d = preg_split('/\s/', $line, -1, PREG_SPLIT_NO_EMPTY); if (empty($d) || substr(reset($d), 0, 1) == "#") continue; if ($d[3] == "#") { $ip = array_shift($d); $fqdn = array_shift($d); $name = array_shift($d); if ($fqdn != "empty") { if ($name != "empty") array_push($etc_hosts, array(ipaddr => "$ip", fqdn => "$fqdn", name => "$name")); else array_push($etc_hosts, array(ipaddr => "$ip", fqdn => "$fqdn")); } } } return $etc_hosts; } function unbound_setup() { global $config, $g; unbound_anchor_setup(); unbound_remote_control_setup(); unbound_keys_setup(); unbound_fetch_root_hints(); unbound_resync_config(); } function unbound_acl_id_used($id) { global $config; if (is_array($config['installedpackages']['unboundacls']['config'])) foreach ($config['installedpackages']['unboundacls']['config'] as & $acls) if ($id == $acls['aclid']) return true; return false; } function unbound_get_next_id() { $aclid = 0; while(unbound_acl_id_used($aclid)) $aclid++; return $aclid; } ?>