# # Shorewall 4.4 -- /usr/share/shorewall/Shorewall/Chains.pm # # This program is under GPL [http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt] # # (c) 2007,2008,2009,2010,2011 - Tom Eastep (teastep@shorewall.net) # # Complete documentation is available at http://shorewall.net # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License # as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # This is the low-level iptables module. It provides the basic services # of chain and rule creation. It is used by the higher level modules such # as Rules to create iptables-restore input. # package Shorewall::Chains; require Exporter; use Scalar::Util 'reftype'; use Shorewall::Config qw(:DEFAULT :internal); use Shorewall::Zones; use Shorewall::IPAddrs; use strict; our @ISA = qw(Exporter); our @EXPORT = qw( add_rule add_irule add_jump add_ijump insert_rule insert_irule clone_rule insert_ijump rule_target clear_rule_target set_rule_target set_rule_option add_trule add_commands incr_cmd_level decr_cmd_level new_chain new_manual_chain ensure_filter_chain ensure_manual_chain ensure_audit_chain ensure_blacklog_chain require_audit newlogchain log_rule_limit dont_optimize dont_delete dont_move get_action_logging %chain_table %helpers $raw_table $rawpost_table $nat_table $mangle_table $filter_table ); our %EXPORT_TAGS = ( internal => [ qw( STANDARD NATRULE BUILTIN NONAT NATONLY REDIRECT ACTION MACRO LOGRULE NFQ CHAIN SET AUDIT NO_RESTRICT PREROUTE_RESTRICT DESTIFACE_DISALLOW INPUT_RESTRICT OUTPUT_RESTRICT POSTROUTE_RESTRICT ALL_RESTRICT ALL_COMMANDS NOT_RESTORE state_imatch initialize_chain_table copy_rules move_rules insert_rule1 delete_jumps add_tunnel_rule process_comment no_comment macro_comment clear_comment push_comment pop_comment forward_chain rules_chain blacklist_chain zone_forward_chain use_forward_chain filter_chain input_chain zone_input_chain use_input_chain output_chain prerouting_chain postrouting_chain zone_output_chain use_output_chain masq_chain syn_flood_chain mac_chain macrecent_target dnat_chain snat_chain ecn_chain notrack_chain first_chains reserved_name find_chain ensure_chain ensure_accounting_chain accounting_chainrefs ensure_mangle_chain ensure_nat_chain ensure_raw_chain ensure_rawpost_chain new_standard_chain new_builtin_chain new_nat_chain optimize_chain check_optimization optimize_ruleset setup_zone_mss newexclusionchain newnonatchain source_exclusion source_iexclusion dest_exclusion dest_iexclusion clearrule port_count do_proto do_iproto do_mac do_imac verify_mark verify_small_mark validate_mark do_test do_ratelimit do_connlimit do_time do_user do_length do_tos do_connbytes do_helper validate_helper do_headers do_condition have_ipset_rules record_runtime_address conditional_rule conditional_rule_end match_source_dev imatch_source_dev match_dest_dev imatch_dest_dev iprange_match match_source_net imatch_source_net match_dest_net imatch_dest_net match_orig_dest match_ipsec_in match_ipsec_out do_ipsec_options do_ipsec log_rule expand_rule promote_blacklist_rules addnatjump set_chain_variables mark_firewall_not_started mark_firewall6_not_started get_interface_address get_interface_addresses get_interface_bcasts get_interface_acasts get_interface_gateway get_interface_mac have_global_variables set_global_variables save_dynamic_chains load_ipsets create_netfilter_load preview_netfilter_load create_chainlist_reload create_stop_load %targets ) ], ); Exporter::export_ok_tags('internal'); our $VERSION = 'MODULEVERSION'; # # Chain Table # # %chain_table { => { => { name => # table =>
# is_policy => undef|1 -- if 1, this is a policy chain # provisional => undef|1 -- See below. # referenced => undef|1 -- If 1, will be written to the iptables-restore-input. # builtin => undef|1 -- If 1, one of Netfilter's built-in chains. # manual => undef|1 -- If 1, a manual chain. # accounting => undef|1 -- If 1, an accounting chain # dont_optimize=> undef|1 -- Don't optimize away if this chain is 'short' # dont_delete => undef|1 -- Don't delete if this chain is not referenced # dont_move => undef|1 -- Don't copy the rules of this chain somewhere else # log => # policy => # policychain => -- self-reference if this is a policy chain # policypair => [ , ] -- Used for reporting duplicated policies # loglevel => # synparams => # synchain => # default => # cmdlevel => # new => undef| # rules => [ # # ... # ] # logchains => { = , ... } # references => { => , => , ... } # blacklist => ( 0 or 1 ) # blacklistsection # => Chain was created by entries in the BLACKLIST section of the rules file # action => # restricted => Logical OR of restrictions of rules in this chain. # restriction => Restrictions on further rules in this chain. # audit => Audit the result. # filtered => Number of filter rules at the front of an interface forward chain # digest => string representation of the chain's rules for use in optimization # level 8. # accepted => A 'ESTABLISHED,RELATED' ACCEPT rule has been added to this chain. # } , # => ... # } # } # # 'provisional' only applies to policy chains; when true, indicates that this is a provisional policy chain which might be # replaced. Policy chains created under the IMPLICIT_CONTINUE=Yes option are marked with provisional == 1 as are intra-zone # ACCEPT policies. # # Only 'referenced' chains get written to the iptables-restore input. # # 'loglevel', 'synparams', 'synchain', 'audit' and 'default' only apply to policy chains. # our %chain_table; our $raw_table; our $rawpost_table; our $nat_table; our $mangle_table; our $filter_table; our %helpers; my $comment; my @comments; my $export; my %renamed; # # Target Types # use constant { STANDARD => 1, #defined by Netfilter NATRULE => 2, #Involves NAT BUILTIN => 4, #A built-in action NONAT => 8, #'NONAT' or 'ACCEPT+' NATONLY => 16, #'DNAT-' or 'REDIRECT-' REDIRECT => 32, #'REDIRECT' ACTION => 64, #An action (may be built-in) MACRO => 128, #A Macro LOGRULE => 256, #'LOG','NFLOG' NFQ => 512, #'NFQUEUE' CHAIN => 1024, #Manual Chain SET => 2048, #SET AUDIT => 4096, #A_ACCEPT, etc }; # # Valid Targets -- value is a combination of one or more of the above # our %targets; # # expand_rule() restrictions # use constant { NO_RESTRICT => 0, # FORWARD chain rule - Both -i and -o may be used in the rule PREROUTE_RESTRICT => 1, # PREROUTING chain rule - -o converted to -d
using main routing table INPUT_RESTRICT => 4, # INPUT chain rule - -o not allowed OUTPUT_RESTRICT => 8, # OUTPUT chain rule - -i not allowed POSTROUTE_RESTRICT => 16, # POSTROUTING chain rule - -i converted to -s
using main routing table ALL_RESTRICT => 12, # fw->fw rule - neither -i nor -o allowed DESTIFACE_DISALLOW => 32, # Don't allow dest interface. Similar to INPUT_RESTRICT but generates a more relevant error message }; # # See initialize() below for additional comments on these variables # my $iprangematch; my %chainseq; my $idiotcount; my $idiotcount1; my $warningcount; my $hashlimitset; my $global_variables; my $ipset_rules; # # Determines the commands for which a particular interface-oriented shell variable needs to be set # use constant { ALL_COMMANDS => 1, NOT_RESTORE => 2 }; # # These hashes hold the shell code to set shell variables. The key is the name of the variable; the value is the code to generate the variable's contents # my %interfaceaddr; # First interface address my %interfaceaddrs; # All interface addresses my %interfacenets; # Networks routed out of the interface my %interfacemacs; # Interface MAC my %interfacebcasts; # Broadcast addresses associated with the interface (IPv4) my %interfaceacasts; # Anycast addresses associated with the interface (IPv6) my %interfacegateways; # Gateway of default route out of the interface # # Built-in Chains # my @builtins = qw(PREROUTING INPUT FORWARD OUTPUT POSTROUTING); # # Mode of the emitter (part of this module that converts rules in the chain table into iptables-restore input) # use constant { NULL_MODE => 0 , # Emitting neither shell commands nor iptables-restore input CAT_MODE => 1 , # Emitting iptables-restore input CMD_MODE => 2 }; # Emitting shell commands. my $mode; # # Address Family # our $family; # # These are the current builtin targets # my %builtin_target = ( ACCEPT => 1, ACCOUNT => 1, AUDIT => 1, CHAOS => 1, CHECKSUM => 1, CLASSIFY => 1, CLUSTERIP => 1, CONNMARK => 1, CONNSECMARK => 1, COUNT => 1, CT => 1, DELUDE => 1, DHCPMAC => 1, DNAT => 1, DNETMAP => 1, DROP => 1, DSCP => 1, ECHO => 1, ECN => 1, HL => 1, IDLETIMER => 1, IPMARK => 1, LOG => 1, LOGMARK => 1, MARK => 1, MASQUERADE => 1, MIRROR => 1, NETMAP => 1, NFLOG => 1, NFQUEUE => 1, NOTRACK => 1, QUEUE => 1, RATEEST => 1, RAWDNAT => 1, RAWSNAT => 1, REDIRECT => 1, REJECT => 1, RETURN => 1, SAME => 1, SECMARK => 1, SET => 1, SNAT => 1, STEAL => 1, SYSRQ => 1, TARPIT => 1, TCPMSS => 1, TCPOPTSTRIP => 1, TEE => 1, TOS => 1, TPROXY => 1, TRACE => 1, TTL => 1, ULOG => 1, ); my %ipset_exists; # # Rules are stored in an internal form # # { mode => CAT_MODE if rule is not part of a conditional block or loop # => CMD_MODE if the rule contains a shell command or if it # part of a loop or conditional block. If it is a # shell command, the text of the command is in # the cmd # cmd => Shell command, if mode == CMD_MODE and cmdlevel == 0 # cmdlevel => nesting level within loops and conditional blocks. # determines indentation # simple => true|false. If true, there are no matches or options # jump => 'j' or 'g' (determines whether '-j' or '-g' is included) # Omitted, if target is ''. # target => Rule target, if jump is 'j' or 'g'. # targetopts => Target options. Only included if non-empty #