From 4b1fb10d7e1a8f24055316268318e6025aecd06d Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Thu, 3 Jan 2019 23:12:29 -0500 Subject: [PATCH 1/5] DNS Resolver - Python GUI Integration --- src/usr/local/www/services_unbound.php | 63 ++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/usr/local/www/services_unbound.php b/src/usr/local/www/services_unbound.php index de334f090f..e81063a096 100644 --- a/src/usr/local/www/services_unbound.php +++ b/src/usr/local/www/services_unbound.php @@ -47,6 +47,9 @@ if (isset($a_unboundcfg['enablessl'])) { if (isset($a_unboundcfg['dnssec'])) { $pconfig['dnssec'] = true; } +if (isset($a_unboundcfg['python'])) { + $pconfig['python'] = true; +} if (isset($a_unboundcfg['forwarding'])) { $pconfig['forwarding'] = true; } @@ -63,6 +66,8 @@ if (isset($a_unboundcfg['regovpnclients'])) { $pconfig['regovpnclients'] = true; } +$pconfig['python_order'] = $a_unboundcfg['python_order']; +$pconfig['python_script'] = $a_unboundcfg['python_script']; $pconfig['port'] = $a_unboundcfg['port']; $pconfig['sslport'] = $a_unboundcfg['sslport']; $pconfig['sslcertref'] = $a_unboundcfg['sslcertref']; @@ -198,6 +203,20 @@ if ($_POST['save']) { $a_unboundcfg['sslport'] = $pconfig['sslport']; $a_unboundcfg['sslcertref'] = $pconfig['sslcertref']; $a_unboundcfg['dnssec'] = isset($pconfig['dnssec']); + + $a_unboundcfg['python'] = isset($pconfig['python']); + if (isset($pconfig['python'])) { + $a_unboundcfg['python_order'] = $pconfig['python_order']; + $a_unboundcfg['python_script'] = $pconfig['python_script']; + } else { + if (isset($a_unboundcfg['python_order'])) { + unset($a_unboundcfg['python_order']); + } + if (isset($a_unboundcfg['python_script'])) { + unset($a_unboundcfg['python_script']); + } + } + $a_unboundcfg['forwarding'] = isset($pconfig['forwarding']); $a_unboundcfg['forward_tls_upstream'] = isset($pconfig['forward_tls_upstream']); $a_unboundcfg['regdhcp'] = isset($pconfig['regdhcp']); @@ -380,6 +399,39 @@ $section->addInput(new Form_Checkbox( $pconfig['dnssec'] )); +$section->addInput(new Form_Checkbox( + 'python', + 'Python Module', + 'Enable Python Module', + $pconfig['python'] +))->setHelp('Enable the Python Module.'); + +$python_files = glob("{$g['unbound_chroot_path']}/*.py"); +$python_scripts = array(); +if (!empty($python_files)) { + foreach ($python_files as $file) { + $file = pathinfo($file, PATHINFO_FILENAME); + $python_scripts[$file] = $file; + } +} +else { + $python_scripts = array('' => 'No Python Module scripts found'); +} + +$section->addInput(new Form_Select( + 'python_order', + 'Python Module Order', + $pconfig['python_order'], + [ 'pre_validator' => 'Pre Validator', 'post_validator' => 'Post Validator' ] +))->setHelp('Select the Python Module ordering.'); + +$section->addInput(new Form_Select( + 'python_script', + 'Python Module Script', + $pconfig['python_script'], + $python_scripts +))->setHelp('Select the Python module script to utilize.'); + $section->addInput(new Form_Checkbox( 'forwarding', 'DNS Query Forwarding', @@ -506,6 +558,17 @@ events.push(function() { hideGeneral(); show_advcustom(true); + // When the Python Module 'enable' is clicked, disable/enable the Python Module options + function show_python_script() { + var python = $('#python').prop('checked'); + hideInput('python_order', !python); + hideInput('python_script', !python); + } + show_python_script(); + $('#python').click(function () { + show_python_script(); + }); + }); //]]> From 241c4b583a72c0a6bff7def62a5c2bd00e0714cf Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Thu, 3 Jan 2019 23:18:32 -0500 Subject: [PATCH 2/5] Update unbound.inc --- src/etc/inc/unbound.inc | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/etc/inc/unbound.inc b/src/etc/inc/unbound.inc index 350cf56ccd..7044eea95a 100644 --- a/src/etc/inc/unbound.inc +++ b/src/etc/inc/unbound.inc @@ -115,6 +115,17 @@ function test_unbound_config($unboundcfg, &$output) { unbound_remote_control_setup($cfgsubdir); do_as_unbound_user("unbound-anchor", $cfgsubdir); + // Copy the Python files to the test folder + if (isset($unboundcfg['python']) && !empty($unboundcfg['python_script'])) { + $python_files = glob("{$g['unbound_chroot_path']}/{$unboundcfg['python_script']}.*"); + if (is_array($python_files)) { + foreach ($python_files as $file) { + $file = pathinfo($file, PATHINFO_BASENAME); + @copy("{$g['unbound_chroot_path']}/{$file}", "{$cfgdir}/{$file}"); + } + } + } + $rv = 0; exec("/usr/local/sbin/unbound-checkconf {$cfgdir}/unbound.conf 2>&1", $output, $rv); @@ -156,14 +167,26 @@ function unbound_generate_config_text($unboundcfg = NULL, $cfgsubdir = "") { // Setup optimization $optimization = unbound_optimization(); + $module_config = ''; + + // Setup Python module (pre validator) + if (isset($unboundcfg['python']) && !empty($unboundcfg['python_script']) && $unboundcfg['python_order'] == 'pre_validator') { + $module_config .= 'python '; + } + // Setup DNSSEC support if (isset($unboundcfg['dnssec'])) { - $module_config = "validator iterator"; + $module_config .= 'validator '; $anchor_file = "auto-trust-anchor-file: {$g['unbound_chroot_path']}{$cfgsubdir}/root.key"; - } else { - $module_config = "iterator"; } + // Setup Python module (post validator) + if (isset($unboundcfg['python']) && !empty($unboundcfg['python_script']) && $unboundcfg['python_order'] == 'post_validator') { + $module_config .= 'python '; + } + + $module_config .= 'iterator'; + // Setup DNS Rebinding if (!isset($config['system']['webgui']['nodnsrebindcheck'])) { // Private-addresses for DNS Rebinding @@ -371,6 +394,15 @@ EOD; } } + $python_module = ''; + if (isset($unboundcfg['python']) && !empty($unboundcfg['python_script'])) { + $python_path = ''; + if (!empty($cfgsubdir)) { + $python_path = "{$g['unbound_chroot_path']}{$cfgsubdir}/"; + } + $python_module = "\n# Python Module\npython:\npython-script: {$python_path}{$unboundcfg['python_script']}.py"; + } + $unboundconf = << Date: Mon, 7 Jan 2019 14:22:06 -0500 Subject: [PATCH 3/5] pfSense Unbound - Mount folders for python * DNS Resolver python integration --- src/etc/inc/services.inc | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/etc/inc/services.inc b/src/etc/inc/services.inc index 8fc5309f2c..757a41c96a 100644 --- a/src/etc/inc/services.inc +++ b/src/etc/inc/services.inc @@ -2204,6 +2204,50 @@ function services_unbound_configure($restart_dhcp = true) { } } + /* DNS Resolver python integration */ + $base_folder = '/usr/local'; + foreach (array('/bin', '/lib') as $dir) { + $validate = exec("/sbin/mount | /usr/bin/grep '{$g['unbound_chroot_path']}{$base_folder}{$dir}' 2>&1"); + if (isset($config['unbound']['python']) && !empty($config['unbound']['python_script'])) { + + // Add DNS Resolver python integration + if (empty($validate)) { + if (!is_dir("{$g['unbound_chroot_path']}{$base_folder}{$dir}")) { + exec("/bin/mkdir -p {$g['unbound_chroot_path']}{$base_folder}{$dir} 2>&1"); + } + exec("/sbin/mount_nullfs -o ro /usr/local{$dir} {$g['unbound_chroot_path']}{$base_folder}{$dir} 2>&1", $output, $retval); + + // Disable Unbound python on mount failure + if ($retval != 0) { + $config['unbound']['python'] = ''; + $log_msg = "[Unbound-pymod]: Disabling Unbound python due to failed mount"; + write_config($log_msg); + log_error($log_msg); + } + } + } + + // Remove DNS Resolver python integration + elseif (!empty($validate)) { + exec("/sbin/umount -t nullfs {$g['unbound_chroot_path']}{$base_folder}{$dir} 2>&1", $output, $retval); + if ($retval == 0) { + foreach (array( "/usr/local{$dir}", '/usr/local', '/usr') as $folder) { + if (is_dir("{$g['unbound_chroot_path']}{$folder}")) { + rmdir("{$g['unbound_chroot_path']}{$folder}"); + } + + // Delete remaining subfolders on next loop + if ($dir == '/bin') { + break; + } + } + } + else { + log_error("[Unbound-pymod]: Failed to unmount!"); + } + } + } + if (platform_booting()) { echo gettext("Starting DNS Resolver..."); } else { From 14b1c98d82d842bbdc3fe0ed556f3343f332541b Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Mon, 7 Jan 2019 16:53:31 -0500 Subject: [PATCH 4/5] Unbound python integration * Add changes as requested by @jim-p --- src/etc/inc/services.inc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/etc/inc/services.inc b/src/etc/inc/services.inc index 757a41c96a..7067228e72 100644 --- a/src/etc/inc/services.inc +++ b/src/etc/inc/services.inc @@ -2213,10 +2213,10 @@ function services_unbound_configure($restart_dhcp = true) { // Add DNS Resolver python integration if (empty($validate)) { if (!is_dir("{$g['unbound_chroot_path']}{$base_folder}{$dir}")) { - exec("/bin/mkdir -p {$g['unbound_chroot_path']}{$base_folder}{$dir} 2>&1"); + safe_mkdir("{$g['unbound_chroot_path']}{$base_folder}{$dir}"); } - exec("/sbin/mount_nullfs -o ro /usr/local{$dir} {$g['unbound_chroot_path']}{$base_folder}{$dir} 2>&1", $output, $retval); - + exec("/sbin/mount_nullfs -o ro " . escapeshellarg("/usr/local{$dir}") . " " . escapeshellarg("{$g['unbound_chroot_path']}{$base_folder}{$dir}") . " 2>&1", $output, $retval); + // Disable Unbound python on mount failure if ($retval != 0) { $config['unbound']['python'] = ''; @@ -2229,10 +2229,10 @@ function services_unbound_configure($restart_dhcp = true) { // Remove DNS Resolver python integration elseif (!empty($validate)) { - exec("/sbin/umount -t nullfs {$g['unbound_chroot_path']}{$base_folder}{$dir} 2>&1", $output, $retval); + exec("/sbin/umount -t nullfs " . escapeshellarg("{$g['unbound_chroot_path']}{$base_folder}{$dir}") . " 2>&1", $output, $retval); if ($retval == 0) { foreach (array( "/usr/local{$dir}", '/usr/local', '/usr') as $folder) { - if (is_dir("{$g['unbound_chroot_path']}{$folder}")) { + if (!empty($g['unbound_chroot_path']) && $g['unbound_chroot_path'] != '/' && is_dir("{$g['unbound_chroot_path']}{$folder}")) { rmdir("{$g['unbound_chroot_path']}{$folder}"); } From 6a4635fc80c0a0dc04a1a5505989ecd7189e4f4f Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Tue, 23 Apr 2019 20:29:24 -0400 Subject: [PATCH 5/5] Unbound python mod - services.inc * Include any additional functions as defined by python script include file * Add missing escapeshellarg()'s * Make grep mount validation cmd more specific to include "(nullfs" --- src/etc/inc/services.inc | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/etc/inc/services.inc b/src/etc/inc/services.inc index 7067228e72..b51e27c7b9 100644 --- a/src/etc/inc/services.inc +++ b/src/etc/inc/services.inc @@ -2204,19 +2204,35 @@ function services_unbound_configure($restart_dhcp = true) { } } + $python_mode = false; + if (isset($config['unbound']['python']) && !empty($config['unbound']['python_script'])) { + $python_mode = true; + } + + /* Include any additional functions as defined by python script include file */ + if (file_exists("{$g['unbound_chroot_path']}/{$config['unbound']['python_script']}_include.inc")) { + exec("/usr/local/bin/php -l " . escapeshellarg("{$g['unbound_chroot_path']}/{$config['unbound']['python_script']}_include.inc") + . " 2>&1", $py_output, $py_retval); + if ($py_retval == 0) { + require_once("{$g['unbound_chroot_path']}/{$config['unbound']['python_script']}_include.inc"); + } + } + /* DNS Resolver python integration */ $base_folder = '/usr/local'; foreach (array('/bin', '/lib') as $dir) { - $validate = exec("/sbin/mount | /usr/bin/grep '{$g['unbound_chroot_path']}{$base_folder}{$dir}' 2>&1"); - if (isset($config['unbound']['python']) && !empty($config['unbound']['python_script'])) { + $validate = exec("/sbin/mount | /usr/bin/grep " . escapeshellarg("{$g['unbound_chroot_path']}{$base_folder}{$dir} (nullfs") . " 2>&1"); + if ($python_mode) { // Add DNS Resolver python integration if (empty($validate)) { if (!is_dir("{$g['unbound_chroot_path']}{$base_folder}{$dir}")) { safe_mkdir("{$g['unbound_chroot_path']}{$base_folder}{$dir}"); } - exec("/sbin/mount_nullfs -o ro " . escapeshellarg("/usr/local{$dir}") . " " . escapeshellarg("{$g['unbound_chroot_path']}{$base_folder}{$dir}") . " 2>&1", $output, $retval); - + $output = $retval = ''; + exec("/sbin/mount_nullfs -o ro " . escapeshellarg("/usr/local{$dir}") . ' ' + . escapeshellarg("{$g['unbound_chroot_path']}{$base_folder}{$dir}") . " 2>&1", $output, $retval); + // Disable Unbound python on mount failure if ($retval != 0) { $config['unbound']['python'] = ''; @@ -2233,7 +2249,7 @@ function services_unbound_configure($restart_dhcp = true) { if ($retval == 0) { foreach (array( "/usr/local{$dir}", '/usr/local', '/usr') as $folder) { if (!empty($g['unbound_chroot_path']) && $g['unbound_chroot_path'] != '/' && is_dir("{$g['unbound_chroot_path']}{$folder}")) { - rmdir("{$g['unbound_chroot_path']}{$folder}"); + @rmdir(escapeshellarg("{$g['unbound_chroot_path']}{$folder}")); } // Delete remaining subfolders on next loop