X-Git-Url: http://git.ipfire.org/?p=ipfire-2.x.git;a=blobdiff_plain;f=config%2Ffirewall%2Frules.pl;h=cd2f3a63590cb2428d7ba9e0fbcbc7f3bf4fa22e;hp=50fff3f09f97f28726eed8f733000845b89342af;hb=bc9446c65ff048ebce8c0665cc0efe2231fb37de;hpb=296a73a5326636a53c642dcd046b03fcff221835 diff --git a/config/firewall/rules.pl b/config/firewall/rules.pl old mode 100755 new mode 100644 index 50fff3f09f..cd2f3a6359 --- a/config/firewall/rules.pl +++ b/config/firewall/rules.pl @@ -47,32 +47,41 @@ my @PROTOCOLS_WITH_PORTS = ("tcp", "udp"); my @VALID_TARGETS = ("ACCEPT", "DROP", "REJECT"); my %fwdfwsettings=(); +my %fwoptions = (); my %defaultNetworks=(); my %configfwdfw=();; my %customgrp=(); my %configinputfw=(); my %configoutgoingfw=(); my %confignatfw=(); -my %aliases=(); my @p2ps=(); my $configfwdfw = "${General::swroot}/firewall/config"; my $configinput = "${General::swroot}/firewall/input"; my $configoutgoing = "${General::swroot}/firewall/outgoing"; my $p2pfile = "${General::swroot}/firewall/p2protocols"; +my $geoipfile = "${General::swroot}/firewall/geoipblock"; my $configgrp = "${General::swroot}/fwhosts/customgroups"; my $netsettings = "${General::swroot}/ethernet/settings"; &General::readhash("${General::swroot}/firewall/settings", \%fwdfwsettings); +&General::readhash("${General::swroot}/optionsfw/settings", \%fwoptions); &General::readhash("$netsettings", \%defaultNetworks); &General::readhasharray($configfwdfw, \%configfwdfw); &General::readhasharray($configinput, \%configinputfw); &General::readhasharray($configoutgoing, \%configoutgoingfw); &General::readhasharray($configgrp, \%customgrp); -&General::get_aliases(\%aliases); my @log_limit_options = &make_log_limit_options(); +my $POLICY_INPUT_ALLOWED = 0; +my $POLICY_FORWARD_ALLOWED = ($fwdfwsettings{"POLICY"} eq "MODE2"); +my $POLICY_OUTPUT_ALLOWED = ($fwdfwsettings{"POLICY1"} eq "MODE2"); + +my $POLICY_INPUT_ACTION = $fwoptions{"FWPOLICY2"}; +my $POLICY_FORWARD_ACTION = $fwoptions{"FWPOLICY"}; +my $POLICY_OUTPUT_ACTION = $fwoptions{"FWPOLICY1"}; + # MAIN &main(); @@ -86,6 +95,9 @@ sub main { # Load P2P block rules. &p2pblock(); + # Load GeoIP block rules. + &geoipblock(); + # Reload firewall policy. run("/usr/sbin/firewall-policy"); } @@ -123,6 +135,12 @@ sub print_rule { print "\n"; } +sub count_elements { + my $hash = shift; + + return scalar @$hash; +} + sub flush { run("$IPTABLES -F $CHAIN_INPUT"); run("$IPTABLES -F $CHAIN_FORWARD"); @@ -133,24 +151,54 @@ sub flush { } sub preparerules { - if (! -z "${General::swroot}/firewall/config"){ - &buildrules(\%configfwdfw); - } if (! -z "${General::swroot}/firewall/input"){ &buildrules(\%configinputfw); } if (! -z "${General::swroot}/firewall/outgoing"){ &buildrules(\%configoutgoingfw); } + if (! -z "${General::swroot}/firewall/config"){ + &buildrules(\%configfwdfw); + } } sub buildrules { my $hash = shift; + # Search for targets that need to be specially handled when adding + # forwarding rules. Additional rules will automatically get inserted + # into the INPUT/OUTPUT chains for these targets. + my @special_input_targets = (); + if (!$POLICY_FORWARD_ALLOWED) { + push(@special_input_targets, "ACCEPT"); + } + + if ($POLICY_INPUT_ACTION eq "DROP") { + push(@special_input_targets, "REJECT"); + } elsif ($POLICY_INPUT_ACTION eq "REJECT") { + push(@special_input_targets, "DROP"); + } + + my @special_output_targets = (); + if ($POLICY_OUTPUT_ALLOWED) { + push(@special_output_targets, ("DROP", "REJECT")); + } else { + push(@special_output_targets, "ACCEPT"); + + if ($POLICY_OUTPUT_ACTION eq "DROP") { + push(@special_output_targets, "REJECT"); + } elsif ($POLICY_OUTPUT_ACTION eq "REJECT") { + push(@special_output_targets, "DROP"); + } + } + foreach my $key (sort {$a <=> $b} keys %$hash) { # Skip disabled rules. next unless ($$hash{$key}[2] eq 'ON'); + # Count number of elements in this line + my $elements = &count_elements($$hash{$key}); + if ($DEBUG) { print_rule($$hash{$key}); } @@ -170,10 +218,13 @@ sub buildrules { } # Collect all sources. - my @sources = &get_addresses($hash, $key, "src"); + my @sources = &fwlib::get_addresses($hash, $key, "src"); # Collect all destinations. - my @destinations = &get_addresses($hash, $key, "tgt"); + my @destinations = &fwlib::get_addresses($hash, $key, "tgt"); + + # True if the destination is the firewall itself. + my $destination_is_firewall = ($$hash{$key}[5] eq "ipfire"); # Check if logging should be enabled. my $LOG = ($$hash{$key}[17] eq 'ON'); @@ -230,6 +281,34 @@ sub buildrules { } } + # Concurrent connection limit + my @ratelimit_options = (); + + if (($elements ge 34) && ($$hash{$key}[32] eq 'ON')) { + my $conn_limit = $$hash{$key}[33]; + + if ($conn_limit ge 1) { + push(@ratelimit_options, ("-m", "connlimit")); + + # Use the the entire source IP address + push(@ratelimit_options, "--connlimit-saddr"); + push(@ratelimit_options, ("--connlimit-mask", "32")); + + # Apply the limit + push(@ratelimit_options, ("--connlimit-upto", $conn_limit)); + } + } + + # Ratelimit + if (($elements ge 37) && ($$hash{$key}[34] eq 'ON')) { + my $rate_limit = "$$hash{$key}[35]/$$hash{$key}[36]"; + + if ($rate_limit) { + push(@ratelimit_options, ("-m", "limit")); + push(@ratelimit_options, ("--limit", $rate_limit)); + } + } + # Check which protocols are used in this rule and so that we can # later group rules by protocols. my @protocols = &get_protocols($hash, $key); @@ -246,32 +325,42 @@ sub buildrules { } # Prepare protocol options (like ICMP types, ports, etc...). - my @protocol_options = &get_protocol_options($hash, $key, $protocol); + my @protocol_options = &get_protocol_options($hash, $key, $protocol, 0); # Check if this protocol knows ports. my $protocol_has_ports = ($protocol ~~ @PROTOCOLS_WITH_PORTS); - foreach my $source (@sources) { - foreach my $destination (@destinations) { - # Skip invalid rules. - next if (!$source || !$destination || ($destination eq "none")); + foreach my $src (@sources) { + # Skip invalid source. + next unless (defined $src); + next unless ($src); - # Sanitize source. - if ($source ~~ @ANY_ADDRESSES) { - $source = ""; - } + # Sanitize source. + my $source = @$src[0]; + if ($source ~~ @ANY_ADDRESSES) { + $source = ""; + } + + my $source_intf = @$src[1]; + + foreach my $dst (@destinations) { + # Skip invalid rules. + next unless (defined $dst); + next if (!$dst || ($dst eq "none")); # Sanitize destination. + my $destination = @$dst[0]; if ($destination ~~ @ANY_ADDRESSES) { $destination = ""; } + my $destination_intf = @$dst[1]; + # Array with iptables arguments. my @options = (); # Append protocol. if ($protocol ne "all") { - push(@options, ("-p", $protocol)); push(@options, @protocol_options); } @@ -292,14 +381,22 @@ sub buildrules { # Add time constraint options. push(@options, @time_options); - my $firewall_is_in_source_subnet = 0; + # Add ratelimiting option + push(@options, @ratelimit_options); + + my $firewall_is_in_source_subnet = 1; if ($source) { $firewall_is_in_source_subnet = &firewall_is_in_subnet($source); } + my $firewall_is_in_destination_subnet = 1; + if ($destination) { + $firewall_is_in_destination_subnet = &firewall_is_in_subnet($destination); + } + # Process NAT rules. if ($NAT) { - my $nat_address = &get_nat_address($$hash{$key}[29], $source); + my $nat_address = &fwlib::get_nat_address($$hash{$key}[29], $source); # Skip NAT rules if the NAT address is unknown # (i.e. no internet connection has been established, yet). @@ -307,31 +404,59 @@ sub buildrules { # Destination NAT if ($NAT_MODE eq "DNAT") { + my @nat_options = (); + if ($protocol ne "all") { + my @nat_protocol_options = &get_protocol_options($hash, $key, $protocol, 1); + push(@nat_options, @nat_protocol_options); + } + push(@nat_options, @time_options); + # Make port-forwardings useable from the internal networks. - my @internal_addresses = &get_internal_firewall_ip_addresses(1); + my @internal_addresses = &fwlib::get_internal_firewall_ip_addresses(1); unless ($nat_address ~~ @internal_addresses) { - &add_dnat_mangle_rules($nat_address, @options); + &add_dnat_mangle_rules($nat_address, $source_intf, @nat_options); } - my @nat_options = @options; push(@nat_options, @source_options); push(@nat_options, ("-d", $nat_address)); - my ($dnat_address, $dnat_mask) = split("/", $destination); - @destination_options = ("-d", $dnat_address); - + my $dnat_port; if ($protocol_has_ports) { - my $dnat_port = &get_dnat_target_port($hash, $key); + $dnat_port = &get_dnat_target_port($hash, $key); + } + + my @nat_action_options = (); + + # Use iptables REDIRECT + my $use_redirect = ($destination_is_firewall && !$destination && $protocol_has_ports && $dnat_port); + if ($use_redirect) { + push(@nat_action_options, ("-j", "REDIRECT", "--to-ports", $dnat_port)); + + # Use iptables DNAT + } else { + if ($destination_is_firewall && !$destination) { + $destination = &fwlib::get_external_address(); + } + next unless ($destination); + + my ($dnat_address, $dnat_mask) = split("/", $destination); + @destination_options = ("-d", $dnat_address); + + if ($protocol_has_ports) { + my $dnat_port = &get_dnat_target_port($hash, $key); - if ($dnat_port) { - $dnat_address .= ":$dnat_port"; + if ($dnat_port) { + $dnat_address .= ":$dnat_port"; + } } + + push(@nat_action_options, ("-j", "DNAT", "--to-destination", $dnat_address)); } if ($LOG) { run("$IPTABLES -t nat -A $CHAIN_NAT_DESTINATION @nat_options @log_limit_options -j LOG --log-prefix 'DNAT '"); } - run("$IPTABLES -t nat -A $CHAIN_NAT_DESTINATION @nat_options -j DNAT --to-destination $dnat_address"); + run("$IPTABLES -t nat -A $CHAIN_NAT_DESTINATION @nat_options @nat_action_options"); # Source NAT } elsif ($NAT_MODE eq "SNAT") { @@ -347,15 +472,18 @@ sub buildrules { } } - push(@options, @source_options); + # Add source and destination interface to the filter rules. + # These are supposed to help filtering forged packets that originate + # from BLUE with an IP address from GREEN for instance. + if ($source_intf) { + push(@source_options, ("-i", $source_intf)); + } - if ($firewall_is_in_source_subnet && ($fwdfwsettings{"POLICY"} eq "MODE1") && ($chain eq $CHAIN_FORWARD)) { - if ($LOG && !$NAT) { - run("$IPTABLES -A $CHAIN_INPUT @options @log_limit_options -j LOG --log-prefix '$CHAIN_INPUT '"); - } - run("$IPTABLES -A $CHAIN_INPUT @options -j $target"); + if ($destination_intf) { + push(@destination_options, ("-o", $destination_intf)); } + push(@options, @source_options); push(@options, @destination_options); # Insert firewall rule. @@ -363,69 +491,35 @@ sub buildrules { run("$IPTABLES -A $chain @options @log_limit_options -j LOG --log-prefix '$chain '"); } run("$IPTABLES -A $chain @options -j $target"); - } - } - } - } -} - -sub get_external_interface() { - open(IFACE, "/var/ipfire/red/iface") or return ""; - my $iface = ; - close(IFACE); - return $iface; -} - -sub get_external_address() { - open(ADDR, "/var/ipfire/red/local-ipaddress") or return ""; - my $address = ; - close(ADDR); - - return $address; -} - -sub get_alias { - my $id = shift; - - foreach my $alias (sort keys %aliases) { - if ($id eq $alias) { - return $aliases{$alias}; - } - } -} - -sub get_nat_address { - my $zone = shift; - my $source = shift; - - # Any static address of any zone. - if ($zone eq "AUTO") { - if ($source) { - my $firewall_ip = &get_internal_firewall_ip_address($source, 1); - if ($firewall_ip) { - return $firewall_ip; - } + # Handle forwarding rules and add corresponding rules for firewall access. + if ($chain eq $CHAIN_FORWARD) { + # If the firewall is part of the destination subnet and access to the destination network + # is granted/forbidden for any network that the firewall itself is part of, we grant/forbid access + # for the firewall, too. + if ($firewall_is_in_destination_subnet && ($target ~~ @special_input_targets)) { + if ($LOG && !$NAT) { + run("$IPTABLES -A $CHAIN_INPUT @options @log_limit_options -j LOG --log-prefix '$CHAIN_INPUT '"); + } + run("$IPTABLES -A $CHAIN_INPUT @options -j $target"); + } - $firewall_ip = &get_matching_firewall_address($source, 1); - if ($firewall_ip) { - return $firewall_ip; + # Likewise. + if ($firewall_is_in_source_subnet && ($target ~~ @special_output_targets)) { + if ($LOG && !$NAT) { + run("$IPTABLES -A $CHAIN_OUTPUT @options @log_limit_options -j LOG --log-prefix '$CHAIN_OUTPUT '"); + } + run("$IPTABLES -A $CHAIN_OUTPUT @options -j $target"); + } + } + } } } - - return &get_external_address(); - - } elsif ($zone eq "RED" || $zone eq "GREEN" || $zone eq "ORANGE" || $zone eq "BLUE") { - return $defaultNetworks{$zone . "_ADDRESS"}; - - } elsif ($zone eq "Default IP") { - return &get_external_address(); - - } else { - return &get_alias($zone); } - - print_error("Could not find NAT address"); + #Reload firewall.local if present + if ( -f '/etc/sysconfig/firewall.local'){ + run("/etc/sysconfig/firewall.local reload"); + } } # Formats the given timestamp into the iptables format which is "hh:mm" UTC. @@ -467,179 +561,54 @@ sub time_convert_to_minutes { } sub p2pblock { - my $P2PSTRING = ""; - my $DO; - open( FILE, "< $p2pfile" ) or die "Unable to read $p2pfile"; - @p2ps = ; - close FILE; - my $CMD = "-m ipp2p"; - foreach my $p2pentry (sort @p2ps) { - my @p2pline = split( /\;/, $p2pentry ); - if ( $fwdfwsettings{'POLICY'} eq 'MODE1' ) { - $DO = "ACCEPT"; - if ("$p2pline[2]" eq "on") { - $P2PSTRING = "$P2PSTRING --$p2pline[1]"; - } - }else { - $DO = "RETURN"; - if ("$p2pline[2]" eq "off") { - $P2PSTRING = "$P2PSTRING --$p2pline[1]"; - } - } - } + open(FILE, "<$p2pfile") or die "Unable to read $p2pfile"; + my @protocols = (); + foreach my $p2pentry () { + my @p2pline = split(/\;/, $p2pentry); + next unless ($p2pline[2] eq "off"); - if($P2PSTRING) { - run("$IPTABLES -A FORWARDFW $CMD $P2PSTRING -j $DO"); + push(@protocols, "--$p2pline[1]"); } -} + close(FILE); -sub get_addresses { - my $hash = shift; - my $key = shift; - my $type = shift; - - my @addresses = (); - my $addr_type; - my $value; - my $group_name; - - if ($type eq "src") { - $addr_type = $$hash{$key}[3]; - $value = $$hash{$key}[4]; - - } elsif ($type eq "tgt") { - $addr_type = $$hash{$key}[5]; - $value = $$hash{$key}[6]; + run("$IPTABLES -F P2PBLOCK"); + if (@protocols) { + run("$IPTABLES -A P2PBLOCK -m ipp2p @protocols -j DROP"); } +} - if ($addr_type ~~ ["cust_grp_src", "cust_grp_tgt"]) { - foreach my $grp (sort {$a <=> $b} keys %customgrp) { - if ($customgrp{$grp}[0] eq $value) { - my @address = &get_address($customgrp{$grp}[3], $customgrp{$grp}[2], $type); +sub geoipblock { + my %geoipsettings = (); - if (@address) { - push(@addresses, @address); - } - } - } + # Check if the geoip settings file exists + if (-e "$geoipfile") { + # Read settings file + &General::readhash("$geoipfile", \%geoipsettings); } else { - my @address = &get_address($addr_type, $value, $type); - - if (@address) { - push(@addresses, @address); - } + # Exit submodule, go on processing the remaining script + return; } - return @addresses; -} - -sub get_address { - my $key = shift; - my $value = shift; - my $type = shift; - - my @ret = (); - - # If the user manually typed an address, we just check if it is a MAC - # address. Otherwise, we assume that it is an IP address. - if ($key ~~ ["src_addr", "tgt_addr"]) { - if (&General::validmac($value)) { - push(@ret, "-m mac --mac-source $value"); - } else { - push(@ret, $value); - } - - # If a default network interface (GREEN, BLUE, etc.) is selected, we - # try to get the corresponding address of the network. - } elsif ($key ~~ ["std_net_src", "std_net_tgt", "Standard Network"]) { - my $external_interface = &get_external_interface(); - - my $network_address = &fwlib::get_std_net_ip($value, $external_interface); - if ($network_address) { - push(@ret, $network_address); - } - - # Custom networks. - } elsif ($key ~~ ["cust_net_src", "cust_net_tgt", "Custom Network"]) { - my $network_address = &fwlib::get_net_ip($value); - if ($network_address) { - push(@ret, $network_address); - } - - # Custom hosts. - } elsif ($key ~~ ["cust_host_src", "cust_host_tgt", "Custom Host"]) { - my $host_address = &fwlib::get_host_ip($value, $type); - if ($host_address) { - push(@ret, $host_address); - } - - # OpenVPN networks. - } elsif ($key ~~ ["ovpn_net_src", "ovpn_net_tgt", "OpenVPN static network"]) { - my $network_address = &fwlib::get_ovpn_net_ip($value, 1); - if ($network_address) { - push(@ret, $network_address); - } - - # OpenVPN hosts. - } elsif ($key ~~ ["ovpn_host_src", "ovpn_host_tgt", "OpenVPN static host"]) { - my $host_address = &fwlib::get_ovpn_host_ip($value, 33); - if ($host_address) { - push(@ret, $host_address); - } - - # OpenVPN N2N. - } elsif ($key ~~ ["ovpn_n2n_src", "ovpn_n2n_tgt", "OpenVPN N-2-N"]) { - my $network_address = &fwlib::get_ovpn_n2n_ip($value, 11); - if ($network_address) { - push(@ret, $network_address); - } + # If geoip blocking is not enabled, we are finished here. + if ($geoipsettings{'GEOIPBLOCK_ENABLED'} ne "on") { + # Exit submodule. Process remaining script. + return; + } - # IPsec networks. - } elsif ($key ~~ ["ipsec_net_src", "ipsec_net_tgt", "IpSec Network"]) { - my $network_address = &fwlib::get_ipsec_net_ip($value, 11); - if ($network_address) { - push(@ret, $network_address); - } + # Get supported locations. + my @locations = &fwlib::get_geoip_locations(); - # The firewall's own IP addresses. - } elsif ($key ~~ ["ipfire", "ipfire_src"]) { - # ALL - if ($value eq "ALL") { - push(@ret, "0/0"); - - # GREEN - } elsif ($value eq "GREEN") { - push(@ret, $defaultNetworks{"GREEN_ADDRESS"}); - - # BLUE - } elsif ($value eq "BLUE") { - push(@ret, $defaultNetworks{"BLUE_ADDRESS"}); - - # ORANGE - } elsif ($value eq "ORANGE") { - push(@ret, $defaultNetworks{"ORANGE_ADDRESS"}); - - # RED - } elsif ($value ~~ ["RED", "RED1"]) { - my $address = &get_external_address(); - if ($address) { - push(@ret, $address); - } + # Create iptables chain. + run("$IPTABLES -F GEOIPBLOCK"); - # Aliases - } else { - my %alias = &get_alias($value); - if (%alias) { - push(@ret, $alias{"IPT"}); - } + # Loop through all supported geoip locations and + # create iptables rules, if blocking this country + # is enabled. + foreach my $location (@locations) { + if($geoipsettings{$location} eq "on") { + run("$IPTABLES -A GEOIPBLOCK -m geoip --src-cc $location -j DROP"); } - - # If nothing was selected, we assume "any". - } else { - push(@ret, "0/0"); } - - return @ret; } sub get_protocols { @@ -701,45 +670,55 @@ sub get_protocol_options { my $hash = shift; my $key = shift; my $protocol = shift; + my $nat_options_wanted = shift; my @options = (); - # Process source ports. - my $use_src_ports = ($$hash{$key}[7] eq "ON"); - my $src_ports = $$hash{$key}[10]; - - if ($use_src_ports && $src_ports) { - push(@options, &format_ports($src_ports, "src")); + # Nothing to do if no protocol is specified. + if ($protocol eq "all") { + return @options; + } else { + push(@options, ("-p", $protocol)); } - # Process destination ports. - my $use_dst_ports = ($$hash{$key}[11] eq "ON"); - my $use_dnat = (($$hash{$key}[28] eq "ON") && ($$hash{$key}[31] eq "dnat")); + if ($protocol ~~ @PROTOCOLS_WITH_PORTS) { + # Process source ports. + my $use_src_ports = ($$hash{$key}[7] eq "ON"); + my $src_ports = $$hash{$key}[10]; - if ($use_dst_ports) { - my $dst_ports_mode = $$hash{$key}[14]; - my $dst_ports = $$hash{$key}[15]; + if ($use_src_ports && $src_ports) { + push(@options, &format_ports($src_ports, "src")); + } - if (($dst_ports_mode eq "TGT_PORT") && $dst_ports) { - if ($use_dnat && $$hash{$key}[30]) { - $dst_ports = $$hash{$key}[30]; - } - push(@options, &format_ports($dst_ports, "dst")); + # Process destination ports. + my $use_dst_ports = ($$hash{$key}[11] eq "ON"); + my $use_dnat = (($$hash{$key}[28] eq "ON") && ($$hash{$key}[31] eq "dnat")); + + if ($use_dst_ports) { + my $dst_ports_mode = $$hash{$key}[14]; + my $dst_ports = $$hash{$key}[15]; - } elsif ($dst_ports_mode eq "cust_srv") { - if ($protocol eq "ICMP") { - push(@options, ("--icmp-type", &fwlib::get_srv_port($dst_ports, 3, "ICMP"))); - } else { - $dst_ports = &fwlib::get_srv_port($dst_ports, 1, uc($protocol)); + if (($dst_ports_mode eq "TGT_PORT") && $dst_ports) { + if ($nat_options_wanted && $use_dnat && $$hash{$key}[30]) { + $dst_ports = $$hash{$key}[30]; + } push(@options, &format_ports($dst_ports, "dst")); - } - } elsif ($dst_ports_mode eq "cust_srvgrp") { - push(@options, &fwlib::get_srvgrp_port($dst_ports, uc($protocol))); + } elsif ($dst_ports_mode eq "cust_srv") { + if ($protocol eq "ICMP") { + push(@options, ("--icmp-type", &fwlib::get_srv_port($dst_ports, 3, "ICMP"))); + } else { + $dst_ports = &fwlib::get_srv_port($dst_ports, 1, uc($protocol)); + push(@options, &format_ports($dst_ports, "dst")); + } + + } elsif ($dst_ports_mode eq "cust_srvgrp") { + push(@options, &fwlib::get_srvgrp_port($dst_ports, uc($protocol))); + } } } # Check if a single ICMP type is selected. - if (!$use_src_ports && !$use_dst_ports && $protocol eq "icmp") { + if ($protocol eq "icmp") { my $icmp_type = $$hash{$key}[9]; if (($icmp_type ne "All ICMP-Types") && $icmp_type) { @@ -791,6 +770,7 @@ sub get_dnat_target_port { sub add_dnat_mangle_rules { my $nat_address = shift; + my $interface = shift; my @options = @_; my $mark = 0; @@ -801,6 +781,8 @@ sub add_dnat_mangle_rules { next unless (exists $defaultNetworks{$zone . "_NETADDRESS"}); next unless (exists $defaultNetworks{$zone . "_NETMASK"}); + next if ($interface && $interface ne $defaultNetworks{$zone . "_DEV"}); + my @mangle_options = @options; my $netaddress = $defaultNetworks{$zone . "_NETADDRESS"}; @@ -828,50 +810,12 @@ sub make_log_limit_options { return @options; } -sub get_internal_firewall_ip_addresses { - my $use_orange = shift; - - my @zones = ("GREEN", "BLUE"); - if ($use_orange) { - push(@zones, "ORANGE"); - } - - my @addresses = (); - for my $zone (@zones) { - next unless (exists $defaultNetworks{$zone . "_ADDRESS"}); - - my $zone_address = $defaultNetworks{$zone . "_ADDRESS"}; - push(@addresses, $zone_address); - } - - return @addresses; -} - -sub get_internal_firewall_ip_address { - my $subnet = shift; - my $use_orange = shift; - - my ($net_address, $net_mask) = split("/", $subnet); - if ((!$net_mask) || ($net_mask ~~ ["32", "255.255.255.255"])) { - return 0; - } - - my @addresses = &get_internal_firewall_ip_addresses($use_orange); - foreach my $zone_address (@addresses) { - if (&General::IpInSubnet($zone_address, $net_address, $net_mask)) { - return $zone_address; - } - } - - return 0; -} - sub firewall_is_in_subnet { my $subnet = shift; # ORANGE is missing here, because nothing may ever access # the firewall from this network. - my $address = &get_internal_firewall_ip_address($subnet, 0); + my $address = &fwlib::get_internal_firewall_ip_address($subnet, 0); if ($address) { return 1; @@ -879,28 +823,3 @@ sub firewall_is_in_subnet { return 0; } - -sub get_matching_firewall_address { - my $addr = shift; - my $use_orange = shift; - - my ($address, $netmask) = split("/", $addr); - - my @zones = ("GREEN", "BLUE"); - if ($use_orange) { - push(@zones, "ORANGE"); - } - - foreach my $zone (@zones) { - next unless (exists $defaultNetworks{$zone . "_ADDRESS"}); - - my $zone_subnet = $defaultNetworks{$zone . "_NETADDRESS"}; - my $zone_mask = $defaultNetworks{$zone . "_NETMASK"}; - - if (&General::IpInSubnet($address, $zone_subnet, $zone_mask)) { - return $defaultNetworks{$zone . "_ADDRESS"}; - } - } - - return 0; -}