aboutsummaryrefslogtreecommitdiffstats
path: root/config/bind/bind.inc
diff options
context:
space:
mode:
Diffstat (limited to 'config/bind/bind.inc')
-rw-r--r--config/bind/bind.inc605
1 files changed, 605 insertions, 0 deletions
diff --git a/config/bind/bind.inc b/config/bind/bind.inc
new file mode 100644
index 00000000..65d3c4f7
--- /dev/null
+++ b/config/bind/bind.inc
@@ -0,0 +1,605 @@
+<?PHP
+/* $Id$ */
+/*
+ bind.inc
+ part of the Bind package for pfSense
+ Copyright (C) 2013 Juliano Oliveira/Adriano Brancher
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+*/
+$shortcut_section = "bind";
+require_once('globals.inc');
+require_once('config.inc');
+require_once('util.inc');
+require_once('pfsense-utils.inc');
+require_once('pkg-utils.inc');
+require_once('service-utils.inc');
+if(!function_exists("filter_configure"))
+ require_once("filter.inc");
+
+function bind_sync(){
+
+ global $config;
+
+ $bind = $config["installedpackages"]["bind"]["config"][0];
+ $bind_enable = $bind['enable_bind'];
+ $bind_forwarder = $bind['bind_forwarder'];
+ $forwader_ips = $bind['bind_forwader_ips'];
+ $ram_limite = $bind['bind_ram_limite'];
+ $hide_version = $bind['bind_hide_version'];
+ $bind_notify = $bind['bind_notify'];
+ $custom_options = base64_decode($bind['bind_custom_options']);
+ $bind_logging = $bind['bind_logging'];
+
+
+ $bind_conf ="#Bind pfsense configuration\n";
+ $bind_conf .="#Do not edit this file!!!\n";
+$bind_conf .= <<<EOD
+
+ options {
+ directory "/etc/namedb";
+ pid-file "/var/run/named/pid";
+ statistics-file "/var/log/named.stats";
+
+ max-cache-size $ram_limite;\n
+EOD;
+
+ //check ips to listen on
+ if (preg_match("/All/",$bind['listenon'])){
+ $bind_listenonv6="Any;";
+ $bind_listenon="Any;";
+ }
+ else{
+ $bind_listenonv6="";
+ $bind_listenon ="";
+ foreach (explode(',',$bind['listenon']) as $listenon){
+ if (is_ipaddrv6($listenon))
+ $bind_listenonv6 .= $listenon."; ";
+ elseif (is_ipaddr($listenon))
+ $bind_listenon .= $listenon."; ";
+ else{
+ $listenon=(pfSense_get_interface_addresses(convert_friendly_interface_to_real_interface_name($listenon)));
+ if (is_ipaddr($listenon['ipaddr']))
+ $bind_listenon .= $listenon['ipaddr']."; ";
+ elseif(is_ipaddrv6($listenon['ipaddr']))
+ $bind_listenonv6 .= $listenon['ipaddr']."; ";
+ }
+ }
+ }
+ $bind_listenonv6=($bind_listenonv6==""?"none;":$bind_listenonv6);
+ $bind_listenon=($bind_listenon==""?"none;":$bind_listenon);
+ print "<PRE>$bind_listenonv6 $bind_listenon";
+ if (key_exists("ipv6allow",$config['system'])){
+ $bind_conf .="\t\tlisten-on-v6 { $bind_listenonv6 };\n";
+ }
+ $bind_conf .="\t\tlisten-on { $bind_listenon };\n";
+
+ #forwarder config
+ if ($bind_forwarder == on)
+ $bind_conf .="\t\tforwarders { $forwader_ips };\n";
+ if ($bind_notify == on)
+ $bind_conf .="\t\tnotify yes;\n";
+ if ($hide_version == on)
+ $bind_conf .="\t\tversion \"N/A\";\n";
+
+ $bind_conf .="\t\t$custom_options\n";
+ $bind_conf .= "\t};\n\n";
+
+ if ($bind_logging == on){
+$bind_conf .= <<<EOD
+
+ logging {
+ channel custom {
+ file "/var/log/named.log";
+ print-time yes;
+ print-category yes;
+ };
+
+ category config {custom;};
+ category notify {custom;};
+ category dnssec {custom;};
+ category general {custom;};
+ category security {custom;};
+ category xfer-out {custom;};
+ category lame-servers {custom;};
+ };
+
+EOD;
+ }
+
+
+ #Config Zone domain
+ if(is_array($config["installedpackages"]["bindacls"]))
+ $bindacls = $config["installedpackages"]["bindacls"]["config"];
+ else
+ $bindacls =array();
+
+ for ($i=0; $i<sizeof($bindacls); $i++)
+ {
+ $aclname = $bindacls[$i]['name'];
+ $aclhost = $bindacls[$i]['row'];
+ if($aclname != "any"){
+ $bind_conf .= "acl \"$aclname\" {\n";
+ for ($u=0; $u<sizeof($aclhost); $u++)
+ {
+ $aclhostvalue = $aclhost[$u]['value'];
+ $bind_conf .= "\t$aclhostvalue;\n";
+ }
+ $bind_conf .= "};\n\n";
+ }
+ }
+
+ if(is_array($config["installedpackages"]["bindviews"]))
+ $bindview = $config["installedpackages"]["bindviews"]["config"];
+ else
+ $bindview =array();
+
+ for ($i=0; $i<sizeof($bindview); $i++)
+ {
+ $views = $config["installedpackages"]["bindviews"]["config"][$i];
+ $viewname = $views['name'];
+ $viewrecursion = $views['recursion'];
+ if($views['match-clients'] == '')
+ $viewmatchclients = "none";
+ else
+ $viewmatchclients = str_replace(',','; ',$views['match-clients']);
+ if($views['allow-recursion'] == '')
+ $viewallowrecursion = "none";
+ else
+ $viewallowrecursion = str_replace(',','; ',$views['allow-recursion']);
+ $viewcustomoptions = $views['bind_custom_options'];
+
+ $bind_conf .= "view \"$viewname\" { \n\n";
+ $bind_conf .= "\trecursion $viewrecursion;\n";
+ $bind_conf .= "\tmatch-clients { $viewmatchclients;};\n";
+ $bind_conf .= "\tallow-recursion { $viewallowrecursion;};\n";
+ $bind_conf .= "\t$viewcustomoptions\n\n";
+
+ $bind_conf .="\tzone \".\" {\n";
+ $bind_conf .="\t\ttype hint;\n";
+ $bind_conf .="\t\tfile \"/etc/namedb/named.root\";\n";
+ $bind_conf .= "\t};\n\n";
+
+ for ($x=0; $x<sizeof($config["installedpackages"]["bindzone"]["config"]); $x++)
+ {
+ $zone = $config["installedpackages"]["bindzone"]["config"][$x];
+
+ $zonename = $zone['name'];
+ $zonetype = $zone['type'];
+ $zoneview = $zone['view'];
+ $zonecuston = $zone['custon'];
+ $zoneipslave = $zone['slaveip'];
+ $zonereverso = $zone['reverso'];
+ if($zone['allowupdate'] == '')
+ $zoneallowupdate = "none";
+ else
+ $zoneallowupdate = str_replace(',','; ',$zone['allowupdate']);
+ if($zone['allowquery'] == '')
+ $zoneallowquery = "none";
+ else
+ $zoneallowquery = str_replace(',','; ',$zone['allowquery']);
+ if($zone['allowtransfer'] == '')
+ $zoneallowtransfer = "none";
+ else
+ $zoneallowtransfer = str_replace(',','; ',$zone['allowtransfer']);
+
+ if ($zoneview == $viewname)
+ {
+ if($zonereverso == "on")
+ $bind_conf .= "\tzone \"$zonename.in-addr.arpa\" {\n";
+ else
+ $bind_conf .= "\tzone \"$zonename\" {\n";
+
+ $bind_conf .= "\t\ttype $zonetype;\n";
+ $bind_conf .= "\t\tfile \"/etc/namedb/$zonetype/$zoneview/$zonename.DB\";\n";
+ if ($zonetype == "slave")
+ $bind_conf .= "\t\tmasters { $zoneipslave };\n";
+ if ($zonetype != "slave")
+ $bind_conf .= "\t\tallow-update { $zoneallowupdate;};\n";
+ if ($zonetype != "slave")
+ $bind_conf .= "\t\tallow-query { $zoneallowquery;};\n";
+ if ($zonetype != "slave")
+ $bind_conf .= "\t\tallow-transfer { $zoneallowtransfer;};\n";
+ if ($zonecuston != '')
+ $bind_conf .= "\t\t$zonecuston\n";
+ $bind_conf .= "\t};\n\n";
+
+ if (!(file_exists("/etc/namedb/$zonetype"))) {
+ mwexec("mkdir /etc/namedb/$zonetype");
+ }
+
+ if (!(file_exists("/etc/namedb/$zonetype/$zoneview"))) {
+ mwexec("mkdir /etc/namedb/$zonetype/$zoneview");
+ }
+
+ if ($zonetype == "master"){
+ $zonetll = $zone['tll'];
+ $zonemail = $zone['mail'];
+ $zoneserial = $zone['serial'];
+ $zonerefresh = $zone['refresh'];
+ $zoneretry = $zone['retry'];
+ $zoneexpire = $zone['expire'];
+ $zoneminimum = $zone['minimum'];
+ $zonenameserver = $zone['nameserver'];
+ $zoneipns = $zone['ipns'];
+ $zonereverso = $zone['reverso'];
+ if($zone['allowupdate'] == '')
+ $zoneallowupdate = "none";
+ else
+ $zoneallowupdate = str_replace(',','; ',$zone['allowupdate']);
+ if($zone['allowquery'] == '')
+ $zoneallowquery = "none";
+ else
+ $zoneallowquery = str_replace(',','; ',$zone['allowquery']);
+ if($zone['allowtransfer'] == '')
+ $zoneallowtransfer = "none";
+ else
+ $zoneallowtransfer = str_replace(',','; ',$zone['allowtransfer']);
+ $zone_conf = ";$zonename\n";
+ $zone_conf .= "\$TTL $zonetll\n\n";
+
+ if($zonereverso == "on")
+ $zone_conf .= "@\t IN SOA $zonenameserver. \t $zonemail. (\n";
+ else
+ $zone_conf .= "$zonename.\t IN SOA $zonenameserver. \t $zonemail. (\n";
+
+ $zone_conf .= "\t$zoneserial\n";
+ $zone_conf .= "\t$zonerefresh\n";
+ $zone_conf .= "\t$zoneretry\n";
+ $zone_conf .= "\t$zoneexpire\n";
+ $zone_conf .= "\t$zoneminimum)\n\n";
+
+ if($zonereverso == "on")
+ $zone_conf .= "\t IN NS \t\t$zonenameserver.\n";
+ else{
+ $zone_conf .= "@ \t IN NS \t\t$zonenameserver.\n";
+ $zone_conf .= "@ \t IN A \t\t$zoneipns\n";
+ }
+ for ($y=0; $y<sizeof($zone['row']); $y++)
+ {
+ $hostname = $zone['row'][$y]['hostname'];
+ $hosttype = $zone['row'][$y]['hosttype'];
+ $hostdst = $zone['row'][$y]['hostdst'];
+ $hostvalue = $zone['row'][$y]['hostvalue'];
+
+ $zone_conf .= "$hostname \t IN $hosttype $hostvalue \t$hostdst\n";
+ }
+ file_put_contents("/etc/namedb/$zonetype/$zoneview/$zonename.DB", $zone_conf);
+
+ #reader file domain zone
+ #reader file host definition
+ }
+ }
+ }
+
+ $bind_conf .= "};\n";
+ }
+ if (!is_dir("/etc/namedb"))
+ mkdir("/etc/namedb",0755);
+ file_put_contents('/etc/namedb/named.conf', $bind_conf);
+
+
+ if($bind_enable == "on")
+ mwexec("/usr/local/etc/rc.d/named.sh restart");
+ else
+ mwexec("/usr/local/etc/rc.d/named.sh stop");
+}
+
+function bind_print_javascript_type_zone(){
+?>
+ <script language="JavaScript">
+ <!--
+ function on_type_zone_changed() {
+
+ var field = document.iform.type;
+ var tipo = field.options[field.selectedIndex].value;
+ if (tipo == 'master') {
+
+ document.iform.slaveip.disabled = 1;
+ document.iform.tll.disabled = 0;
+ document.iform.nameserver.disabled = 0;
+ document.iform.ipns.disabled = 0;
+ document.iform.mail.disabled = 0;
+ document.iform.serial.disabled = 0;
+ document.iform.refresh.disabled = 0;
+ document.iform.retry.disabled = 0;
+ document.iform.expire.disabled = 0;
+ document.iform.minimum.disabled = 0;
+
+ }
+ else {
+ document.iform.slaveip.disabled = 0;
+ document.iform.tll.disabled = 1;
+ document.iform.nameserver.disabled = 1;
+ document.iform.ipns.disabled = 1;
+ document.iform.mail.disabled = 1;
+ document.iform.serial.disabled = 1;
+ document.iform.refresh.disabled = 1;
+ document.iform.retry.disabled = 1;
+ document.iform.expire.disabled = 1;
+ document.iform.minimum.disabled = 1;
+ }
+ }
+ -->
+ </script>
+<?php
+}
+
+function bind_print_javascript_type_zone2(){
+ print("<script language=\"JavaScript\">on_type_zone_changed()</script>\n");
+}
+
+# Carregar o campo com os dados da views
+# -----------------------------------------------------------------------------
+
+function get_bind_conf_items_list($data_group, $fieldname) {
+ global $config;
+ $res = '';
+ if (is_array($config["installedpackages"][$data_group])){
+ $conf = $config["installedpackages"][$data_group]["config"];
+ if (is_array($conf))
+ foreach($conf as $cf) $res[] = $cf[$fieldname];
+ }
+ return $res;
+}
+
+# Carregar o campo com os dados da views
+# -----------------------------------------------------------------------------
+
+function bind_views_before_form_dest($pkg,$data_group,$fieldname,$dest) {
+
+ $destination_items = get_bind_conf_items_list($data_group,$fieldname);
+ $i=0;
+ if (is_array($pkg['fields']['field']))
+ foreach($pkg['fields']['field'] as $field) {
+ #
+ if ($field['fieldname'] == $dest) {
+ $fld = &$pkg['fields']['field'][$i];
+ if (is_array($destination_items))
+ foreach($destination_items as $nmkey => $nm)
+ $fld['options']['option'][] = array('name'=>ucfirst(strtolower($nm)), 'value'=>strtolower($nm));
+ }
+ $i++;
+ }
+}
+
+# Analizador do serial da zona de dns
+# -----------------------------------------------------------------------------
+
+function get_bind_conf_serial($data_group, $fieldname) {
+ global $config;
+ $res = '';
+ if (is_array($config["installedpackages"][$data_group])){
+ $conf = $config["installedpackages"][$data_group]["config"];
+ if (is_array($conf))
+ foreach($conf as $cf) $res[] = $cf[$fieldname];
+ }
+ return $res;
+}
+
+# Carregar o campo com os dados da views
+# -----------------------------------------------------------------------------
+
+function bind_zona_before_form_dest($pkg,$data_group,$fieldname,$dest) {
+
+ $destination_items = get_bind_conf_serial($data_group,$fieldname);
+ $i=0;
+ if (is_array($pkg['fields']['field']))
+ foreach($pkg['fields']['field'] as $field) {
+ #
+ if ($field['fieldname'] == $dest) {
+ $fld = &$pkg['fields']['field'][$i];
+ $fld['default_value'] = date("Y")."000000";
+ #$fld['value'] = date("Ymdhms")."boa";
+ }
+ $i++;
+ }
+}
+function bind_write_rcfile() {
+ $rc = array();
+ $BIND_LOCALBASE = "/usr/local";
+ $rc['file'] = 'named.sh';
+ $rc['start'] = <<<EOD
+if [ -z "`ps auxw | grep "[n]amed -c /etc/namedb/named.conf"|awk '{print $2}'`" ];then
+ {$BIND_LOCALBASE}/sbin/named -c /etc/namedb/named.conf -u bind
+fi
+
+EOD;
+ $rc['stop'] = <<<EOD
+killall -9 named 2>/dev/null
+sleep 2
+EOD;
+ $rc['restart'] = <<<EOD
+if [ -z "`ps auxw | grep "[n]amed -c /etc/namedb/named.conf"|awk '{print $2}'`" ];then
+ {$BIND_LOCALBASE}/sbin/named -c /etc/namedb/named.conf -u bind
+ else
+ killall -9 named 2>/dev/null
+ sleep 3
+ $BIND_LOCALBASE}/sbin/named -c /etc/namedb/named.conf -u bind
+ fi
+
+EOD;
+ conf_mount_rw();
+ write_rcfile($rc);
+ conf_mount_ro();
+}
+
+function create_log_file(){
+ mwexec("touch /var/log/named.log");
+ mwexec("chown bind:bind /var/log/named.log");
+ mwexec("chmod 755 /var/log/named.log");
+}
+
+function delete_log_file(){
+ mwexec("rm /var/log/named.log");
+}
+/* Uses XMLRPC to synchronize the changes to a remote node */
+function bind_sync_on_changes() {
+ global $config, $g;
+ if (is_array($config['installedpackages']['bind']['config'])){
+ $bind_sync=$config['installedpackages']['bind']['config'][0];
+ $synconchanges = $bind_sync['synconchanges'];
+ $synctimeout = $bind_sync['synctimeout'];
+ switch ($synconchanges){
+ case "manual":
+ if (is_array($bind_sync[row])){
+ $rs=$bind_sync[row];
+ }
+ else{
+ log_error("[bind] xmlrpc sync is enabled but there is no hosts to push on bind config.");
+ return;
+ }
+ break;
+ case "auto":
+ if (is_array($config['installedpackages']['carpsettings']) && is_array($config['installedpackages']['carpsettings']['config'])){
+ $system_carp=$config['installedpackages']['carpsettings']['config'][0];
+ $rs[0]['ipaddress']=$system_carp['synchronizetoip'];
+ $rs[0]['username']=$system_carp['username'];
+ $rs[0]['password']=$system_carp['password'];
+ }
+ else{
+ log_error("[bind] xmlrpc sync is enabled but there is no system backup hosts to push bind config.");
+ return;
+ }
+ break;
+ default:
+ return;
+ break;
+ }
+ if (is_array($rs)){
+ log_error("[bind] xmlrpc sync is starting.");
+ foreach($rs as $sh){
+ $sync_to_ip = $sh['ipaddress'];
+ $password = $sh['password'];
+ if($sh['username'])
+ $username = $sh['username'];
+ else
+ $username = 'admin';
+ if($password && $sync_to_ip)
+ bind_do_xmlrpc_sync($sync_to_ip, $username, $password,$synctimeout);
+ }
+ log_error("[bind] xmlrpc sync is ending.");
+ }
+ }
+}
+/* Do the actual XMLRPC sync */
+function bind_do_xmlrpc_sync($sync_to_ip, $username, $password, $synctimeout) {
+ global $config, $g;
+
+ if(!$username)
+ return;
+
+ if(!$password)
+ return;
+
+ if(!$sync_to_ip)
+ return;
+
+ if(!$synctimeout)
+ $synctimeout=25;
+
+
+ $xmlrpc_sync_neighbor = $sync_to_ip;
+ if($config['system']['webgui']['protocol'] != "") {
+ $synchronizetoip = $config['system']['webgui']['protocol'];
+ $synchronizetoip .= "://";
+ }
+ $port = $config['system']['webgui']['port'];
+ /* if port is empty lets rely on the protocol selection */
+ if($port == "") {
+ if($config['system']['webgui']['protocol'] == "http")
+ $port = "80";
+ else
+ $port = "443";
+ }
+ $synchronizetoip .= $sync_to_ip;
+
+ /* xml will hold the sections to sync */
+ $xml = array();
+ $xml['bind'] = $config['installedpackages']['bind'];
+ $xml['bindacls'] = $config['installedpackages']['bindacls'];
+ $xml['bindviews'] = $config['installedpackages']['bindviews'];
+ $xml['bindzone'] = $config['installedpackages']['bindzone'];
+ /* assemble xmlrpc payload */
+ $params = array(
+ XML_RPC_encode($password),
+ XML_RPC_encode($xml)
+ );
+
+ /* set a few variables needed for sync code borrowed from filter.inc */
+ $url = $synchronizetoip;
+ log_error("[bind] Beginning bind XMLRPC sync to {$url}:{$port}.");
+ $method = 'pfsense.merge_installedpackages_section_xmlrpc';
+ $msg = new XML_RPC_Message($method, $params);
+ $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port);
+ $cli->setCredentials($username, $password);
+ if($g['debug'])
+ $cli->setDebug(1);
+ /* send our XMLRPC message and timeout after defined sync timeout value*/
+ $resp = $cli->send($msg, $synctimeout);
+ if(!$resp) {
+ $error = "A communications error occurred while attempting bind XMLRPC sync with {$url}:{$port}.";
+ log_error($error);
+ file_notice("sync_settings", $error, "bind Settings Sync", "");
+ } elseif($resp->faultCode()) {
+ $cli->setDebug(1);
+ $resp = $cli->send($msg, $synctimeout);
+ $error = "An error code was received while attempting bind XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString();
+ log_error($error);
+ file_notice("sync_settings", $error, "bind Settings Sync", "");
+ } else {
+ log_error("[bind] XMLRPC sync successfully completed with {$url}:{$port}.");
+ }
+
+ /* tell bind to reload our settings on the destination sync host. */
+ $method = 'pfsense.exec_php';
+ $execcmd = "require_once('/usr/local/pkg/bind.inc');\n";
+ $execcmd .= "bind_sync('yes');";
+ /* assemble xmlrpc payload */
+ $params = array(
+ XML_RPC_encode($password),
+ XML_RPC_encode($execcmd)
+ );
+
+ log_error("[bind] XMLRPC reload data {$url}:{$port}.");
+ $msg = new XML_RPC_Message($method, $params);
+ $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port);
+ $cli->setCredentials($username, $password);
+ $resp = $cli->send($msg, $synctimeout);
+ if(!$resp) {
+ $error = "A communications error occurred while attempting bind XMLRPC sync with {$url}:{$port} (pfsense.exec_php).";
+ log_error($error);
+ file_notice("sync_settings", $error, "Bind Settings Sync", "");
+ } elseif($resp->faultCode()) {
+ $cli->setDebug(1);
+ $resp = $cli->send($msg, $synctimeout);
+ $error = "[Bind] An error code was received while attempting bind XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString();
+ log_error($error);
+ file_notice("sync_settings", $error, "bind Settings Sync", "");
+ } else {
+ log_error("Bind XMLRPC reload data success with {$url}:{$port} (pfsense.exec_php).");
+ }
+
+}
+?>