diff options
Diffstat (limited to 'src/etc/inc/filter.inc')
-rw-r--r-- | src/etc/inc/filter.inc | 219 |
1 files changed, 129 insertions, 90 deletions
diff --git a/src/etc/inc/filter.inc b/src/etc/inc/filter.inc index 18cae55..a06b63e 100644 --- a/src/etc/inc/filter.inc +++ b/src/etc/inc/filter.inc @@ -1,5 +1,4 @@ <?php -/* $Id$ */ /* filter.inc Copyright (C) 2004-2006 Scott Ullrich @@ -32,10 +31,6 @@ 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. - - pfSense_BUILDER_BINARIES: /sbin/kldload /usr/sbin/tcpdump /sbin/pfctl /bin/rm - pfSense_BUILDER_BINARIES: /usr/sbin/inetd - pfSense_MODULE: filter */ @@ -278,8 +273,6 @@ function filter_configure_sync($delete_states_if_needed = true) { } update_filter_reload_status(gettext("Generating ALTQ queues")); $altq_queues = filter_generate_altq_queues(); - update_filter_reload_status(gettext("Generating Layer7 rules")); - generate_layer7_files(); if (platform_booting() == true) { echo "."; } @@ -433,31 +426,32 @@ function filter_configure_sync($delete_states_if_needed = true) { * then output the contents of the error to the caller */ if ($rules_loading <> 0) { - $saved_line_error = $rules_error[0]; - $line_error = explode(":", $rules_error[0]); - $line_number = $line_error[1]; - $line_split = file("{$g['tmp_path']}/rules.debug"); - if (is_array($line_split)) { - $line_error = sprintf(gettext('The line in question reads [%1$d]: %2$s'), $line_number, $line_split[$line_number-1]); - } - unset($line_split); - - /* Brutal ugly hack but required -- PF is stuck, unwedge */ - if (strstr("$rules_error[0]", "busy")) { - exec("/sbin/pfctl -d; /sbin/pfctl -e; /sbin/pfctl -f {$g['tmp_path']}/rules.debug"); - $error_msg = gettext("PF was wedged/busy and has been reset."); - file_notice("pf_busy", $error_msg, "pf_busy", ""); - } else { - $_grbg = exec("/sbin/pfctl -o basic -f {$g['tmp_path']}/rules.debug.old 2>&1"); + foreach ($rules_error as $errorline) { + $saved_line_error = $errorline; + $line_error = explode(":", $errorline); + $line_number = $line_error[1]; + $line_split = file("{$g['tmp_path']}/rules.debug"); + if (is_array($line_split)) { + $line_error = sprintf(gettext('The line in question reads [%1$d]: %2$s'), $line_number, $line_split[$line_number-1]); + } + unset($line_split); + + /* Brutal ugly hack but required -- PF is stuck, unwedge */ + if (strstr("$rules_error[0]", "busy")) { + exec("/sbin/pfctl -d; /sbin/pfctl -e; /sbin/pfctl -f {$g['tmp_path']}/rules.debug"); + $error_msg = gettext("PF was wedged/busy and has been reset."); + file_notice("pf_busy", $error_msg, "pf_busy", ""); + } else { + $_grbg = exec("/sbin/pfctl -o basic -f {$g['tmp_path']}/rules.debug.old 2>&1"); + } + if ($line_error and $line_number) { + file_notice("filter_load", sprintf(gettext('There were error(s) loading the rules: %1$s - %2$s'), $saved_line_error, $line_error), "Filter Reload", ""); + update_filter_reload_status(sprintf(gettext('There were error(s) loading the rules: %1$s - %2$s'), $saved_line_error, $line_error)); + unlock($filterlck); + return; + } } unset($rules_loading, $rules_error); - - if ($line_error and $line_number) { - file_notice("filter_load", sprintf(gettext('There were error(s) loading the rules: %1$s - %2$s'), $saved_line_error, $line_error), "Filter Reload", ""); - update_filter_reload_status(sprintf(gettext('There were error(s) loading the rules: %1$s - %2$s'), $saved_line_error, $line_error)); - unlock($filterlck); - return; - } } # If we are not using bogonsv6 then we can remove any bogonsv6 table from the running pf (if the table is not there, the kill is still fine). @@ -465,9 +459,6 @@ function filter_configure_sync($delete_states_if_needed = true) { $_grbg = exec("/sbin/pfctl -t bogonsv6 -T kill 2>/dev/null"); } - update_filter_reload_status(gettext("Starting up layer7 daemon")); - layer7_start_l7daemon(); - if (!platform_booting()) { if (!empty($filterdns)) { @file_put_contents("{$g['varetc_path']}/filterdns.conf", implode("", $filterdns)); @@ -934,13 +925,13 @@ function filter_get_vpns_list() { $vpns_arr = array(); /* ipsec */ - if (isset($config['ipsec']['enable'])) { + if (!function_exists('ipsec_enabled')) { + require_once("ipsec.inc"); + } + if (ipsec_enabled()) { if (is_array($config['ipsec']['phase2'])) { foreach ($config['ipsec']['phase2'] as $ph2ent) { if ((!$ph2ent['mobile']) && ($ph2ent['mode'] != 'transport')) { - if (!function_exists('ipsec_idinfo_to_cidr')) { - require_once("ipsec.inc"); - } if (!is_array($ph2ent['remoteid'])) { continue; } @@ -1067,7 +1058,6 @@ function filter_generate_optcfg_array() { echo "filter_generate_optcfg_array() being called $mt\n"; } - read_layer7_config(); /* if list */ $iflist = get_configured_interface_with_descr(); foreach ($iflist as $if => $ifdetail) { @@ -1172,7 +1162,10 @@ function filter_generate_optcfg_array() { } } /* add ipsec interfaces */ - if (isset($config['ipsec']['enable']) || isset($config['ipsec']['client']['enable'])) { + if (!function_exists('ipsec_enabled')) { + require_once("ipsec.inc"); + } + if (ipsec_enabled()) { $oic = array(); $oic['if'] = 'enc0'; $oic['descr'] = 'IPsec'; @@ -1329,12 +1322,12 @@ function filter_generate_reflection_nat($rule, &$route_table, $nat_ifs, $protoco return $natrules; } -function filter_generate_reflection_proxy($rule, $nordr, $rdr_ifs, $srcaddr, $dstaddr_port, &$starting_localhost_port, &$reflection_txt) { +function filter_generate_reflection_proxy($rule, $nordr, $rdr_ifs, $srcaddr, $dstaddr_port, &$starting_localhost_port, &$reflection_rules) { global $FilterIflist, $config; // Initialize natrules holder string $natrules = ""; - $reflection_txt = array(); + $reflection_rules = array(); if (!empty($rdr_ifs)) { if ($config['system']['reflectiontimeout']) { @@ -1509,17 +1502,27 @@ function filter_generate_reflection_proxy($rule, $nordr, $rdr_ifs, $srcaddr, $ds if ($reflect_proto == "udp") { $socktype = "dgram"; $dash_u = "-u "; - $wait = "wait\t"; + $wait = "yes"; } else { $socktype = "stream"; $dash_u = ""; - $wait = "nowait/0"; + $wait = "no"; } foreach ($rtarget as $targip) { if (empty($targip)) { continue; } - $reflection_txt[] = "{$inetdport}\t{$socktype}\t{$reflect_proto}\t{$wait}\tnobody\t/usr/bin/nc\tnc {$dash_u}-w {$reflectiontimeout} {$targip} {$tda}\n"; + $reflection_rule = array( + 'port' => $inetdport, + 'socket_type' => $socktype, + 'protocol' => $reflect_proto, + 'wait' => $wait, + 'user' => 'nobody', + 'server' => '/usr/bin/nc', + 'server_args' => "{$dash_u}-w {$reflectiontimeout} {$targip} {$tda}" + ); + $reflection_rules[] = $reflection_rule; + unset($reflection_rule); } } $inetdport++; @@ -1532,8 +1535,6 @@ function filter_generate_reflection_proxy($rule, $nordr, $rdr_ifs, $srcaddr, $ds break; } } - - $reflection_txt = array_unique($reflection_txt); } return $natrules; @@ -1787,6 +1788,26 @@ function filter_nat_rules_generate_if ($if, $src = "any", $srcport = "", $dst = return $natrule; } +function xinetd_service_entry($entry_array) { + $entry = <<<EOD +service {$entry_array['port']}-{$entry_array['protocol']} +{ + type = unlisted + bind = 127.0.0.1 + port = {$entry_array['port']} + socket_type = {$entry_array['socket_type']} + protocol = {$entry_array['protocol']} + wait = {$entry_array['wait']} + user = {$entry_array['user']} + server = {$entry_array['server']} + server_args = {$entry_array['server_args']} +} + + +EOD; + return $entry; +} + function filter_nat_rules_generate() { global $config, $g, $after_filter_configure_run, $FilterIflist, $GatewaysList, $aliases; @@ -1896,12 +1917,19 @@ function filter_nat_rules_generate() { } /* ipsec nat */ - if (is_array($config['ipsec']) && isset($config['ipsec']['enable'])) { + if (!function_exists('ipsec_enabled')) { + require_once("ipsec.inc"); + } + if (ipsec_enabled()) { if (is_array($config['ipsec']['phase2'])) { foreach ($config['ipsec']['phase2'] as $ph2ent) { - if ($ph2ent['mode'] != 'transport' && !empty($ph2ent['natlocalid'])) { - if (!function_exists('ipsec_idinfo_to_cidr')) { - require_once("ipsec.inc"); + if ($ph2ent['mode'] != 'transport' && !empty($ph2ent['natlocalid']) && !isset($ph2ent['disabled'])) { + ipsec_lookup_phase1($ph2ent, $ph1ent); + if (!is_array($ph1ent)) { + continue; + } + if (isset($ph1ent['disabled'])) { + continue; } if (!is_array($ph2ent['localid'])) { $ph2ent['localid'] = array(); @@ -2069,13 +2097,21 @@ function filter_nat_rules_generate() { $natrules .= "rdr on \${$FilterIflist['wan']['descr']} proto ipv6 from any to any -> {$config['diag']['ipv6nat']['ipaddr']}\n"; } - if (file_exists("/var/etc/inetd.conf")) { - @unlink("/var/etc/inetd.conf"); - } - // Open inetd.conf write handle - $inetd_fd = fopen("/var/etc/inetd.conf", "w"); + unlink_if_exists("{$g['varetc_path']}/xinetd.conf"); + // Open xinetd.conf write handle + $xinetd_fd = fopen("{$g['varetc_path']}/xinetd.conf", "w"); + /* add tftp protocol helper */ - fwrite($inetd_fd, "tftp-proxy\tdgram\tudp\twait\t\troot\t/usr/libexec/tftp-proxy\ttftp-proxy -v\n"); + $ftp_proxy_entry = array( + 'port' => 6969, + 'socket_type' => 'dgram', + 'protocol' => 'udp', + 'wait' => 'yes', + 'user' => 'root', + 'server' => '/usr/libexec/tftp-proxy', + 'server_args' => '-v' + ); + fwrite($xinetd_fd, xinetd_service_entry($ftp_proxy_entry)); if (isset($config['nat']['rule'])) { /* start reflection redirects on port 19000 of localhost */ @@ -2257,8 +2293,8 @@ function filter_nat_rules_generate() { if ($reflection_type == "proxy" && !isset($rule['nordr'])) { $natrules .= filter_generate_reflection_proxy($rule, $nordr, $nat_if_list, $srcaddr, $dstaddr, $starting_localhost_port, $reflection_rules); $nat_if_list = array($natif); - foreach ($reflection_rules as $txtline) { - fwrite($inetd_fd, $txtline); + foreach ($reflection_rules as $reflection_rule) { + fwrite($xinetd_fd, xinetd_service_entry($reflection_rule)); } } else if ($reflection_type == "purenat" || isset($rule['nordr'])) { $rdr_if_list = implode(" ", $nat_if_list); @@ -2282,7 +2318,7 @@ function filter_nat_rules_generate() { } } } - fclose($inetd_fd); // Close file handle + fclose($xinetd_fd); // Close file handle $natrules .= discover_pkg_rules("nat"); @@ -2293,13 +2329,15 @@ function filter_nat_rules_generate() { $natrules .= "\n# Reflection redirects and NAT for 1:1 mappings\n" . $reflection_txt; } - // Check if inetd is running, if not start it. If so, restart it gracefully. - $helpers = isvalidproc("inetd"); - if (file_exists("/var/etc/inetd.conf")) { - if (!$helpers) { - mwexec("/usr/sbin/inetd -wW -R 0 -a 127.0.0.1 /var/etc/inetd.conf"); + // Check if xinetd is running, if not start it. If so, restart it gracefully. + if (file_exists("{$g['varetc_path']}/xinetd.conf")) { + if (isvalidpid("{$g['varrun_path']}/xinetd.pid")) { + sigkillbypid("{$g['varrun_path']}/xinetd.pid", "HUP"); } else { - sigkillbypid("/var/run/inetd.pid", "HUP"); + mwexec("/usr/local/sbin/xinetd " . + "-syslog daemon " . + "-f {$g['varetc_path']}/xinetd.conf " . + "-pidfile {$g['varrun_path']}/xinetd.pid"); } } @@ -2558,7 +2596,7 @@ function filter_generate_address(& $rule, $target = "source", $isnat = false) { function filter_generate_user_rule($rule) { global $config, $g, $FilterIflist, $GatewaysList; - global $layer7_rules_list, $dummynet_name_list; + global $dummynet_name_list; if (isset($config['system']['developerspew'])) { $mt = microtime(); @@ -2668,7 +2706,7 @@ function filter_generate_user_rule($rule) { $rg = get_interface_gateway($rule['interface']); if (is_ipaddrv4($rg)) { $aline['reply'] = "reply-to ( {$ifcfg['if']} {$rg} ) "; - } + } } } /* if user has selected a custom gateway, lets work with it */ @@ -2719,15 +2757,6 @@ function filter_generate_user_rule($rule) { } $aline['dst'] = "to $dst "; - //Layer7 support - $l7_present = false; - $l7_structures = array(); - if (isset($rule['l7container']) && $rule['l7container'] != "none") { - $l7_present = true; - $l7rule =& $layer7_rules_list[$rule['l7container']]; - $l7_structures = $l7rule->get_unique_structures(); - $aline['divert'] = "divert-to " . $l7rule->GetRPort() . " "; - } if (($rule['protocol'] == "icmp") && $rule['icmptype'] && ($rule['ipprotocol'] == "inet")) { $aline['icmp-type'] = "icmp-type {$rule['icmptype']} "; } @@ -2866,7 +2895,7 @@ function filter_generate_user_rule($rule) { $rule['nopfsync'] = true; } - if ($noadvoptions == false || $l7_present) { + if ($noadvoptions == false) { if ((isset($rule['source-track']) and $rule['source-track'] <> "") or (isset($rule['max']) and $rule['max'] <> "") or (isset($rule['max-src-nodes']) and $rule['max-src-nodes'] <> "") or @@ -2877,8 +2906,7 @@ function filter_generate_user_rule($rule) { (isset($rule['max-src-conn-rate']) and $rule['max-src-conn-rate'] <> "") or (isset($rule['max-src-conn-rates']) and $rule['max-src-conn-rates'] <> ""))) or (isset($rule['sloppy'])) or - (isset($rule['nopfsync'])) or - ($l7_present)) { + (isset($rule['nopfsync']))) { $aline['flags'] .= "( "; if (isset($rule['sloppy'])) { $aline['flags'] .= "sloppy "; @@ -2917,10 +2945,6 @@ function filter_generate_user_rule($rule) { $aline['flags'] .= "/" . $rule['max-src-conn-rates'] . ", overload <virusprot> flush global "; } - if (!empty($aline['divert'])) { - $aline['flags'] .= "max-packets 8 "; - } - $aline['flags'] .= " ) "; } } @@ -2991,7 +3015,7 @@ function filter_generate_user_rule($rule) { /* piece together the actual user rule */ $line .= $aline['type'] . $aline['direction'] . $aline['log'] . $aline['quick'] . $aline['interface'] . $aline['reply'] . $aline['route'] . $aline['ipprotocol'] . $aline['prot'] . $aline['src'] . $aline['os'] . $aline['dst'] . - $aline['divert'] . $aline['icmp-type'] . $aline['icmp6-type'] . $aline['tag'] . $aline['tagged'] . $aline['dscp'] . $aline['tracker'] . + $aline['icmp-type'] . $aline['icmp6-type'] . $aline['tag'] . $aline['tagged'] . $aline['dscp'] . $aline['tracker'] . $aline['vlanprio'] . $aline['vlanprioset'] . $aline['allowopts'] . $aline['flags'] . $aline['queue'] . $aline['dnpipe'] . $aline['schedlabel']; unset($aline); @@ -3333,6 +3357,19 @@ EOD; } } + /* allow access to DHCP relay on interfaces */ + if (isset($config['dhcrelay']['enable'])) { + $dhcifaces = explode(",", $dhcrelaycfg['interface']); + foreach ($dhcifaces as $dhcrelayif) { + if ($dhcrelayif == $on) { + $ipfrules .= <<<EOD +# allow access to DHCP relay on {$oc['descr']} +pass in {$log['pass']} quick on \${$oc['descr']} proto udp from any port = 68 to 255.255.255.255 port = 67 tracker {$increment_tracker($tracker)} label "allow access to DHCP relay" + +EOD; + } + } + } break; } @@ -3460,7 +3497,10 @@ EOD; $saved_tracker += 300; $tracker = $saved_tracker; /* add ipsec interfaces */ - if (isset($config['ipsec']['enable']) || isset($config['ipsec']['client']['enable'])) { + if (!function_exists('ipsec_enabled')) { + require_once("ipsec.inc"); + } + if (ipsec_enabled()) { $ipfrules .= "pass out {$log['pass']} on \$IPsec all tracker {$increment_tracker($tracker)} tracker {$increment_tracker($tracker)} keep state label \"IPsec internal host to host\"\n"; } @@ -3948,8 +3988,10 @@ function filter_generate_ipsec_rules($log = array()) { $increment_tracker = 'filter_rule_tracker'; $ipfrules = "\n# VPN Rules\n"; - if ((isset($config['ipsec']['enable'])) && - (is_array($config['ipsec']['phase1']))) { + if (!function_exists('ipsec_enabled')) { + require_once("ipsec.inc"); + } + if (ipsec_enabled()) { /* step through all phase1 entries */ foreach ($config['ipsec']['phase1'] as $ph1ent) { $tracker += 10; @@ -3959,9 +4001,6 @@ function filter_generate_ipsec_rules($log = array()) { } /* determine local and remote peer addresses */ if (!isset($ph1ent['mobile'])) { - if (!function_exists('ipsec_get_phase1_dst')) { - require_once("ipsec.inc"); - } $rgip = ipsec_get_phase1_dst($ph1ent); if (!$rgip) { $ipfrules .= "# ERROR! Unable to determine remote IPsec peer address for {$ph1ent['remote-gateway']}\n"; |