From 627713e6214ea0f5c87194aaaf2eeace2d6dd75d Mon Sep 17 00:00:00 2001 From: teastep Date: Wed, 2 Feb 2005 21:13:44 +0000 Subject: [PATCH] Move 2.2.0+ to Lrp2 git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@1940 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb --- Lrp2/etc/shorewall/accounting | 33 +- Lrp2/etc/shorewall/actions | 2 +- Lrp2/etc/shorewall/blacklist | 14 +- Lrp2/etc/shorewall/ecn | 6 +- Lrp2/etc/shorewall/hosts | 17 +- Lrp2/etc/shorewall/init | 2 +- Lrp2/etc/shorewall/initdone | 2 +- Lrp2/etc/shorewall/interfaces | 18 +- Lrp2/etc/shorewall/ipsec | 58 + Lrp2/etc/shorewall/maclist | 6 +- Lrp2/etc/shorewall/masq | 82 +- Lrp2/etc/shorewall/modules | 2 +- Lrp2/etc/shorewall/nat | 12 +- Lrp2/etc/shorewall/params | 2 +- Lrp2/etc/shorewall/policy | 6 +- Lrp2/etc/shorewall/proxyarp | 2 +- Lrp2/etc/shorewall/routestopped | 6 +- Lrp2/etc/shorewall/rules | 54 +- Lrp2/etc/shorewall/shorewall.conf | 106 +- Lrp2/etc/shorewall/start | 4 +- Lrp2/etc/shorewall/stop | 4 +- Lrp2/etc/shorewall/stopped | 2 +- Lrp2/etc/shorewall/tcrules | 103 +- Lrp2/etc/shorewall/tos | 8 +- Lrp2/etc/shorewall/tunnels | 9 +- Lrp2/etc/shorewall/zones | 2 +- Lrp2/sbin/shorewall | 214 +- Lrp2/usr/share/shorewall/action.AllowAuth | 2 +- Lrp2/usr/share/shorewall/action.AllowDNS | 2 +- Lrp2/usr/share/shorewall/action.AllowFTP | 2 +- Lrp2/usr/share/shorewall/action.AllowICMPs | 11 + Lrp2/usr/share/shorewall/action.AllowIMAP | 2 +- Lrp2/usr/share/shorewall/action.AllowNNTP | 2 +- Lrp2/usr/share/shorewall/action.AllowNTP | 3 +- Lrp2/usr/share/shorewall/action.AllowPCA | 2 +- Lrp2/usr/share/shorewall/action.AllowPOP3 | 2 +- Lrp2/usr/share/shorewall/action.AllowPing | 2 +- Lrp2/usr/share/shorewall/action.AllowRdate | 2 +- Lrp2/usr/share/shorewall/action.AllowSMB | 2 +- Lrp2/usr/share/shorewall/action.AllowSMTP | 2 +- Lrp2/usr/share/shorewall/action.AllowSNMP | 2 +- Lrp2/usr/share/shorewall/action.AllowSSH | 2 +- Lrp2/usr/share/shorewall/action.AllowTelnet | 2 +- Lrp2/usr/share/shorewall/action.AllowTrcrt | 2 +- Lrp2/usr/share/shorewall/action.AllowVNC | 2 +- Lrp2/usr/share/shorewall/action.AllowVNCL | 2 +- Lrp2/usr/share/shorewall/action.AllowWeb | 4 +- Lrp2/usr/share/shorewall/action.Drop | 41 +- Lrp2/usr/share/shorewall/action.DropDNSrep | 2 +- Lrp2/usr/share/shorewall/action.DropPing | 2 +- Lrp2/usr/share/shorewall/action.DropSMB | 2 +- Lrp2/usr/share/shorewall/action.DropUPnP | 2 +- Lrp2/usr/share/shorewall/action.Reject | 38 +- Lrp2/usr/share/shorewall/action.RejectAuth | 2 +- Lrp2/usr/share/shorewall/action.RejectSMB | 2 +- Lrp2/usr/share/shorewall/action.template | 18 +- Lrp2/usr/share/shorewall/actions.std | 11 +- Lrp2/usr/share/shorewall/bogons | 6 +- Lrp2/usr/share/shorewall/firewall | 2726 +++++++++++++------ Lrp2/usr/share/shorewall/functions | 77 +- Lrp2/usr/share/shorewall/help | 49 +- Lrp2/usr/share/shorewall/rfc1918 | 9 +- Lrp2/usr/share/shorewall/version | 2 +- Lrp2/var/lib/lrpkg/shorwall.conf | 1 + Lrp2/var/lib/lrpkg/shorwall.version | 2 +- 65 files changed, 2737 insertions(+), 1083 deletions(-) create mode 100644 Lrp2/etc/shorewall/ipsec create mode 100644 Lrp2/usr/share/shorewall/action.AllowICMPs diff --git a/Lrp2/etc/shorewall/accounting b/Lrp2/etc/shorewall/accounting index a0d352255..d21c03326 100644 --- a/Lrp2/etc/shorewall/accounting +++ b/Lrp2/etc/shorewall/accounting @@ -1,5 +1,5 @@ # -# Shorewall version 2.0 - Accounting File +# Shorewall version 2.2 - Accounting File # # /etc/shorewall/accounting # @@ -47,9 +47,12 @@ # Format the same as the SOURCE column. # # PROTOCOL A protocol name (from /etc/protocols), a protocol -# number. +# number, or "ipp2p" # -# DEST PORT Destination Port number +# DEST PORT Destination Port number. If the PROTOCOL is "ipp2p" then +# this column must contain an ipp2p option ("iptables -m +# ipp2p --help") without the leading "--". If no option +# is given in this column, "ipp2p" is assumed. # # Service name from /etc/services or port number. May # only be specified if the protocol is TCP or UDP (6 @@ -61,13 +64,33 @@ # only be specified if the protocol is TCP or UDP (6 # or 17). # +# USER/GROUP This column may only be non-empty if the CHAIN is +# OUTPUT. +# +# The column may contain: +# +# [!][][:] +# +# When this column is non-empty, the rule applies only +# if the program generating the output is running under +# the effective and/or specified (or is +# NOT running under that id if "!" is given). +# +# Examples: +# +# joe #program must be run by joe +# :kids #program must be run by a member of +# #the 'kids' group +# !:kids #program must not be run by a member +# #of the 'kids' group +# # In all of the above columns except ACTION and CHAIN, the values "-", # "any" and "all" may be used as wildcards # # Please see http://shorewall.net/Accounting.html for examples and # additional information about how to use this file. # -#ACTION CHAIN SOURCE DESTINATION PROTO DEST SOURCE -# PORT PORT +#ACTION CHAIN SOURCE DESTINATION PROTO DEST SOURCE USER/ +# PORT PORT GROUP # #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Lrp2/etc/shorewall/actions b/Lrp2/etc/shorewall/actions index 9f6bca91f..4ddb30e91 100644 --- a/Lrp2/etc/shorewall/actions +++ b/Lrp2/etc/shorewall/actions @@ -1,5 +1,5 @@ # -# Shorewall 2.1 /etc/shorewall/actions +# Shorewall 2.2 /etc/shorewall/actions # # This file allows you to define new ACTIONS for use in rules # (/etc/shorewall/rules). You define the iptables rules to diff --git a/Lrp2/etc/shorewall/blacklist b/Lrp2/etc/shorewall/blacklist index 063724daa..4cb06756d 100644 --- a/Lrp2/etc/shorewall/blacklist +++ b/Lrp2/etc/shorewall/blacklist @@ -1,5 +1,5 @@ # -# Shorewall 2.0 -- Blacklist File +# Shorewall 2.2 -- Blacklist File # # /etc/shorewall/blacklist # @@ -7,7 +7,9 @@ # # Columns are: # -# ADDRESS/SUBNET - Host address, subnetwork or MAC address +# ADDRESS/SUBNET - Host address, subnetwork, MAC address or IP address +# range (if your kernel and iptables contain iprange +# match support). # # MAC addresses must be prefixed with "~" and use "-" # as a separator. @@ -21,10 +23,10 @@ # is TCP (6) or UDP (17). A comma-separated list # of port numbers or service names from /etc/services. # -# When a packet arrives on in interface that has the 'blacklist' option -# specified, its source IP address is checked against this file and disposed of -# according to the BLACKLIST_DISPOSITION and BLACKLIST_LOGLEVEL variables in -# /etc/shorewall/shorewall.conf +# When a packet arrives on an interface that has the 'blacklist' option +# specified in /etc/shorewall/interfaces, its source IP address is checked +# against this file and disposed of according to the BLACKLIST_DISPOSITION and +# BLACKLIST_LOGLEVEL variables in /etc/shorewall/shorewall.conf # # If PROTOCOL or PROTOCOL and PORTS are supplied, only packets matching # the protocol (and one of the ports if PORTS supplied) are blocked. diff --git a/Lrp2/etc/shorewall/ecn b/Lrp2/etc/shorewall/ecn index 644a63500..e09e32540 100644 --- a/Lrp2/etc/shorewall/ecn +++ b/Lrp2/etc/shorewall/ecn @@ -1,5 +1,5 @@ # -# Shorewall 2.0 - /etc/shorewall/ecn +# Shorewall 2.2 - /etc/shorewall/ecn # # Use this file to list the destinations for which you want to # disable ECN. @@ -12,7 +12,9 @@ # the firewall # HOST(S) - (Optional) Comma-separated list of IP/subnet # If left empty or supplied as "-", -# 0.0.0.0/0 is assumed. +# 0.0.0.0/0 is assumed. If your kernel and iptables +# include iprange match support then IP address ranges +# are also permitted. ############################################################################## #INTERFACE HOST(S) #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Lrp2/etc/shorewall/hosts b/Lrp2/etc/shorewall/hosts index 49e322adb..1fbd5e51c 100644 --- a/Lrp2/etc/shorewall/hosts +++ b/Lrp2/etc/shorewall/hosts @@ -1,5 +1,5 @@ # -# Shorewall 2.0 - /etc/shorewall/hosts +# Shorewall 2.2 - /etc/shorewall/hosts # # THE ONLY TIME YOU NEED THIS FILE IS WHERE YOU HAVE MORE THAN # ONE ZONE CONNECTED THROUGH A SINGLE INTERFACE. @@ -28,12 +28,15 @@ # a) The IP address of a host # b) A subnetwork in the form # / -# c) A physical port name; only allowed when the +# c) An IP address range of the form -. Your kernel and iptables must have iprange +# match support. +# d) A physical port name; only allowed when the # interface names a bridge created by the # brctl addbr command. This port must not # be defined in /etc/shorewall/interfaces and may # optionally followed by a colon (":") and a -# host or network IP. +# host or network IP or a range. # See http://www.shorewall.net/Bridge.html for details. # # Examples: @@ -43,6 +46,7 @@ # eth3:192.168.2.0/24,192.168.3.1 # br0:eth4 # br0:eth0:192.168.1.16/28 +# eth4:192.168.1.44-192.168.1.49 # # OPTIONS - A comma-separated list of options. Currently-defined # options are: @@ -124,5 +128,12 @@ # This option has no effect if # NEWNOTSYN=Yes. # +# ipsec - The zone is accessed via a +# kernel 2.6 ipsec SA. Note that if the +# zone named in the ZONE column is +# specified as an IPSEC zone in the +# /etc/shorewall/ipsec file then you do NOT +# need to specify the 'ipsec' option here. +# #ZONE HOST(S) OPTIONS #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS LINE -- DO NOT REMOVE diff --git a/Lrp2/etc/shorewall/init b/Lrp2/etc/shorewall/init index cdd21c79b..7fb3988e1 100644 --- a/Lrp2/etc/shorewall/init +++ b/Lrp2/etc/shorewall/init @@ -1,5 +1,5 @@ ############################################################################ -# Shorewall 2.0 -- /etc/shorewall/init +# Shorewall 2.2 -- /etc/shorewall/init # # Add commands below that you want to be executed at the beginning of # a "shorewall start" or "shorewall restart" command. diff --git a/Lrp2/etc/shorewall/initdone b/Lrp2/etc/shorewall/initdone index 35148d94a..efd2be5d2 100644 --- a/Lrp2/etc/shorewall/initdone +++ b/Lrp2/etc/shorewall/initdone @@ -1,5 +1,5 @@ ############################################################################ -# Shorewall 2.0 -- /etc/shorewall/initdone +# Shorewall 2.2 -- /etc/shorewall/initdone # # Add commands below that you want to be executed during # "shorewall start" or "shorewall restart" commands at the point where diff --git a/Lrp2/etc/shorewall/interfaces b/Lrp2/etc/shorewall/interfaces index 8397e28a6..f2e62605d 100644 --- a/Lrp2/etc/shorewall/interfaces +++ b/Lrp2/etc/shorewall/interfaces @@ -1,5 +1,5 @@ # -# Shorewall 2.0 -- Interfaces File +# Shorewall 2.2 -- Interfaces File # # /etc/shorewall/interfaces # @@ -75,12 +75,23 @@ # option does not cover those ranges # reserved by RFC 1918 -- see above). # +# I PERSONALLY RECOMMEND AGAINST USING +# THE 'nobogons' OPTION. +# # routefilter - turn on kernel route filtering for this # interface (anti-spoofing measure). This # option can also be enabled globally in # the /etc/shorewall/shorewall.conf file. # -# . . blacklist - Check packets arriving on this interface +# logmartians - turn on kernel martian logging (logging +# of packets with impossible source +# addresses. It is suggested that if you +# set routefilter on an interface that +# you also set logmartians. This option +# may also be enabled globally in the +# /etc/shorewall/shorewall.conf file. +# +# blacklist - Check packets arriving on this interface # against the /etc/shorewall/blacklist # file. # @@ -190,6 +201,7 @@ # net ppp0 - ############################################################################## #ZONE INTERFACE BROADCAST OPTIONS +# net eth0 detect dhcp,routefilter,norfc1918 -loc eth1 detect +loc eth1 detect dhcp #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Lrp2/etc/shorewall/ipsec b/Lrp2/etc/shorewall/ipsec new file mode 100644 index 000000000..b6692d8fd --- /dev/null +++ b/Lrp2/etc/shorewall/ipsec @@ -0,0 +1,58 @@ +# +# Shorewall 2.2 - /etc/shorewall/ipsec +# +# This file defines the attributes of zones with respect to +# IPSEC. To use this file, you must be running a 2.6 kernel and +# both your kernel and iptables must include Policy Match Support. +# +# The columns are: +# +# ZONE The name of a zone defined in /etc/shorewall/zones. The +# $FW zone may not be listed. +# +# IPSEC Yes -- Communication with all zone hosts is encrypted +# ONLY No -- Communication with some zone hosts is encrypted. +# Encrypted hosts are designated using the 'ipsec' +# option in /etc/shorewall/hosts. +# +# OPTIONS, A comma-separated list of options as follows: +# IN OPTIONS, +# OUT OPTIONS reqid= where is specified +# using setkey(8) using the 'unique: +# option for the SPD level. +# +# spi= where is the SPI of +# the SA used to encrypt/decrypt packets. +# +# proto=ah|esp|ipcomp +# +# mss= (sets the MSS field in TCP packets) +# +# mode=transport|tunnel +# +# tunnel-src=
[/] (only +# available with mode=tunnel) +# +# tunnel-dst=
[/] (only +# available with mode=tunnel) +# +# strict Means that packets must match all rules. +# +# next Separates rules; can only be used with +# strict.. +# +# Example: +# mode=transport,reqid=44 +# +# The options in the OPTIONS column are applied to both incoming +# and outgoing traffic. The IN OPTIONS are applied to incoming +# traffic (in addition to OPTIONS) and the OUT OPTIONS are +# applied to outgoing traffic. +# +# If you wish to leave a column empty but need to make an entry +# in a following column, use "-". +################################################################################### +#ZONE IPSEC OPTIONS IN OUT +# ONLY OPTIONS OPTIONS +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE + diff --git a/Lrp2/etc/shorewall/maclist b/Lrp2/etc/shorewall/maclist index 3374fd83c..b200ddda2 100644 --- a/Lrp2/etc/shorewall/maclist +++ b/Lrp2/etc/shorewall/maclist @@ -1,5 +1,5 @@ # -# Shorewall 2.0 - MAC list file +# Shorewall 2.2 - MAC list file # # /etc/shorewall/maclist # @@ -15,7 +15,9 @@ # # IP ADDRESSES Optional -- if specified, both the MAC and IP address # must match. This column can contain a comma-separated -# list of host and/or subnet addresses. +# list of host and/or subnet addresses. If your kernel +# and iptables have iprange match support then IP +# address ranges are also allowed. ############################################################################## #INTERFACE MAC IP ADDRESSES (Optional) #LAST LINE -- ADD YOUR ENTRIES ABOVE THIS LINE -- DO NOT REMOVE diff --git a/Lrp2/etc/shorewall/masq b/Lrp2/etc/shorewall/masq index e00044725..34e81d93d 100644 --- a/Lrp2/etc/shorewall/masq +++ b/Lrp2/etc/shorewall/masq @@ -1,5 +1,5 @@ # -# Shorewall 2.0 - Masquerade file +# Shorewall 2.2 - Masquerade file # # /etc/shorewall/masq # @@ -20,6 +20,24 @@ # This may be qualified by adding the character # ":" followed by a destination host or subnet. # +# If you wish to inhibit the action of ADD_SNAT_ALIASES +# for this entry then include the ":" but omit the digit: +# +# eth0: +# eth2::192.0.2.32/27 +# +# Normally Masq/SNAT rules are evaluated after those for +# one-to-one NAT (/etc/shorewall/nat file). If you want +# the rule to be applied before one-to-one NAT rules, +# prefix the interface name with "+": +# +# +eth0 +# +eth0:192.0.2.32/27 +# +eth0:2 +# +# This feature should only be required if you need to +# insert rules in this file that preempt entries in +# /etc/shorewall/nat. # # SUBNET -- Subnet that you wish to masquerade. You can specify this as # a subnet or as an interface. If you give the name of an @@ -42,13 +60,6 @@ # will automatically add this address to the # INTERFACE named in the first column. # -# If you have set ADD_SNAT_ALIASES=Yes in -# /etc/shorewall/shorewall.conf then DO NOT -# PLACE YOUR EXTERNAL INTERFACE'S PRIMARY IP -# ADDRESS IN THIS COLUMN -- If you do so, you -# will loose your default route when Shorewall -# starts. -# # You may also specify a range of up to 256 # IP addresses if you want the SNAT address to # be assigned from that range in a round-robin @@ -59,9 +70,22 @@ # # Finally, you may also specify a comma-separated # list of ranges and/or addresses in this column. -# +# # This column may not contain DNS Names. # +# Normally, Netfilter will attempt to retain +# the source port number. You may cause +# netfilter to remap the source port by following +# an address or range (if any) by ":" and +# a port range with the format - +# . If this is done, you must +# specify "tcp" or "udp" in the PROTO column. +# +# Examples: +# +# 192.0.2.4:5000-6000 +# :4000-5000 +# # If you want to leave this column empty # but you need to specify the next column then # place a hyphen ("-") here. @@ -82,6 +106,42 @@ # support and a maximum of 15 ports may be # listed. # +# IPSEC -- (Optional) If you specify a value other than "-" in this +# column, you must be running kernel 2.6 and +# your kernel and iptables must include policy +# match support. +# +# Comma-separated list of options from the following. +# Only packets that will be encrypted via an SA that +# matches these options will have their source address +# changed. +# +# Yes or yes -- must be the only option listed +# and matches all outbound traffic that will be +# encrypted. +# +# reqid= where is specified +# using setkey(8) using the 'unique: +# option for the SPD level. +# +# spi= where is the SPI of +# the SA. +# +# proto=ah|esp|ipcomp +# +# mode=transport|tunnel +# +# tunnel-src=
[/] (only +# available with mode=tunnel) +# +# tunnel-dst=
[/] (only +# available with mode=tunnel) +# +# strict Means that packets must match all +# rules. +# +# next Separates rules; can only be used +# with strict.. # # Example 1: # @@ -136,6 +196,6 @@ # THE ORDER OF THE ABOVE TWO RULES IS SIGNIFICANT!!!!! # ############################################################################### -#INTERFACE SUBNET ADDRESS PROTO PORT(S) -eth0 eth1 +#INTERFACE SUBNET ADDRESS PROTO PORT(S) IPSEC +eth0 eth1 #LAST LINE -- ADD YOUR ENTRIES ABOVE THIS LINE -- DO NOT REMOVE diff --git a/Lrp2/etc/shorewall/modules b/Lrp2/etc/shorewall/modules index 6621f36b3..f658e3576 100644 --- a/Lrp2/etc/shorewall/modules +++ b/Lrp2/etc/shorewall/modules @@ -1,5 +1,5 @@ ############################################################################## -# Shorewall 2.0 /etc/shorewall/modules +# Shorewall 2.2 /etc/shorewall/modules # # This file loads the modules needed by the firewall. # diff --git a/Lrp2/etc/shorewall/nat b/Lrp2/etc/shorewall/nat index dbd44c4f0..76991ebdd 100644 --- a/Lrp2/etc/shorewall/nat +++ b/Lrp2/etc/shorewall/nat @@ -1,6 +1,6 @@ ############################################################################## # -# Shorewall 2.0 -- Network Address Translation Table +# Shorewall 2.2 -- Network Address Translation Table # # /etc/shorewall/nat # @@ -16,6 +16,7 @@ # EXTERNAL External IP Address - this should NOT be the primary # IP address of the interface named in the next # column and must not be a DNS Name. +# # INTERFACE Interface that you want to EXTERNAL address to appear # on. If ADD_IP_ALIASES=Yes in shorewall.conf, you may # follow the interface name with ":" and a digit to @@ -24,14 +25,21 @@ # see the alias with ifconfig. THAT IS THE ONLY THING # THAT THIS NAME IS GOOD FOR -- YOU CANNOT USE IT # ANYWHERE ELSE IN YOUR SHORWALL CONFIGURATION. +# +# If you want to override ADD_IP_ALIASES=Yes for a +# particular entry, follow the interface name with +# ":" and no digit (e.g., "eth0:"). # INTERNAL Internal Address (must not be a DNS Name). +# # ALL INTERFACES If Yes or yes, NAT will be effective from all hosts. # If No or no (or left empty) then NAT will be effective # only through the interface named in the INTERFACE # column +# # LOCAL If Yes or yes, NAT will be effective from the firewall # system ############################################################################## -#EXTERNAL INTERFACE INTERNAL ALL LOCAL +#EXTERNAL INTERFACE INTERNAL ALL LOCAL # INTERFACES +# #LAST LINE -- ADD YOUR ENTRIES ABOVE THIS LINE -- DO NOT REMOVE diff --git a/Lrp2/etc/shorewall/params b/Lrp2/etc/shorewall/params index 5873bf90a..24d1c94ae 100644 --- a/Lrp2/etc/shorewall/params +++ b/Lrp2/etc/shorewall/params @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/params +# Shorewall 2.2 /etc/shorewall/params # # Assign any variables that you need here. # diff --git a/Lrp2/etc/shorewall/policy b/Lrp2/etc/shorewall/policy index 9a62ef3ab..60a1a6749 100644 --- a/Lrp2/etc/shorewall/policy +++ b/Lrp2/etc/shorewall/policy @@ -1,5 +1,5 @@ # -# Shorewall 2.0 -- Policy File +# Shorewall 2.2 -- Policy File # # /etc/shorewall/policy # @@ -82,8 +82,4 @@ net all DROP ULOG # remove the comment from the following line. #fw net ACCEPT -# -# THE FOLLOWING POLICY MUST BE LAST -# -all all REJECT ULOG #LAST LINE -- DO NOT REMOVE diff --git a/Lrp2/etc/shorewall/proxyarp b/Lrp2/etc/shorewall/proxyarp index b21a4f432..c80c1b21c 100644 --- a/Lrp2/etc/shorewall/proxyarp +++ b/Lrp2/etc/shorewall/proxyarp @@ -1,6 +1,6 @@ ############################################################################## # -# Shorewall 2.0 -- Proxy ARP +# Shorewall 2.2 -- Proxy ARP # # /etc/shorewall/proxyarp # diff --git a/Lrp2/etc/shorewall/routestopped b/Lrp2/etc/shorewall/routestopped index 8d5a0b41c..df8ea4582 100644 --- a/Lrp2/etc/shorewall/routestopped +++ b/Lrp2/etc/shorewall/routestopped @@ -1,6 +1,6 @@ ############################################################################## # -# Shorewall 2.0 -- Hosts Accessible when the Firewall is Stopped +# Shorewall 2.2 -- Hosts Accessible when the Firewall is Stopped # # /etc/shorewall/routestopped # @@ -12,6 +12,10 @@ # INTERFACE - Interface through which host(s) communicate with # the firewall # HOST(S) - (Optional) Comma-separated list of IP/subnet +# addresses. If your kernel and iptables include +# iprange match support, IP address ranges are also +# allowed. +# # If left empty or supplied as "-", # 0.0.0.0/0 is assumed. # OPTIONS - (Optional) A comma-separated list of diff --git a/Lrp2/etc/shorewall/rules b/Lrp2/etc/shorewall/rules index ec70e947f..a9183d59d 100644 --- a/Lrp2/etc/shorewall/rules +++ b/Lrp2/etc/shorewall/rules @@ -1,5 +1,5 @@ # -# Shorewall version 2.0 - Rules File +# Shorewall version 2.2 - Rules File # # /etc/shorewall/rules # @@ -72,6 +72,20 @@ # DNAT:debug). This causes the packet to be # logged at the specified level. # +# If the ACTION names an action defined in +# /etc/shorewall/actions or in +# /usr/share/shorewall/actions.std then: +# +# - If the log level is followed by "!' then all rules +# in the action are logged at the log level. +# +# - If the log level is not followed by "!" then only +# those rules in the action that do not specify +# logging are logged at the specified level. +# +# - The special log level 'none!' suppresses logging +# by the action. +# # You may also specify ULOG (must be in upper case) as a # log level.This will log to the ULOG target for routing # to a separate log through use of ulogd @@ -104,6 +118,10 @@ # address; mac addresses must begin with "~" and must use # "-" as a separator. # +# Hosts may be specified as an IP address range using the +# syntax -. This requires that +# your kernel and iptables contain iprange match support. +# # dmz:192.168.2.2 Host 192.168.2.2 in the DMZ # # net:155.186.235.0/24 Subnet 155.186.235.0/24 on the @@ -115,6 +133,10 @@ # loc:~00-A0-C9-15-39-78 Host in the local zone with # MAC address 00:A0:C9:15:39:78. # +# net:192.0.2.11-192.0.2.17 +# Hosts 192.0.2.11-192.0.2.17 in +# the net zone. +# # Alternatively, clients may be specified by interface # by appending ":" to the zone name followed by the # interface name. For example, loc:eth1 specifies a @@ -145,7 +167,7 @@ # 3. You may not specify both an interface and # an address. # -# Unlike in the SOURCE column, you may specify a range of +# Like in the SOURCE column, you may specify a range of # up to 256 IP addresses using the syntax # -. When the ACTION is DNAT or DNAT-, # the connections will be assigned to addresses in the @@ -196,7 +218,7 @@ # # If you don't want to restrict client ports but need to # specify an ORIGINAL DEST in the next column, then place -# "-" in this column. +# "-" in this column. # # If your kernel contains multi-port match support, then # only a single Netfilter rule will be generated if in @@ -223,14 +245,6 @@ # destination address in the connection request does not # match any of the addresses listed. # -# The address (list) may optionally be followed by -# a colon (":") and a second IP address. This causes -# Shorewall to use the second IP address as the source -# address in forwarded packets. See the Shorewall -# documentation for restrictions concerning this feature. -# If no source IP address is given, the original source -# address is not altered. -# # RATE LIMIT You may rate-limit the rule by placing a value in # this colume: # @@ -281,9 +295,9 @@ # to local system 192.168.1.3 with a limit of 3 per second and # a maximum burst of 10 # -# #ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL -# # PORT PORT(S) DEST -# DNAT<3/sec:10> net loc:192.168.1.3 tcp http +# #ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE +# # PORT PORT(S) DEST LIMIT +# DNAT net loc:192.168.1.3 tcp http - - 3/sec:10 # # Example: Redirect all locally-originating www connection requests to # port 3128 on the firewall (Squid running on the firewall @@ -310,7 +324,6 @@ #################################################################################################### #ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE USER/ # PORT PORT(S) DEST LIMIT GROUP -# PORT PORT(S) DEST LIMIT # Accept DNS connections from the firewall to the network # ACCEPT fw net tcp 53 @@ -318,18 +331,19 @@ ACCEPT fw net udp 53 # Accept SSH connections from the local network for administration # ACCEPT loc fw tcp 22 -# Allow Ping To And From Firewall +# Allow Ping To Firewall # ACCEPT loc fw icmp 8 ACCEPT net fw icmp 8 -ACCEPT fw loc icmp 8 -ACCEPT fw net icmp 8 +# +# Allow all ICMP types (including ping) From Firewall +# +ACCEPT fw loc icmp +ACCEPT fw net icmp # # Bering specific rules: # allow loc to fw udp/53 for local/caching DNS servers to work # allow loc to fw tcp/80 for weblet to work -# allow loc to fw udp/67 and udp/68 for dnsmasq's dhcpd to work ACCEPT loc fw udp 53 ACCEPT loc fw tcp 80 -ACCEPT loc fw udp 67,68 #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Lrp2/etc/shorewall/shorewall.conf b/Lrp2/etc/shorewall/shorewall.conf index c11134f14..56051afcd 100755 --- a/Lrp2/etc/shorewall/shorewall.conf +++ b/Lrp2/etc/shorewall/shorewall.conf @@ -1,5 +1,4 @@ -############################################################################## -# /etc/shorewall/shorewall.conf V2.0 - Change the following variables to +/shorewall/shorewall.conf V2.1 - Change the following variables to # match your setup # # This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] @@ -7,6 +6,14 @@ # This file should be placed in /etc/shorewall # # (c) 1999,2000,2001,2002,2003,2004 - Tom Eastep (teastep@shorewall.net) +############################################################################## +# S T A R T U P E N A B L E D +############################################################################## +# Once you have configured Shorewall, you may change the setting of +# this variable to 'Yes' + +STARTUP_ENABLED=No + ############################################################################## # L O G G I N G ############################################################################## @@ -80,6 +87,18 @@ LOGFILE=/var/log/shorewall.log LOGFORMAT="Shorewall:%s:%s:" +# +# LOG FORMAT Continued +# +# Using the default LOGFORMAT, chain names may not exceed 11 characters or +# truncation of the log prefix may occur. Longer chain names may be used with +# log tags if you set LOGTAGONLY=Yes. With LOGTAGONLY=Yes, if a log tag is +# specified then the tag is included in the log prefix in place of the chain +# name. +# + +LOGTAGONLY=No + # # LOG RATE LIMITING # @@ -110,6 +129,18 @@ LOGFORMAT="Shorewall:%s:%s:" LOGRATE= LOGBURST= +# +# LOG ALL NEW +# +# This option should only be used when you are trying to analyze a problem. +# It causes all packets in the Netfilter NEW state to be logged as the +# first rule in each builtin chain. To use this option, set LOGALLNEW to +# the log level that you want these packets logged at (e.g., +# LOGALLNEW=debug). +# + +LOGALLNEW= + # # BLACKLIST LOG LEVEL # @@ -201,9 +232,29 @@ SMURF_LOG_LEVEL=ULOG # BOGON_LOG_LEVEL=ULOG + +# +# MARTIAN LOGGING +# +# Setting LOG_MARTIANS=Yes will enable kernel logging of all received packets +# that have impossible source IP addresses. This logging may be enabled +# on individual interfaces by using the 'logmartians' option in +# /etc/shorewall/interfaces. +# + +LOG_MARTIANS=No ################################################################################ # L O C A T I O N O F F I L E S A N D D I R E C T O R I E S ################################################################################ +# +# IPTABLES +# +# Full path to iptables executable Shorewall uses to build the firewall. If +# not specified or if specified with an empty value (e.g., IPTABLES="") then +# the iptables executable located via the PATH setting below is used. +# +IPTABLES= + # # PATH - Change this if you want to change the order in which Shorewall # searches directories for executable files. @@ -320,14 +371,28 @@ ADD_IP_ALIASES=Yes # ADD_SNAT_ALIASES=No +# +# RETAIN EXISTING ALIASES/IP ADDRESSES +# +# Normally, when ADD_IP_ALIASES=Yes and/or ADD_SNAT_ALIASES=Yes then Shorewall +# will first delete the address then re-add it. This is to ensure that the +# address is added with the specified label. Unfortunately, this can cause +# problems if it results in the deletion of the last IP address on an +# interface because then all routes through the interface are automatically +# removed. +# +# You can cause Shorewall to retain existing addresses by setting +# RETAIN_ALIASES=Yes. +# +RETAIN_ALIASES=No + # # ENABLE TRAFFIC SHAPING # # If you say "Yes" or "yes" here, Traffic Shaping is enabled in the firewall. If # you say "No" or "no" then traffic shaping is not enabled. If you enable traffic -# shaping you must have iproute[2] installed (the "ip" and "tc" utilities) and -# you must enable packet mangling above. -# +# shaping you must have iproute[2] installed (the "ip" and "tc" utilities). + TC_ENABLED=No # @@ -393,6 +458,14 @@ MARK_IN_FORWARD_CHAIN=No # # If left blank, or set to "No" or "no", the option is not enabled. # +# You may also set this option to a numeric value in which case Shorewall will +# set up a rule to modify the MSS value in SYN packets to the value that +# you specify. +# +# Example: +# +# CLAMPMSS=1400 +# CLAMPMSS=No # @@ -470,7 +543,7 @@ MUTEX_TIMEOUT=60 # A packet is said to be NEW if it is not part of or related to an already # established connection. # -# The NEWNOTSYN option determines the handling of non-SYN packets (those with +# The NETNOTSYN option determines the handling of non-SYN packets (those with # SYN off or with ACK or RST on) that are not associated with an already # established connection. # @@ -551,6 +624,14 @@ ADMINISABSENTMINDED=Yes # BLACKLISTNEWONLY=Yes +# +# Users with a large blacklist find that "shorwall [re]start" takes a long +# time and that new connections are disabled during that time. By setting +# DELAYBLACKLISTLOAD=Yes, you can cause Shorewall to enable new connections +# before loading the blacklist. + +DELAYBLACKLISTLOAD=No + # MODULE NAME SUFFIX # # When loading a module named in /etc/shorewall/modules, Shorewall normally @@ -610,16 +691,9 @@ DYNAMIC_ZONES=No # USE PKTTYPE MATCH # # Some users have reported problems with the PKTTYPE match extension not being -# able to match certain broadcast packets. -# -# Other users have complained of the following message when -# starting Shorewall: -# -# modprobe: cant locate module ipt_pkttype -# -# If you set PKTTYPE=No then Shorewallwill use IP addresses to detect -# broadcasts rather than pkttype. If not given or if given as empty -# (PKTTYPE="") then PKTTYPE=Yes is assumed. +# able to patch certail broadcast packets. If you set PKTTYPE=No then Shorewall +# will use IP addresses to detect broadcasts rather than pkttype. If not given +# or if given as empty (PKTTYPE="") then PKTTYPE=Yes is assumed. PKTTYPE=Yes diff --git a/Lrp2/etc/shorewall/start b/Lrp2/etc/shorewall/start index 8f48d2565..37077dfb6 100644 --- a/Lrp2/etc/shorewall/start +++ b/Lrp2/etc/shorewall/start @@ -1,5 +1,5 @@ ############################################################################ -# Shorewall 2.0 -- /etc/shorewall/start +# Shorewall 2.2 -- /etc/shorewall/start # # Add commands below that you want to be executed after shorewall has # been started or restarted. @@ -7,4 +7,4 @@ for file in /etc/shorewall/start.d/* ; do run_user_exit $file done - \ No newline at end of file + diff --git a/Lrp2/etc/shorewall/stop b/Lrp2/etc/shorewall/stop index f5be35a72..ab48d5961 100644 --- a/Lrp2/etc/shorewall/stop +++ b/Lrp2/etc/shorewall/stop @@ -1,5 +1,5 @@ ############################################################################ -# Shorewall 2.0 -- /etc/shorewall/stop +# Shorewall 2.2 -- /etc/shorewall/stop # # Add commands below that you want to be executed at the beginning of a # "shorewall stop" command. @@ -7,4 +7,4 @@ for file in /etc/shorewall/stop.d/* ; do run_user_exit $file done - \ No newline at end of file + diff --git a/Lrp2/etc/shorewall/stopped b/Lrp2/etc/shorewall/stopped index 16feb827b..d31d023c7 100644 --- a/Lrp2/etc/shorewall/stopped +++ b/Lrp2/etc/shorewall/stopped @@ -1,5 +1,5 @@ ############################################################################ -# Shorewall 2.0 -- /etc/shorewall/stopped +# Shorewall 2.2 -- /etc/shorewall/stopped # # Add commands below that you want to be executed at the completion of a # "shorewall stop" command. diff --git a/Lrp2/etc/shorewall/tcrules b/Lrp2/etc/shorewall/tcrules index d2ff68ba5..94d686e96 100644 --- a/Lrp2/etc/shorewall/tcrules +++ b/Lrp2/etc/shorewall/tcrules @@ -1,5 +1,5 @@ # -# Shorewall version 2.0 - Traffic Control Rules File +# Shorewall version 2.2 - Traffic Control Rules File # # /etc/shorewall/tcrules # @@ -19,20 +19,65 @@ # Columns are: # # -# MARK The mark value which is an -# integer in the range 1-255 +# MARK/ a) A mark value which is a integer in the range 1-255 +# CLASSIFY +# May optionally be followed by ":P" or ":F" +# where ":P" indicates that marking should occur in +# the PREROUTING chain and ":F" indicates that marking +# should occur in the FORWARD chain. If neither +# ":P" nor ":F" follow the mark value then the chain is +# determined by the setting of MARK_IN_FORWARD_CHAIN in +# /etc/shorewall/shorewall.conf. # -# May optionally be followed by ":P" or ":F" -# where ":P" indicates that marking should occur in -# the PREROUTING chain and ":F" indicates that marking -# should occur in the FORWARD chain. If neither -# ":P" nor ":F" follow the mark value then the chain is -# determined by the setting of MARK_IN_FORWARD_CHAIN in -# /etc/shorewall/shorewall.conf. +# If your kernel and iptables include CONNMARK support +# then you can also mark the connection rather than +# the packet. +# +# The mark value may be optionally followed by "/" +# and a mask value (used to determine those bits of +# the connection mark to actually be set). The +# mark and optional mask are then followed by one of: +# +# C - Mark the connection in the chain determined +# by the setting of MARK_IN_FORWARD_CHAIN +# +# CF: Mark the conneciton in the FORWARD chain +# +# CP: Mark the connection in the PREROUTING chain. +# +# b) A classification of the form : where +# and are integers. Corresponds to +# the 'class' specification in these traffic shaping +# modules: +# +# - atm +# - cbq +# - dsmark +# - pfifo_fast +# - htb +# - prio +# +# Classify always occurs in the POSTROUTING chain. +# +# c) RESTORE[/mask] -- restore the packet's mark from the +# connection's mark using the supplied mask if any. +# Your kernel and iptables must include CONNMARK support. +# As in a) above, may be followed by ":P" or ":F +# +# c) SAVE[/mask] -- save the packet's mark to the +# connection's mark using the supplied mask if any. +# Your kernel and iptables must include CONNMARK support. +# As in a) above, may be followed by ":P" or ":F +# +# d) CONTINUE -- don't process any more marking rules in +# the table. As in a) above, may be followed by ":P" or +# ":F". # # SOURCE Source of the packet. A comma-separated list of # interface names, IP addresses, MAC addresses -# and/or subnets. Use $FW if the packet originates on +# and/or subnets. If your kernel and iptables include +# iprange match support, IP address ranges are also +# allowed. Use $FW if the packet originates on # the firewall in which case the MARK column may NOT # specify either ":P" or ":F" (marking always occurs # in the OUTPUT chain). @@ -43,22 +88,34 @@ # Example: ~00-A0-C9-15-39-78 # # DEST Destination of the packet. Comma separated list of -# IP addresses and/or subnets. +# IP addresses and/or subnets. If your kernel and +# iptables include iprange match support, IP address +# ranges are also allowed. # -# PROTO Protocol - Must be "tcp", "udp", "icmp", a number, -# or "all". +# If the MARK column specificies a classification of +# the form : then this column may also +# contain an interface name. +# +# PROTO Protocol - Must be "tcp", "udp", "icmp", "ipp2p", +# a number, or "all". "ipp2p" requires ipp2p match +# support in your kernel and iptables. # # PORT(S) Destination Ports. A comma-separated list of Port # names (from /etc/services), port numbers or port # ranges; if the protocol is "icmp", this column is # interpreted as the destination icmp-type(s). # +# If the protocol is ipp2p, this column is interpreted +# as an ipp2p option without the leading "--" (example "bit" +# for bit-torrent). If no PORT is given, "ipp2p" is +# assumed. +# # This column is ignored if PROTOCOL = all but must be # entered if any of the following field is supplied. # In that case, it is suggested that this field contain # "-" # -# CLIENT PORT(S) (Optional) Port(s) used by the client. If omitted, +# SOURCE PORT(S) (Optional) Source port(s). If omitted, # any source port is acceptable. Specified as a comma- # separated list of port names, port numbers or port # ranges. @@ -75,9 +132,21 @@ # []:[] # # The colon is optionnal when specifying only a user. -# Examples : john: / john / :users / john:users +# Examples : john: / john / :users / john:users # +# TEST Defines a test on the existing packet or connection mark. +# The rule will match only if the test returns true. Tests +# have the format [!][/][:C] +# +# Where: +# +# ! Inverts the test (not equal) +# Value of the packet or connection mark. +# A mask to be applied to the mark before +# testing +# :C Designates a connection mark. If omitted, +# the packet mark's value is tested. ############################################################################## -#MARK SOURCE DEST PROTO PORT(S) CLIENT USER +#MARK SOURCE DEST PROTO PORT(S) CLIENT USER TEST # PORT(S) #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Lrp2/etc/shorewall/tos b/Lrp2/etc/shorewall/tos index 9f9d2bd91..1a41a5d6c 100644 --- a/Lrp2/etc/shorewall/tos +++ b/Lrp2/etc/shorewall/tos @@ -1,5 +1,5 @@ # -# Shorewall 2.0 -- /etc/shorewall/tos +# Shorewall 2.2 -- /etc/shorewall/tos # # This file defines rules for setting Type Of Service (TOS) # @@ -43,10 +43,4 @@ # ############################################################################## #SOURCE DEST PROTOCOL SOURCE PORTS DEST PORTS TOS -all all tcp - 22 16 -all all tcp 22 - 16 -all all tcp - 21 16 -all all tcp 21 - 16 -all all tcp 20 - 8 -all all tcp - 20 8 #LAST LINE -- Add your entries above -- DO NOT REMOVE diff --git a/Lrp2/etc/shorewall/tunnels b/Lrp2/etc/shorewall/tunnels index 2c032cb21..c764d63ba 100644 --- a/Lrp2/etc/shorewall/tunnels +++ b/Lrp2/etc/shorewall/tunnels @@ -1,5 +1,5 @@ # -# Shorewall 2.0 - /etc/shorewall/tunnels +# Shorewall 2.2 - /etc/shorewall/tunnels # # This file defines IPSEC, GRE, IPIP and OPENVPN tunnels. # @@ -9,7 +9,7 @@ # # The columns are: # -# TYPE -- must start in column 1 and be "ipsec", "ipsecnat","ip" +# TYPE -- must start in column 1 and be "ipsec", "ipsecnat","ipip" # "gre", "6to4", "pptpclient", "pptpserver", "openvpn" or # "generic" # @@ -34,7 +34,10 @@ # # GATEWAY -- The IP address of the remote tunnel gateway. If the # remote getway has no fixed address (Road Warrior) -# then specify the gateway as 0.0.0.0/0. +# then specify the gateway as 0.0.0.0/0. May be +# specified as a network address and if your kernel and +# iptables include iprange match support then IP address +# ranges are also allowed. # # GATEWAY # ZONES -- Optional. If the gateway system specified in the third diff --git a/Lrp2/etc/shorewall/zones b/Lrp2/etc/shorewall/zones index 7b50b4fd3..74c828682 100755 --- a/Lrp2/etc/shorewall/zones +++ b/Lrp2/etc/shorewall/zones @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/zones +# Shorewall 2.2 /etc/shorewall/zones # # This file determines your network zones. Columns are: # diff --git a/Lrp2/sbin/shorewall b/Lrp2/sbin/shorewall index d0d9ca1a2..fd1d8ac0c 100755 --- a/Lrp2/sbin/shorewall +++ b/Lrp2/sbin/shorewall @@ -1,6 +1,6 @@ #!/bin/sh # -# Shorewall Packet Filtering Firewall Control Program - V2.0 - 3/14/2004 +# Shorewall Packet Filtering Firewall Control Program - V2.2 # # This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] # @@ -33,7 +33,7 @@ # # shorewall add [:] zone Adds a host or subnet to a zone # shorewall delete [:] zone Deletes a host or subnet from a zone -# shorewall start Starts the firewall +# shorewall start Starts the firewall # shorewall restart Restarts the firewall # shorewall stop Stops the firewall # shorewall monitor [ refresh-interval ] Repeatedly Displays firewall status @@ -134,6 +134,24 @@ showchain() # $1 = name of chain fi } +# +# The 'awk' hack that compensates for a bug in iptables-save (actually in libipt_policy.so) and can be removed when that bug is fixed. +# + +iptablesbug() +{ + if qt which awk ; then + awk 'BEGIN {sline=""; };\ + /^-j/ { print sline $0; next };\ + /-m policy.*-j/ { print $0; next };\ + /-m policy/ { sline=$0; next };\ + {print ; sline="" }' + else + echo " Warning: You don't have 'awk' on this system so the output of the save command may be unusable" >&2 + cat + fi +} + # # Validate the value of RESTOREFILE # @@ -174,6 +192,19 @@ get_config() { [ -n "$LOGFORMAT" ] || LOGFORMAT="Shorewall:" + if [ -n "$IPTABLES" ]; then + if [ ! -e "$IPTABLES" ]; then + echo " ERROR: The program specified in IPTABLES does not exist or is not executable" >&2 + exit 2 + fi + else + IPTABLES=$(which iptables 2> /dev/null) + if [ -z "$IPTABLES" ] ; then + echo " ERROR: Can't find iptables executable" >&2 + exit 2 + fi + fi + if [ -n "$SHOREWALL_SHELL" ]; then if [ ! -e "$SHOREWALL_SHELL" ]; then echo " ERROR: The program specified in SHOREWALL_SHELL does not exist or is not executable" >&2 @@ -205,7 +236,7 @@ display_chains() TMPFILE=$(mktempfile) [ -n "$TMPFILE" ] || { echo " ERROR:Cannot create temporary file" >&2; exit 1; } - iptables -L $IPT_OPTIONS >> $TMPFILE + $IPTABLES -L $IPT_OPTIONS >> $TMPFILE clear echo "$banner $(date)" @@ -288,7 +319,7 @@ display_chains() qt rm -f $TMPFILE else - iptables -L -n -v + $IPTABLES -L -n -v timed_read fi trap - 1 2 3 4 5 6 9 @@ -315,10 +346,9 @@ packet_log() # $1 = number of messages [ -n "$realtail" ] && options="-n$1" - grep "${LOGFORMAT}\|ipt_unclean" $LOGFILE | \ + grep "${LOGFORMAT}" $LOGFILE | \ sed s/" kernel:"// | \ sed s/" $host $LOGFORMAT"/" "/ | \ - sed s/" $host kernel: ipt_unclean: "/" "/ | \ sed 's/MAC=.* SRC=/SRC=/' | \ tail $options } @@ -388,9 +418,8 @@ monitor_firewall() # $1 = timeout -- if negative, prompt each time that # an 'interesting' packet count changes { - get_config host=$(echo $HOSTNAME | sed 's/\..*$//') - oldrejects=$(iptables -L -v -n | grep 'LOG') + oldrejects=$($IPTABLES -L -v -n | grep 'LOG') if [ $1 -lt 0 ]; then let "timeout=- $1" @@ -423,7 +452,7 @@ monitor_firewall() # $1 = timeout -- if negative, prompt each time that show_reset - rejects=$(iptables -L -v -n | grep 'LOG') + rejects=$($IPTABLES -L -v -n | grep 'LOG') if [ "$rejects" != "$oldrejects" ]; then oldrejects="$rejects" @@ -450,7 +479,7 @@ monitor_firewall() # $1 = timeout -- if negative, prompt each time that echo echo "NAT Status" echo - iptables -t nat -L $IPT_OPTIONS + $IPTABLES -t nat -L $IPT_OPTIONS timed_read clear @@ -459,7 +488,7 @@ monitor_firewall() # $1 = timeout -- if negative, prompt each time that echo echo "TOS/MARK Status" echo - iptables -t mangle -L $IPT_OPTIONS + $IPTABLES -t mangle -L $IPT_OPTIONS timed_read clear @@ -498,9 +527,8 @@ logwatch() # $1 = timeout -- if negative, prompt each time that # an 'interesting' packet count changes { - get_config host=$(echo $HOSTNAME | sed 's/\..*$//') - oldrejects=$(iptables -L -v -n | grep 'LOG') + oldrejects=$($IPTABLES -L -v -n | grep 'LOG') if [ $1 -lt 0 ]; then timeout=$((- $1)) @@ -522,7 +550,7 @@ logwatch() # $1 = timeout -- if negative, prompt each time that show_reset - rejects=$(iptables -L -v -n | grep 'LOG') + rejects=$($IPTABLES -L -v -n | grep 'LOG') if [ "$rejects" != "$oldrejects" ]; then oldrejects="$rejects" @@ -562,11 +590,11 @@ usage() # $1 = exit status { echo "Usage: $(basename $0) [debug|trace] [nolock] [-c ] [ -x ] [ -q ] [ -f ] " echo "where is one of:" - echo " add [:] " + echo " add [:{[:]|}[,...]] ... " echo " allow
..." - echo " check" + echo " check [ ]" echo " clear" - echo " delete [:] " + echo " delete [:{[:]|}[,...]] ... " echo " drop
..." echo " forget [ ]" echo " help [ | host | address ]" @@ -578,15 +606,17 @@ usage() # $1 = exit status echo " refresh" echo " reject
..." echo " reset" - echo " restart" + echo " restart [ ]" echo " restore [ ]" echo " save [ ]" - echo " show [ [ ... ]|classifiers|connections|log|nat|tc|tos]" - echo " start" + echo " show [ [ ... ]|classifiers|connections|log|nat|tc|tos|zones]" + echo " start [ ]" echo " stop" echo " status" echo " try [ ]" echo " version" + echo + echo "The -c and -f options may not be specified with a in the start, restart and check commands" exit $1 } @@ -598,8 +628,11 @@ show_reset() { echo "Counters reset $(cat $STATEDIR/restarted)" && \ echo } - -show_proc() { +# +# Display's the passed file name followed by "=" and the file's contents. +# +show_proc() # $1 = name of a file +{ [ -f $1 ] && echo " $1 = $(cat $1)" } @@ -721,6 +754,8 @@ ensure_config_path export CONFIG_PATH +get_config + [ -z "${STATEDIR}" ] && STATEDIR=/var/state/shorewall if [ ! -f $FIREWALL ]; then @@ -765,8 +800,28 @@ esac case "$1" in start) - [ $# -ne 1 ] && usage 1 - get_config + case $# in + 1) + ;; + 2) + [ -n "$SHOREWALL_DIR" -o -n "$FAST" ] && usage 2 + + if [ ! -d $2 ]; then + if [ -e $2 ]; then + echo "$2 is not a directory" >&2 && exit 2 + else + echo "Directory $2 does not exist" >&2 && exit 2 + fi + fi + + SHOREWALL_DIR=$2 + export SHOREWALL_DIR + ;; + *) + usage 1 + ;; + esac + if [ -n "$FAST" ]; then RESTOREPATH=/var/lib/shorewall/$RESTOREFILE @@ -783,15 +838,37 @@ case "$1" in exec $SHOREWALL_SHELL $FIREWALL $debugging $nolock start fi ;; - stop|restart|reset|clear|refresh|check) + stop|reset|clear|refresh) [ $# -ne 1 ] && usage 1 - get_config + exec $SHOREWALL_SHELL $FIREWALL $debugging $nolock $1 + ;; + check|restart) + case $# in + 1) + ;; + 2) + [ -n "$SHOREWALL_DIR" ] && usage 2 + + if [ ! -d $2 ]; then + if [ -e $2 ]; then + echo "$2 is not a directory" >&2 && exit 2 + else + echo "Directory $2 does not exist" >&2 && exit 2 + fi + fi + + SHOREWALL_DIR=$2 + export SHOREWALL_DIR + ;; + *) + usage 1 + ;; + esac exec $SHOREWALL_SHELL $FIREWALL $debugging $nolock $1 ;; add|delete) - [ $# -ne 3 ] && usage 1 - get_config - exec $SHOREWALL_SHELL $FIREWALL $debugging $nolock $1 $2 $3 + [ $# -lt 3 ] && usage 1 + exec $SHOREWALL_SHELL $FIREWALL $debugging $nolock $@ ;; show|list) [ -n "$debugging" ] && set -x @@ -807,18 +884,17 @@ case "$1" in echo "Shorewall-$version NAT at $HOSTNAME - $(date)" echo show_reset - iptables -t nat -L $IPT_OPTIONS + $IPTABLES -t nat -L $IPT_OPTIONS ;; tos|mangle) [ $# -gt 2 ] && usage 1 echo "Shorewall-$version TOS at $HOSTNAME - $(date)" echo show_reset - iptables -t mangle -L $IPT_OPTIONS + $IPTABLES -t mangle -L $IPT_OPTIONS ;; log) [ $# -gt 2 ] && usage 1 - get_config echo "Shorewall-$version Log at $HOSTNAME - $(date)" echo show_reset @@ -837,6 +913,24 @@ case "$1" in echo show_classifiers ;; + zones) + [ $# -gt 2 ] && usage 1 + [ -z "${STATEDIR}" ] && STATEDIR=/var/state/shorewall + if [ -f $STATEDIR/zones ]; then + echo "Shorewall-$version Zones at $HOSTNAME - $(date)" + echo + while read zone hosts; do + echo $zone + for host in $hosts; do + echo " $host" + done + done < $STATEDIR/zones + echo + else + echo " ERROR: $STATEDIR/zones does not exist" >&2 + exit 1 + fi + ;; *) shift @@ -845,10 +939,10 @@ case "$1" in show_reset if [ $# -gt 0 ]; then for chain in $*; do - iptables -L $chain $IPT_OPTIONS + $IPTABLES -L $chain $IPT_OPTIONS done else - iptables -L $IPT_OPTIONS + $IPTABLES -L $IPT_OPTIONS fi ;; esac @@ -866,29 +960,32 @@ case "$1" in status) [ -n "$debugging" ] && set -x [ $# -eq 1 ] || usage 1 - get_config clear echo "Shorewall-$version Status at $HOSTNAME - $(date)" echo show_reset host=$(echo $HOSTNAME | sed 's/\..*$//') - iptables -L $IPT_OPTIONS + $IPTABLES -L $IPT_OPTIONS echo packet_log 20 echo echo "NAT Table" echo - iptables -t nat -L $IPT_OPTIONS + $IPTABLES -t nat -L $IPT_OPTIONS echo echo "Mangle Table" echo - iptables -t mangle -L $IPT_OPTIONS + $IPTABLES -t mangle -L $IPT_OPTIONS echo cat /proc/net/ip_conntrack echo echo "IP Configuration" echo ip addr ls + echo + echo "IP Stats" + echo + ip -stat link ls if qt which brctl; then echo @@ -902,9 +999,10 @@ case "$1" in echo show_proc /proc/sys/net/ipv4/ip_forward + show_proc /proc/sys/net/ipv4/icmp_echo_ignore_all for directory in /proc/sys/net/ipv4/conf/*; do - for file in proxy_arp arp_filter rp_filter; do + for file in proxy_arp arp_filter rp_filter log_martians; do show_proc $directory/$file done done @@ -920,11 +1018,17 @@ case "$1" in echo ip route ls table $table done + + if qt which lsmod; then + echo + echo "Modules" + echo + lsmod | grep -E '^ip_|^ipt_' + fi ;; hits) [ -n "$debugging" ] && set -x [ $# -eq 1 ] || usage 1 - get_config clear echo "Shorewall-$version Hits at $HOSTNAME - $(date)" echo @@ -972,10 +1076,10 @@ case "$1" in [ -n "$SHOREWALL_DIR" ] && startup_error "Error: -c option may not be used with \"try\"" [ $# -lt 2 -o $# -gt 3 ] && usage 1 if ! $0 $debugging -c $2 restart; then - if ! iptables -L shorewall > /dev/null 2> /dev/null; then + if ! $IPTABLES -L shorewall > /dev/null 2> /dev/null; then $0 start fi - elif ! iptables -L shorewall > /dev/null 2> /dev/null; then + elif ! $IPTABLES -L shorewall > /dev/null 2> /dev/null; then $0 start elif [ $# -eq 3 ]; then sleep $3 @@ -998,9 +1102,9 @@ case "$1" in mutex_on while [ $# -gt 1 ]; do shift - qt iptables -D dynamic -s $1 -j reject - qt iptables -D dynamic -s $1 -j DROP - iptables -A dynamic -s $1 -j DROP || break 1 + qt $IPTABLES -D dynamic -s $1 -j reject + qt $IPTABLES -D dynamic -s $1 -j DROP + $IPTABLES -A dynamic -s $1 -j DROP || break 1 echo "$1 Dropped" done mutex_off @@ -1011,9 +1115,9 @@ case "$1" in mutex_on while [ $# -gt 1 ]; do shift - qt iptables -D dynamic -s $1 -j reject - qt iptables -D dynamic -s $1 -j DROP - iptables -A dynamic -s $1 -j reject || break 1 + qt $IPTABLES -D dynamic -s $1 -j reject + qt $IPTABLES -D dynamic -s $1 -j DROP + $IPTABLES -A dynamic -s $1 -j reject || break 1 echo "$1 Rejected" done mutex_off @@ -1024,7 +1128,7 @@ case "$1" in mutex_on while [ $# -gt 1 ]; do shift - if qt iptables -D dynamic -s $1 -j reject || qt iptables -D dynamic -s $1 -j DROP; then + if qt $IPTABLES -D dynamic -s $1 -j reject || qt $IPTABLES -D dynamic -s $1 -j DROP; then echo "$1 Allowed" else echo "$1 Not Dropped or Rejected" @@ -1035,8 +1139,6 @@ case "$1" in save) [ -n "$debugging" ] && set -x - get_config - case $# in 1) ;; @@ -1053,7 +1155,7 @@ case "$1" in mutex_on - if qt iptables -L shorewall -n; then + if qt $IPTABLES -L shorewall -n; then [ -d /var/lib/shorewall ] || mkdir -p /var/lib/shorewall if [ -f $RESTOREPATH -a ! -x $RESTOREPATH ]; then @@ -1064,11 +1166,11 @@ case "$1" in echo " ERROR: Reserved file name: $RESTOREFILE" ;; *) - if iptables -L dynamic -n > /var/lib/shorewall/save; then + if $IPTABLES -L dynamic -n > /var/lib/shorewall/save; then echo " Dynamic Rules Saved" if [ -f /var/lib/shorewall/restore-base ]; then cp -f /var/lib/shorewall/restore-base /var/lib/shorewall/restore-$$ - if iptables-save >> /var/lib/shorewall/restore-$$ ; then + if iptables-save | iptablesbug >> /var/lib/shorewall/restore-$$ ; then echo __EOF__ >> /var/lib/shorewall/restore-$$ [ -f /var/lib/shorewall/restore-tail ] && \ cat /var/lib/shorewall/restore-tail >> /var/lib/shorewall/restore-$$ @@ -1094,7 +1196,6 @@ case "$1" in mutex_off ;; forget) - get_config case $# in 1) ;; @@ -1114,7 +1215,7 @@ case "$1" in rm -f $RESTOREPATH echo " $RESTOREPATH removed" elif [ -f $RESTOREPATH ]; then - echo " ERROR: $RESTOREPATH exists and is not a saved Shorewall configuration" + echo " $RESTOREPATH exists and is not a saved Shorewall configuration" fi ;; ipcalc) @@ -1153,7 +1254,6 @@ case "$1" in esac ;; restore) - get_config case $# in 1) ;; diff --git a/Lrp2/usr/share/shorewall/action.AllowAuth b/Lrp2/usr/share/shorewall/action.AllowAuth index 78bdc1266..af54a9e9c 100644 --- a/Lrp2/usr/share/shorewall/action.AllowAuth +++ b/Lrp2/usr/share/shorewall/action.AllowAuth @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowAuth +# Shorewall 2.2 /usr/share/shorewall/action.AllowAuth # # This action accepts Auth (identd) traffic. # diff --git a/Lrp2/usr/share/shorewall/action.AllowDNS b/Lrp2/usr/share/shorewall/action.AllowDNS index 2ac6a72ce..9887b9795 100644 --- a/Lrp2/usr/share/shorewall/action.AllowDNS +++ b/Lrp2/usr/share/shorewall/action.AllowDNS @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowDNS +# Shorewall 2.2 /usr/share/shorewall/action.AllowDNS # # This action accepts DNS traffic. # diff --git a/Lrp2/usr/share/shorewall/action.AllowFTP b/Lrp2/usr/share/shorewall/action.AllowFTP index cab5fa4e1..0a0c9951b 100644 --- a/Lrp2/usr/share/shorewall/action.AllowFTP +++ b/Lrp2/usr/share/shorewall/action.AllowFTP @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowFTP +# Shorewall 2.2 /usr/share/shorewall/action.AllowFTP # # This action accepts FTP traffic. See # http://www.shorewall.net/FTP.html for additional considerations. diff --git a/Lrp2/usr/share/shorewall/action.AllowICMPs b/Lrp2/usr/share/shorewall/action.AllowICMPs new file mode 100644 index 000000000..7235d8dff --- /dev/null +++ b/Lrp2/usr/share/shorewall/action.AllowICMPs @@ -0,0 +1,11 @@ +# +# Shorewall 2.1 /usr/share/shorewall/action.AllowICMPs +# +# ACCEPT needed ICMP types +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +# +ACCEPT - - icmp fragmentation-needed +ACCEPT - - icmp time-exceeded diff --git a/Lrp2/usr/share/shorewall/action.AllowIMAP b/Lrp2/usr/share/shorewall/action.AllowIMAP index 333bdf779..71e7b15d1 100644 --- a/Lrp2/usr/share/shorewall/action.AllowIMAP +++ b/Lrp2/usr/share/shorewall/action.AllowIMAP @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowIMAP +# Shorewall 2.2 /usr/share/shorewall/action.AllowIMAP # # This action accepts IMAP traffic (secure and insecure): # diff --git a/Lrp2/usr/share/shorewall/action.AllowNNTP b/Lrp2/usr/share/shorewall/action.AllowNNTP index 3bf9f4926..a5d68b49e 100644 --- a/Lrp2/usr/share/shorewall/action.AllowNNTP +++ b/Lrp2/usr/share/shorewall/action.AllowNNTP @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /usr/share/shorewall/action.AllowNNTP +# Shorewall 2.2 /usr/share/shorewall/action.AllowNNTP # # This action accepts NNTP traffic (Usenet) and encrypted NNTP (NNTPS) # diff --git a/Lrp2/usr/share/shorewall/action.AllowNTP b/Lrp2/usr/share/shorewall/action.AllowNTP index 6ef93652c..936954769 100644 --- a/Lrp2/usr/share/shorewall/action.AllowNTP +++ b/Lrp2/usr/share/shorewall/action.AllowNTP @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowNTP +# Shorewall 2.2 /usr/share/shorewall/action.AllowNTP # # This action accepts NTP traffic (ntpd). # @@ -7,4 +7,5 @@ #TARGET SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE # PORT PORT(S) DEST LIMIT ACCEPT - - udp 123 +ACCEPT - - udp 1024: 123 #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Lrp2/usr/share/shorewall/action.AllowPCA b/Lrp2/usr/share/shorewall/action.AllowPCA index bda0e4a1f..b6e424ca3 100644 --- a/Lrp2/usr/share/shorewall/action.AllowPCA +++ b/Lrp2/usr/share/shorewall/action.AllowPCA @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowPCA +# Shorewall 2.2 /usr/share/shorewall/action.AllowPCA # # This action accepts PCAnywere (tm) # diff --git a/Lrp2/usr/share/shorewall/action.AllowPOP3 b/Lrp2/usr/share/shorewall/action.AllowPOP3 index b7756fee5..4634b9bbd 100644 --- a/Lrp2/usr/share/shorewall/action.AllowPOP3 +++ b/Lrp2/usr/share/shorewall/action.AllowPOP3 @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowPOP3 +# Shorewall 2.2 /usr/share/shorewall/action.AllowPOP3 # # This action accepts POP3 traffic (secure and insecure): # diff --git a/Lrp2/usr/share/shorewall/action.AllowPing b/Lrp2/usr/share/shorewall/action.AllowPing index f18492201..4ef4eeae1 100644 --- a/Lrp2/usr/share/shorewall/action.AllowPing +++ b/Lrp2/usr/share/shorewall/action.AllowPing @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowPing +# Shorewall 2.2 /usr/share/shorewall/action.AllowPing # # This action accepts 'ping' requests. # diff --git a/Lrp2/usr/share/shorewall/action.AllowRdate b/Lrp2/usr/share/shorewall/action.AllowRdate index 34cb7f75c..5c1d8054f 100644 --- a/Lrp2/usr/share/shorewall/action.AllowRdate +++ b/Lrp2/usr/share/shorewall/action.AllowRdate @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowRdate +# Shorewall 2.2 /usr/share/shorewall/action.AllowRdate # # This action accepts remote time retrieval (rdate). # diff --git a/Lrp2/usr/share/shorewall/action.AllowSMB b/Lrp2/usr/share/shorewall/action.AllowSMB index 8914eae98..b7f1e4412 100644 --- a/Lrp2/usr/share/shorewall/action.AllowSMB +++ b/Lrp2/usr/share/shorewall/action.AllowSMB @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowSMB +# Shorewall 2.2 /usr/share/shorewall/action.AllowSMB # # Allow Microsoft SMB traffic. You need to invoke this action in # both directions. diff --git a/Lrp2/usr/share/shorewall/action.AllowSMTP b/Lrp2/usr/share/shorewall/action.AllowSMTP index 5a802a2d1..2ad5f2597 100644 --- a/Lrp2/usr/share/shorewall/action.AllowSMTP +++ b/Lrp2/usr/share/shorewall/action.AllowSMTP @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowSMTP +# Shorewall 2.2 /usr/share/shorewall/action.AllowSMTP # # This action accepts SMTP (email) traffic. # diff --git a/Lrp2/usr/share/shorewall/action.AllowSNMP b/Lrp2/usr/share/shorewall/action.AllowSNMP index 11d78d126..33b1b4c0d 100644 --- a/Lrp2/usr/share/shorewall/action.AllowSNMP +++ b/Lrp2/usr/share/shorewall/action.AllowSNMP @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowSNMP +# Shorewall 2.2 /usr/share/shorewall/action.AllowSNMP # # This action accepts SNMP traffic (including traps): # diff --git a/Lrp2/usr/share/shorewall/action.AllowSSH b/Lrp2/usr/share/shorewall/action.AllowSSH index 78e25bba9..71ae5adbf 100644 --- a/Lrp2/usr/share/shorewall/action.AllowSSH +++ b/Lrp2/usr/share/shorewall/action.AllowSSH @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowSSH +# Shorewall 2.2 /usr/share/shorewall/action.AllowSSH # # This action accepts secure shell (SSH) traffic. # diff --git a/Lrp2/usr/share/shorewall/action.AllowTelnet b/Lrp2/usr/share/shorewall/action.AllowTelnet index 5eebbb095..3b06d098a 100644 --- a/Lrp2/usr/share/shorewall/action.AllowTelnet +++ b/Lrp2/usr/share/shorewall/action.AllowTelnet @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowTelnet +# Shorewall 2.2 /usr/share/shorewall/action.AllowTelnet # # This action accepts Telnet traffic. For traffic over the # internet, telnet is inappropriate; use SSH instead diff --git a/Lrp2/usr/share/shorewall/action.AllowTrcrt b/Lrp2/usr/share/shorewall/action.AllowTrcrt index 1b6180003..9fbce93fa 100644 --- a/Lrp2/usr/share/shorewall/action.AllowTrcrt +++ b/Lrp2/usr/share/shorewall/action.AllowTrcrt @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowTrcrt +# Shorewall 2.2 /usr/share/shorewall/action.AllowTrcrt # # This action accepts Traceroute (for up to 30 hops): # diff --git a/Lrp2/usr/share/shorewall/action.AllowVNC b/Lrp2/usr/share/shorewall/action.AllowVNC index 423c30c77..bf6a40aa9 100644 --- a/Lrp2/usr/share/shorewall/action.AllowVNC +++ b/Lrp2/usr/share/shorewall/action.AllowVNC @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowVNC +# Shorewall 2.2 /usr/share/shorewall/action.AllowVNC # # This action accepts VNC traffic for VNC display's 0 - 9. # diff --git a/Lrp2/usr/share/shorewall/action.AllowVNCL b/Lrp2/usr/share/shorewall/action.AllowVNCL index 83ff3fe81..2bcabd2a4 100644 --- a/Lrp2/usr/share/shorewall/action.AllowVNCL +++ b/Lrp2/usr/share/shorewall/action.AllowVNCL @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowVNC +# Shorewall 2.2 /usr/share/shorewall/action.AllowVNCL # # This action accepts VNC traffic from Vncservers to Vncviewers in listen mode. # diff --git a/Lrp2/usr/share/shorewall/action.AllowWeb b/Lrp2/usr/share/shorewall/action.AllowWeb index f88028b12..f32049606 100644 --- a/Lrp2/usr/share/shorewall/action.AllowWeb +++ b/Lrp2/usr/share/shorewall/action.AllowWeb @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.AllowWeb +# Shorewall 2.2 /usr/share/shorewall/action.AllowWeb # # This action accepts WWW traffic (secure and insecure): # @@ -7,5 +7,5 @@ #TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ # PORT PORT(S) LIMIT GROUP ACCEPT - - tcp 80 -ACCEPT - - TCP 443 +ACCEPT - - tcp 443 #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Lrp2/usr/share/shorewall/action.Drop b/Lrp2/usr/share/shorewall/action.Drop index 721a46126..fc8188d18 100644 --- a/Lrp2/usr/share/shorewall/action.Drop +++ b/Lrp2/usr/share/shorewall/action.Drop @@ -1,16 +1,49 @@ # -# Shorewall 2.0 /etc/shorewall/action.Drop +# Shorewall 2.2 /usr/share/shorewall/action.Drop # # The default DROP common rules # +# This action is invoked before a DROP policy is enforced. The purpose of the action +# is: +# +# a) Avoid logging lots of useless cruft. +# b) Ensure that 'auth' requests are rejected, even if the policy is DROP. +# Otherwise, you may experience problems establishing connections with +# servers that use auth. +# c) Ensure that certain ICMP packets that are necessary for successful +# internet operation are always ACCEPTed. +# +# IF YOU ARE HAVING CONNECTION PROBLEMS, CHANGING THIS FILE WON'T HELP!!!!!!!!!!!! ###################################################################################### -#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ -# PORT PORT(S) LIMIT GROUP +#TARGET SOURCE DEST PROTO +# +# Reject 'auth' +# RejectAuth +# +# Don't log broadcasts +# dropBcast +# +# ACCEPT critical ICMP types +# +AllowICMPs - - icmp +# +# Drop packets that in the INVALID state -- these are usually ICMP packets and just +# confuse people when they appear in the log. +# dropInvalid +# +# Drop Microsoft noise so that it doesn't clutter up the log. +# DropSMB DropUPnP -dropNotSyn +# +# Drop 'newnotsyn' traffic so that it doesn't get logged. +# +dropNotSyn - - tcp +# +# Drop late-arriving DNS replies. These are just a nuisance and clutter up the log. +# DropDNSrep #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Lrp2/usr/share/shorewall/action.DropDNSrep b/Lrp2/usr/share/shorewall/action.DropDNSrep index 949e3e655..760ac92e3 100644 --- a/Lrp2/usr/share/shorewall/action.DropDNSrep +++ b/Lrp2/usr/share/shorewall/action.DropDNSrep @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.DropDNSrep +# Shorewall 2.2 /usr/share/shorewall/action.DropDNSrep # # This action silently drops DNS UDP replies # diff --git a/Lrp2/usr/share/shorewall/action.DropPing b/Lrp2/usr/share/shorewall/action.DropPing index 5aba7c207..fb079bac6 100644 --- a/Lrp2/usr/share/shorewall/action.DropPing +++ b/Lrp2/usr/share/shorewall/action.DropPing @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.DropPing +# Shorewall 2.2 /usr/share/shorewall/action.DropPing # # This action silently drops 'ping' requests. # diff --git a/Lrp2/usr/share/shorewall/action.DropSMB b/Lrp2/usr/share/shorewall/action.DropSMB index 03a9ee15b..ac2218470 100644 --- a/Lrp2/usr/share/shorewall/action.DropSMB +++ b/Lrp2/usr/share/shorewall/action.DropSMB @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.DropSMB +# Shorewall 2.2 /usr/share/shorewall/action.DropSMB # # This action silently drops Microsoft SMB traffic # diff --git a/Lrp2/usr/share/shorewall/action.DropUPnP b/Lrp2/usr/share/shorewall/action.DropUPnP index 8ef56119c..30a4865f8 100644 --- a/Lrp2/usr/share/shorewall/action.DropUPnP +++ b/Lrp2/usr/share/shorewall/action.DropUPnP @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.DropUPnP +# Shorewall 2.2 /usr/share/shorewall/action.DropUPnP # # This action silently drops UPnP probes on UDP port 1900 # diff --git a/Lrp2/usr/share/shorewall/action.Reject b/Lrp2/usr/share/shorewall/action.Reject index 8cfd666ec..9e116eb22 100644 --- a/Lrp2/usr/share/shorewall/action.Reject +++ b/Lrp2/usr/share/shorewall/action.Reject @@ -1,16 +1,46 @@ # -# Shorewall 2.0 /etc/shorewall/action.Reject +# Shorewall 2.2 /usr/share/shorewall/action.Reject # # The default REJECT action common rules # +# This action is invoked before a REJECT policy is enforced. The purpose of the action +# is: +# +# a) Avoid logging lots of useless cruft. +# b) Ensure that certain ICMP packets that are necessary for successful +# internet operation are always ACCEPTed. +# +# IF YOU ARE HAVING CONNECTION PROBLEMS, CHANGING THIS FILE WON'T HELP!!!!!!!!!!!! ###################################################################################### -#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ -# PORT PORT(S) LIMIT GROUP +#TARGET SOURCE DEST PROTO +# +# Don't log 'auth' REJECT +# RejectAuth +# +# Drop Broadcasts so they don't clutter up the log (broadcasts must *not* be rejected). +# dropBcast +# +# ACCEPT critical ICMP types +# +AllowICMPs - - icmp +# +# Drop packets that in the INVALID state -- these are usually ICMP packets and just +# confuse people when they appear in the log (these ICMPs cannot be rejected). +# dropInvalid +# +# Drop Microsoft noise so that it doesn't clutter up the lot. +# RejectSMB DropUPnP -dropNotSyn +# +# Drop 'newnotsyn' traffic so that it doesn't get logged. +# +dropNotSyn - - tcp +# +# Drop late-arriving DNS replies. These are just a nuisance and clutter up the log. +# DropDNSrep #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Lrp2/usr/share/shorewall/action.RejectAuth b/Lrp2/usr/share/shorewall/action.RejectAuth index e3675d5bb..a89ee4dfc 100644 --- a/Lrp2/usr/share/shorewall/action.RejectAuth +++ b/Lrp2/usr/share/shorewall/action.RejectAuth @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.RejectAuth +# Shorewall 2.2 /usr/share/shorewall/action.RejectAuth # # This action silently rejects Auth (tcp 113) traffic # diff --git a/Lrp2/usr/share/shorewall/action.RejectSMB b/Lrp2/usr/share/shorewall/action.RejectSMB index db820e5dc..19cc5af2d 100644 --- a/Lrp2/usr/share/shorewall/action.RejectSMB +++ b/Lrp2/usr/share/shorewall/action.RejectSMB @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.RejectSMB +# Shorewall 2.2 /usr/share/shorewall/action.RejectSMB # # This action silently rejects Microsoft SMB traffic # diff --git a/Lrp2/usr/share/shorewall/action.template b/Lrp2/usr/share/shorewall/action.template index b20af0e09..80152daa5 100644 --- a/Lrp2/usr/share/shorewall/action.template +++ b/Lrp2/usr/share/shorewall/action.template @@ -1,5 +1,5 @@ # -# Shorewall 2.0 /etc/shorewall/action.template +# Shorewall 2.2 /etc/shorewall/action.template # # This file is a template for files with names of the form # /etc/shorewall/action. where is an @@ -37,6 +37,10 @@ # ACCEPT:debugging). This causes the packet to be # logged at the specified level. # +# The special log level 'none' does not result in logging +# but rather exempts the rule from being overridden by a +# non-forcing log level when the action is invoked. +# # You may also specify ULOG (must be in upper case) as a # log level.This will log to the ULOG target for routing # to a separate log through use of ulogd @@ -61,6 +65,10 @@ # # 155.186.235.0/24 Subnet 155.186.235.0/24 # +# 10.0.0.4-10.0.0.9 Range of IP addresses; your +# kernel and iptables must have +# iprange match support. +# # 192.168.1.1,192.168.1.2 # Hosts 192.168.1.1 and # 192.168.1.2. @@ -77,10 +85,6 @@ # DEST Location of Server. Same as above with the exception that # MAC addresses are not allowed. # -# Unlike in the SOURCE column, you may specify a range of -# up to 256 IP addresses using the syntax -# -. -# # PROTO Protocol - Must be "tcp", "udp", "icmp", a number, or # "all". # @@ -155,6 +159,6 @@ # #of the 'kids' group # ###################################################################################### -#TARGET SOURCE DEST PROTO DEST SOURCE RATE -# PORT PORT(S) LIMIT +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Lrp2/usr/share/shorewall/actions.std b/Lrp2/usr/share/shorewall/actions.std index 89f9ad504..ccdc2eb4b 100644 --- a/Lrp2/usr/share/shorewall/actions.std +++ b/Lrp2/usr/share/shorewall/actions.std @@ -1,19 +1,17 @@ # -# Shorewall 2.0 /usr/share/shorewall/actions.std +# Shorewall 2.2 /usr/share/shorewall/actions.std # # # Builtin Actions are: # +# allowBcast #Silently Allow Broadcast/multicast # dropBcast #Silently Drop Broadcast/multicast # dropNonSyn #Silently Drop Non-syn TCP packets # rejNonSyn #Silently Reject Non-syn TCP packets -# logNonSyn #Log Non-syn TCP packets with disposition LOG -# dLogNonSyn #Log Non-syn TCP packets with disposition DROP -# rLogNonSyn #Log Non-syn TCP packets with disposition REJECT # dropInvalid #Silently Drop packets that are in the INVALID # #conntrack state. -# allowInvalid #Accept packets that are in the INVALID conntrack -# #state +# allowInvalid #Accept packets that are in the INVALID +# #conntrack state. # # The NonSyn logging builtins log at the level specified by LOGNEWNOTSYN in # shorewall.conf. If that option isn't specified then 'info' is used. @@ -36,6 +34,7 @@ AllowSMB #Allow MS Networking AllowAuth #Allow Auth (identd) AllowSMTP #Allow SMTP (Email) AllowPOP3 #Allow reading mail via POP3 +AllowICMPs #Allows critical ICMP types AllowIMAP #Allow reading mail via IMAP AllowTelnet #Allow Telnet Access (not recommended for use over the #Internet) diff --git a/Lrp2/usr/share/shorewall/bogons b/Lrp2/usr/share/shorewall/bogons index 46af67c47..43c37b1f2 100644 --- a/Lrp2/usr/share/shorewall/bogons +++ b/Lrp2/usr/share/shorewall/bogons @@ -1,5 +1,5 @@ # -# Shorewall 2.0-- Bogons File +# Shorewall 2.2-- Bogons File # # /etc/shorewall/bogons # @@ -14,7 +14,9 @@ # # Columns are: # -# SUBNET The subnet (host addresses also allowed) +# SUBNET The subnet (host addresses also allowed as are IP +# address ranges provided that your kernel and iptables +# include iprange match support). # TARGET Where to send packets to/from this subnet # RETURN - let the packet be processed normally # DROP - silently drop the packet diff --git a/Lrp2/usr/share/shorewall/firewall b/Lrp2/usr/share/shorewall/firewall index ae564c8f4..8f7e72314 100755 --- a/Lrp2/usr/share/shorewall/firewall +++ b/Lrp2/usr/share/shorewall/firewall @@ -1,10 +1,10 @@ #!/bin/sh # -# The Shoreline Firewall (Shorewall) Packet Filtering Firewall - V2.0 3/14/2004 +# The Shoreline Firewall (Shorewall) Packet Filtering Firewall - V2.2 # # This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] # -# (c) 1999,2000,2001,2002,2003 - Tom Eastep (teastep@shorewall.net) +# (c) 1999,2000,2001,2002,2003,2004,2005 - Tom Eastep (teastep@shorewall.net) # # Complete documentation is available at http://shorewall.net # @@ -74,7 +74,7 @@ fatal_error() # $* = Error Message } # -# Fatal error during startup -- generate an error message and abend with +# Fatal error during startup -- generate an error message and abend without # altering the state of the firewall # startup_error() # $* = Error Message @@ -153,10 +153,15 @@ append_file() # $1 = File Name # run_iptables() { - [ -n "$BRIDGING" ] && [ -f $TMP_DIR/physdev ] && rm -f $TMP_DIR/physdev + [ -n "$BRIDGING" ] && [ -f $TMP_DIR/physdev ] && rm -f $TMP_DIR/physdev + [ -n "$IPRANGE_MATCH" ] && [ -f $TMP_DIR/iprange ] && rm -f $TMP_DIR/iprange - if ! iptables $@ ; then - [ -z "$stopping" ] && { stop_firewall; exit 2; } + if ! $IPTABLES $@ ; then + if [ -z "$stopping" ]; then + error_message "ERROR: Command \"$IPTABLES $@\" Failed" + stop_firewall + exit 2 + fi fi } @@ -165,17 +170,15 @@ run_iptables() { # run_iptables2() { - if [ "x${*%!*}" = "x$*" ]; then - # - # No "!" in the command -- just execute it - # - run_iptables $@ - return - fi - # - # Need to insert white space before each "!" - # - run_iptables $(fix_bang $@) + case "$@" in + *!*) + run_iptables $(fix_bang $@) + ;; + *) + run_iptables $@ + ;; + esac + } # @@ -184,8 +187,9 @@ run_iptables2() { qt_iptables() { [ -n "$BRIDGING" ] && [ -f $TMP_DIR/physdev ] && rm -f $TMP_DIR/physdev + [ -n "$IPRANGE_MATCH" ] && [ -f $TMP_DIR/iprange ] && rm -f $TMP_DIR/iprange - qt iptables $@ + qt $IPTABLES $@ } # @@ -193,16 +197,11 @@ qt_iptables() { # run_ip() { if ! ip $@ ; then - [ -z "$stopping" ] && { stop_firewall; exit 2; } - fi -} - -# -# Run arp and if an error occurs, stop the firewall and quit -# -run_arp() { - if ! arp $@ ; then - [ -z "$stopping" ] && { stop_firewall; exit 2; } + if [ -z "$stopping" ]; then + error_message "ERROR: Command \"ip $@\" Failed" + stop_firewall + exit 2 + fi fi } @@ -211,7 +210,11 @@ run_arp() { # run_tc() { if ! tc $@ ; then - [ -z "$stopping" ] && { stop_firewall; exit 2; } + if [ -z "$stopping" ]; then + error_message "ERROR: Command \"tc $@\" Failed" + stop_firewall + exit 2 + fi fi } @@ -242,7 +245,7 @@ createchain2() # $1 = chain name, $2 = If "yes", create default rules { local c=$(chain_base $1) - if iptables -N $1; then + if $IPTABLES -N $1; then if [ $2 = yes ]; then run_iptables -A $1 -m state --state ESTABLISHED,RELATED -j ACCEPT @@ -273,7 +276,7 @@ havechain() # $1 = name of chain # chain_exists() # $1 = chain name { - qt iptables -L $1 -n + qt $IPTABLES -L $1 -n } # @@ -281,7 +284,7 @@ chain_exists() # $1 = chain name # mangle_chain_exists() # $1 = chain name { - qt iptables -t mangle -L $1 -n + qt $IPTABLES -t mangle -L $1 -n } # @@ -301,6 +304,12 @@ ensurechain1() # $1 = chain name # Add a rule to a chain creating the chain if necessary # addrule() # $1 = chain name, remainder of arguments specify the rule +{ + ensurechain $1 + run_iptables -A $@ +} + +addrule2() # $1 = chain name, remainder of arguments specify the rule { ensurechain $1 run_iptables2 -A $@ @@ -353,7 +362,7 @@ addnatrule() # $1 = chain name, remainder of arguments specify the rule # deletechain() # $1 = name of chain { - qt iptables -L $1 -n && qt iptables -F $1 && qt iptables -X $1 + qt $IPTABLES -L $1 -n && qt $IPTABLES -F $1 && qt $IPTABLES -X $1 } # @@ -409,7 +418,7 @@ find_interfaces() # $1 = interface zone local z local interface - for interface in $all_interfaces; do + for interface in $ALL_INTERFACES; do eval z=\$$(chain_base $interface)_zone [ "x${z}" = x${zne} ] && echo $interface done @@ -489,9 +498,9 @@ dnat_chain() # $1 = zone } # -# SNAT Chain to a zone +# SNAT Chain to a zone or from an interface # -snat_chain() # $1 = zone +snat_chain() # $1 = zone or interface { echo $(chain_base $1)_snat } @@ -515,7 +524,92 @@ first_chains() #$1 = interface } # -# Horrible hack to work around an iptables bug +# Horrible hack to work around an iptables limitation +# +iprange_echo() +{ + if [ -f $TMP_DIR/iprange ]; then + echo $@ + else + echo "-m iprange $@" + > $TMP_DIR/iprange + fi +} + + +# +# Source IP range +# +source_ip_range() # $1 = Address or Address Range +{ + case $1 in + *.*.*.*-*.*.*.*) + case $1 in + !*) + iprange_echo "! --src-range ${1#!}" + ;; + *) + iprange_echo "--src-range $1" + ;; + esac + ;; + *) + echo "-s $1" + ;; + esac +} + +# +# Destination IP range +# +dest_ip_range() # $1 = Address or Address Range +{ + case $1 in + *.*.*.*-*.*.*.*) + case $1 in + !*) + iprange_echo "! --dst-range ${1#!}" + ;; + *) + iprange_echo "--dst-range $1" + ;; + esac + ;; + *) + echo "-d $1" + ;; + esac +} + +both_ip_ranges() # $1 = Source address or range, $2 = dest address or range +{ + local prefix= match= + + case $1 in + *.*.*.*-*.*.*.*) + prefix="-m iprange" + match="--src-range $1" + ;; + *) + match="-s $1" + ;; + esac + + case $2 in + *.*.*.*-*.*.*.*) + prefix="-m iprange" + match="$match --dst-range $2" + ;; + *) + match="$match -d $2" + ;; + esac + + echo "$prefix $match" +} + +# +# Horrible hack to work around an iptables limitation # physdev_echo() { @@ -536,17 +630,17 @@ match_source_hosts() if [ -n "$BRIDGING" ]; then case $1 in *:*) - physdev_echo "--physdev-in ${1%:*} -s ${1#*:}" + physdev_echo "--physdev-in ${1%:*} $(source_ip_range ${1#*:})" ;; *.*.*.*) - echo -s $1 + echo $(source_ip_range $1) ;; *) physdev_echo "--physdev-in $1" ;; esac else - echo -s $1 + echo $(source_ip_range $1) fi } @@ -555,17 +649,17 @@ match_dest_hosts() if [ -n "$BRIDGING" ]; then case $1 in *:*) - physdev_echo "--physdev-out ${1%:*} -d ${1#*:}" + physdev_echo "--physdev-out ${1%:*} $(dest_ip_range ${1#*:})" ;; *.*.*.*) - echo -d $1 + echo $(dest_ip_range $1) ;; *) physdev_echo "--physdev-out $1" ;; esac else - echo -d $1 + echo $(dest_ip_range $1) fi } @@ -581,7 +675,7 @@ known_interface() # $1 = interface name { local iface - for iface in $all_interfaces ; do + for iface in $ALL_INTERFACES ; do if if_match $iface $1 ; then return 0 fi @@ -610,7 +704,53 @@ match_dest_dev() verify_interface() { - known_interface $1 || { [ -n $BRIDGING ] && list_search $1 $all_ports ; } + known_interface $1 || { [ -n "$BRIDGING" ] && list_search $1 $all_ports ; } +} + +# +# Determine if communication to/from a host is encrypted using IPSEC +# +is_ipsec_host() # $1 = zone, $2 = host +{ + eval local is_ipsec=\$${1}_is_ipsec + eval local hosts=\"\$${1}_ipsec_hosts\" + + test -n "$is_ipsec" || list_search $2 $hosts +} + +# +# Generate a match for decrypted packets +# +match_ipsec_in() # $1 = zone, $2 = host +{ + if is_ipsec_host $1 $2 ; then + eval local options=\"\$${1}_ipsec_options \$${1}_ipsec_in_options\" + echo "-m policy --pol ipsec --dir in $options" + elif [ -n "$POLICY_MATCH" ]; then + echo "-m policy --pol none --dir in" + fi +} + +# +# Generate a match for packets that will be encrypted +# +match_ipsec_out() # $1 = zone, $2 = host +{ + if is_ipsec_host $1 $2 ; then + eval local options=\"\$${1}_ipsec_options \$${1}_ipsec_out_options\" + echo "-m policy --pol ipsec --dir out $options" + elif [ -n "$POLICY_MATCH" ]; then + echo "-m policy --pol none --dir out" + fi +} + +# +# Jacket for ip_range() that takes care of iprange match +# + +firewall_ip_range() # $1 = IP address or range +{ + [ -n "$IPRANGE_MATCH" ] && echo $1 || ip_range $1 } # @@ -636,6 +776,17 @@ find_hosts() # $1 = host zone done < $TMP_DIR/hosts } +# +# Check for duplicate zone definitions +# +check_duplicate_zones() { + local localzones= + + for zone in $zones; do + list_search $zone $localzones && startup_error "Zone $zone is defined more than once" + localzones="$localzones $zone" + done +} # # Determine the interfaces on the firewall # @@ -680,15 +831,15 @@ determine_hosts() { networks=0.0.0.0/0 fi - for network in $networks; do + for networks in $networks; do if [ -z "$hosts" ]; then - hosts=$interface:$network + hosts=$interface:$networks else - hosts="$hosts $interface:$network" + hosts="$hosts $interface:$networks" fi if interface_has_option $interface routeback; then - eval ${zone}_routeback=\"$interface:$network \$${zone}_routeback\" + eval ${zone}_routeback=\"$interface:$networks \$${zone}_routeback\" fi done done @@ -757,7 +908,7 @@ validate_interfaces_file() { validate_zone $z || startup_error "Invalid zone ($z) in record \"$r\"" fi - list_search $interface $all_interfaces && \ + list_search $interface $ALL_INTERFACES && \ startup_error "Duplicate Interface $interface" wildcard= @@ -771,7 +922,7 @@ validate_interfaces_file() { ;; esac - all_interfaces="$all_interfaces $interface" + ALL_INTERFACES="$ALL_INTERFACES $interface" options=$(separate_list $options) iface=$(chain_base $interface) @@ -781,20 +932,7 @@ validate_interfaces_file() { for option in $options; do case $option in - dhcp|norfc1918|nobogons|tcpflags|newnotsyn|arp_filter|routefilter|blacklist|proxyarp|maclist|nosmurfs|-) - ;; - dropunclean|logunclean) - if [ -z "$found_obsolete_option" ]; then - found_obsolete_option=yes - error_message \ - "WARNING: The 'dropunclean' and 'logunclean' options are not supported by Shorewall 2.0" - error_message \ - " PLEASE STAND BY WHILE SHOREWALL REFORMATS YOUR HARD DRIVE TO REMOVE THESE OPTIONS..." - sleep 5 - error_message "GOTCHA!!!! :-)" - error_message \ - " Now please remove these options from your interfaces file -- Thanks" - fi + dhcp|norfc1918|nobogons|tcpflags|newnotsyn|arp_filter|routefilter|logmartians|sourceroute|blacklist|proxyarp|maclist|nosmurfs|-) ;; detectnets) [ -n "$wildcard" ] && \ @@ -809,7 +947,7 @@ validate_interfaces_file() { esac done - [ -z "$all_interfaces" ] && startup_error "No Interfaces Defined" + [ -z "$ALL_INTERFACES" ] && startup_error "No Interfaces Defined" done < $TMP_DIR/interfaces } @@ -827,62 +965,69 @@ validate_hosts_file() { list_search $1 $all_ports || all_ports="$all_ports $1" } - while read z hosts options; do - expandv z hosts options - r="$z $hosts $options" - validate_zone1 $z || startup_error "Invalid zone ($z) in record \"$r\"" + while read z hosts options; do + expandv z hosts options + r="$z $hosts $options" + validate_zone1 $z || startup_error "Invalid zone ($z) in record \"$r\"" - interface=${hosts%%:*} - iface=$(chain_base $interface) + interface=${hosts%%:*} + iface=$(chain_base $interface) - list_search $interface $all_interfaces || \ - startup_error "Unknown interface ($interface) in record \"$r\"" + list_search $interface $ALL_INTERFACES || \ + startup_error "Unknown interface ($interface) in record \"$r\"" - hosts=${hosts#*:} + hosts=${hosts#*:} - eval ports=\$${iface}_ports - eval zports=\$${z}_ports + eval ports=\$${iface}_ports + eval zports=\$${z}_ports - for host in $(separate_list $hosts); do + for host in $(separate_list $hosts); do + if [ -n "$BRIDGING" ]; then + case $host in + *:*) + known_interface ${host%:*} && \ + startup_error "Bridged interfaces may not be defined in /etc/shorewall/interfaces: $host" + check_bridge_port ${host%%:*} + ;; + *.*.*.*) + ;; + *) + known_interface $host && \ + startup_error "Bridged interfaces may not be defined in /etc/shorewall/interfaces: $host" + check_bridge_port $host + ;; + esac + fi - [ -n "$BRIDGING" ] && case $host in - *:*) - known_interface ${host%:*} && \ - startup_error "Bridged interfaces may not be defined in /etc/shorewall/interfaces: $host" - check_bridge_port ${host%%:*} - ;; - *.*.*.*) - ;; - *) - known_interface $host && \ - startup_error "Bridged interfaces may not be defined in /etc/shorewall/interfaces: $host" - check_bridge_port $host - ;; - esac + for option in $(separate_list $options) ; do + case $option in + maclist|norfc1918|nobogons|blacklist|tcpflags|nosmurfs|newnotsyn|-) + ;; + ipsec) + [ -n "$POLICY_MATCH" ] || \ + startup_error "Your kernel and/or iptables does not support policy match: ipsec" + eval ${z}_ipsec_hosts=\"\$${z}_ipsec_hosts $interface:$host\" + eval ${z}_is_complex=Yes + ;; + routeback) + [ -z "$ports" ] && \ + eval ${z}_routeback=\"$interface:$host \$${z}_routeback\" + ;; + *) + error_message "Warning: Invalid option ($option) in record \"$r\"" + ;; + esac + done + done - for option in $(separate_list $options) ; do - case $option in - maclist|norfc1918|nobogons|blacklist|tcpflags|nosmurfs|newnotsyn|-) - ;; - routeback) - [ -z "$ports" ] && \ - eval ${z}_routeback=\"$interface:$host \$${z}_routeback\" - ;; - *) - error_message "Warning: Invalid option ($option) in record \"$r\"" - ;; - esac - done - done + if [ -n "$ports" ]; then + eval ${iface}_ports=\"$ports\" + eval ${z}_ports=\"$zports\" + fi + + done < $TMP_DIR/hosts - if [ -n "$ports" ]; then - eval ${iface}_ports=\"$ports\" - eval ${z}_ports=\"$zports\" - fi - - done < $TMP_DIR/hosts - - [ -n "$all_ports" ] && echo " Bridge ports are: $all_ports" + [ -n "$all_ports" ] && echo " Bridge ports are: $all_ports" } # @@ -1025,7 +1170,7 @@ validate_policy() # Find broadcast addresses # find_broadcasts() { - for interface in $all_interfaces; do + for interface in $ALL_INTERFACES; do eval bcast=\$$(chain_base $interface)_broadcast if [ "x$bcast" = "xdetect" ]; then ip -f inet addr show $interface 2> /dev/null | grep 'inet.*brd' | sed 's/inet.*brd //; s/scope.*//;' | sort -u @@ -1039,7 +1184,7 @@ find_broadcasts() { # Find interface address--returns the first IP address assigned to the passed # device # -find_interface_address() # $1 = interface +find_first_interface_address() # $1 = interface { # # get the line of output containing the first IP address @@ -1056,21 +1201,12 @@ find_interface_address() # $1 = interface echo $addr | sed 's/inet //;s/\/.*//;s/ peer.*//' } -# -# Find interface addresses--returns the set of addresses assigned to the passed -# device -# -find_interface_addresses() # $1 = interface -{ - ip -f inet addr show $1 | grep inet | sed 's/inet //;s/\/.*//;s/ peer.*//' -} - # # Find interfaces that have the passed option specified # find_interfaces_by_option() # $1 = option { - for interface in $all_interfaces; do + for interface in $ALL_INTERFACES; do eval options=\$$(chain_base $interface)_options list_search $1 $options && echo $interface done @@ -1081,48 +1217,28 @@ find_interfaces_by_option() # $1 = option # find_hosts_by_option() # $1 = option { - local ignore hosts interface address addresses options + local ignore hosts interface address addresses options ipsec= list while read ignore hosts options; do expandv options - if list_search $1 $(separate_list $options); then + list=$(separate_list $options) + if list_search $1 $list; then + list_search ipsec $list && ipsec=ipsec || ipsec=none expandv hosts interface=${hosts%%:*} addresses=${hosts#*:} for address in $(separate_list $addresses); do - echo $interface:$address + echo ${ipsec}^$interface:$address done fi done < $TMP_DIR/hosts - for interface in $all_interfaces; do + for interface in $ALL_INTERFACES; do interface_has_option $interface $1 && \ - echo ${interface}:0.0.0.0/0 + echo none^${interface}:0.0.0.0/0 done } -# -# Determine if there are interfaces of the given zone and option -# -# Returns zero if any such interfaces are found and returns one otherwise. -# -have_interfaces_in_zone_with_option() # $1 = zone, $2 = option -{ - local zne=$1 - local z - local interface - - for interface in $all_interfaces; do - eval z=\$$(chain_base $interface)_zone - - [ "x$z" = "x$zne" ] && \ - list_search $1 $options && \ - return 0 - done - - return 1 -} - # # Flush and delete all user-defined chains in the filter table # @@ -1147,43 +1263,50 @@ run_user_exit() # $1 = file name # # Add a logging rule. # -log_rule_limit() # $1 = log level, $2 = chain, $3 = disposition , $4 = rate limit $5=log tag $... = predicates for the rule +log_rule_limit() # $1 = log level, $2 = chain, $3 = display Chain $4 = disposition , $5 = rate limit $6=log tag $7=command $... = predicates for the rule { local level=$1 local chain=$2 - local disposition=$3 + local displayChain=$3 + local disposition=$4 local rulenum= - local limit="${4:-$LOGLIMIT}" - local tag=${5:+$5 } + local limit="${5:-$LOGLIMIT}" + local tag=${6:+$6 } + local command=${7:--A} local prefix local base=$(chain_base $displayChain) - shift;shift;shift;shift;shift + shift;shift;shift;shift;shift;shift;shift + + if [ -n "$tag" -a -n "$LOGTAGONLY" ]; then + displayChain=$tag + tag= + fi if [ -n "$LOGRULENUMBERS" ]; then eval rulenum=\$${base}_logrules rulenum=${rulenum:-1} - prefix="$(printf "$LOGFORMAT" $chain $rulenum $disposition)${tag}" + prefix="$(printf "$LOGFORMAT" $displayChain $rulenum $disposition)${tag}" rulenum=$(($rulenum + 1)) eval ${base}_logrules=$rulenum else - prefix="$(printf "$LOGFORMAT" $chain $disposition)${tag}" + prefix="$(printf "$LOGFORMAT" $displayChain $disposition)${tag}" fi if [ ${#prefix} -gt 29 ]; then - prefix="$(echo $prefix | cut -b -29)" + prefix="$(echo $prefix | truncate 29)" error_message "Warning: Log Prefix shortened to \"$prefix\"" fi case $level in ULOG) - iptables -A $chain $@ $limit -j ULOG $LOGPARMS --ulog-prefix "$prefix" + $IPTABLES $command $chain $@ $limit -j ULOG $LOGPARMS --ulog-prefix "$prefix" ;; *) - iptables -A $chain $@ $limit -j LOG $LOGPARMS --log-level $level --log-prefix "$prefix" + $IPTABLES $command $chain $@ $limit -j LOG $LOGPARMS --log-level $level --log-prefix "$prefix" ;; esac @@ -1200,7 +1323,7 @@ log_rule() # $1 = log level, $2 = chain, $3 = disposition , $... = predicates fo shift;shift;shift - log_rule_limit $level $chain $disposition "$LOGLIMIT" "" $@ + log_rule_limit $level $chain $chain $disposition "$LOGLIMIT" "" -A $@ } # @@ -1341,7 +1464,7 @@ stop_firewall() { routeback= - if [ -n $options ]; then + if [ -n "$options" ]; then for option in $(separate_list $options); do case $option in routeback) @@ -1350,7 +1473,7 @@ stop_firewall() { else routeback=Yes for h in $(separate_list $host); do - iptables -A FORWARD -i $interface -s $h -o $interface -d $h -j ACCEPT + $IPTABLES -A FORWARD -i $interface -o $interface $(both_ip_ranges $h $h) -j ACCEPT done fi ;; @@ -1366,27 +1489,27 @@ stop_firewall() { for host in $hosts; do interface=${host%:*} networks=${host#*:} - iptables -A INPUT -i $interface -s $networks -j ACCEPT + $IPTABLES -A INPUT -i $interface $(source_ip_range $networks) -j ACCEPT [ -z "$ADMINISABSENTMINDED" ] && \ - iptables -A OUTPUT -o $interface -d $networks -j ACCEPT + $IPTABLES -A OUTPUT -o $interface $(dest_ip_range $networks) -j ACCEPT for host1 in $hosts; do - [ "$host" != "$host1" ] && iptables -A FORWARD -i $interface -s $networks -o ${host1%:*} -d ${host1#*:} -j ACCEPT + [ "$host" != "$host1" ] && $IPTABLES -A FORWARD -i $interface -o ${host1%:*} $(both_ip_ranges $networks ${host1#*:}) -j ACCEPT done done - iptables -A INPUT -i lo -j ACCEPT + $IPTABLES -A INPUT -i lo -j ACCEPT [ -z "$ADMINISABSENTMINDED" ] && \ - iptables -A OUTPUT -o lo -j ACCEPT + $IPTABLES -A OUTPUT -o lo -j ACCEPT for interface in $(find_interfaces_by_option dhcp); do - iptables -A INPUT -p udp -i $interface --dport 67:68 -j ACCEPT + $IPTABLES -A INPUT -p udp -i $interface --dport 67:68 -j ACCEPT [ -z "$ADMINISABSENTMINDED" ] && \ - iptables -A OUTPUT -p udp -o $interface --dport 67:68 -j ACCEPT + $IPTABLES -A OUTPUT -p udp -o $interface --dport 67:68 -j ACCEPT # # This might be a bridge # - iptables -A FORWARD -p udp -i $interface -o $interface --dport 67:68 -j ACCEPT + $IPTABLES -A FORWARD -p udp -i $interface -o $interface --dport 67:68 -j ACCEPT done case "$IP_FORWARDING" in @@ -1454,6 +1577,7 @@ setup_tunnels() # $1 = name of tunnels file local inchain local outchain + setup_one_ipsec() # $1 = gateway $2 = Tunnel Kind $3 = gateway zones { local kind=$2 noah= @@ -1469,34 +1593,34 @@ setup_tunnels() # $1 = name of tunnels file [ $kind = IPSEC ] && kind=ipsec options="-m state --state NEW -j ACCEPT" - addrule $inchain -p 50 -s $1 -j ACCEPT - addrule $outchain -p 50 -d $1 -j ACCEPT + addrule2 $inchain -p 50 $(source_ip_range $1) -j ACCEPT + addrule2 $outchain -p 50 $(dest_ip_range $1) -j ACCEPT + if [ -z "$noah" ]; then - run_iptables -A $inchain -p 51 -s $1 -j ACCEPT - run_iptables -A $outchain -p 51 -d $1 -j ACCEPT + run_iptables -A $inchain -p 51 $(source_ip_range $1) -j ACCEPT + run_iptables -A $outchain -p 51 $(dest_ip_range $1) -j ACCEPT fi - run_iptables -A $outchain -p udp -d $1 --dport 500 --sport 500 $options + run_iptables -A $outchain -p udp $(dest_ip_range $1) --dport 500 $options if [ $kind = ipsec ]; then - run_iptables -A $inchain -p udp -s $1 --sport 500 --dport 500 $options + run_iptables -A $inchain -p udp $(source_ip_range $1) --dport 500 $options else - run_iptables -A $inchain -p udp -s $1 --dport 500 $options - run_iptables -A $inchain -p udp -s $1 --dport 4500 $options + run_iptables -A $inchain -p udp $(source_ip_range $1) --dport 500 $options + run_iptables -A $inchain -p udp $(source_ip_range $1) --dport 4500 $options fi for z in $(separate_list $3); do if validate_zone $z; then - addrule ${FW}2${z} -p udp --sport 500 --dport 500 $options + addrule ${FW}2${z} -p udp --dport 500 $options if [ $kind = ipsec ]; then - addrule ${z}2${FW} -p udp --sport 500 --dport 500 $options + addrule ${z}2${FW} -p udp --dport 500 $options else addrule ${z}2${FW} -p udp --dport 500 $options addrule ${z}2${FW} -p udp --dport 4500 $options fi else - error_message "Warning: Invalid gateway zone ($z)" \ - " -- Tunnel \"$tunnel\" may encounter keying problems" + fatal_error "Invalid gateway zone ($z) -- Tunnel \"$tunnel\"" fi done @@ -1505,45 +1629,50 @@ setup_tunnels() # $1 = name of tunnels file setup_one_other() # $1 = TYPE, $2 = gateway, $3 = protocol { - addrule $inchain -p $3 -s $2 -j ACCEPT - addrule $outchain -p $3 -d $2 -j ACCEPT + addrule2 $inchain -p $3 $(source_ip_range $2) -j ACCEPT + addrule2 $outchain -p $3 $(dest_ip_range $2) -j ACCEPT progress_message " $1 tunnel to $2 defined." } setup_pptp_client() # $1 = gateway { - addrule $outchain -p 47 -d $1 -j ACCEPT - addrule $inchain -p 47 -j ACCEPT - addrule $outchain -p tcp --dport 1723 -d $1 -j ACCEPT + addrule2 $outchain -p 47 $(dest_ip_range $1) -j ACCEPT + addrule2 $inchain -p 47 $(source_ip_range $1) -j ACCEPT + addrule2 $outchain -p tcp --dport 1723 $(dest_ip_range $1) -j ACCEPT progress_message " PPTP tunnel to $1 defined." } setup_pptp_server() # $1 = gateway { - addrule $inchain -p 47 -s $1 -j ACCEPT - addrule $outchain -p 47 -d $1 -j ACCEPT - addrule $inchain -p tcp --dport 1723 -s $1 -j ACCEPT + addrule2 $inchain -p 47 $(source_ip_range $1) -j ACCEPT + addrule2 $outchain -p 47 $(dest_ip_range $1) -j ACCEPT + addrule2 $inchain -p tcp --dport 1723 $(source_ip_range $1) -j ACCEPT progress_message " PPTP server defined." } setup_one_openvpn() # $1 = gateway, $2 = kind[:port] { + local protocol=udp + local p=1194 + case $2 in + *:*:*) + protocol=${2%:*} + protocol=${protocol#*:} + p=${2##*:} + ;; *:*) p=${2#*:} ;; - *) - p=5000 - ;; esac - addrule $inchain -p udp -s $1 --sport $p --dport $p -j ACCEPT - addrule $outchain -p udp -d $1 --sport $p --dport $p -j ACCEPT + addrule2 $inchain -p $protocol $(source_ip_range $1) --dport $p -j ACCEPT + addrule2 $outchain -p $protocol $(dest_ip_range $1) --dport $p -j ACCEPT - progress_message " OPENVPN tunnel to $1:$p defined." + progress_message " OPENVPN tunnel to $1:$protocol:$p defined." } setup_one_generic() # $1 = gateway, $2 = kind:protocol[:port], $3 = Gateway Zone @@ -1568,8 +1697,8 @@ setup_tunnels() # $1 = name of tunnels file p=${p:+--dport $p} - addrule $inchain -p $protocol -s $1 $p -j ACCEPT - addrule $outchain -p $protocol -d $1 $p -j ACCEPT + addrule2 $inchain -p $protocol $(source_ip_range $1) $p -j ACCEPT + addrule2 $outchain -p $protocol $(dest_ip_range $1) $p -j ACCEPT for z in $(separate_list $3); do if validate_zone $z; then @@ -1612,7 +1741,7 @@ setup_tunnels() # $1 = name of tunnels file pptpclient|PPTPCLIENT) setup_pptp_client $gateway ;; - pptpserver|PPTPSERVER) + pptpserver|PPTPSERVER) setup_pptp_server $gateway ;; openvpn|OPENVPN|openvpn:*|OPENVPN:*) @@ -1633,11 +1762,122 @@ setup_tunnels() # $1 = name of tunnels file done < $TMP_DIR/tunnels } +# +# Process the ipsec file +# +setup_ipsec() { + local zone + # + # Add a --set-mss rule to the passed chain + # + set_mss1() # $1 = chain, $2 = MSS + { + eval local policy=\$${1}_policy + + if [ "$policy" != NONE ]; then + case $COMMAND in + start|restart) + ensurechain $1 + run_iptables -I $1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss $2 + ;; + esac + fi + } + # + # Set up rules to set MSS to and/or from zone "$zone" + # + set_mss() # $1 = MSS value, $2 = _in, _out or "" + { + if [ $COMMAND != check ]; then + for z in $zones; do + case $2 in + _in) + set_mss1 ${zone}2${z} $1 + ;; + _out) + set_mss1 ${z}2${zone} $1 + ;; + *) + set_mss1 ${z}2${zone} $1 + set_mss1 ${zone}2${z} $1 + ;; + esac + done + fi + } + + do_options() # $1 = _in, _out or "" - $2 = option list + { + local option opts newoptions= val + + [ x${2} = x- ] && return + + opts=$(separate_list $2) + + for option in $opts; do + val=${option#*=} + + case $option in + mss=[0-9]*) set_mss $val $1 ;; + strict) newoptions="$newoptions --strict" ;; + next) newoptions="$newoptions --next" ;; + reqid=*) newoptions="$newoptions --reqid $val" ;; + spi=*) newoptions="$newoptions --spi $val" ;; + proto=*) newoptions="$newoptions --proto $val" ;; + mode=*) newoptions="$newoptions --mode $val" ;; + tunnel-src=*) newoptions="$newoptions --tunnel-src $val" ;; + tunnel-dst=*) newoptions="$newoptions --tunnel-dst $val" ;; + reqid!=*) newoptions="$newoptions ! --reqid $val" ;; + spi!=*) newoptions="$newoptions ! --spi $val" ;; + proto!=*) newoptions="$newoptions ! --proto $val" ;; + mode!=*) newoptions="$newoptions ! --mode $val" ;; + tunnel-src!=*) newoptions="$newoptions ! --tunnel-src $val" ;; + tunnel-dst!=*) newoptions="$newoptions ! --tunnel-dst $val" ;; + *) fatal_error "Invalid option \"$option\" for zone $zone" ;; + esac + done + + if [ -n "$newoptions" ]; then + eval ${zone}_is_complex=Yes + eval ${zone}_ipsec${1}_options=\"${newoptions# }\" + fi + } + + strip_file ipsec $1 + + while read zone ipsec options in_options out_options mss; do + expandv zone ipsec options in_options out_options mss + + [ -n "$POLICY_MATCH" ] || fatal_error "Your kernel and/or iptables does not support policy match" + + validate_zone1 $zone || fatal_error "Unknown zone: $zone" + + case $ipsec in + -|No|no) + ;; + Yes|yes) + eval ${zone}_is_ipsec=Yes + eval ${zone}_is_complex=Yes + ;; + *) + fatal_error "Invalid IPSEC column value: $ipsec" + ;; + esac + + do_options "" $options + do_options "_in" $in_options + do_options "_out" $out_options + + done < $TMP_DIR/ipsec +} + # # Setup Proxy ARP # setup_proxy_arp() { + local setlist= resetlist= + print_error() { error_message "Invalid value for HAVEROUTE - ($haveroute)" error_message "Entry \"$address $interface $external $haveroute\" ignored" @@ -1691,9 +1931,6 @@ setup_proxy_arp() { ensure_and_save_command arp -i $external -Ds $address $external pub - run_and_save_command "echo 1 > /proc/sys/net/ipv4/conf/$interface/proxy_arp" - run_and_save_command "echo 0 > /proc/sys/net/ipv4/conf/$external/proxy_arp" - echo $address $interface $external $haveroute >> ${STATEDIR}/proxyarp progress_message " Host $address connected to $interface added to ARP on $external" @@ -1705,9 +1942,20 @@ setup_proxy_arp() { while read address interface external haveroute persistent; do expandv address interface external haveroute persistent + list_search $interface $setlist || setlist="$setlist $interface" + list_search $external $resetlist || list_search $external $setlist || resetlist="$resetlist $external" setup_one_proxy_arp done < $TMP_DIR/proxyarp + for interface in $resetlist; do + list_search $interface $setlist || \ + run_and_save_command "echo 0 > /proc/sys/net/ipv4/conf/$interface/proxy_arp" + done + + for interface in $setlist; do + run_and_save_command "echo 1 > /proc/sys/net/ipv4/conf/$interface/proxy_arp" + done + interfaces=$(find_interfaces_by_option proxyarp) for interface in $interfaces; do @@ -1729,16 +1977,18 @@ setup_mac_lists() { local addresses local address local chain - local logpart local macpart local blob local hosts + local ipsec + local policy= # # Generate the list of interfaces having MAC verification # maclist_interfaces= for hosts in $maclist_hosts; do + hosts=${hosts#*^} interface=${hosts%%:*} if ! list_search $interface $maclist_interfaces; then\ if [ -z "$maclist_interfaces" ]; then @@ -1754,20 +2004,11 @@ setup_mac_lists() { # Be sure that they are all ethernet interfaces # for interface in $maclist_interfaces; do - case $interface in - eth*|wlan*|br[0-9]|ath[0-9]) - ;; - *) - fatal_error "MAC verification is only supported on ethernet and 802.11b devices: $interface" - ;; - esac - createchain $(mac_chain $interface) no done # # Process the maclist file producing the verification rules # - while read interface mac addresses; do expandv interface mac addresses @@ -1829,11 +2070,14 @@ setup_mac_lists() { # Generate jumps from the input and forward chains # for hosts in $maclist_hosts; do + ipsec=${hosts%^*} + hosts=${hosts#*^} + [ -n "$POLICY_MATCH" ] && policy="-m policy --pol $ipsec --dir in" || policy= interface=${hosts%%:*} hosts=${hosts#*:} for chain in $(first_chains $interface) ; do run_iptables -A $chain $(match_source_hosts $hosts) -m state --state NEW \ - -j $(mac_chain $interface) + $policy -j $(mac_chain $interface) done done } @@ -1860,7 +2104,7 @@ setup_syn_flood_chain () run_iptables -N $chain run_iptables -A $chain -m limit --limit $limit $limit_burst -j RETURN [ -n "$3" ] && \ - log_rule_limit $3 $chain DROP "-m limit --limit 5/min --limit-burst 5" "" + log_rule_limit $3 $chain $chain DROP "-m limit --limit 5/min --limit-burst 5" "" "" run_iptables -A $chain -j DROP } @@ -1891,8 +2135,8 @@ delete_proxy_arp() { [ -d ${STATEDIR} ] && touch ${STATEDIR}/proxyarp - for f in $(ls /proc/sys/net/ipv4/conf/*/proxy_arp); do - echo 0 > $f + for f in /proc/sys/net/ipv4/conf/*; do + [ -f $f/proxy_arp ] && echo 0 > $f/proxy_arp done } @@ -1900,47 +2144,75 @@ delete_proxy_arp() { # Setup Static Network Address Translation (NAT) # setup_nat() { - local allints + local external= interface= internal= allints= localnat= policyin= policyout= + + validate_one() #1 = Variable Name, $2 = Column name, $3 = value + { + case $3 in + Yes|yes) + ;; + No|no) + eval ${1}= + ;; + *) + [ -n "$3" ] && \ + fatal_error "Invalid value ($3) for $2 in entry \"$external $interface $internal $allints $localnat\"" + ;; + esac + } + + do_one_nat() { + local add_ip_aliases=$ADD_IP_ALIASES iface=${interface%:*} + + if [ -n "$add_ip_aliases" ]; then + case $interface in + *:) + interface=${interface%:} + add_ip_aliases= + ;; + *) + [ -n "$RETAIN_ALIASES" ] || run_and_save_command qt ip addr del $external dev $iface + ;; + esac + else + interface=${interface%:} + fi + + validate_one allints "ALL INTERFACES" $allints + validate_one localnat "LOCAL" $localnat + + if [ -n "$allints" ]; then + addnatrule nat_in -d $external $policyin -j DNAT --to-destination $internal + addnatrule nat_out -s $internal $policyout -j SNAT --to-source $external + else + addnatrule $(input_chain $iface) -d $external $policyin -j DNAT --to-destination $internal + addnatrule $(output_chain $iface) -s $internal $policyout -j SNAT --to-source $external + fi + + [ -n "$localnat" ] && \ + run_iptables2 -t nat -A OUTPUT -d $external $policyout -j DNAT --to-destination $internal + + if [ -n "$add_ip_aliases" ]; then + list_search $external $aliases_to_add || \ + aliases_to_add="$aliases_to_add $external $interface" + fi + } # # At this point, we're just interested in the network translation # > ${STATEDIR}/nat - save_progress_message "Restoring one-to-one NAT..." + if [ -n "$POLICY_MATCH" ]; then + policyin="-m policy --pol none --dir in" + policyout="-m policy --pol none --dir out" + fi + + [ -n "$RETAIN_ALIASES" ] || save_progress_message "Restoring one-to-one NAT..." while read external interface internal allints localnat; do expandv external interface internal allints localnat - - iface=${interface%:*} - - if [ -n "$ADD_IP_ALIASES" ]; then - run_and_save_command qt ip addr del $external dev $iface - fi - - if [ "x$allints" = "xYes" -o "x$allints" = "xyes" ]; then - addnatrule nat_in -d $external -j DNAT --to-destination $internal - addnatrule nat_out -s $internal -j SNAT --to-source $external - - elif [ -z "$allints" -o "x$allints" = "x-" -o "x$allints" = "xNo" -o "x$allints" = "xno" ]; then - addnatrule $(input_chain $iface) \ - -d $external -j DNAT --to-destination $internal - addnatrule $(output_chain $iface) \ - -s $internal -j SNAT --to-source $external - else - fatal_error "Invalid value ($allints) for ALL INTERFACES in entry \"$external $interface $internal $allints $localnat\"" - fi - - if [ "x$localnat" = "xYes" -o "x$localnat" = "xyes" ]; then - run_iptables2 -t nat -A OUTPUT -d $external -j DNAT --to-destination $internal - elif [ "x$localnat" != "x-" -a -n "$localnat" -a "x$localnat" != "xNo" -a "x$localnat" != "xno" ]; then - fatal_error "Invalid value ($allints) for LOCAL in entry \"$external $interface $internal $allints $localnat\"" - fi - - - if [ -n "$ADD_IP_ALIASES" ]; then - list_search $external $aliases_to_add || \ - aliases_to_add="$aliases_to_add $external $interface" - fi + + do_one_nat progress_message " Host $internal NAT $external on $interface" done < $TMP_DIR/nat @@ -1972,7 +2244,7 @@ setup_netmap() { while read type net1 interface net2 ; do expandv type net1 interface net2 - list_search $interface $all_interfaces || \ + list_search $interface $ALL_INTERFACES || \ fatal_error "Unknown interface $interface in entry \"$type $net1 $interface $net2\"" case $type in @@ -1998,7 +2270,7 @@ setup_netmap() { setup_ecn() # $1 = file name { local interfaces="" - local hosts + local hosts= local h strip_file ecn $1 @@ -2007,7 +2279,7 @@ setup_ecn() # $1 = file name while read interface host; do expandv interface host - list_search $interface $all_interfaces || \ + list_search $interface $ALL_INTERFACES || \ startup_error "Unknown interface $interface" list_search $interface $interfaces || \ interfaces="$interfaces $interface" @@ -2034,20 +2306,27 @@ setup_ecn() # $1 = file name for host in $hosts; do interface=${host%:*} h=${host#*:} - run_iptables -t mangle -A $(ecn_chain $interface) -p tcp -d $h -j ECN --ecn-tcp-remove + run_iptables -t mangle -A $(ecn_chain $interface) -p tcp $(dest_ip_range $h) -j ECN --ecn-tcp-remove progress_message " ECN Disabled to $h through $interface" done fi } # -# Process a TC Rule - $marking_chain is assumed to contain the name of the +# Process a TC Rule - $MARKING_CHAIN is assumed to contain the name of the # default marking chain # process_tc_rule() { - chain=$marking_chain - + chain=$MARKING_CHAIN target="MARK --set-mark" marktest= + + verify_designator() { + [ "$chain" = tcout ] && \ + fatal_error "Chain designator not allowed when source is \$FW; rule \"$rule\"" + chain=$1 + mark="${mark%:*}" + } + add_a_tc_rule() { r= @@ -2089,37 +2368,112 @@ process_tc_rule() esac fi - [ "x$dest" = "x-" ] || r="${r}-d $dest " - [ "x$proto" = "x-" ] && proto=all - [ "x$proto" = "x" ] && proto=all - [ "$proto" = "all" ] || r="${r}-p $proto " - [ "x$port" = "x-" ] || r="${r}--dport $port " + [ -n "$marktest" ] && r="${r}-m ${marktest}--mark $testval " + + if [ "x$dest" != "x-" ]; then + case $dest in + *.*.*) + r="${r}$(dest_ip_range $dest) " + ;; + *) + r="${r}$(match_dest_dev $dest) " + ;; + esac + fi + + if [ "x$proto" = xipp2p ]; then + [ "x$port" = "x-" ] && port="ipp2p" + r="${r}-p tcp -m ipp2p --${port} " + else + [ "x$proto" = "x-" ] && proto=all + [ "x$proto" = "x" ] && proto=all + [ "$proto" = "all" ] || r="${r}-p $proto " + [ "x$port" = "x-" ] || r="${r}--dport $port " + fi + [ "x$sport" = "x-" ] || r="${r}--sport $sport " - run_iptables2 -t mangle -A $chain $r -j MARK --set-mark $mark + case $chain in + tcpost) + run_iptables2 -t mangle -A tcpost $r -j CLASSIFY --set-class $mark + ;; + *) + run_iptables2 -t mangle -A $chain $r -j $target $mark + ;; + esac } if [ "$mark" != "${mark%:*}" ]; then - - [ "$chain" = tcout ] && \ - fatal_error "Chain designator not allowed when source is \$FW; rule \"$rule\"" - case "${mark#*:}" in p|P) - chain=tcpre + verify_designator tcpre + ;; + cp|CP) + verify_designator tcpre + target="CONNMARK --set-mark" ;; f|F) - chain=tcfor + verify_designator tcfor + ;; + cf|CF) + verify_designator tcfor + target="CONNMARK --set-mark" + ;; + c|C) + target="CONNMARK --set-mark" + mark=${mark%:*} ;; *) - fatal_error "Invalid chain designator: (${mark#*:}) in rule \"$rule\"" + chain=tcpost ;; esac - - mark="${mark%:*}" fi + case $mark in + SAVE) + target="CONNMARK --save-mark" + mark= + ;; + SAVE/*) + target="CONNMARK --save-mark --mask" + mark=${mark#*/} + ;; + RESTORE) + target="CONNMARK --restore-mark" + mark= + ;; + RESTORE/*) + target="CONNMARK --restore-mark --mask" + mark=${mark#*/} + ;; + CONTINUE) + target=RETURN + mark= + ;; + esac + + case $testval in + -) + ;; + !*:C) + marktest="connmark ! " + testval=${testval%:*} + testval=${testval#!} + ;; + *:C) + marktest="connmark " + testval=${testval%:*} + ;; + !*) + marktest="mark ! " + testval=${testval#!} + ;; + *) + [ -n "$testval" ] && marktest="mark " + ;; + esac + for source in $(separate_list ${sources:=-}); do for dest in $(separate_list ${dests:=-}); do for port in $(separate_list ${ports:=-}); do @@ -2144,29 +2498,35 @@ setup_tc1() { run_iptables -t mangle -N tcpre run_iptables -t mangle -N tcfor run_iptables -t mangle -N tcout + run_iptables -t mangle -N tcpost # # Process the TC Rules File # strip_file tcrules - while read mark sources dests proto ports sports user; do - expandv mark sources dests proto ports sports user - rule=$(echo "$mark $sources $dests $proto $ports $sports $user") + while read mark sources dests proto ports sports user testval; do + expandv mark sources dests proto ports sports user testval + rule=$(echo "$mark $sources $dests $proto $ports $sports $user $testval") process_tc_rule done < $TMP_DIR/tcrules # # Link to the TC mangle chains from the main chains # - run_iptables -t mangle -A FORWARD -j tcfor - run_iptables -t mangle -A PREROUTING -j tcpre - run_iptables -t mangle -A OUTPUT -j tcout + run_iptables -t mangle -A FORWARD -j tcfor + run_iptables -t mangle -A PREROUTING -j tcpre + run_iptables -t mangle -A OUTPUT -j tcout + run_iptables -t mangle -A POSTROUTING -j tcpost - run_user_exit tcstart + f=$(find_file tcstart) - save_progress_message "Restoring Traffic Control..." - save_command . $(find_file tcstart) + if [ -f $f ]; then + run_user_exit tcstart + + save_progress_message "Restoring Traffic Control..." + save_command . $(find_file tcstart) + fi } setup_tc() { @@ -2236,11 +2596,11 @@ process_accounting_rule() { jumpchain= accounting_error() { - error_message "Warning: Invalid Accounting rule" $action $chain $source $dest $proto $port $sport + error_message "Warning: Invalid Accounting rule" $action $chain $source $dest $proto $port $sport $user } accounting_interface_error() { - error_message "Warning: Unknown interface $1 in " $action $chain $source $dest $proto $port $sport + error_message "Warning: Unknown interface $1 in " $action $chain $source $dest $proto $port $sport $user } accounting_interface_verify() { @@ -2279,10 +2639,10 @@ process_accounting_rule() { [ -n "$dest" ] && case $dest in *:*) accounting_interface_verify ${dest%:*} - rule="$rule -d ${dest#*:} $(match_dest_dev ${dest%:*})" + rule="$rule $(dest_ip_range ${dest#*:}) $(match_dest_dev ${dest%:*})" ;; *.*.*.*) - rule="$rule -d $dest" + rule="$rule $(dest_ip_range $dest)" ;; -|all|any) ;; @@ -2295,6 +2655,10 @@ process_accounting_rule() { [ -n "$proto" ] && case $proto in -|any|all) ;; + ipp2p) + rule="$rule -p tcp -m ipp2p --${port:-ipp2p}" + port= + ;; *) rule="$rule -p $proto" ;; @@ -2316,6 +2680,25 @@ process_accounting_rule() { ;; esac + [ -n "$user" ] && case $user in + -|any|all) + ;; + *:*) + [ "$chain" != OUTPUT ] && \ + fatal_error "Invalid use of a user/group: chain is not OUTPUT but $chain" + rule="$rule -m owner" + temp="${user%:*}" + [ -n "$temp" ] && rule="$rule --uid-owner $temp " + temp="${user#*:}" + [ -n "$temp" ] && rule="$rule --gid-owner $temp " + ;; + *) + [ "$chain" != OUTPUT ] && \ + fatal_error "Invalid use of a user/group: chain is not OUTPUT but $chain" + rule="$rule -m owner --uid-owner $user " + ;; + esac + case $action in COUNT) ;; @@ -2342,9 +2725,9 @@ process_accounting_rule() { ensurechain1 $chain - if iptables -A $chain $(fix_bang $rule) ; then + if $IPTABLES -A $chain $(fix_bang $rule) ; then [ -n "$rule2" ] && run_iptables2 -A $jumpchain $rule2 - progress_message " Accounting rule" $action $chain $source $dest $proto $port $sport Added + progress_message " Accounting rule" $action $chain $source $dest $proto $port $sport $user Added else accounting_error fi @@ -2360,8 +2743,8 @@ setup_accounting() # $1 = Name of accounting file strip_file accounting $1 - while read action chain source dest proto port sport ; do - expandv action chain source dest proto port sport + while read action chain source dest proto port sport user ; do + expandv action chain source dest proto port sport user process_accounting_rule done < $TMP_DIR/accounting @@ -2394,14 +2777,25 @@ check_config() { verify_os_version + if [ -n "$BRIDGING" ]; then + [ -n "$PHYSDEV_MATCH" ] || startup_error "BRIDGING=Yes requires Physdev Match support in your Kernel and iptables" + fi + echo "Determining Zones..." determine_zones + check_duplicate_zones [ -z "$zones" ] && startup_error "ERROR: No Zones Defined" display_list "Zones:" $zones + ipsecfile=$(find_file ipsec) + + [ -f $ipsecfile ] && \ + echo "Validating ipsec file..." && \ + setup_ipsec $ipsecfile + echo "Validating interfaces file..." validate_interfaces_file @@ -2432,6 +2826,7 @@ check_config() { echo "Validating Actions..." process_actions2 + process_actions3 rm -rf $TMP_DIR [ -n "$RESTOREBASE" ] && rm -f $RESTOREBASE @@ -2482,7 +2877,7 @@ refresh_tc() { # Add one Filter Rule from an action -- Helper function for the action file processor # # The caller has established the following variables: -# check = current command. If 'check', we're executing a 'check' +# COMMAND = current command. If 'check', we're executing a 'check' # which only goes through the motions. # client = SOURCE IP or MAC # server = DESTINATION IP or interface @@ -2537,7 +2932,7 @@ add_an_action() ;; *:*) action_interface_verify ${client%:*} - cli="$(match_source_dev ${client%:*}) -s ${client#*:}" + cli="$(match_source_dev ${client%:*}) $(source_ip_range ${client#*:})" ;; *.*.*) cli="-s $client" @@ -2616,23 +3011,23 @@ add_an_action() if [ $COMMAND != check ]; then if [ -n "${serv}" ]; then for serv1 in $(separate_list $serv); do - for srv in $(ip_range $serv1); do + for srv in $(firewall_ip_range $serv1); do if [ -n "$loglevel" ]; then - log_rule_limit $loglevel $action $logtarget "$ratelimit" "$logtag" $userandgroup \ - $(fix_bang $proto $sports $multiport $cli -d $srv $dports) + log_rule_limit $loglevel $chain $action $logtarget "$ratelimit" "$logtag" -A $userandgroup \ + $(fix_bang $proto $sports $multiport $cli $(source_ip_range $srv) $dports) fi - run_iptables2 -A $action $proto $multiport $cli $sports \ - -d $srv $dports $ratelimit $userandgroup -j $target + run_iptables2 -A $chain $proto $multiport $cli $sports \ + $(dest_ip_range $srv) $dports $ratelimit $userandgroup -j $target done done else if [ -n "$loglevel" ]; then - log_rule_limit $loglevel $action $logtarget "$ratelimit" "$logtag" $userandgroup \ + log_rule_limit $loglevel $chain $action $logtarget "$ratelimit" "$logtag" -A $userandgroup \ $(fix_bang $proto $sports $multiport $cli $dest_interface $dports) fi - run_iptables2 -A $action $proto $multiport $cli $dest_interface $sports \ + run_iptables2 -A $chain $proto $multiport $cli $dest_interface $sports \ $dports $ratelimit $userandgroup -j $target fi fi @@ -2641,26 +3036,27 @@ add_an_action() # # Process a record from an action file for the 'start', 'restart' or 'check' commands # -process_action() # $1 = action - # $2 = target - # $3 = clients - # $4 = servers - # $5 = protocol - # $6 = ports - # $7 = cports - # $8 = ratelimit - # $9 = userspec +process_action() # $1 = chain (Chain to add the rules to) + # $2 = action (The action name for logging purposes) + # $3 = target (The (possibly modified) contents of the TARGET column) + # $4 = clients + # $5 = servers + # $6 = protocol + # $7 = ports + # $8 = cports + # $9 = ratelimit + # $10 = userspec { - local action="$1" - local target="$2" - local clients="$3" - local servers="$4" - local protocol="$5" - local ports="$6" - local cports="$7" - local ratelimit="$8" - local userspec="$9" - local rule="$(echo $target $clients $servers $protocol $ports $cports $ratelimit)" + local chain="$1" + local action="$2" + local target="$3" + local clients="$4" + local servers="$5" + local protocol="$6" + local ports="$7" + local cports="$8" + local ratelimit="$9" + local userspec="${10}" local userandgroup= local logtag= @@ -2723,7 +3119,16 @@ process_action() # $1 = action loglevel="${loglevel%:*}" expandv logtag fi - + + case $loglevel in + none*) + loglevel= + logtag= + [ $target = LOG ] && return + ;; + esac + + loglevel=${loglevel%\!} fi logtarget="$target" @@ -2791,23 +3196,215 @@ process_action() # $1 = action } # -# Create an action chain and run it's associated user exit +# Create and record a log action chain -- Log action chains have names +# that are formed from the action name by prepending a "%" and appending +# a 1- or 2-digit sequence number. In the functions that follow, +# the CHAIN, LEVEL and TAG variable serves as arguments to the user's +# exit. We call the exit corresponding to the name of the action but we +# set CHAIN to the name of the iptables chain where rules are to be added. +# Similarly, LEVEL and TAG contain the log level and log tag respectively. # +# For each , we maintain two variables: +# +# _actchain - The action chain number. +# _chains - List of ( level[:tag] , chainname ) pairs +# +# The maximum length of a chain name is 30 characters -- since the log +# action chain name is 2-3 characters longer than the base chain name, +# this function truncates the original chain name where necessary before +# it adds the leading "%" and trailing sequence number. -createactionchain() # $1 = chain name +createlogactionchain() # $1 = Action Name, $2 = Log Level [: Log Tag ] { - createchain $1 no - run_user_exit $1 + local actchain= action=$1 level=$2 + + eval actchain=\${${action}_actchain} + + case ${#action} in + 29|30) + CHAIN=$(echo $action | truncate 28) # %...n makes 30 + ;; + *) + CHAIN=${action} + ;; + esac + + [ "$COMMAND" != check ] && \ + while havechain %${CHAIN}${actchain}; do + actchain=$(($actchain + 1)) + [ $actchain -eq 10 -a ${#CHAIN} -eq 28 ] && CHAIN=$(echo $CHAIN | truncate 27) # %...nn makes 30 + done + + CHAIN=%${CHAIN}${actchain} + + eval ${action}_actchain=$(($actchain + 1)) + + if [ $COMMAND != check ]; then + createchain $CHAIN No + LEVEL=${level%:*} + TAG=${level#*:} + run_user_exit $1 + fi + + eval ${action}_chains=\"\$${action}_chains $level $CHAIN\" + } # -# Read /etc/shorewall/actions and for each defined , pre-process -# /etc/shorewall/action. +# Create an action chain and run it's associated user exit # +createactionchain() # $1 = Action, including log level and tag if any +{ + case $1 in + *:*:*) + set -- $(split $1) + createlogactionchain $1 $2:$3 + ;; + *:*) + set -- $(split $1) + createlogactionchain $1 $2 + ;; + *) + CHAIN=$1 + if [ $COMMAND != check ]; then + LEVEL= + TAG= + createchain $CHAIN no + run_user_exit $CHAIN + fi + ;; + esac +} + +# +# Find the chain that handles the passed action. If the chain cannot be found, +# a fatal error is generated and the function does not return. +# +find_logactionchain() # $1 = Action, including log level and tag if any +{ + local fullaction=$1 action=${1%%:*} level= chains= + + case $fullaction in + *:*) + level=${fullaction#*:} + ;; + *) + if [ $COMMAND != check ]; then + havechain $action || fatal_error "Fatal error in find_logactionchain" + fi + + echo $action + return + ;; + esac + + eval chains="\$${action}_chains" + + set -- $chains + + while [ $# -gt 0 ]; do + [ "$1" = "$level" ] && { echo $2 ; return ; } + shift;shift + done + + fatal_error "Fatal error in find_logactionchain" + +} + +# +# This function determines the logging for a subordinate action or a rule within a subordinate action +# +merge_levels() # $1=level at which superior action is called, $2=level at which the subordinate rule is called +{ + local superior=$1 subordinate=$2 + + set -- $(split $1) + + case $superior in + *:*:*) + case $2 in + 'none!') + echo ${subordinate%%:*}:'none!' + return + ;; + *'!') + echo ${subordinate%%:*}:$2:$3 + return + ;; + *) + case $subordinate in + *:*) + echo $subordinate + return + ;; + *) + echo ${subordinate%%:*}:$2:$3 + return + ;; + esac + ;; + esac + ;; + *:*) + case $2 in + 'none!') + echo ${subordinate%%:*}:'none!' + return + ;; + *'!') + echo ${subordinate%%:*}:$2 + return + ;; + *) + case $subordinate in + *:*) + echo $subordinate + return + ;; + *) + echo ${subordinate%%:*}:$2 + return + ;; + esac + ;; + esac + ;; + *) + echo $subordinate + ;; + esac +} + +# +# The next three functions implement the three phases of action processing. +# +# The first phase (process_actions1) occurs before the rules file is processed. /usr/share/shorewall/actions.std +# and /etc/shorewall/actions are scanned (in that order) and for each action: +# +# a) The related action definition file is located and scanned. +# b) Forward and unresolved action references are trapped as errors. +# c) A dependency graph is created. For each , the variable 'requiredby_' lists the +# action[:level[:tag]] of each action invoked by . +# d) All actions are listed in the global variable ACTIONS. +# e) Common actions are recorded (in variables of the name _common) and are added to the global +# USEDACTIONS +# +# As the rules file is scanned, each action[:level[:tag]] is merged onto the USEDACTIONS list. When an +# is merged onto this list, its action chain is created. Where logging is specified, a chain with the name +# %n is used where the name is truncated on the right where necessary to ensure that the total +# length of the chain name does not exceed 30 characters. +# +# The second phase (process_actions2) occurs after the rules file is scanned. The transitive closure of +# USEDACTIONS is generated; again, as new actions are merged onto this list, their action chains are created. +# +# The final phase (process_actions3) is to traverse the USEDACTIONS list populating each chain appropriately +# by reading the action definition files and creating rules. Note that a given action definition file is +# processed once for each unique [:level[:tag]] applied to an invocation of the action. +# process_actions1() { - ACTIONS="dropBcast dropNonSyn dropNotSyn rejNotSyn logNotSyn rLogNotSyn dLogNotSyn dropInvalid allowInvalid" + ACTIONS="dropBcast allowBcast dropNonSyn dropNotSyn rejNotSyn dropInvalid allowInvalid" USEDACTIONS= strip_file actions @@ -2821,24 +3418,24 @@ process_actions1() { case $xaction in *:*) temp=${xaction#*:} + [ ${#temp} -le 30 ] || fatal_error "Action Name Longer than 30 Characters: $temp" xaction=${xaction%:*} case $temp in ACCEPT|REJECT|DROP) eval ${temp}_common=$xaction if [ -n "$xaction" ] && ! list_search $xaction $USEDACTIONS; then USEDACTIONS="$USEDACTIONS $xaction" - [ $COMMAND = check ] || createactionchain $xaction fi ;; *) - fatal_error "Common Actions are only allowed for ACCEPT, DROP and REJECT" + startup_error "Common Actions are only allowed for ACCEPT, DROP and REJECT" ;; esac esac [ -z "$xaction" ] && continue - [ "$xaction" = "$(chain_base $xaction)" ] || fatal_error "Invalid Action Name: $xaction" + [ "$xaction" = "$(chain_base $xaction)" ] || startup_error "Invalid Action Name: $xaction" if ! list_search $xaction $ACTIONS; then f=action.$xaction @@ -2852,22 +3449,22 @@ process_actions1() { while read xtarget xclients xservers xprotocol xports xcports xratelimit $xuserspec; do expandv xtarget temp="${xtarget%%:*}" - case "${temp%<*}" in + case "$temp" in ACCEPT|DROP|REJECT|LOG|QUEUE|CONTINUE) ;; *) if list_search $temp $ACTIONS; then - eval requiredby_${xaction}=\"\$requiredby_${xaction} $temp\" + eval requiredby_${xaction}=\"\$requiredby_${xaction} $xtarget\" else rule="$(echo $xtarget $xclients $xservers $xprotocol $xports $xcports $xratelimit $xuserspec)" - fatal_error "Invalid TARGET in rule \"$rule\"" + startup_error "Invalid TARGET in rule \"$rule\"" fi ;; esac done < $TMP_DIR/$f else - fatal_error "Missing Action File: $f" + startup_error "Missing Action File: $f" fi ACTIONS="$ACTIONS $xaction" @@ -2875,94 +3472,198 @@ process_actions1() { done < $TMP_DIR/$inputfile done } -# -# Generate the transitive closure of $USEDACTIONS (the actions directly referred to in rules and as common actions) then -# process the associated action files. -# + process_actions2() { - log_action() { - [ "$COMMAND" != check ] && log_rule ${LOGNEWNOTSYN:-info} $1 $2 "" "" -p tcp ! --syn - } + progress_message " Generating Transitive Closure of Used-action List..." - drop_broadcasts() { - for address in $(find_broadcasts) 255.255.255.255 224.0.0.0/4 ; do - run_iptables -A dropBcast -d $address -j DROP - done - } - - # - # Generate the transitive closure of $USEDACTIONS - # changed=Yes while [ -n "$changed" ]; do changed= for xaction in $USEDACTIONS; do - eval required=\"\$requiredby_${xaction}\" - for action in $required; do - if ! list_search $action $USEDACTIONS; then - USEDACTIONS="$USEDACTIONS $action" - [ $COMMAND = check ] || createactionchain $action + + eval required=\"\$requiredby_${xaction%%:*}\" + + for xaction1 in $required; do + # + # Generate the action that will be passed to process_action by merging the + # logging specified when the action was invoked with the logging in the + # invocation of the subordinate action (usually no logging) + # + xaction2=$(merge_levels $xaction $xaction1) + + if ! list_search $xaction2 $USEDACTIONS; then + # + # We haven't seen this one before -- create and record a chain to handle it + # + USEDACTIONS="$USEDACTIONS $xaction2" + createactionchain $xaction2 changed=Yes fi done done done - # - # Now process the relevant action files -- they were already stripped in process_actions1() above. - # +} + +process_actions3() { + for xaction in $USEDACTIONS; do - case $xaction in + # + # Find the chain associated with this action:level:tag + # + xchain=$(find_logactionchain $xaction) + # + # Split the action:level:tag + # + set -- $(split $xaction) + + xaction1=$1 + xlevel=$2 + xtag=$3 + # + # Handle Builtin actions + # + case $xaction1 in dropBcast) if [ "$COMMAND" != check ]; then if [ -n "$PKTTYPE" ]; then - qt iptables -A dropBcast -m pkttype --pkt-type broadcast -j DROP - if ! qt iptables -A dropBcast -m pkttype --pkt-type multicast -j DROP; then - # - # No pkttype support -- do it the hard way - # - drop_broadcasts - fi + case $xlevel in + none'!') + ;; + *) + if [ -n "$xlevel" ]; then + log_rule_limit ${xlevel%\!} $xchain dropBcast $2 "" "$xtag" -A -m pkttype --pkt-type broadcast + log_rule_limit ${xlevel%\!} $xchain dropBcast $2 "" "$xtag" -A -m pkttype --pkt-type multicast + fi + ;; + esac + + run_iptables -A dropBcast -m pkttype --pkt-type broadcast -j DROP + run_iptables -A dropBcast -m pkttype --pkt-type multicast -j DROP else - drop_broadcasts + for address in $(find_broadcasts) 255.255.255.255 224.0.0.0/4 ; do + case $xlevel in + none*) + ;; + *) + [ -n "$xlevel" ] && \ + log_rule_limit ${xlevel%\!} $xchain dropBcast $2 "" "$xtag" -A -d $address + ;; + esac + + run_iptables -A $xchain -d $address -j DROP + done fi fi - ;; + ;; + allowBcast) + if [ "$COMMAND" != check ]; then + if [ -n "$PKTTYPE" ]; then + case $xlevel in + none'!') + ;; + *) + if [ -n "$xlevel" ]; then + log_rule_limit ${xlevel%\!} $xchain allowBcast $2 "" "$xtag" -A -m pkttype --pkt-type broadcast + log_rule_limit ${xlevel%\!} $xchain allowBcast $2 "" "$xtag" -A -m pkttype --pkt-type multicast + fi + ;; + esac + + run_iptables -A allowBcast -m pkttype --pkt-type broadcast -j ACCEPT + run_iptables -A allowBcast -m pkttype --pkt-type multicast -j ACCEPT + else + for address in $(find_broadcasts) 255.255.255.255 224.0.0.0/4 ; do + case $xlevel in + none*) + ;; + *) + [ -n "$xlevel" ] && \ + log_rule_limit ${xlevel%\!} $xchain allowBcast $2 "" "$xtag" -A -d $address + ;; + esac + + run_iptables -A $xchain -d $address -j ACCEPT + done + fi + fi + ;; dropNonSyn) error_message "WARNING: \"dropNonSyn\" has been replaced by \"dropNotSyn\"" - [ "$COMMAND" != check ] && run_iptables -A dropNonSyn -p tcp ! --syn -j DROP + + if [ "$COMMAND" != check ]; then + [ -n "$xlevel" ] && \ + log_rule_limit ${xlevel%\!} $xchain dropNonSyn $2 "" "$xtag" -A -p tcp ! --syn + run_iptables -A $xchain -p tcp ! --syn -j DROP + fi ;; - dropNotSyn) - [ "$COMMAND" != check ] && run_iptables -A dropNotSyn -p tcp ! --syn -j DROP + if [ "$COMMAND" != check ]; then + [ -n "$xlevel" ] && \ + log_rule_limit ${xlevel%\!} $xchain dropNotSyn $2 "" "$xtag" -A -p tcp ! --syn + run_iptables -A $xchain -p tcp ! --syn -j DROP + fi ;; rejNotSyn) - [ "$COMMAND" != check ] && run_iptables -A rejectNotSyn -p tcp ! --syn -j REJECT --reject-with tcp-reset - ;; - logNotSyn) - log_action logNotSyn LOG - ;; - rLogNotSyn) - log_action rLogNotSyn REJECT - ;; - dLogNotSyn) - log_action dLogNotSyn DROP + if [ "$COMMAND" != check ]; then + [ -n "$xlevel" ] && \ + log_rule_limit ${xlevel%\!} $xchain rejNotSyn $2 "" "$xtag" -A -p tcp ! --syn + run_iptables -A $xchain -p tcp ! --syn -j REJECT --reject-with tcp-reset + fi ;; dropInvalid) - [ "$COMMAND" != check ] && run_iptables -A dropInvalid -m state --state INVALID -j DROP + if [ "$COMMAND" != check ]; then + [ -n "$xlevel" ] && \ + log_rule_limit ${xlevel%\!} $xchain dropInvalid $2 "" "$xtag" -A -m state --state INVALID + run_iptables -A $xchain -m state --state INVALID -j DROP + fi ;; allowInvalid) - [ "$COMMAND" != check ] && run_iptables -A dropInvalid -m state --state INVALID -j ACCEPT + if [ "$COMMAND" != check ]; then + [ -n "$xlevel" ] && \ + log_rule_limit ${xlevel%\!} $xchain allowInvalid $2 "" "$xtag" -A -m state --state INVALID + run_iptables -A $xchain -m state --state INVALID -j ACCEPT + fi ;; *) - f=action.$xaction - fn=$(find_file $f) + # + # Not a builtin + # + f=action.$xaction1 + + echo "Processing $(find_file $f) for Chain $xchain..." - echo "Processing $fn..." - while read xtarget xclients xservers xprotocol xports xcports xratelimit xuserspec ; do - expandv xtarget xclients xservers xprotocol xports xcports xratelimit xuserspec - process_action $xaction $xtarget $xclients $xservers $xprotocol $xports $xcports $xratelimit $xuserspec + while read xtarget xclients xservers xprotocol xports xcports xratelimit xuserspec; do + expandv xtarget + # + # Generate the target:level:tag to pass to process_action() + # + xaction2=$(merge_levels $xaction $xtarget) + + case ${xaction2%%:*} in + ACCEPT|DROP|REJECT|LOG|QUEUE|CONTINUE) + # + # Builtin target -- Nothing to do + # + ;; + *) + # + # Not a builtin target -- Replace the target from the file + # -- with the one generated above + xtarget=$xaction2 + # + # And locate the chain for that action:level:tag + # + xaction2=$(find_logactionchain $xtarget) + ;; + esac + + expandv xclients xservers xprotocol xports xcports xratelimit xuserspec + + rule="$(echo $xtarget $xclients $xservers $xprotocol $xports $xcports $xratelimit $xuserspec)" + process_action $xchain $xaction1 $xaction2 $xclients $xservers $xprotocol $xports $xcports $xratelimit $xuserspec + done < $TMP_DIR/$f ;; esac @@ -2973,7 +3674,7 @@ process_actions2() { # Add a NAT rule - Helper function for the rules file processor # # The caller has established the following variables: -# command = The current command -- if 'check', we just go through +# COMMAND = The current command -- if 'check', we just go through # the motions. # cli = Source IP, interface or MAC Specification # serv = Destination IP Specification @@ -3002,10 +3703,7 @@ add_nat_rule() { # Parse SNAT address if any if [ "$addr" != "${addr%:*}" ]; then - snat="${addr#*:}" - addr="${addr%:*}" - else - snat="" + fatal_error "SNAT may no longer be specified in a DNAT rule; use /etc/shorewall/masq instead" fi # Set original destination address @@ -3019,7 +3717,7 @@ add_nat_rule() { if [ -n "$DETECT_DNAT_IPADDRS" -a "$source" != "$FW" ]; then eval interfaces=\$${source}_interfaces for interface in $interfaces; do - addr=${addr:+$addr,}$(find_interface_address $interface) + addr=${addr:+$addr,}$(find_first_interface_address $interface) done fi ;; @@ -3060,11 +3758,11 @@ add_nat_rule() { createnatchain $chain for adr in $(separate_list $addr); do - run_iptables2 -t nat -A OUTPUT $cli $proto $userandgroup $multiport $sports $dports -d $adr -j $chain + run_iptables2 -t nat -A OUTPUT $cli $proto $userandgroup $multiport $sports $dports $(dest_ip_range $adr) -j $chain done for adr in $excludedests; do - addnatrule $chain -d $adr -j RETURN + addnatrule $chain $(dest_ip_range $adr) -j RETURN done if [ -n "$loglevel" ]; then @@ -3075,11 +3773,11 @@ add_nat_rule() { else for adr in $(separate_list $addr); do if [ -n "$loglevel" ]; then - log_rule_limit $loglevel OUTPUT $logtarget "$ratelimit" "$logtag" -t nat \ - $(fix_bang $proto $cli $sports $userandgroup -d $adr $multiport $dports) + log_rule_limit $loglevel OUTPUT OUTPUT $logtarget "$ratelimit" "$logtag" -A -t nat \ + $(fix_bang $proto $cli $sports $userandgroup $(dest_ip_range $adr) $multiport $dports) fi - run_iptables2 -t nat -A OUTPUT $ratelimit $proto $sports $userandgroup -d $adr $multiport $dports -j $target1 + run_iptables2 -t nat -A OUTPUT $ratelimit $proto $sports $userandgroup $(dest_ip_range $adr) $multiport $dports -j $target1 done fi else @@ -3091,7 +3789,7 @@ add_nat_rule() { createnatchain $chain for adr in $(separate_list $addr); do - addnatrule $(dnat_chain $source) $cli $proto $multiport $sports $dports -d $adr -j $chain + addnatrule $(dnat_chain $source) $cli $proto $multiport $sports $dports $(dest_ip_range $adr) -j $chain done for z in $(separate_list $excludezones); do @@ -3102,11 +3800,11 @@ add_nat_rule() { done for adr in $excludedests; do - addnatrule $chain -d $adr -j RETURN + addnatrule $chain $(dest_ip_range $adr) -j RETURN done if [ -n "$loglevel" ]; then - log_rule_limit $loglevel $chain $logtarget "$ratelimit" "$logtag" -t nat + log_rule_limit $loglevel $chain $chain $logtarget "$ratelimit" "$logtag" -A -t nat fi addnatrule $chain $ratelimit $proto -j $target1 # Protocol is necessary for port redirection @@ -3114,8 +3812,8 @@ add_nat_rule() { for adr in $(separate_list $addr); do if [ -n "$loglevel" ]; then ensurenatchain $chain - log_rule_limit $loglevel $chain $logtarget "$ratelimit" "$logtag" -t nat \ - $(fix_bang $proto $cli $sports -d $adr $multiport $dports) + log_rule_limit $loglevel $chain $chain $logtarget "$ratelimit" "$logtag" -A -t nat \ + $(fix_bang $proto $cli $sports $(dest_ip_range $adr) $multiport $dports) fi addnatrule $chain $proto $ratelimit $cli $sports \ @@ -3135,24 +3833,6 @@ add_nat_rule() { fi fi - # Handle SNAT - - if [ -n "$snat" ]; then - if [ -n "$cli" ]; then - [ $COMMAND = check ] || addnatrule $(snat_chain $dest) $proto $cli $multiport \ - $sports -d $serv $dports -j SNAT --to-source $snat - else - for source_host in $source_hosts; do - [ "x${source_host#*:}" = "x0.0.0.0/0" ] && \ - error_message "Warning: SNAT will occur on all connections to this server and port - rule \"$rule\"" - - [ $COMMAND = check ] || addnatrule $(snat_chain $dest) \ - $(match_source_hosts ${source_host#*:}) $proto $sports $multiport \ - -d $serv $dports -j SNAT --to-source $snat - done - fi - fi - [ "x$addr" = "x0.0.0.0/0" ] && addr= ratelimit= } @@ -3161,7 +3841,7 @@ add_nat_rule() { # Add one Filter Rule -- Helper function for the rules file processor # # The caller has established the following variables: -# command = current command. If 'check', we're executing a 'check' +# COMMAND = current command. If 'check', we're executing a 'check' # which only goes through the motions. # client = SOURCE IP or MAC # server = DESTINATION IP or interface @@ -3220,10 +3900,10 @@ add_a_rule() ;; *:*) rule_interface_verify ${client%:*} - cli="$(match_source_dev ${client%:*}) -s ${client#*:}" + cli="$(match_source_dev ${client%:*}) $(source_ip_range ${client#*:})" ;; *.*.*) - cli="-s $client" + cli="$(source_ip_range $client)" ;; ~*) cli=$(mac_match $client) @@ -3287,6 +3967,12 @@ add_a_rule() fatal_error "Port number not allowed with protocol \"all\"; rule: \"$rule\"" proto= ;; + ipp2p) + dports="-m ipp2p --${port:-ipp2p}" + port= + proto=tcp + do_ports + ;; *) [ -n "$port" ] && \ fatal_error "Port number not allowed with protocol \"$proto\"; rule: \"$rule\"" @@ -3299,26 +3985,25 @@ add_a_rule() case "$logtarget" in ACCEPT|DROP|REJECT|CONTINUE) - [ "$logtarget" = REJECT -a -n "$servport" ] && \ - fatal_error "Server port may not be specified in a REJECT rule; rule: \"$rule\"" if [ -z "$proto" -a -z "$cli" -a -z "$serv" -a -z "$servport" -a -z "$userspec" ] ; then error_message "Warning -- Rule \"$rule\" is a POLICY" error_message " -- and should be moved to the policy file" fi ;; REDIRECT) - [ -n "$serv" ] && startup_error "REDIRECT rules cannot"\ - " specify a server IP; rule: \"$rule\"" + [ -n "$serv" ] && \ + fatal_error "REDIRECT rules cannot specify a server IP; rule: \"$rule\"" servport=${servport:=$port} natrule=Yes ;; DNAT) - [ -n "$serv" ] || fatal_error "DNAT rules require a" \ - " server address; rule: \"$rule\"" + [ -n "$serv" ] || \ + fatal_error "DNAT rules require a server address; rule: \"$rule\"" natrule=Yes ;; LOG) - [ -z "$loglevel" ] && fatal_error "LOG requires log level" + [ -z "$loglevel" ] && \ + fatal_error "LOG requires log level" ;; esac @@ -3336,36 +4021,36 @@ add_a_rule() if [ -z "$dnat_only" ]; then if [ -n "$serv" ]; then for serv1 in $(separate_list $serv); do - for srv in $(ip_range $serv1); do + for srv in $(firewall_ip_range $serv1); do if [ -n "$addr" -a -n "$CONNTRACK_MATCH" ]; then for adr in $(separate_list $addr); do if [ -n "$loglevel" -a -z "$natrule" ]; then - log_rule_limit $loglevel $chain $logtarget "$ratelimit" "$logtag" -m conntrack --ctorigdst $adr \ - $userandgroup $(fix_bang $proto $sports $multiport $cli -d $srv $dports) + log_rule_limit $loglevel $chain $chain $logtarget "$ratelimit" "$logtag" -A -m conntrack --ctorigdst $adr \ + $userandgroup $(fix_bang $proto $sports $multiport $cli $(dest_ip_range $srv) $dports) fi run_iptables2 -A $chain $proto $ratelimit $multiport $cli $sports \ - -d $srv $dports -m conntrack --ctorigdst $adr $userandgroup -j $target + $(dest_ip_range $srv) $dports -m conntrack --ctorigdst $adr $userandgroup -j $target done else if [ -n "$loglevel" -a -z "$natrule" ]; then - log_rule_limit $loglevel $chain $logtarget "$ratelimit" "$logtag" $userandgroup \ - $(fix_bang $proto $sports $multiport $cli -d $srv $dports) + log_rule_limit $loglevel $chain $chain $logtarget "$ratelimit" "$logtag" -A $userandgroup \ + $(fix_bang $proto $sports $multiport $cli $(dest_ip_range $srv) $dports) fi [ -n "$nonat" ] && \ addnatrule $(dnat_chain $source) $proto $multiport \ - $cli $sports -d $srv $dports $ratelimit $userandgroup -j RETURN + $cli $sports $(dest_ip_range $srv) $dports $ratelimit $userandgroup -j RETURN [ "$logtarget" != NONAT ] && \ run_iptables2 -A $chain $proto $multiport $cli $sports \ - -d $srv $dports $ratelimit $userandgroup -j $target + $(dest_ip_range $srv) $dports $ratelimit $userandgroup -j $target fi done done else if [ -n "$loglevel" -a -z "$natrule" ]; then - log_rule_limit $loglevel $chain $logtarget "$ratelimit" "$logtag" $userandgroup \ + log_rule_limit $loglevel $chain $chain $logtarget "$ratelimit" "$logtag" -A $userandgroup \ $(fix_bang $proto $sports $multiport $cli $dports) fi @@ -3389,7 +4074,7 @@ add_a_rule() if [ $COMMAND != check ]; then if [ -n "$loglevel" ]; then - log_rule_limit $loglevel $chain $logtarget "$ratelimit" "$logtag" $userandgroup \ + log_rule_limit $loglevel $chain $chain $logtarget "$ratelimit" "$logtag" -A $userandgroup \ $(fix_bang $proto $multiport $cli $dest_interface $sports $dports) fi @@ -3429,7 +4114,6 @@ process_rule() # $1 = target local ratelimit="$8" local userspec="$9" local userandgroup= - local rule="$(echo $target $clients $servers $protocol $ports $cports $address $ratelimit $userspec)" local logtag= local nonat= @@ -3461,7 +4145,14 @@ process_rule() # $1 = target loglevel="${loglevel%:*}" expandv logtag fi - + + if [ "$loglevel" = none ]; then + [ "$target" = LOG ] && return + loglevel= + logtag= + fi + + loglevel=${loglevel%\!} fi # # Save the original target in 'logtarget' for logging rules @@ -3761,21 +4452,23 @@ process_rules() } while read xtarget xclients xservers xprotocol xports xcports xaddress xratelimit xuserspec; do - temp="${xtarget%%:*}" - case "${temp%<*}" in + rule="$(echo $xtarget $xclients $xservers $xprotocol $xports $xcports $xaddress $xratelimit $xuserspec)" + expandv xtarget + + case "${xtarget%%:*}" in ACCEPT|ACCEPT+|NONAT|DROP|REJECT|DNAT|DNAT-|REDIRECT|REDIRECT-|LOG|CONTINUE|QUEUE) do_it ;; *) - if list_search $temp $ACTIONS; then - if ! list_search $temp $USEDACTIONS; then - [ $COMMAND = check ] || createactionchain $temp - USEDACTIONS="$USEDACTIONS $temp" + if list_search ${xtarget%%:*} $ACTIONS; then + if ! list_search $xtarget $USEDACTIONS; then + createactionchain $xtarget + USEDACTIONS="$USEDACTIONS $xtarget" fi - do_it + xtarget=$(find_logactionchain $xtarget) + do_it else - rule="$(echo $xtarget $xclients $xservers $xprotocol $xports $xcports $xaddress $xratelimit $xuserspec)" fatal_error "Invalid Action in rule \"$rule\"" fi ;; @@ -3824,7 +4517,7 @@ process_tos_rule() { # # IP Address or networks # - src="-s $src" + src="$(source_ip_range $src)" ;; ~*) src=$(mac_match $src) @@ -3921,7 +4614,7 @@ process_tos_rule() { esac for dest in $dst; do - dest="-d $dest" + dest="$(dest_ip_range $dest)" case $srczone in $FW) @@ -4192,15 +4885,79 @@ get_routed_networks() # $1 = interface name # setup_masq() { + do_ipsec_options() { + local options="$(separate_list $ipsec)" option + policy="-m policy --pol ipsec --dir out" + + for option in $options; do + case $option in + [Yy]es) ;; + strict) policy="$policy --strict" ;; + next) policy="$policy --next" ;; + reqid=*) policy="$policy --reqid ${option#*=}" ;; + spi=*) policy="$policy --spi ${option#*=}" ;; + proto=*) policy="$policy --proto ${option#*=}" ;; + mode=*) policy="$policy --mode ${option#*=}" ;; + tunnel-src=*) policy="$policy --tunnel-src ${option#*=}" ;; + tunnel-dst=*) policy="$policy --tunnel-dst ${option#*=}" ;; + reqid!=*) policy="$policy ! --reqid ${option#*=}" ;; + spi!=*) policy="$policy ! --spi ${option#*=}" ;; + proto!=*) policy="$policy ! --proto ${option#*=}" ;; + mode!=*) policy="$policy ! --mode ${option#*=}" ;; + tunnel-src!=*) policy="$policy ! --tunnel-src ${option#*=}" ;; + tunnel-dst!=*) policy="$policy ! --tunnel-dst ${option#*=}" ;; + *) fatal_error "Invalid IPSEC option \"$option\"" ;; + esac + done + } + setup_one() { - local using + local add_snat_aliases=$ADD_SNAT_ALIASES pre_nat= policy= destnets= + + [ "x$ipsec" = x- ] && ipsec= + + case $ipsec in + Yes|yes) + [ -n "$POLICY_MATCH" ] || \ + fatal_error "IPSEC=Yes requires policy match support in your kernel and iptables" + policy="-m policy --pol ipsec --dir out" + ;; + No|no) + [ -n "$POLICY_MATCH" ] || \ + fatal_error "IPSEC=No requires policy match support in your kernel and iptables" + policy="-m policy --pol none --dir out" + ;; + *) + if [ -n "$ipsec" ]; then + do_ipsec_options + elif [ -n "$POLICY_MATCH" ]; then + policy="-m policy --pol none --dir out" + fi + ;; + esac case $fullinterface in + +*) + pre_nat=Yes + fullinterface=${fullinterface#+} + ;; + esac + + case $fullinterface in + *::*) + add_snat_aliases= + destnets="${fullinterface##*:}" + fullinterface="${fullinterface%:*}" + ;; *:*:*) # Both alias name and networks destnets="${fullinterface##*:}" fullinterface="${fullinterface%:*}" ;; + *:) + add_snat_aliases= + fullinterface=${fullinterface%:} + ;; *:*) # Alias name OR networks case ${fullinterface#*:} in @@ -4211,18 +4968,16 @@ setup_masq() ;; *) #it's an alias name - destnets="0.0.0.0/0" ;; esac ;; *) - destnets="0.0.0.0/0" ;; esac interface=${fullinterface%:*} - if ! list_search $interface $all_interfaces; then + if ! list_search $interface $ALL_INTERFACES; then fatal_error "Unknown interface $interface" fi @@ -4236,7 +4991,7 @@ setup_masq() source="$networks" - case $networks in + case $source in *.*.*) ;; *) @@ -4248,19 +5003,22 @@ setup_masq() [ "x$addresses" = x- ] && addresses= - if [ -n "$addresses" -a -n "$ADD_SNAT_ALIASES" ]; then + if [ -n "$addresses" -a -n "$add_snat_aliases" ]; then for address in $(separate_list $addresses); do - for addr in $(ip_range_explicit $address) ; do - if ! list_search $addr $aliases_to_add; then - save_command qt ip addr del $addr dev $interface - aliases_to_add="$aliases_to_add $addr $fullinterface" - case $fullinterface in - *:*) - fullinterface=${fullinterface%:*}:$((${fullinterface#*:} + 1 )) - ;; - esac - fi - done + address=${address%:)} + if [ -n "$address" ]; then + for addr in $(ip_range_explicit ${address%:*}) ; do + if ! list_search $addr $aliases_to_add; then + [ -n "$RETAIN_ALIASES" ] || save_command qt ip addr del $addr dev $interface + aliases_to_add="$aliases_to_add $addr $fullinterface" + case $fullinterface in + *:*) + fullinterface=${fullinterface%:*}:$((${fullinterface#*:} + 1 )) + ;; + esac + fi + done + fi done fi @@ -4285,7 +5043,7 @@ setup_masq() ;; *) if [ -n "$MULTIPORT" ]; then - [ $listcount -gt 15 ] && fatal_error "Too many entries in port list ($ports)" + [ $listcount -le 15 ] || fatal_error "More than 15 entries in port list ($ports)" ports="-m multiport --dports $ports" else fatal_error "Port Ranges require multiport match support in your kernel ($ports)" @@ -4308,9 +5066,9 @@ setup_masq() [ -n "$ports" ] && fatal_error "Ports only allowed with UDP or TCP ($ports)" fi - destination=$destnets + destination=${destnets:=0.0.0.0/0} - chain=$(masq_chain $interface) + [ -z "$pre_nat" ] && chain=$(masq_chain $interface) || chain=$(snat_chain $interface) case $destnets in !*) @@ -4319,12 +5077,12 @@ setup_masq() destnets=${destnets#!} for destnet in $(separate_list $destnets); do - addnatrule $newchain -d $destnet -j RETURN + addnatrule $newchain $(dest_ip_range $destnet) -j RETURN done if [ -n "$networks" ]; then for s in $networks; do - addnatrule $chain -s $s $proto $ports -j $newchain + addnatrule $chain $(source_ip_range $s) $proto $ports $policy -j $newchain done networks= else @@ -4336,10 +5094,11 @@ setup_masq() destnets=0.0.0.0/0 proto= ports= + policy= if [ -n "$nomasq" ]; then for addr in $(separate_list $nomasq); do - addnatrule $chain -s $addr -j RETURN + addnatrule $chain $(source_ip_range $addr) -j RETURN done source="$source except $nomasq" fi @@ -4352,12 +5111,12 @@ setup_masq() if [ -n "$networks" ]; then for s in $networks; do for destnet in $(separate_list $destnets); do - addnatrule $chain -d $destnet -s $s $proto $ports -j $newchain + addnatrule $chain $(both_ip_ranges $s $destnet) $proto $ports -j $newchain done done else for destnet in $(separate_list $destnets); do - addnatrule $chain -d $destnet $proto $ports -j $newchain + addnatrule $chain $(dest_ip_range $destnet) $proto $ports $policy -j $newchain done fi @@ -4367,9 +5126,10 @@ setup_masq() destnets=0.0.0.0/0 proto= ports= - + policy= + for addr in $(separate_list $nomasq); do - addnatrule $chain -s $addr -j RETURN + addnatrule $chain $(source_ip_range $addr) -j RETURN done source="$source except $nomasq" @@ -4378,47 +5138,57 @@ setup_masq() esac addrlist= + target=MASQUERADE if [ -n "$addresses" ]; then for address in $(separate_list $addresses); do - addrlist="$addrlist --to-source $address" + case $address in + *.*.*.*) + target=SNAT + addrlist="$addrlist --to-source $address" + ;; + *) + addrlist="$addrlist --to-ports ${address#:}" + ;; + esac done fi if [ -n "$networks" ]; then - for s in $networks; do + for network in $networks; do + for destnet in $(separate_list $destnets); do + addnatrule $chain $(both_ip_ranges $network $destnet) $proto $ports $policy -j $target $addrlist + done + if [ -n "$addresses" ]; then - for destnet in $(separate_list $destnets); do - addnatrule $chain -s $s -d $destnet $proto $ports -j SNAT $addrlist - done - progress_message " To $destination $displayproto from $s through ${interface} using $addresses" + progress_message " To $destination $displayproto from $network through ${interface} using $addresses" else - for destnet in $(separate_list $destnets); do - addnatrule $chain -s $s -d $destnet $proto $ports -j MASQUERADE - done - progress_message " To $destination $displayproto from $s through ${interface}" + progress_message " To $destination $displayproto from $network through ${interface}" fi done - elif [ -n "$addresses" ]; then - for destnet in $(separate_list $destnets); do - addnatrule $chain -d $destnet $proto $ports -j SNAT $addrlist - done - echo " To $destination $displayproto from $source through ${interface} using $addresses" else for destnet in $(separate_list $destnets); do - addnatrule $chain -d $destnet $proto $ports -j MASQUERADE + addnatrule $chain $(dest_ip_range $destnet) $proto $ports $policy -j $target $addrlist done - progress_message " To $destination $displayproto from $source through ${interface}" + + if [ -n "$addresses" ]; then + progress_message " To $destination $displayproto from $source through ${interface} using $addresses" + else + progress_message " To $destination $displayproto from $source through ${interface}" + fi fi } strip_file masq $1 - [ -n "$NAT_ENABLED" ] && echo "Masqueraded Networks and Hosts:" && save_progress_message "Restoring Masquerading/SNAT..." + if [ -n "$NAT_ENABLED" ]; then + echo "Masqueraded Networks and Hosts:" + [ -n "$RETAIN_ALIASES" ] || save_progress_message "Restoring Masquerading/SNAT..." + fi - while read fullinterface networks addresses proto ports; do - expandv fullinterface networks addresses proto ports + while read fullinterface networks addresses proto ports ipsec; do + expandv fullinterface networks addresses proto ports ipsec [ -n "$NAT_ENABLED" ] && setup_one || \ error_message "Warning: NAT disabled; masq rule ignored" done < $TMP_DIR/masq @@ -4459,7 +5229,7 @@ process_blacklist_rec() { source="--match mac --mac-source $addr" ;; *) - source="-s $addr" + source="$(source_ip_range $addr)" ;; esac @@ -4521,6 +5291,7 @@ setup_blacklist() { local hosts="$(find_hosts_by_option blacklist)" local f=$(find_file blacklist) local disposition=$BLACKLIST_DISPOSITION + local ipsec policy if [ -n "$hosts" -a -f $f ]; then echo "Setting up Blacklisting..." @@ -4532,11 +5303,14 @@ setup_blacklist() { [ -n "$BLACKLISTNEWONLY" ] && state="-m state --state NEW,INVALID" || state= for host in $hosts; do + ipsec=${host%^*} + host=${host#*^} + [ -n "$POLICY_MATCH" ] && policy="-m policy --pol $ipsec --dir in" || policy= interface=${host%%:*} network=${host#*:} for chain in $(first_chains $interface); do - run_iptables -A $chain $state $(match_source_hosts $network) -j blacklst + run_iptables -A $chain $state $(match_source_hosts $network) $policy -j blacklst done [ $network = 0/0.0.0.0 ] && network= || network=":$network" @@ -4546,11 +5320,12 @@ setup_blacklist() { [ "$disposition" = REJECT ] && disposition=reject - while read networks protocol ports; do - expandv networks protocol ports - process_blacklist_rec - done < $TMP_DIR/blacklist - + if [ -z "$DELAYBLACKLISTLOAD" ]; then + while read networks protocol ports; do + expandv networks protocol ports + process_blacklist_rec + done < $TMP_DIR/blacklist + fi fi } @@ -4561,8 +5336,8 @@ refresh_blacklist() { local f=$(find_file blacklist) local disposition=$BLACKLIST_DISPOSITION - if qt iptables -L blacklst -n ; then - echo "Refreshing Black List..." + if qt $IPTABLES -L blacklst -n ; then + echo "Loading Black List..." strip_file blacklist $f @@ -4629,7 +5404,14 @@ add_ip_aliases() do_one() { val=$(address_details) - ensure_and_save_command ip addr add ${external}${val} dev $interface $label + + if [ -n "$RETAIN_ALIASES" ]; then + run_ip addr add ${external}${val} dev $interface $label + save_command qt ip addr add ${external}${val} dev $interface $label + else + ensure_and_save_command ip addr add ${external}${val} dev $interface $label + fi + echo "$external $interface" >> ${STATEDIR}/nat [ -n "$label" ] && label="with $label" progress_message " IP Address $external added to interface $interface $label" @@ -4707,19 +5489,29 @@ verify_ip() { # Determine which optional facilities are supported by iptables/netfilter # determine_capabilities() { - qt iptables -t nat -L -n && NAT_ENABLED=Yes || NAT_ENABLED= - qt iptables -t mangle -L -n && MANGLE_ENABLED=Yes || MANGLE_ENABLED= + qt $IPTABLES -t nat -L -n && NAT_ENABLED=Yes || NAT_ENABLED= + qt $IPTABLES -t mangle -L -n && MANGLE_ENABLED=Yes || MANGLE_ENABLED= CONNTRACK_MATCH= MULTIPORT= + POLICY_MATCH= + PHYSDEV_MATCH= + IPRANGE_MATCH= - if qt iptables -N fooX1234 ; then - qt iptables -A fooX1234 -m conntrack --ctorigdst 192.168.1.1 -j ACCEPT && CONNTRACK_MATCH=Yes - qt iptables -A fooX1234 -p tcp -m multiport --dports 21,22 -j ACCEPT && MULTIPORT=Yes + qt $IPTABLES -N fooX1234 + qt $IPTABLES -A fooX1234 -m conntrack --ctorigdst 192.168.1.1 -j ACCEPT && CONNTRACK_MATCH=Yes + qt $IPTABLES -A fooX1234 -p tcp -m multiport --dports 21,22 -j ACCEPT && MULTIPORT=Yes + qt $IPTABLES -A fooX1234 -m policy --pol ipsec --dir in -j ACCEPT && POLICY_MATCH=Yes + qt $IPTABLES -A fooX1234 -m physdev --physdev-in eth0 -j ACCEPT && PHYSDEV_MATCH=Yes + qt $IPTABLES -A fooX1234 -m iprange --src-range 192.168.1.5-192.168.1.124 -j ACCEPT && IPRANGE_MATCH=Yes - qt iptables -F fooX1234 - qt iptables -X fooX1234 + + if [ -n "$PKTTYPE" ]; then + qt $IPTABLES -A fooX1234 -m pkttype --pkt-type broadcast -j ACCEPT || PKTTYPE= fi + + qt $IPTABLES -F fooX1234 + qt $IPTABLES -X fooX1234 } report_capability() # $1 = Capability Name, $2 Capability Setting (if any) @@ -4737,6 +5529,10 @@ report_capabilities() { report_capability $MANGLE_ENABLED "Packet Mangling" report_capability $MULTIPORT "Multi-port Match" report_capability $CONNTRACK_MATCH "Connection Tracking Match" + report_capability $PKTTYPE "Packet Type Match" + report_capability $POLICY_MATCH "Policy Match" + report_capability $PHYSDEV_MATCH "Physdev Match" + report_capability $IPRANGE_MATCH "IP range Match" } # @@ -4751,9 +5547,14 @@ initialize_netfilter () { report_capabilities + if [ -n "$BRIDGING" ]; then + [ -n "$PHYSDEV_MATCH" ] || startup_error "BRIDGING=Yes requires Physdev Match support in your Kernel and iptables" + fi + echo "Determining Zones..." determine_zones + check_duplicate_zones [ -z "$zones" ] && startup_error "No Zones Defined" @@ -4790,6 +5591,9 @@ initialize_netfilter () { strip_file nat strip_file netmap + echo "Pre-processing Actions..." + process_actions1 + terminator=fatal_error deletechain shorewall @@ -4806,6 +5610,9 @@ initialize_netfilter () { echo "Deleting user chains..." + exists_INPUT=Yes + exists_OUTPUT=Yes + exists_FORWARD=Yes setpolicy INPUT DROP setpolicy OUTPUT DROP setpolicy FORWARD DROP @@ -4829,7 +5636,7 @@ initialize_netfilter () { [ -f $accounting_file ] && setup_accounting $accounting_file # - # Allow DNS lookups during startup for FQDNs and deep-six INVALID packets + # Allow DNS lookups during startup for FQDNs # for chain in INPUT OUTPUT FORWARD; do @@ -4838,21 +5645,32 @@ initialize_netfilter () { run_iptables -A $chain -p ! icmp -m state --state INVALID -j DROP done - [ -n "$CLAMPMSS" ] && \ - run_iptables -A FORWARD -p tcp \ - --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu + if [ -n "$CLAMPMSS" ]; then + case $CLAMPMSS in + Yes) + option="--clamp-mss-to-pmtu" + ;; + *) + option="--set-mss $CLAMPMSS" + ;; + esac + run_iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS $option + fi if [ -z "$NEWNOTSYN" ]; then createchain newnotsyn no for host in $(find_hosts_by_option newnotsyn); do + ipsec=${host%^*} + host=${host#*^} + [ -n "$POLICY_MATCH" ] && policy="-m policy --pol $ipsec --dir in" || policy= interface=${host%%:*} network=${host#*:} - run_iptables -A newnotsyn -i $interface $(match_source_hosts $network) -p tcp --tcp-flags ACK ACK -j ACCEPT - run_iptables -A newnotsyn -i $interface $(match_source_hosts $network) -p tcp --tcp-flags RST RST -j ACCEPT - run_iptables -A newnotsyn -i $interface $(match_source_hosts $network) -p tcp --tcp-flags FIN FIN -j ACCEPT - run_iptables -A newnotsyn -i $interface $(match_source_hosts ${host#*:}) -j RETURN + run_iptables -A newnotsyn -i $interface $(match_source_hosts $network) $policy -p tcp --tcp-flags ACK ACK -j ACCEPT + run_iptables -A newnotsyn -i $interface $(match_source_hosts $network) $policy -p tcp --tcp-flags RST RST -j ACCEPT + run_iptables -A newnotsyn -i $interface $(match_source_hosts $network) $policy -p tcp --tcp-flags FIN FIN -j ACCEPT + run_iptables -A newnotsyn -i $interface $(match_source_hosts $network) $policy -j RETURN done run_user_exit newnotsyn @@ -4876,7 +5694,7 @@ initialize_netfilter () { while read target ignore1 ignore2 address rest; do case $target in DROP|reject) - run_iptables2 -A dynamic -s $address -j $target + run_iptables -A dynamic -s $address -j $target ;; *) ;; @@ -4889,7 +5707,7 @@ initialize_netfilter () { echo "Creating Interface Chains..." - for interface in $all_interfaces; do + for interface in $ALL_INTERFACES; do createchain $(forward_chain $interface) no run_iptables -A $(forward_chain $interface) $state -j dynamic createchain $(input_chain $interface) no @@ -4915,14 +5733,14 @@ add_common_rules() { # for address in $broadcasts ; do [ -n "$SMURF_LOG_LEVEL" ] && log_rule $SMURF_LOG_LEVEL smurfs DROP -s $address - run_iptables -A smurfs -s $address -j DROP + run_iptables -A smurfs $(source_ip_range $address) -j DROP done # # Reject Rules -- Don't respond to broadcasts with an ICMP # if [ -n "$PKTTYPE" ]; then - qt iptables -A reject -m pkttype --pkt-type broadcast -j DROP - if ! qt iptables -A reject -m pkttype --pkt-type multicast -j DROP; then + qt $IPTABLES -A reject -m pkttype --pkt-type broadcast -j DROP + if ! qt $IPTABLES -A reject -m pkttype --pkt-type multicast -j DROP; then # # No pkttype support -- do it the hard way # @@ -4943,14 +5761,21 @@ add_common_rules() { # # Not all versions of iptables support these so don't complain if they don't work # - qt iptables -A reject -p icmp -j REJECT --reject-with icmp-host-unreachable - if ! qt iptables -A reject -j REJECT --reject-with icmp-host-prohibited; then + qt $IPTABLES -A reject -p icmp -j REJECT --reject-with icmp-host-unreachable + if ! qt $IPTABLES -A reject -j REJECT --reject-with icmp-host-prohibited; then # # In case the above doesn't work # run_iptables -A reject -j REJECT fi + # + # Create common action chains + # + for action in $USEDACTIONS; do + createactionchain $action + done + run_user_exit initdone # @@ -4968,11 +5793,14 @@ add_common_rules() { echo "Adding Anti-smurf Rules" for host in $hosts; do + ipsec=${host%^*} + host=${host#*^} + [ -n "$POLICY_MATCH" ] && policy="-m policy --pol $ipsec --dir in" || policy= interface=${host%%:*} network=${host#*:} for chain in $(first_chains $interface); do - run_iptables -A $chain -m state --state NEW $(match_source_hosts $network) -j smurfs + run_iptables -A $chain -m state --state NEW,INVALID $(match_source_hosts $network) $policy -j smurfs done done fi @@ -4989,10 +5817,10 @@ add_common_rules() { if [ -n "$BRIDGING" ]; then eval is_bridge=\$$(chain_base $interface)_ports [ -n "$is_bridge" ] && \ - iptables -A $(forward_chain $interface) -p udp -o $interface --dport 67:68 -j ACCEPT + $IPTABLES -A $(forward_chain $interface) -p udp -o $interface --dport 67:68 -j ACCEPT fi run_iptables -A $(input_chain $interface) -p udp --dport 67:68 -j ACCEPT - run_iptables -A OUTPUT -o $interface -p udp --dport 67:68 -j ACCEPT + run_iptables -A OUTPUT -o $interface -p udp --dport 67:68 -j ACCEPT done fi # @@ -5040,28 +5868,33 @@ add_common_rules() { ;; esac - run_iptables2 -A norfc1918 -s $networks -j $target - - if [ -n "$CONNTRACK_MATCH" ]; then - # - # We have connection tracking match -- match on the original destination - # - run_iptables2 -A norfc1918 -m conntrack --ctorigdst $networks -j $target - elif [ -n "$MANGLE_ENABLED" ]; then - # - # No connection tracking match but we have mangling -- add a rule to - # the mangle table - # - run_iptables2 -t mangle -A man1918 -d $networks -j $target - fi + for network in $(separate_list $networks); do + run_iptables2 -A norfc1918 $(source_ip_range $network) -j $target + + if [ -n "$CONNTRACK_MATCH" ]; then + # + # We have connection tracking match -- match on the original destination + # + run_iptables2 -A norfc1918 -m conntrack --ctorigdst $network -j $target + elif [ -n "$MANGLE_ENABLED" ]; then + # + # No connection tracking match but we have mangling -- add a rule to + # the mangle table + # + run_iptables2 -t mangle -A man1918 $(dest_ip_range $network) -j $target + fi + done done < $TMP_DIR/rfc1918 for host in $hosts; do + ipsec=${host%^*} + host=${host#*^} + [ -n "$POLICY_MATCH" ] && policy="-m policy --pol $ipsec --dir in" || policy= interface=${host%%:*} networks=${host#*:} for chain in $(first_chains $interface); do - run_iptables -A $chain -m state --state NEW $(match_source_hosts $networks) -j norfc1918 + run_iptables -A $chain -m state --state NEW $(match_source_hosts $networks) $policy -j norfc1918 done [ -n "$MANGLE_ENABLED" -a -z "$CONNTRACK_MATCH" ] && \ @@ -5098,11 +5931,14 @@ add_common_rules() { ;; esac - run_iptables2 -A nobogons -s $networks -j $target + run_iptables2 -A nobogons $(source_ip_range $networks) -j $target done < $TMP_DIR/bogons for host in $hosts; do + ipsec=${host%^*} + host=${host#*^} + [ -n "$POLICY_MATCH" ] && policy="-m policy --pol $ipsec --dir in" || policy= interface=${host%%:*} network=${host#*:} @@ -5157,11 +5993,14 @@ add_common_rules() { run_iptables -A tcpflags -p tcp --syn --sport 0 $disposition for host in $hosts; do + ipsec=${host%^*} + host=${host#*^} + [ -n "$POLICY_MATCH" ] && policy="-m policy --pol $ipsec --dir in" || policy= interface=${host%%:*} network=${host#*:} for chain in $(first_chains $interface); do - run_iptables -A $chain -p tcp $(match_source_hosts $network) -j tcpflags + run_iptables -A $chain -p tcp $(match_source_hosts $network) $policy -j tcpflags done done fi @@ -5170,8 +6009,8 @@ add_common_rules() { # save_progress_message "Restoring ARP filtering..." - for f in /proc/sys/net/ipv4/conf/*/arp_filter; do - run_and_save_command "echo 0 > $f" + for f in /proc/sys/net/ipv4/conf/*; do + run_and_save_command "[ -f $f/arp_filter ] && echo 0 > $f/arp_filter" done interfaces=$(find_interfaces_by_option arp_filter) @@ -5199,8 +6038,8 @@ add_common_rules() { save_progress_message "Restoring Route Filtering..." - for f in /proc/sys/net/ipv4/conf/*/rp_filter; do - run_and_save_command "echo 0 > $f" + for f in /proc/sys/net/ipv4/conf/*; do + run_and_save_command "[ -f $f/rp_filter ] && echo 0 > $f/rp_filter" done for interface in $interfaces; do @@ -5217,15 +6056,72 @@ add_common_rules() { if [ -n "$ROUTE_FILTER" ]; then run_and_save_command "echo 1 > /proc/sys/net/ipv4/conf/default/rp_filter" + run_and_save_command "echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter" fi run_and_save_command ip route flush cache fi + # + # Martian Logging + # + interfaces="$(find_interfaces_by_option logmartians)" + + if [ -n "$interfaces" -o -n "$LOG_MARTIANS" ]; then + echo "Setting up Martian Logging..." + + save_progress_message "Restoring Martian Logging..." + + for f in /proc/sys/net/ipv4/conf/*; do + run_and_save_command "[ -f $f/log_martians ] && echo 0 > $f/log_martians" + done + + for interface in $interfaces; do + file=/proc/sys/net/ipv4/conf/$interface/log_martians + if [ -f $file ]; then + run_and_save_command "echo 1 > $file" + else + error_message \ + "Warning: Cannot set Martian logging on $interface" + fi + done + + if [ -n "$LOG_MARTIANS" ]; then + run_and_save_command "echo 1 > /proc/sys/net/ipv4/conf/default/log_martians" + run_and_save_command "echo 1 > /proc/sys/net/ipv4/conf/all/log_martians" + fi + + fi + + # + # Source Routing + # + save_progress_message "Restoring Accept Source Routing..." + + for f in /proc/sys/net/ipv4/conf/*; do + run_and_save_command "[ -f $f/accept_source_route ] && echo 0 > $f/accept_source_route" + done + + interfaces=$(find_interfaces_by_option sourceroute) + + if [ -n "$interfaces" ]; then + echo "Setting up Accept Source Routing..." + + for interface in $interfaces; do + file=/proc/sys/net/ipv4/conf/$interface/accept_source_route + if [ -f $file ]; then + run_and_save_command "echo 1 > $file" + else + error_message \ + "Warning: Cannot set Accept Source Routing on $interface" + fi + done + fi + if [ -n "$DYNAMIC_ZONES" ]; then echo "Setting up Dynamic Zone Chains..." - for interface in $all_interfaces; do + for interface in $ALL_INTERFACES; do for chain in $(dynamic_chains $interface); do createchain $chain no done @@ -5324,14 +6220,15 @@ activate_rules() if havenatchain $destchain ; then run_iptables -t nat -A $sourcechain $@ -j $destchain - elif [ -n "$BRIDGING" -a -f $TMP_DIR/physdev ]; then - rm -f #TMP_DIR/physdev + else + [ -n "$BRIDGING" -a -f $TMP_DIR/physdev ] && -rm -f $TMP_DIR/physdev + [ -n "$IPRANGE_MATCH" -a -f $TMP_DIR/iprange ] && rm -f $TMP_DIR/iprange fi } # # Jump to a RULES chain from one of the builtin nat chains. These jumps are - # are inserted before jumps to static NAT chains. + # are inserted before jumps to one-to-one NAT chains. # addrulejump() # $1 = BUILTIN chain, $2 = user chain, $3 - * other arguments { @@ -5343,15 +6240,23 @@ activate_rules() eval run_iptables -t nat -I $sourcechain \ \$${sourcechain}_rule $@ -j $destchain eval ${sourcechain}_rule=\$\(\(\$${sourcechain}_rule + 1\)\) - elif [ -n "$BRIDGING" -a -f $TMP_DIR/physdev ]; then - rm -f $TMP_DIR/physdev + else + [ -n "$BRIDGING" -a -f $TMP_DIR/physdev ] && rm -f $TMP_DIR/physdev + [ -n "$IPRANGE_MATCH" -a -f $TMP_DIR/iprange ] && rm -f $TMP_DIR/iprange + fi } + # + # Add jumps to early SNAT chains + # + for interface in $ALL_INTERFACES; do + addnatjump POSTROUTING $(snat_chain $interface) -o $interface + done # # Add jumps for dynamic nat chains # - [ -n "$DYNAMIC_ZONES" ] && for interface in $all_interfaces ; do + [ -n "$DYNAMIC_ZONES" ] && for interface in $ALL_INTERFACES ; do addrulejump PREROUTING $(dynamic_in $interface) -i $interface done # @@ -5360,13 +6265,43 @@ activate_rules() addnatjump PREROUTING nat_in addnatjump POSTROUTING nat_out - for interface in $all_interfaces; do + for interface in $ALL_INTERFACES; do addnatjump PREROUTING $(input_chain $interface) -i $interface addnatjump POSTROUTING $(output_chain $interface) -o $interface done > ${STATEDIR}/chains > ${STATEDIR}/zones + # + # Create forwarding chains for complex zones and generate jumps for IPSEC source hosts to that chain. + # + for zone in $zones; do + if eval test -n \"\$${zone}_is_complex\" ; then + frwd_chain=${zone}_frwd + createchain $frwd_chain No + + if [ -n "$POLICY_MATCH" ]; then + eval is_ipsec=\$${zone}_is_ipsec + + if [ -n "$is_ipsec" ]; then + eval source_hosts=\$${zone}_hosts + if [ -n "$DYNAMIC_ZONES" ]; then + createchain ${zone}_dyn No + run_iptables -A $frwd_chain -j ${zone}_dyn + fi + else + eval source_hosts=\$${zone}_ipsec_hosts + fi + + for host in $source_hosts; do + interface=${host%%:*} + networks=${host#*:} + + run_iptables -A $(forward_chain $interface) $(match_source_hosts $networks) $(match_ipsec_in $zone $host) -j $frwd_chain + done + fi + fi + done for zone in $zones; do eval source_hosts=\$${zone}_hosts @@ -5376,13 +6311,11 @@ activate_rules() eval complex=\$${zone}_is_complex - if [ -n "$complex" ]; then - frwd_chain=${zone}_frwd - createchain $frwd_chain No - fi + [ -n "$complex" ] && frwd_chain=${zone}_frwd + echo $zone $source_hosts >> ${STATEDIR}/zones + if [ -n "$DYNAMIC_ZONES" ]; then - echo $zone $source_hosts >> ${STATEDIR}/zones echo "$FW $zone $chain1" >> ${STATEDIR}/chains echo "$zone $FW $chain2" >> ${STATEDIR}/chains fi @@ -5393,18 +6326,19 @@ activate_rules() interface=${host%%:*} networks=${host#*:} - run_iptables -A OUTPUT -o $interface $(match_dest_hosts $networks) -j $chain1 + run_iptables -A OUTPUT -o $interface $(match_dest_hosts $networks) $(match_ipsec_out $zone $host) -j $chain1 # # Add jumps from the builtin chains for DNAT and SNAT rules # - addrulejump PREROUTING $(dnat_chain $zone) -i $interface $(match_source_hosts $networks) - addrulejump POSTROUTING $(snat_chain $zone) -o $interface $(match_dest_hosts $networks) + addrulejump PREROUTING $(dnat_chain $zone) -i $interface $(match_source_hosts $networks) $(match_ipsec_in $zone $host) + addrulejump POSTROUTING $(snat_chain $zone) -o $interface $(match_dest_hosts $networks) $(match_ipsec_out $zone $host) - run_iptables -A $(input_chain $interface) $(match_source_hosts $networks) -j $chain2 + run_iptables -A $(input_chain $interface) $(match_source_hosts $networks) $(match_ipsec_in $zone $host) -j $chain2 - [ -n "$complex" ] && \ - run_iptables -A $(forward_chain $interface) $(match_source_hosts $networks) -j $frwd_chain + if [ -n "$complex" ] && ! is_ipsec_host $zone $host ; then + run_iptables -A $(forward_chain $interface) $(match_source_hosts $networks) $(match_ipsec_in $zone $host) -j $frwd_chain + fi case $networks in *.*.*.*) @@ -5417,7 +6351,6 @@ activate_rules() esac done - for interface in $need_broadcast ; do run_iptables -A OUTPUT -o $interface -d 255.255.255.255 -j $chain1 run_iptables -A OUTPUT -o $interface -d 224.0.0.0/4 -j $chain1 @@ -5469,22 +6402,22 @@ activate_rules() # routeback was specified for this host group # if [ $zone != $zone1 -o $num_ifaces -gt 1 ] || list_search $host1 $routeback ; then - run_iptables -A $frwd_chain -o $interface1 $(match_dest_hosts $networks1) -j $chain + run_iptables -A $frwd_chain -o $interface1 $(match_dest_hosts $networks1) $(match_ipsec_out $zone1 $host1) -j $chain fi done else for host in $source_hosts; do interface=${host%%:*} networks=${host#*:} - + chain1=$(forward_chain $interface) - + for host1 in $dest_hosts; do interface1=${host1%%:*} networks1=${host1#*:} if [ "$host" != "$host1" ] || list_search $host $routeback; then - run_iptables -A $chain1 $(match_source_hosts $networks) -o $interface1 $(match_dest_hosts $networks1) -j $chain + run_iptables -A $chain1 $(match_source_hosts $networks) -o $interface1 $(match_dest_hosts $networks1) $(match_ipsec_out $zone1 $host1) -j $chain fi done done @@ -5492,7 +6425,7 @@ activate_rules() done done - for interface in $all_interfaces ; do + for interface in $ALL_INTERFACES ; do run_iptables -A FORWARD -i $interface -j $(forward_chain $interface) run_iptables -A INPUT -i $interface -j $(input_chain $interface) addnatjump POSTROUTING $(masq_chain $interface) -o $interface @@ -5531,16 +6464,37 @@ activate_rules() run_iptables -D $chain -m state --state ESTABLISHED,RELATED -j ACCEPT run_iptables -D $chain -p udp --dport 53 -j ACCEPT done + + if [ -n "$LOGALLNEW" ]; then + for table in mangle nat filter; do + case $table in + mangle) + chains="PREROUTING INPUT FORWARD POSTROUTING" + ;; + nat) + chains="PREROUTING POSTROUTING OUTPUT" + ;; + *) + chains="INPUT FORWARD OUTPUT" + ;; + esac + + for chain in $chains; do + log_rule_limit $LOGALLNEW $chain $table $chain "" "" -I -m state --state NEW -t $table + done + done + fi } # # Check for disabled startup # check_disabled_startup() { - if [ -f /etc/shorewall/startup_disabled ]; then + if [ -z "$STARTUP_ENABLED" ]; then echo " Shorewall Startup is disabled -- to enable startup" echo " after you have completed Shorewall configuration," - echo " remove the file /etc/shorewall/startup_disabled" + echo " change the setting of STARTUP_ENABLED to Yes in" + echo " /etc/shorewall/shorewall.conf" [ -n "$TMP_DIR" ] && rm -rf $TMP_DIR my_mutex_off @@ -5572,6 +6526,12 @@ define_firewall() # $1 = Command (Start or Restart) save_command "#" save_command ". /usr/share/shorewall/functions" + f=$(find_file params) + + [ -f $f ] && \ + save_command ". $f" + + save_command "#" save_command "MODULESDIR=\"$MODULESDIR\"" save_command "MODULE_SUFFIX=\"$MODULE_SUFFIX\"" @@ -5587,12 +6547,16 @@ define_firewall() # $1 = Command (Start or Restart) [ -f $tunnels ] && \ echo "Processing $tunnels..." && setup_tunnels $tunnels + ipsecfile=$(find_file ipsec) + [ -f $ipsecfile ] && \ + echo "Processing $ipsecfile..." && setup_ipsec $ipsecfile + maclist_hosts=$(find_hosts_by_option maclist) [ -n "$maclist_hosts" ] && setup_mac_lists - echo "Pre-processing Actions..."; process_actions1 echo "Processing $(find_file rules)..."; process_rules echo "Processing Actions..."; process_actions2 + process_actions3 echo "Processing $(find_file policy)..."; apply_policy_rules masq=$(find_file masq) @@ -5616,22 +6580,24 @@ define_firewall() # $1 = Command (Start or Restart) done save_progress_message "Restoring Netfilter Configuration..." - + save_command 'iptables-restore << __EOF__' - + # 'shorewall save' appends the iptables-save output and '__EOF__' - + mv -f $RESTOREBASE /var/lib/shorewall/restore-base-$$ - + > $RESTOREBASE - + save_command "#" save_command "# Restore tail file generated by Shorewall $version - $(date)" save_command "#" save_command "date > $STATEDIR/restarted" - + run_user_exit start + [ -n "$DELAYBLACKLISTLOAD" ] && refresh_blacklist + createchain shorewall no date > $STATEDIR/restarted @@ -5685,32 +6651,27 @@ refresh_firewall() # # Add a host or networks to a zone # -add_to_zone() # $1 = [:] $2 = zone +add_to_zone() # $1...${n-1} = [:] $n = zone { - local base interface host newhost zone z h z1 z2 chain terminator + local interface host zone z h z1 z2 chain local dhcp_interfaces blacklist_interfaces maclist_interfaces tcpflags_interfaces - local rulenum source_chain dest_hosts iface hosts + local rulenum source_chain dest_hosts iface hosts hostlist= nat_chain_exists() # $1 = chain name { - qt iptables -t nat -L $1 -n + qt $IPTABLES -t nat -L $1 -n } do_iptables() # $@ = command { [ -n "$BRIDGING" ] && [ -f $TMP_DIR/physdev ] && rm -f $TMP_DIR/physdev - if ! iptables $@ ; then - startup_error "Can't add $1 to zone $2" + [ -n "$IPRANGE_MATCH" ] && [ -f $TMP_DIR/iprange ] && rm -f $TMP_DIR/iprange + + if ! $IPTABLES $@ ; then + error_message "Can't add $newhost to zone $zone" fi } - # - # Isolate interface and host parts - # - interface=${1%%:*} - host=${1#*:} - - [ -z "$host" ] && host="0.0.0.0/0" # # Load $zones # @@ -5720,52 +6681,260 @@ add_to_zone() # $1 = [:] $2 = zone # validate_interfaces_file # + # Validate Hosts File + # + validate_hosts_file + # + # Validate IPSec File + # + f=$(find_file ipsec) + + [ -f $f ] && setup_ipsec $f + # + # Normalize host list + # + while [ $# -gt 1 ]; do + interface=${1%%:*} + host=${1#*:} + # + # Be sure that the interface was dynamic at last [re]start + # + if ! chain_exists $(input_chain $interface) ; then + startup_error "Unknown interface $interface" + fi + + if ! chain_exists $(dynamic_in $interface) ; then + startup_error "At last Shorewall [re]start, DYNAMIC_ZONES=No in shorewall.conf" + fi + + if [ -z "$host" ]; then + hostlist="$hostlist $interface:0.0.0.0/0" + else + for h in $(separate_list $host); do + hostlist="$hostlist $interface:$h" + done + fi + + shift + done + # # Validate Zone # - zone=$2 + zone=$1 validate_zone $zone || startup_error "Unknown zone: $zone" [ "$zone" = $FW ] && startup_error "Can't add $1 to firewall zone" - + # # Be sure that Shorewall has been restarted using a DZ-aware version of the code # [ -f ${STATEDIR}/chains ] || startup_error "${STATEDIR}/chains -- file not found" [ -f ${STATEDIR}/zones ] || startup_error "${STATEDIR}/zones -- file not found" # - # Be sure that the interface was dynamic at last [re]start + # Check for duplicates and create a new zone state file # - if ! chain_exists $(input_chain $interface) ; then - startup_error "Unknown interface $interface" - fi + > ${STATEDIR}/zones_$$ - if ! chain_exists $(dynamic_in $interface) ; then - startup_error "At last Shorewall [re]start, DYNAMIC_ZONES=No in shorewall.conf" - fi - # - # Normalize the first argument to this function - # - newhost="$interface:$host" + while read z hosts; do + if [ "$z" = "$zone" ]; then + for h in $hosts; do + for host in $hostlist; do + if [ "$h" = "$host" ]; then + rm -f ${STATEDIR}/zones_$$ + startup_error "$host already in zone $zone" + fi + done + done + + [ -z "$hosts" ] && hosts=$hostlist || hosts="$hosts $hostlist" + fi + + eval ${z}_hosts=\"$hosts\" + + echo "$z $hosts" >> ${STATEDIR}/zones_$$ + done < ${STATEDIR}/zones + + mv -f ${STATEDIR}/zones_$$ ${STATEDIR}/zones terminator=fatal_error # # Create a new Zone state file # + for newhost in $hostlist; do + # + # Isolate interface and host parts + # + interface=${newhost%%:*} + host=${newhost#*:} + # + # If the zone passed in the command has a dnat chain then insert a rule in + # the nat table PREROUTING chain to jump to that chain when the source + # matches the new host(s)# + # + chain=${zone}_dnat + + if nat_chain_exists $chain; then + do_iptables -t nat -A $(dynamic_in $interface) $(source_ip_range $host) $(match_ipsec_in $zone $newhost) -j $chain + fi + # + # Insert new rules into the filter table for the passed interface + # + while read z1 z2 chain; do + if [ "$z1" = "$zone" ]; then + if [ "$z2" = "$FW" ]; then + do_iptables -A $(dynamic_in $interface) $(match_source_hosts $host) $(match_ipsec_in $z1 $newhost) -j $chain + else + source_chain=$(dynamic_fwd $interface) + if is_ipsec_host $z1 $newhost ; then + do_iptables -A $source_chain $(match_source_hosts $host) $(match_ipsec_in $z1 $newhost) -j ${z1}_frwd + else + eval dest_hosts=\"\$${z2}_hosts\" + + for h in $dest_hosts; do + iface=${h%%:*} + hosts=${h#*:} + + if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then + do_iptables -A $source_chain $(match_source_hosts $host) -o $iface $(match_dest_hosts $hosts) $(match_ipsec_out $z2 $h) -j $chain + fi + done + fi + fi + elif [ "$z2" = "$zone" ]; then + if [ "$z1" = "$FW" ]; then + # + # Add a rule to the dynamic out chain for the interface + # + do_iptables -A $(dynamic_out $interface) $(match_dest_hosts $host) $(match_ipsec_out $z2 $newhost) -j $chain + else + eval source_hosts=\"\$${z1}_hosts\" + + for h in $source_hosts; do + iface=${h%%:*} + hosts=${h#*:} + + if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then + if is_ipsec_host $z1 $h; then + do_iptables -A ${z1}_dyn -o $interface $(match_dest_hosts $host) $(match_ipsec_out $z2 $newhost) -j $chain + else + do_iptables -A $(dynamic_fwd $iface) $(match_source_hosts $hosts) -o $interface $(match_dest_hosts $host) $(match_ipsec_out $z2 $newhost) -j $chain + fi + fi + done + fi + fi + done < ${STATEDIR}/chains + + progress_message "$newhost added to zone $zone" + + done + + rm -rf $TMP_DIR +} + +# +# Delete a host or networks from a zone +# +delete_from_zone() # $1 = [:] $2 = zone +{ + local interface host zone z h z1 z2 chain delhost + local dhcp_interfaces blacklist_interfaces maclist_interfaces tcpflags_interfaces + local rulenum source_chain dest_hosts iface hosts hostlist= + + # + # Load $zones + # + determine_zones + # + # Validate Interfaces File + # + validate_interfaces_file + # + # Validate Hosts File + # + validate_hosts_file + # + # Validate IPSec File + # + f=$(find_file ipsec) + + [ -f $f ] && setup_ipsec $f + + # + # Normalize host list + # + while [ $# -gt 1 ]; do + interface=${1%%:*} + host=${1#*:} + # + # Be sure that the interface was dynamic at last [re]start + # + if ! chain_exists $(input_chain $interface) ; then + startup_error "Unknown interface $interface" + fi + + if ! chain_exists $(dynamic_in $interface) ; then + startup_error "At last Shorewall [re]start, DYNAMIC_ZONES=No in shorewall.conf" + fi + + if [ -z "$host" ]; then + hostlist="$hostlist $interface:0.0.0.0/0" + else + for h in $(separate_list $host); do + hostlist="$hostlist $interface:$h" + done + fi + + shift + done + # + # Validate Zone + # + zone=$1 + + validate_zone $zone || startup_error "Unknown zone: $zone" + + [ "$zone" = $FW ] && startup_error "Can't delete from the firewall zone" + + # + # Be sure that Shorewall has been restarted using a DZ-aware version of the code + # + [ -f ${STATEDIR}/chains ] || startup_error "${STATEDIR}/chains -- file not found" + [ -f ${STATEDIR}/zones ] || startup_error "${STATEDIR}/zones -- file not found" + # + # Delete the passed hosts from the zone state file + # > ${STATEDIR}/zones_$$ - # - # Add $1 to the Zone state file - # + while read z hosts; do if [ "$z" = "$zone" ]; then - for h in $hosts; do - if [ "$h" = "$newhost" ]; then - rm -f ${STATEDIR}/zones_$$ - startup_error "$1 already in zone $zone" - fi + temp=$hosts + hosts= + + for host in $hostlist; do + found= + for h in $temp; do + if [ "$h" = "$host" ]; then + found=Yes + break + fi + done + + [ -n "$found" ] || error_message "Warning: $1 does not appear to be in zone $2" done - [ -z "$hosts" ] && hosts=$newhost || hosts="$hosts $newhost" + for h in $temp; do + found= + for host in $hostlist; do + if [ "$h" = "$host" ]; then + found=Yes + break + fi + done + + [ -n "$found" ] || hosts="$hosts $h" + done fi eval ${z}_hosts=\"$hosts\" @@ -5774,187 +6943,69 @@ add_to_zone() # $1 = [:] $2 = zone done < ${STATEDIR}/zones mv -f ${STATEDIR}/zones_$$ ${STATEDIR}/zones - # - # If the zone passed in the command has a dnat chain then insert a rule in - # the nat table PREROUTING chain to jump to that chain when the source - # matches the new host(s)# - # - chain=${zone}_dnat - - if nat_chain_exists $chain; then - do_iptables -t nat -A $(dynamic_in $interface) $(match_source_hosts $host) -j $chain - fi - # - # Insert new rules into the filter table for the passed interface - # - while read z1 z2 chain; do - if [ "$z1" = "$zone" ]; then - if [ "$z2" = "$FW" ]; then - do_iptables -A $(dynamic_in $interface) $(match_source_hosts $host) -j $chain - else - source_chain=$(dynamic_fwd $interface) - eval dest_hosts=\"\$${z2}_hosts\" - - for h in $dest_hosts; do - iface=${h%%:*} - hosts=${h#*:} - - if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then - do_iptables -A $source_chain $(match_source_hosts $host) -o $iface $(match_dest_hosts $hosts) -j $chain - fi - done - fi - elif [ "$z2" = "$zone" ]; then - if [ "$z1" = "$FW" ]; then - # - # Add a rule to the dynamic out chain for the interface - # - do_iptables -A $(dynamic_out $interface) $(match_dest_hosts $host) -j $chain - else - eval source_hosts=\"\$${z1}_hosts\" - - for h in $source_hosts; do - iface=${h%%:*} - hosts=${h#*:} - - if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then - do_iptables -A $(dynamic_fwd $iface) $rulenum $(match_source_hosts $hosts) -o $interface $(match_dest_hosts $host) -j $chain - fi - done - fi - fi - done < ${STATEDIR}/chains - - rm -rf $TMP_DIR - - progress_message "$1 added to zone $2" -} - -# -# Delete a host or networks from a zone -# -delete_from_zone() # $1 = [:] $2 = zone -{ - # - # Delete the subject host(s) from the zone state file - # - delete_from_zones_file() - { - > ${STATEDIR}/zones_$$ - - while read z hosts; do - if [ "$z" = "$zone" ]; then - temp=$hosts - hosts= - - for h in $temp; do - if [ "$h" = "$delhost" ]; then - echo Yes - else - hosts="$hosts $h" - fi - done - fi - - echo "$z $hosts" >> ${STATEDIR}/zones_$$ - done < ${STATEDIR}/zones - - mv -f ${STATEDIR}/zones_$$ ${STATEDIR}/zones - } - # - # Isolate interface and host parts - # - interface=${1%%:*} - host=${1#*:} - - [ -z "$host" ] && host="0.0.0.0/0" - # - # Load $zones - # - determine_zones - - zone=$2 - - validate_zone $zone || startup_error "Unknown zone: $zone" - - [ "$zone" = $FW ] && startup_error "Can't remove $1 from firewall zone" - # - # Be sure that Shorewall has been restarted using a DZ-aware version of the code - # - [ -f ${STATEDIR}/chains ] || startup_error "${STATEDIR}/chains -- file not found" - [ -f ${STATEDIR}/zones ] || startup_error "${STATEDIR}/zones -- file not found" - # - # Be sure that the interface was present at last [re]start - # - if ! chain_exists $(input_chain $interface) ; then - startup_error "Unknown interface $interface" - fi - - if ! chain_exists $(dynamic_in $interface) ; then - startup_error "Interface $interface is not dynamic" - fi - # - # Normalize the first argument to this function - # - delhost="$interface:$host" - # - # Delete the passed hosts from the zone state file - # - [ -z "$(delete_from_zones_file)" ] && \ - error_message "Warning: $1 does not appear to be in zone $2" - # - # Construct the zone host maps - # - while read z hosts; do - eval ${z}_hosts=\"$hosts\" - done < ${STATEDIR}/zones terminator=fatal_error - # - # Delete any nat table entries for the host(s) - # - qt_iptables -t nat -D $(dynamic_in $interface) $(match_source_hosts $host) -j ${zone}_dnat - # - # Delete rules rules the input chains for the passed interface - # - while read z1 z2 chain; do - if [ "$z1" = "$zone" ]; then - if [ "$z2" = "$FW" ]; then - qt_iptables -D $(dynamic_in $interface) $(match_source_hosts $host) -j $chain - else - source_chain=$(dynamic_fwd $interface) - eval dest_hosts=\"\$${z2}_hosts\" - for h in $dest_hosts $delhost; do - iface=${h%%:*} - hosts=${h#*:} + for delhost in $hostlist; do + interface=${delhost%%:*} + host=${delhost#*:} + # + # Delete any nat table entries for the host(s) + # + qt_iptables -t nat -D $(dynamic_in $interface) $(match_source_hosts $host) $(match_ipsec_in $zone $delhost) -j ${zone}_dnat + # + # Delete rules rules the input chains for the passed interface + # + while read z1 z2 chain; do + if [ "$z1" = "$zone" ]; then + if [ "$z2" = "$FW" ]; then + qt_iptables -D $(dynamic_in $interface) $(match_source_hosts $host) $(match_ipsec_in $z1 $delhost) -j $chain + else + source_chain=$(dynamic_fwd $interface) + if is_ipsec_host $z1 $delhost ; then + qt_iptables -D $source_chain $(match_source_hosts $host) $(match_ipsec_in $z1 $newhost) -j ${z1}_frwd + else + eval dest_hosts=\"\$${z2}_hosts\" - if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then - qt_iptables -D $source_chain $(match_source_hosts $host) -o $iface $(match_dest_hosts $hosts) -j $chain + [ "$z2" = "$zone" ] && dest_hosts="$dest_hosts $hostlist" + + for h in $dest_hosts; do + iface=${h%%:*} + hosts=${h#*:} + + if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then + qt_iptables -D $source_chain $(match_source_hosts $host) -o $iface $(match_dest_hosts $hosts) $(match_ipsec_out $z2 $h) -j $chain + fi + done fi - done + fi + elif [ "$z2" = "$zone" ]; then + if [ "$z1" = "$FW" ]; then + qt_iptables -D $(dynamic_out $interface) $(match_dest_hosts $host) $(match_ipsec_out $z2 $delhost) -j $chain + else + eval source_hosts=\"\$${z1}_hosts\" + + for h in $source_hosts; do + iface=${h%%:*} + hosts=${h#*:} + + if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then + if is_ipsec_host $z1 $h; then + qt_iptables -D ${z1}_dyn -o $interface $(match_dest_hosts $host) $(match_ipsec_out $z2 $delhost) -j $chain + else + qt_iptables -D $(dynamic_fwd $iface) $(match_source_hosts $hosts) -o $interface $(match_dest_hosts $host) $(match_ipsec_out $z2 $delhost) -j $chain + fi + fi + done + fi fi - elif [ "$z2" = "$zone" ]; then - if [ "$z1" = "$FW" ]; then - qt_iptables -D $(dynamic_out $interface) $(match_dest_hosts $host) -j $chain - else - eval source_hosts=\"\$${z1}_hosts\" - - for h in $source_hosts; do - iface=${h%%:*} - hosts=${h#*:} + done < ${STATEDIR}/chains - if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then - qt_iptables -D $(dynamic_fwd $iface) $(match_source_hosts $hosts) -o $interface $(match_dest_hosts $host) -j $chain - fi - done - fi - fi - done < ${STATEDIR}/chains + progress_message "$delhost removed from zone $zone" + done + rm -rf $TMP_DIR - - progress_message "$1 removed from zone $2" } # @@ -6023,6 +7074,7 @@ do_initialize() { # Clear all configuration variables # version= + IPTABLES= FW= SUBSYSLOCK= STATEDIR= @@ -6038,6 +7090,7 @@ do_initialize() { BLACKLIST_LOGLEVEL= CLAMPMSS= ROUTE_FILTER= + LOG_MARTIANS= DETECT_DNAT_IPADDRS= MUTEX_TIMEOUT= NEWNOTSYN= @@ -6065,9 +7118,15 @@ do_initialize() { BRIDGING= DYNAMIC_ZONES= PKTTYPE= + RETAIN_ALIASES= + DELAYBLACKLISTLOAD= + LOGTAGONLY= + LOGALLNEW= DROPINVALID= + RESTOREBASE= TMP_DIR= + ALL_INTERFACES= stopping= have_mutex= @@ -6119,12 +7178,21 @@ do_initialize() { ensure_config_path # # Determine the capabilities of the installed iptables/netfilter - # We load the kernel modules here to acurately determine + # We load the kernel modules here to accurately determine # capabilities when module autoloading isn't enabled. # [ -n "$MODULE_SUFFIX" ] || MODULE_SUFFIX="o gz ko o.gz ko.gz" load_kernel_modules + + if [ -z "$IPTABLES" ]; then + IPTABLES=$(which iptables 2> /dev/null) + + [ -z "$IPTABLES" ] && startup_error "Can't find iptables executable" + else + [ -e "$IPTABLES" ] || startup_error "\$IPTABLES=$IPTABLES does not exist or is not executable" + fi + determine_capabilities [ -z "${STATEDIR}" ] && STATEDIR=/var/state/shorewall @@ -6162,10 +7230,18 @@ do_initialize() { fi [ -z "$BLACKLIST_DISPOSITION" ] && BLACKLIST_DISPOSITION=DROP - - CLAMPMSS=$(added_param_value_no CLAMPMSS $CLAMPMSS) + + case "$CLAMPMSS" in + [0-9]*) + ;; + *) + CLAMPMSS=$(added_param_value_no CLAMPMSS $CLAMPMSS) + ;; + esac + ADD_SNAT_ALIASES=$(added_param_value_no ADD_SNAT_ALIASES $ADD_SNAT_ALIASES) ROUTE_FILTER=$(added_param_value_no ROUTE_FILTER $ROUTE_FILTER) + LOG_MARTIANS=$(added_param_value_no LOG_MARTIANS $LOG_MARTIANS) DETECT_DNAT_IPADDRS=$(added_param_value_no DETECT_DNAT_IPADDRS $DETECT_DNAT_IPADDRS) FORWARDPING=$(added_param_value_no FORWARDPING $FORWARDPING) [ -n "$FORWARDPING" ] && \ @@ -6206,7 +7282,7 @@ do_initialize() { [ -z "$BOGON_LOG_LEVEL" ] && BOGON_LOG_LEVEL=info MARK_IN_FORWARD_CHAIN=$(added_param_value_no MARK_IN_FORWARD_CHAIN $MARK_IN_FORWARD_CHAIN) - [ -n "$MARK_IN_FORWARD_CHAIN" ] && marking_chain=tcfor || marking_chain=tcpre + [ -n "$MARK_IN_FORWARD_CHAIN" ] && MARKING_CHAIN=tcfor || MARKING_CHAIN=tcpre if [ -n "$TC_ENABLED" ]; then CLEAR_TC=$(added_param_value_yes CLEAR_TC $CLEAR_TC) else @@ -6227,9 +7303,7 @@ do_initialize() { fi fi - if [ ${#temp} -gt 29 ]; then - startup_error "LOGFORMAT string is too long: \"$LOGFORMAT\"" - fi + [ ${#temp} -le 29 ] || startup_error "LOGFORMAT string is longer than 29 characters: \"$LOGFORMAT\"" else LOGFORMAT="Shorewall:%s:%s:" fi @@ -6238,7 +7312,11 @@ do_initialize() { DISABLE_IPV6=$(added_param_value_no DISABLE_IPV6 $DISABLE_IPV6) BRIDGING=$(added_param_value_no BRIDGING $BRIDGING) DYNAMIC_ZONES=$(added_param_value_no DYNAMIC_ZONES $DYNAMIC_ZONES) - PKTTYPE=$(added_param_value_yes PKTTYPE $PKTTYPE) + PKTTYPE=$(added_param_value_no PKTTYPE $PKTTYPE) + STARTUP_ENABLED=$(added_param_value_yes STARTUP_ENABLED $STARTUP_ENABLED) + RETAIN_ALIASES=$(added_param_value_no RETAIN_ALIASES $RETAIN_ALIASES) + DELAYBLACKLISTLOAD=$(added_param_value_no DELAYBLACKLISTLOAD $DELAYBLACKLISTLOAD) + LOGTAGONLY=$(added_param_value_no LOGTAGONLY $LOGTAGONLY) DROPINVALID=$(added_param_value_yes DROPINVALID $DROPINVALID) # # Strip the files that we use often @@ -6256,7 +7334,7 @@ do_initialize() { fi rm -f $TMP_DIR/physdev - + rm -f $TMP_DIR/iprange } # @@ -6303,7 +7381,7 @@ case "$COMMAND" in [ $# -ne 1 ] && usage do_initialize my_mutex_on - if qt iptables -L shorewall -n ; then + if qt $IPTABLES -L shorewall -n ; then [ -n "$SUBSYSLOCK" ] && touch $SUBSYSLOCK echo "Shorewall Already Started" [ -n "$TMP_DIR" ] && rm -rf $TMP_DIR @@ -6318,7 +7396,7 @@ case "$COMMAND" in [ $# -ne 1 ] && usage do_initialize my_mutex_on - if qt iptables -L shorewall -n ; then + if qt $IPTABLES -L shorewall -n ; then define_firewall "Restart" else echo "Shorewall Not Currently Running" @@ -6333,22 +7411,22 @@ case "$COMMAND" in [ $# -ne 1 ] && usage echo "Shorewall-$version Status at $HOSTNAME - $(date)" echo - iptables -L -n -v + $IPTABLES -L -n -v ;; reset) [ $# -ne 1 ] && usage do_initialize my_mutex_on - if ! qt iptables -L shorewall -n ; then + if ! qt $IPTABLES -L shorewall -n ; then echo "Shorewall Not Started" [ -n "$TMP_DIR" ] && rm -rf $TMP_DIR my_mutex_off exit 2; fi - iptables -Z - iptables -t nat -Z - iptables -t mangle -Z + $IPTABLES -Z + $IPTABLES -t nat -Z + $IPTABLES -t mangle -Z report "Shorewall Counters Reset" date > $STATEDIR/restarted my_mutex_off @@ -6358,7 +7436,7 @@ case "$COMMAND" in [ $# -ne 1 ] && usage do_initialize my_mutex_on - if ! qt iptables -L shorewall -n ; then + if ! qt $IPTABLES -L shorewall -n ; then echo "Shorewall Not Started" [ -n "$TMP_DIR" ] && rm -rf $TMP_DIR my_mutex_off @@ -6386,30 +7464,32 @@ case "$COMMAND" in ;; add) - [ $# -ne 3 ] && usage + [ $# -lt 3 ] && usage do_initialize my_mutex_on - if ! qt iptables -L shorewall -n ; then + if ! qt $IPTABLES -L shorewall -n ; then echo "Shorewall Not Started" [ -n "$TMP_DIR" ] && rm -rf $TMP_DIR my_mutex_off exit 2; fi - add_to_zone $2 $3 + shift + add_to_zone $@ my_mutex_off ;; delete) - [ $# -ne 3 ] && usage + [ $# -lt 3 ] && usage do_initialize my_mutex_on - if ! qt iptables -L shorewall -n ; then + if ! qt $IPTABLES -L shorewall -n ; then echo "Shorewall Not Started" [ -n "$TMP_DIR" ] && rm -rf $TMP_DIR my_mutex_off exit 2; fi - delete_from_zone $2 $3 + shift + delete_from_zone $@ my_mutex_off ;; diff --git a/Lrp2/usr/share/shorewall/functions b/Lrp2/usr/share/shorewall/functions index 152b10e91..80c5ef2d5 100644 --- a/Lrp2/usr/share/shorewall/functions +++ b/Lrp2/usr/share/shorewall/functions @@ -1,6 +1,27 @@ #!/bin/sh # -# Shorewall 2.0 -- /usr/share/shorewall/functions +# Shorewall 2.2 -- /usr/share/shorewall/functions + +# Function to truncate a string -- It uses 'cut -b -' +# rather than ${v:first:last} because light-weight shells like ash and +# dash do not support that form of expansion. +# + +truncate() # $1 = length +{ + cut -b -${1} +} + +# +# Split a colon-separated list into a space-separated list +# +split() { + local ifs=$IFS + IFS=: + set -- $1 + echo $* + IFS=$ifs +} # # Search a list looking for a match -- returns zero if a match found @@ -229,7 +250,7 @@ find_zones() # $1 = name of the zone file \#*) ;; $FW) - echo "Reserved zone name \"$zone\" in zones file ignored" >&2 + echo " Warning: Reserved zone name \"$zone\" in zones file ignored" >&2 ;; *) echo $zone @@ -255,12 +276,16 @@ determine_zones() multi_display=Multi-zone strip_file zones $zonefile zones=$(find_zones $TMP_DIR/zones) - zones=$(echo $zones) # Remove extra trash + newzones= for zone in $zones; do dsply=$(find_display $zone $TMP_DIR/zones) + [ ${#zone} -gt 5 ] && echo " Warning: Zone name longer than 5 characters: $zone" >&2 eval ${zone}_display=\$dsply + newzones="$newzones $zone" done + + zones=${newzones# } } # @@ -377,7 +402,7 @@ mktempfile() { > $1/shorewall-$$ && echo $1/shorewall-$$ ;; *) - echo " ERROR:Internal error in mktempfile" + echo " ERROR:Internal error in mktempfile" >&2 ;; esac else @@ -393,7 +418,7 @@ mktempfile() { > /tmp/shorewall-$$ && echo /tmp/shorewall-$$ ;; *) - echo " ERROR:Internal error in mktempfile" + echo " ERROR:Internal error in mktempfile" >&2 ;; esac fi @@ -417,10 +442,10 @@ mktempdir() { mkdir /tmp/shorewall-$$ && chmod 700 /tmp/shorewall-$$ && echo /tmp/shorewall-$$ ;; *) - echo " ERROR:Internal error in mktempdir" + echo " ERROR:Internal error in mktempdir" >&2 ;; esac -} +} # # Read a file and handle "INCLUDE" directives @@ -531,13 +556,20 @@ encodeaddr() { ip_range() { local first last l x y z vlsm - case $1 in - [0-9]*.*.*.*-*.*.*.*) - ;; - *) - echo $1 - return - ;; + case $1 in + !*) + # + # Let iptables complain if it's a range + # + echo $1 + return + ;; + [0-9]*.*.*.*-*.*.*.*) + ;; + *) + echo $1 + return + ;; esac first=$(decodeaddr ${1%-*}) @@ -680,6 +712,9 @@ chain_base() #$1 = interface *-*) c="${c%-*}_${c##*-}" ;; + *%*) + c="${c%\%*}_${c##*%}" + ;; *) echo ${c:=common} return @@ -699,11 +734,7 @@ if_match() # $1 = Name in interfaces file - may end in "+" case $1 in *+) - # - # Can't use ${2:0:${#pattern}} because ash and dash don't support that flavor of - # variable expansion :-( - # - test "x$(echo $2 | cut -b -${#pattern} )" = "x${pattern}" + test "x$(echo $2 | truncate ${#pattern} )" = "x${pattern}" ;; *) test "x$1" = "x$2" @@ -767,3 +798,11 @@ find_interface_by_address() { [ -n "$dev" ] && echo $dev } +# +# Find interface addresses--returns the set of addresses assigned to the passed +# device +# +find_interface_addresses() # $1 = interface +{ + ip -f inet addr show $1 | grep inet | sed 's/inet //;s/\/.*//;s/ peer.*//' +} diff --git a/Lrp2/usr/share/shorewall/help b/Lrp2/usr/share/shorewall/help index 7343d2f43..56d8de5e3 100755 --- a/Lrp2/usr/share/shorewall/help +++ b/Lrp2/usr/share/shorewall/help @@ -1,6 +1,6 @@ #!/bin/sh # -# Shorewall help subsystem - V2.0 - 2/14/2004 +# Shorewall help subsystem - V2.2 # # # This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] @@ -29,11 +29,18 @@ case $1 in add) - echo "add: add [:][:] - Adds a host or subnet to a dynamic zone usually used with VPN's. + echo "add: add [:] ... + Adds a list of hosts or subnets to a dynamic zone usually used with VPN's. - shorewall add interface[:port][:host] zone - Adds the specified interface - (and bridge port/host if included) to the specified zone. + shorewall add interface:host-list ... zone - Adds the specified interface + (and host-list if included) to the specified zone. + + A host-list is a comma-separated list whose elements are: + + A host or network address + The name of a bridge port + The name of a bridge port followed by a colon (":") and a host or + network address. Example: @@ -46,7 +53,9 @@ add) address|host) echo "<$1>: May be either a host IP address such as 192.168.1.4 or a network address in - CIDR format like 192.168.1.0/24" + CIDR format like 192.168.1.0/24. If your kernel and iptables contain iprange + match support then IP address ranges of the form - + are also permitted." ;; allow) @@ -60,7 +69,7 @@ allow) ;; check) - echo "check: check [ -c ] + echo "check: check [ ] Performs a cursory validation of the zones, interfaces, hosts, rules and policy files. Use this if you are unsure of any edits you have made to the shorewall configuration. See the try command @@ -93,11 +102,18 @@ debug) ;; delete) - echo "delete: delete [:][:] - Deletes a host or subnet from a dynamic zone usually used with VPN's. + echo "delete: delete [:] ... + Deletes a list of hosts or networks from a dynamic zone usually used with VPN's. - shorewall delete interface[:port][:host] zone - Deletes the specified - interface (and bridge port/host if included) from the specified zone. + shorewall delete interface[:host-list] ... zone - Deletes the specified + interfaces (and host list if included) from the specified zone. + + A host-list is a comma-separated list whose elements are: + + A host or network address + The name of a bridge port + The name of a bridge port followed by a colon (":") and a host or + network address. Example: @@ -187,7 +203,7 @@ reset) ;; restart) - echo "restart: restart [ -q ] [ -c ] + echo "restart: [ -q ] restart [ ] Restart is the same as a shorewall stop && shorewall start. Existing connections are maintained. If \"-q\" is specified, less detain is displayed making it easier to spot warnings" @@ -217,7 +233,7 @@ save) ;; show) - echo "show: show [ [ ...] |classifiers|connections|log|nat|tc|tos] + echo "show: show [ [ ...] |classifiers|connections|log|nat|tc|tos|zones] shorewall [-x] show [ ... ] - produce a verbose report about the IPtable chain(s). (iptables -L chain -n -v) @@ -236,17 +252,20 @@ show) shorewall show tc - displays information about the traffic control/shaping configuration. + shorewall show zones - displays the contents of all zones. + When -x is given, that option is also passed to iptables to display actual packet and byte counts." ;; start) - echo "start: [ -q ] [ -f ] [ -c ] start + echo "start: [ -q ] [ -f ] start [ ] Start shorewall. Existing connections through shorewall managed interfaces are untouched. New connections will be allowed only if they are allowed by the firewall rules or policies. If \"-q\" is specified, less detail is displayed making it easier to spot warnings If \"-f\" is specified, the saved configuration specified by the RESTOREFILE option - in shorewall.conf will be restored if that saved configuration exists" + in shorewall.conf will be restored if that saved configuration exists. In that + case, a may not be specified". ;; stop) diff --git a/Lrp2/usr/share/shorewall/rfc1918 b/Lrp2/usr/share/shorewall/rfc1918 index 42bd82e3d..038525465 100644 --- a/Lrp2/usr/share/shorewall/rfc1918 +++ b/Lrp2/usr/share/shorewall/rfc1918 @@ -1,5 +1,5 @@ # -# Shorewall 2.0-- RFC1918 File +# Shorewall 2.2 -- RFC1918 File # # /etc/shorewall/rfc1918 # @@ -12,14 +12,17 @@ # # Columns are: # -# SUBNET The subnet (host addresses also allowed) +# SUBNETS A comma-separated list of subnet addresses +# (host addresses also allowed as are IP +# address ranges provided that your kernel and iptables +# have iprange match support). # TARGET Where to send packets to/from this subnet # RETURN - let the packet be processed normally # DROP - silently drop the packet # logdrop - log then drop # ############################################################################### -#SUBNET TARGET +#SUBNETS TARGET 172.16.0.0/12 logdrop # RFC 1918 192.168.0.0/16 logdrop # RFC 1918 10.0.0.0/8 logdrop # RFC 1918 diff --git a/Lrp2/usr/share/shorewall/version b/Lrp2/usr/share/shorewall/version index a14da2902..ccbccc3dc 100644 --- a/Lrp2/usr/share/shorewall/version +++ b/Lrp2/usr/share/shorewall/version @@ -1 +1 @@ -2.0.16 +2.2.0 diff --git a/Lrp2/var/lib/lrpkg/shorwall.conf b/Lrp2/var/lib/lrpkg/shorwall.conf index 7a5ea778e..4ad7b9d67 100644 --- a/Lrp2/var/lib/lrpkg/shorwall.conf +++ b/Lrp2/var/lib/lrpkg/shorwall.conf @@ -1,6 +1,7 @@ /etc/shorewall/params Params Assign parameter values /etc/shorewall/zones Zones Partition the network into Zones /etc/shorewall/interfaces Ifaces Shorewall Networking Interfaces +/etc/shorewall/ipsec Ipsec Define Zone IPSEC Properties /etc/shorewall/hosts Hosts Define specific zones /etc/shorewall/policy Policy Firewall high-level policy /etc/shorewall/rules Rules Exceptions to policy diff --git a/Lrp2/var/lib/lrpkg/shorwall.version b/Lrp2/var/lib/lrpkg/shorwall.version index ddcd0db02..a14da2902 100644 --- a/Lrp2/var/lib/lrpkg/shorwall.version +++ b/Lrp2/var/lib/lrpkg/shorwall.version @@ -1 +1 @@ -2.0.2c +2.0.16