From 921a7223d4a548c3d0b92abf5a5a52da17aec8c0 Mon Sep 17 00:00:00 2001 From: paulgear Date: Sat, 9 Jul 2005 04:45:32 +0000 Subject: [PATCH] Copy latest 2.0 code from STABLE2/ git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@2262 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb --- Shorewall/INSTALL | 21 +- Shorewall/accounting | 2 +- Shorewall/action.AllowAuth | 10 + Shorewall/action.AllowDNS | 11 + Shorewall/action.AllowFTP | 11 + Shorewall/action.AllowIMAP | 11 + Shorewall/action.AllowNNTP | 11 + Shorewall/action.AllowNTP | 10 + Shorewall/action.AllowPCA | 11 + Shorewall/action.AllowPOP3 | 11 + Shorewall/action.AllowPing | 10 + Shorewall/action.AllowRdate | 10 + Shorewall/action.AllowSMB | 14 + Shorewall/action.AllowSMTP | 15 + Shorewall/action.AllowSNMP | 11 + Shorewall/action.AllowSSH | 10 + Shorewall/action.AllowTelnet | 11 + Shorewall/action.AllowTrcrt | 11 + Shorewall/action.AllowVNC | 10 + Shorewall/action.AllowVNCL | 10 + Shorewall/action.AllowWeb | 11 + Shorewall/action.Drop | 16 + Shorewall/action.DropDNSrep | 10 + Shorewall/action.DropPing | 10 + Shorewall/action.DropSMB | 15 + Shorewall/action.DropUPnP | 10 + Shorewall/action.Reject | 16 + Shorewall/action.RejectAuth | 10 + Shorewall/action.RejectSMB | 15 + Shorewall/action.template | 37 +- Shorewall/actions | 19 +- Shorewall/actions.std | 53 + Shorewall/blacklist | 2 +- Shorewall/bogons | 70 + Shorewall/bogons.new | 63 + Shorewall/changelog.txt | 124 +- Shorewall/common.def | 49 - Shorewall/configpath | 7 + Shorewall/default.debian | 18 + Shorewall/ecn | 2 +- Shorewall/fallback.sh | 58 +- Shorewall/firewall | 3086 ++++++++++++++++++++-------------- Shorewall/functions | 380 ++++- Shorewall/help | 114 +- Shorewall/hosts | 105 +- Shorewall/init | 2 +- Shorewall/init.debian.sh | 129 ++ Shorewall/init.sh | 14 +- Shorewall/initdone | 7 + Shorewall/install.sh | 353 ++-- Shorewall/interfaces | 78 +- Shorewall/maclist | 7 +- Shorewall/masq | 56 +- Shorewall/modules | 2 +- Shorewall/nat | 11 +- Shorewall/netmap | 38 + Shorewall/params | 2 +- Shorewall/policy | 21 +- Shorewall/proxyarp | 24 +- Shorewall/releasenotes.txt | 330 +++- Shorewall/rfc1918 | 49 +- Shorewall/routestopped | 12 +- Shorewall/rules | 105 +- Shorewall/shorewall | 429 +++-- Shorewall/shorewall.conf | 209 ++- Shorewall/shorewall.spec | 153 +- Shorewall/start | 2 +- Shorewall/stop | 2 +- Shorewall/stopped | 2 +- Shorewall/tcrules | 7 +- Shorewall/tos | 14 +- Shorewall/tunnel | 13 +- Shorewall/tunnels | 13 +- Shorewall/uninstall.sh | 29 +- Shorewall/users | 25 - Shorewall/usersets | 29 - Shorewall/zones | 2 +- 77 files changed, 4490 insertions(+), 2200 deletions(-) create mode 100644 Shorewall/action.AllowAuth create mode 100644 Shorewall/action.AllowDNS create mode 100644 Shorewall/action.AllowFTP create mode 100644 Shorewall/action.AllowIMAP create mode 100644 Shorewall/action.AllowNNTP create mode 100644 Shorewall/action.AllowNTP create mode 100644 Shorewall/action.AllowPCA create mode 100644 Shorewall/action.AllowPOP3 create mode 100644 Shorewall/action.AllowPing create mode 100644 Shorewall/action.AllowRdate create mode 100644 Shorewall/action.AllowSMB create mode 100644 Shorewall/action.AllowSMTP create mode 100644 Shorewall/action.AllowSNMP create mode 100644 Shorewall/action.AllowSSH create mode 100644 Shorewall/action.AllowTelnet create mode 100644 Shorewall/action.AllowTrcrt create mode 100644 Shorewall/action.AllowVNC create mode 100644 Shorewall/action.AllowVNCL create mode 100644 Shorewall/action.AllowWeb create mode 100644 Shorewall/action.Drop create mode 100644 Shorewall/action.DropDNSrep create mode 100644 Shorewall/action.DropPing create mode 100644 Shorewall/action.DropSMB create mode 100644 Shorewall/action.DropUPnP create mode 100644 Shorewall/action.Reject create mode 100644 Shorewall/action.RejectAuth create mode 100644 Shorewall/action.RejectSMB create mode 100644 Shorewall/actions.std create mode 100644 Shorewall/bogons create mode 100644 Shorewall/bogons.new delete mode 100644 Shorewall/common.def create mode 100644 Shorewall/configpath create mode 100644 Shorewall/default.debian create mode 100755 Shorewall/init.debian.sh create mode 100755 Shorewall/initdone create mode 100644 Shorewall/netmap delete mode 100644 Shorewall/users delete mode 100644 Shorewall/usersets diff --git a/Shorewall/INSTALL b/Shorewall/INSTALL index c62b8f681..572c32e29 100644 --- a/Shorewall/INSTALL +++ b/Shorewall/INSTALL @@ -1,4 +1,4 @@ -Shoreline Firewall (Shorewall) Version 1.4 - 3/14/2003 +Shoreline Firewall (Shorewall) Version 2.0 - 2/14/2004 ----- ---- ----------------------------------------------------------------------------- @@ -30,18 +30,23 @@ o Edit the configuration files to fit your environment. http://www.shorewall.net/shorewall_quickstart_guide.htm -o If you are using Caldera, Redhat, Mandrake, Corel, Slackware, SuSE or - Debian, then type "./install.sh". -o For other distributions, determine where your distribution installs - init scripts and type "./install.sh " +o Slackware users type: + + DEST=/etc/rc.d INIT=rc.firewall ./install.sh + + All other users type: + + ./install.sh + o Start the firewall by typing "shorewall start" o If the install script was unable to configure Shoreline Firewall to - start automatically at boot, see the HTML documentation contains in the - "documentation" directory. + start automatically at boot, you will have to used your + distribution's runlevel editor to configure Shorewall manually. Upgrade: o run the install script as described above. -o shorewall restart +o "shorewall check" and correct any errors found. +o "shorewall restart" diff --git a/Shorewall/accounting b/Shorewall/accounting index 29a912813..a0d352255 100755 --- a/Shorewall/accounting +++ b/Shorewall/accounting @@ -1,5 +1,5 @@ # -# Shorewall version 1.4 - Accounting File +# Shorewall version 2.0 - Accounting File # # /etc/shorewall/accounting # diff --git a/Shorewall/action.AllowAuth b/Shorewall/action.AllowAuth new file mode 100644 index 000000000..78bdc1266 --- /dev/null +++ b/Shorewall/action.AllowAuth @@ -0,0 +1,10 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowAuth +# +# This action accepts Auth (identd) traffic. +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - tcp 113 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowDNS b/Shorewall/action.AllowDNS new file mode 100644 index 000000000..2ac6a72ce --- /dev/null +++ b/Shorewall/action.AllowDNS @@ -0,0 +1,11 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowDNS +# +# This action accepts DNS traffic. +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - udp 53 +ACCEPT - - tcp 53 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowFTP b/Shorewall/action.AllowFTP new file mode 100644 index 000000000..cab5fa4e1 --- /dev/null +++ b/Shorewall/action.AllowFTP @@ -0,0 +1,11 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowFTP +# +# This action accepts FTP traffic. See +# http://www.shorewall.net/FTP.html for additional considerations. +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - tcp 21 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowIMAP b/Shorewall/action.AllowIMAP new file mode 100644 index 000000000..333bdf779 --- /dev/null +++ b/Shorewall/action.AllowIMAP @@ -0,0 +1,11 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowIMAP +# +# This action accepts IMAP traffic (secure and insecure): +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - tcp 143 #Unsecure IMAP +ACCEPT - - tcp 993 #Secure IMAP +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowNNTP b/Shorewall/action.AllowNNTP new file mode 100644 index 000000000..3bf9f4926 --- /dev/null +++ b/Shorewall/action.AllowNNTP @@ -0,0 +1,11 @@ +# +# Shorewall 2.0 /usr/share/shorewall/action.AllowNNTP +# +# This action accepts NNTP traffic (Usenet) and encrypted NNTP (NNTPS) +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - tcp 119 +ACCEPT - - tcp 563 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowNTP b/Shorewall/action.AllowNTP new file mode 100644 index 000000000..6ef93652c --- /dev/null +++ b/Shorewall/action.AllowNTP @@ -0,0 +1,10 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowNTP +# +# This action accepts NTP traffic (ntpd). +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE +# PORT PORT(S) DEST LIMIT +ACCEPT - - udp 123 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowPCA b/Shorewall/action.AllowPCA new file mode 100644 index 000000000..bda0e4a1f --- /dev/null +++ b/Shorewall/action.AllowPCA @@ -0,0 +1,11 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowPCA +# +# This action accepts PCAnywere (tm) +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - udp 5631 +ACCEPT - - tcp 5632 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowPOP3 b/Shorewall/action.AllowPOP3 new file mode 100644 index 000000000..b7756fee5 --- /dev/null +++ b/Shorewall/action.AllowPOP3 @@ -0,0 +1,11 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowPOP3 +# +# This action accepts POP3 traffic (secure and insecure): +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE +# PORT PORT(S) DEST LIMIT +ACCEPT - - tcp 110 #Unsecure POP3 +ACCEPT - - tcp 995 #Secure POP3 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowPing b/Shorewall/action.AllowPing new file mode 100644 index 000000000..f18492201 --- /dev/null +++ b/Shorewall/action.AllowPing @@ -0,0 +1,10 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowPing +# +# This action accepts 'ping' requests. +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - icmp 8 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowRdate b/Shorewall/action.AllowRdate new file mode 100644 index 000000000..34cb7f75c --- /dev/null +++ b/Shorewall/action.AllowRdate @@ -0,0 +1,10 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowRdate +# +# This action accepts remote time retrieval (rdate). +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - tcp 37 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowSMB b/Shorewall/action.AllowSMB new file mode 100644 index 000000000..8914eae98 --- /dev/null +++ b/Shorewall/action.AllowSMB @@ -0,0 +1,14 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowSMB +# +# Allow Microsoft SMB traffic. You need to invoke this action in +# both directions. +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - udp 135,445 +ACCEPT - - udp 137:139 +ACCEPT - - udp 1024: 137 +ACCEPT - - tcp 135,139,445 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowSMTP b/Shorewall/action.AllowSMTP new file mode 100644 index 000000000..5a802a2d1 --- /dev/null +++ b/Shorewall/action.AllowSMTP @@ -0,0 +1,15 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowSMTP +# +# This action accepts SMTP (email) traffic. +# +# Note: This action allows traffic between an MUA (Email client) +# and an MTA (mail server) or between MTAs. It does not enable +# reading of email via POP3 or IMAP. For those you need to use +# the AllowPOP3 or AllowIMAP actions. +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - tcp 25 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowSNMP b/Shorewall/action.AllowSNMP new file mode 100644 index 000000000..11d78d126 --- /dev/null +++ b/Shorewall/action.AllowSNMP @@ -0,0 +1,11 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowSNMP +# +# This action accepts SNMP traffic (including traps): +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - udp 161:162 +ACCEPT - - tcp 161 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowSSH b/Shorewall/action.AllowSSH new file mode 100644 index 000000000..78e25bba9 --- /dev/null +++ b/Shorewall/action.AllowSSH @@ -0,0 +1,10 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowSSH +# +# This action accepts secure shell (SSH) traffic. +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - tcp 22 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowTelnet b/Shorewall/action.AllowTelnet new file mode 100644 index 000000000..5eebbb095 --- /dev/null +++ b/Shorewall/action.AllowTelnet @@ -0,0 +1,11 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowTelnet +# +# This action accepts Telnet traffic. For traffic over the +# internet, telnet is inappropriate; use SSH instead +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - tcp 23 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowTrcrt b/Shorewall/action.AllowTrcrt new file mode 100644 index 000000000..1b6180003 --- /dev/null +++ b/Shorewall/action.AllowTrcrt @@ -0,0 +1,11 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowTrcrt +# +# This action accepts Traceroute (for up to 30 hops): +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - udp 33434:33524 #UDP Traceroute +ACCEPT - - icmp 8 #ICMP Traceroute +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowVNC b/Shorewall/action.AllowVNC new file mode 100644 index 000000000..423c30c77 --- /dev/null +++ b/Shorewall/action.AllowVNC @@ -0,0 +1,10 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowVNC +# +# This action accepts VNC traffic for VNC display's 0 - 9. +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - tcp 5900:5909 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowVNCL b/Shorewall/action.AllowVNCL new file mode 100644 index 000000000..83ff3fe81 --- /dev/null +++ b/Shorewall/action.AllowVNCL @@ -0,0 +1,10 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowVNC +# +# This action accepts VNC traffic from Vncservers to Vncviewers in listen mode. +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - tcp 5500 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.AllowWeb b/Shorewall/action.AllowWeb new file mode 100644 index 000000000..f88028b12 --- /dev/null +++ b/Shorewall/action.AllowWeb @@ -0,0 +1,11 @@ +# +# Shorewall 2.0 /etc/shorewall/action.AllowWeb +# +# This action accepts WWW traffic (secure and insecure): +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +ACCEPT - - tcp 80 +ACCEPT - - TCP 443 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.Drop b/Shorewall/action.Drop new file mode 100644 index 000000000..721a46126 --- /dev/null +++ b/Shorewall/action.Drop @@ -0,0 +1,16 @@ +# +# Shorewall 2.0 /etc/shorewall/action.Drop +# +# The default DROP common rules +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +RejectAuth +dropBcast +dropInvalid +DropSMB +DropUPnP +dropNotSyn +DropDNSrep +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.DropDNSrep b/Shorewall/action.DropDNSrep new file mode 100644 index 000000000..949e3e655 --- /dev/null +++ b/Shorewall/action.DropDNSrep @@ -0,0 +1,10 @@ +# +# Shorewall 2.0 /etc/shorewall/action.DropDNSrep +# +# This action silently drops DNS UDP replies +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +DROP - - udp - 53 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.DropPing b/Shorewall/action.DropPing new file mode 100644 index 000000000..5aba7c207 --- /dev/null +++ b/Shorewall/action.DropPing @@ -0,0 +1,10 @@ +# +# Shorewall 2.0 /etc/shorewall/action.DropPing +# +# This action silently drops 'ping' requests. +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +DROP - - icmp 8 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.DropSMB b/Shorewall/action.DropSMB new file mode 100644 index 000000000..03a9ee15b --- /dev/null +++ b/Shorewall/action.DropSMB @@ -0,0 +1,15 @@ +# +# Shorewall 2.0 /etc/shorewall/action.DropSMB +# +# This action silently drops Microsoft SMB traffic +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +DROP - - udp 135 +DROP - - udp 137:139 +DROP - - udp 445 +DROP - - tcp 135 +DROP - - tcp 139 +DROP - - tcp 445 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.DropUPnP b/Shorewall/action.DropUPnP new file mode 100644 index 000000000..8ef56119c --- /dev/null +++ b/Shorewall/action.DropUPnP @@ -0,0 +1,10 @@ +# +# Shorewall 2.0 /etc/shorewall/action.DropUPnP +# +# This action silently drops UPnP probes on UDP port 1900 +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +DROP - - udp 1900 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.Reject b/Shorewall/action.Reject new file mode 100644 index 000000000..8cfd666ec --- /dev/null +++ b/Shorewall/action.Reject @@ -0,0 +1,16 @@ +# +# Shorewall 2.0 /etc/shorewall/action.Reject +# +# The default REJECT action common rules +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +RejectAuth +dropBcast +dropInvalid +RejectSMB +DropUPnP +dropNotSyn +DropDNSrep +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.RejectAuth b/Shorewall/action.RejectAuth new file mode 100644 index 000000000..e3675d5bb --- /dev/null +++ b/Shorewall/action.RejectAuth @@ -0,0 +1,10 @@ +# +# Shorewall 2.0 /etc/shorewall/action.RejectAuth +# +# This action silently rejects Auth (tcp 113) traffic +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +REJECT - - tcp 113 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.RejectSMB b/Shorewall/action.RejectSMB new file mode 100644 index 000000000..db820e5dc --- /dev/null +++ b/Shorewall/action.RejectSMB @@ -0,0 +1,15 @@ +# +# Shorewall 2.0 /etc/shorewall/action.RejectSMB +# +# This action silently rejects Microsoft SMB traffic +# +###################################################################################### +#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT PORT(S) LIMIT GROUP +REJECT - - udp 135 +REJECT - - udp 137:139 +REJECT - - udp 445 +REJECT - - tcp 135 +REJECT - - tcp 139 +REJECT - - tcp 445 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/action.template b/Shorewall/action.template index 2a4df614a..b20af0e09 100644 --- a/Shorewall/action.template +++ b/Shorewall/action.template @@ -1,5 +1,5 @@ # -# Shorewall 1.4 /etc/shorewall/action.template +# Shorewall 2.0 /etc/shorewall/action.template # # This file is a template for files with names of the form # /etc/shorewall/action. where is an @@ -24,6 +24,9 @@ # LOG -- Simply log the packet and continue. # QUEUE -- Queue the packet to a user-space # application such as p2pwall. +# CONTINUE -- Discontinue processing this action +# and return to the point where the +# action was invoked. # -- An defined in # /etc/shorewall/actions. The # must appear in that file BEFORE the @@ -39,6 +42,15 @@ # to a separate log through use of ulogd # (http://www.gnumonks.org/projects/ulogd). # +# Actions specifying logging may be followed by a +# log tag (a string of alphanumeric characters) +# are appended to the string generated by the +# LOGPREFIX (in /etc/shorewall/shorewall.conf). +# +# Example: ACCEPT:info:ftp would include 'ftp ' +# at the end of the log prefix generated by the +# LOGPREFIX setting. +# # SOURCE Source hosts to which the rule applies. # A comma-separated list of subnets # and/or hosts. Hosts may be specified by IP or MAC @@ -80,7 +92,7 @@ # A port range is expressed as :. # # This column is ignored if PROTOCOL = all but must be -# entered if any of the following ields are supplied. +# entered if any of the following fields are supplied. # In that case, it is suggested that this field contain # "-" # @@ -122,8 +134,25 @@ # # Example: 10/sec:20 # -# If you place a rate limit in this column, you may not -# place a similar limit in the TARGET column. +# USER/GROUP This column may only be non-empty if the SOURCE is +# the firewall itself. +# +# 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 # ###################################################################################### #TARGET SOURCE DEST PROTO DEST SOURCE RATE diff --git a/Shorewall/actions b/Shorewall/actions index d48927a96..bc6757a03 100644 --- a/Shorewall/actions +++ b/Shorewall/actions @@ -1,5 +1,5 @@ # -# Shorewall 1.4 /etc/shorewall/actions +# Shorewall 2.0 /etc/shorewall/actions # # This file allows you to define new ACTIONS for use in rules # (/etc/shorewall/rules). You define the iptables rules to @@ -8,8 +8,21 @@ # # ACTION names should begin with an upper-case letter to # distinguish them from Shorewall-generated chain names and -# they must need the requirements of a Netfilter chain -# name. +# they must need the requirements of a Netfilter chain. If +# you intend to log from the action then the name must be +# no longer than 11 character in length. Names must also +# meet the requirements for a Bourne Shell identifier (must +# begin with a letter and be composed of letters, digits and +# underscore characters). +# +# If you follow the action name with ":DROP", ":REJECT" or +# :ACCEPT then the action will be taken before a DROP, REJECT or +# ACCEPT policy respectively is enforced. If you specify ":DROP", +# ":REJECT" or ":ACCEPT" on more than one action then only the +# last such action will be taken. +# +# If you specify ":DROP", ":REJECT" or ":ACCEPT" on a line by +# itself, the associated policy will have no common action. # #ACTION diff --git a/Shorewall/actions.std b/Shorewall/actions.std new file mode 100644 index 000000000..89f9ad504 --- /dev/null +++ b/Shorewall/actions.std @@ -0,0 +1,53 @@ +# +# Shorewall 2.0 /usr/share/shorewall/actions.std +# +# +# Builtin Actions are: +# +# 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 +# +# The NonSyn logging builtins log at the level specified by LOGNEWNOTSYN in +# shorewall.conf. If that option isn't specified then 'info' is used. +# +#ACTION + +DropSMB #Silently Drops Microsoft SMB Traffic +RejectSMB #Silently Reject Microsoft SMB Traffic +DropUPnP #Silently Drop UPnP Probes +RejectAuth #Silently Reject Auth +DropPing #Silently Drop Ping +DropDNSrep #Silently Drop DNS Replies + +AllowPing #Accept Ping +AllowFTP #Accept FTP +AllowDNS #Accept DNS +AllowSSH #Accept SSH +AllowWeb #Allow Web Browsing +AllowSMB #Allow MS Networking +AllowAuth #Allow Auth (identd) +AllowSMTP #Allow SMTP (Email) +AllowPOP3 #Allow reading mail via POP3 +AllowIMAP #Allow reading mail via IMAP +AllowTelnet #Allow Telnet Access (not recommended for use over the + #Internet) +AllowVNC #Allow VNC viewer->server, Displays 0-9 +AllowVNCL #Allow VNC server->viewer in listening mode +AllowNTP #Allow Network Time Protocol (ntpd) +AllowRdate #Allow remote time (rdate). +AllowNNTP #Allow network news (Usenet). +AllowTrcrt #Allows Traceroute (20 hops) +AllowSNMP #Allows SNMP (including traps) +AllowPCA #Allows PCAnywhere (tm) + +Drop:DROP #Common Action for DROP policy +Reject:REJECT #Common Action for REJECT policy +#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONE - DO NOT REMOVE diff --git a/Shorewall/blacklist b/Shorewall/blacklist index 66ca0d9e4..063724daa 100755 --- a/Shorewall/blacklist +++ b/Shorewall/blacklist @@ -1,5 +1,5 @@ # -# Shorewall 1.4 -- Blacklist File +# Shorewall 2.0 -- Blacklist File # # /etc/shorewall/blacklist # diff --git a/Shorewall/bogons b/Shorewall/bogons new file mode 100644 index 000000000..46af67c47 --- /dev/null +++ b/Shorewall/bogons @@ -0,0 +1,70 @@ +# +# Shorewall 2.0-- Bogons File +# +# /etc/shorewall/bogons +# +# Lists the subnetworks that are blocked by the 'nobogons' interface option. +# +# The default list includes those those ip ADDRESSES listed +# as 'reserved' by the IANA, the DHCP Autoconfig class B, and the class C +# reserved for use in documentation and examples. +# +# DO NOT MODIFY THIS FILE. IF YOU NEED TO MAKE CHANGES, COPY THE FILE +# TO /etc/shorewall AND MODIFY THE COPY. +# +# Columns are: +# +# SUBNET The subnet (host addresses also allowed) +# 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 +0.0.0.0 RETURN # Stop the DHCP whining +255.255.255.255 RETURN # We need to allow limited broadcast +169.254.0.0/16 DROP # DHCP autoconfig +192.0.2.0/24 logdrop # Example addresses (RFC 3330) +# +# The following are generated with the help of the Python program found at: +# +# http://www.shorewall.net/pub/shorewall/contrib/iana_reserved/ +# +# The program was contributed by Andy Wiggin +# +0.0.0.0/7 logdrop # Reserved +2.0.0.0/8 logdrop # Reserved +5.0.0.0/8 logdrop # Reserved +7.0.0.0/8 logdrop # Reserved +23.0.0.0/8 logdrop # Reserved +27.0.0.0/8 logdrop # Reserved +31.0.0.0/8 logdrop # Reserved +36.0.0.0/7 logdrop # Reserved +39.0.0.0/8 logdrop # Reserved +41.0.0.0/8 logdrop # Reserved +42.0.0.0/8 logdrop # Reserved +49.0.0.0/8 logdrop # JTC - Returned to IANA Mar 98 +50.0.0.0/8 logdrop # JTC - Returned to IANA Mar 98 +73.0.0.0/8 logdrop # Reserved +74.0.0.0/7 logdrop # Reserved +76.0.0.0/6 logdrop # Reserved +89.0.0.0/8 logdrop # Reserved +90.0.0.0/7 logdrop # Reserved +92.0.0.0/6 logdrop # Reserved +96.0.0.0/3 logdrop # Reserved +127.0.0.0/8 logdrop # Loopback +173.0.0.0/8 logdrop # Reserved +174.0.0.0/7 logdrop # Reserved +176.0.0.0/5 logdrop # Reserved +184.0.0.0/6 logdrop # Reserved +189.0.0.0/8 logdrop # Reserved +190.0.0.0/8 logdrop # Reserved +197.0.0.0/8 logdrop # Reserved +198.18.0.0/15 logdrop # Reserved +223.0.0.0/8 logdrop # Reserved - Returned by APNIC in 2003 +240.0.0.0/4 logdrop # Reserved +# +# End of generated entries +# +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/bogons.new b/Shorewall/bogons.new new file mode 100644 index 000000000..6c5951bb7 --- /dev/null +++ b/Shorewall/bogons.new @@ -0,0 +1,63 @@ +# +# Shorewall 2.0-- Bogons File +# +# /etc/shorewall/bogons +# +# Lists the subnetworks that are blocked by the 'nobogons' interface option. +# +# The default list includes those those ip ADDRESSES listed +# as 'reserved' by the IANA, the DHCP Autoconfig class B, and the class C +# reserved for use in documentation and examples. +# +# DO NOT MODIFY THIS FILE. IF YOU NEED TO MAKE CHANGES, COPY THE FILE +# TO /etc/shorewall AND MODIFY THE COPY. +# +# Columns are: +# +# SUBNET The subnet (host addresses also allowed) +# 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 +0.0.0.0 RETURN # Stop the DHCP whining +255.255.255.255 RETURN # We need to allow limited broadcast +169.254.0.0/16 DROP # DHCP autoconfig +192.0.2.0/24 logdrop # Example addresses (RFC 3330) +# +# The following are generated with the help of the Python program found at: +# +# http://www.shorewall.net/pub/shorewall/contrib/iana_reserved/ +# +# The program was contributed by Andy Wiggin +# +0.0.0.0/7 logdrop # Reserved +2.0.0.0/8 logdrop # Reserved +5.0.0.0/8 logdrop # Reserved +7.0.0.0/8 logdrop # Reserved +23.0.0.0/8 logdrop # Reserved +27.0.0.0/8 logdrop # Reserved +31.0.0.0/8 logdrop # Reserved +36.0.0.0/7 logdrop # Reserved +39.0.0.0/8 logdrop # Reserved +42.0.0.0/8 logdrop # Reserved +77.0.0.0/8 logdrop # Reserved +78.0.0.0/7 logdrop # Reserved +92.0.0.0/6 logdrop # Reserved +96.0.0.0/4 logdrop # Reserved +112.0.0.0/5 logdrop # Reserved +120.0.0.0/6 logdrop # Reserved +127.0.0.0/8 logdrop # Reserved +173.0.0.0/8 logdrop # Reserved +174.0.0.0/7 logdrop # Reserved +176.0.0.0/5 logdrop # Reserved +184.0.0.0/6 logdrop # Reserved +197.0.0.0/8 logdrop # Reserved +223.0.0.0/8 logdrop # Reserved +240.0.0.0/4 logdrop # Reserved +# +# End of generated entries +# +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/changelog.txt b/Shorewall/changelog.txt index 1096e9606..a149cc9d3 100755 --- a/Shorewall/changelog.txt +++ b/Shorewall/changelog.txt @@ -1,37 +1,121 @@ -Changes since 1.4.9 +Changes in 2.0.4 -1) Implement destination list in masq file. +1) Fix DNAT logging with 'fw' as the source zone. -2) Appled Frédéric LESPEZ's patch for packet marking by user/group id. +Change in 2.0.5 -3) Correct column headings in action.template +1) Eradicate more RESTOREBASE messages. -4) Handle IPV6 addresses correctly with ADD_IP_ALIASES=Yes or - ADD_SNAT_ALIASES=Yes. +2) Remove 'mangle' reference from shorewall.conf. -5) Implement "detectnets" option. +Change in 2.0.6 -6) Correct the CONTINUE target and fix a couple of bugs in rate - limiting (with an assist from Steven Jan Springl). +1) Add PKTTYPE option. -7) Silently drop smurfs and broadcasts in the 'reject' chain. + shorewall.conf + firewall -8) Add multicast to 'detectnets' zones. +2) Sanitized some correct but confusing code in determine_hosts(). -9) Don't add broadcasts to /0 groups. + There was a loop: -10) Fix "-" in PROTO column of an action file. + for networks in $networks + ... -11) Fix the enhancement in 1) above to avoid startup errors. + It now reads: -12) Allow maclist with Atheros cards + for network in $networks + ... -13) Fix masq file problem with exclusion in the source column. -14) Fix silly tcrules file problem. +3) Don't give shorewall.conf and zones execute permission. + +4) Backport 'dropInvalid' from 2.1 -15) Fix multiple excluded zones in DNAT/REDIRECT rules. +Changes in 2.0.7 -16) Correct reporting of POLICY rules. +1) Include output of "ip rule ls" and "ip route ls" in "shorewall + status". -17) Implement Sean Mathews's fix for Proxy ARP/IPSEC. +2) Consult PKTTYPE when generating 'REJECT' rules. + +3) Enhance IP/Routing output in "shorewall status". + +4) Correct handling of multiple 'blacklist' interfaces. + +5) Add "0.0.0.0 RETURN" to nobogons. + +Changes in 2.0.8 + +1) Removed dead code from process_actions2() + +2) Corrected read command in process_actions2() (userspec) + +Changes in 2.0.9 + +1) Corrected setup_tc1() handling of the PROTO column. + +2) Added warning about ADD_SNAT_ALIASES in the masq file. + +3) Added "brctl show" to the status command. + +Changes in 2.0.10 + +1) Corrected GATEWAY handling for 'pptpserver's + +2) Correct log rule number generation. + +3) Add clarification to /etc/shorewall/tcrules. + +4) Apply part of Ian Allen's fix for down interface in the SUBNET + column of /etc/shorewall/masq. + +5) Add key /proc settings to "shorewall status" output. + +Changes in 2.0.11 + +1) Add note for Slackware users to INSTALL. + +2) Correct bogons file. + +3) Replace service names by port numbers in /etc/shorewall/tos. + +4) Added NNTPS to action.AllowNNTP. + +5) Fix install.sh + +Changes in 2.0.12 + +1) Correct typo in shorewall.conf. + +2) Fix "shorewall add" and "shorewall delete" with bridging. + +3) Implement variable expansion in INCLUDE directives + +4) Split restore-base into two files. + +5) Correct dynamic zone OUTPUT handling. + +Changes in 2.0.13 + +1) Correct typo in "shorewall add" code. + +Changes in 2.0.14 + +1) Log drops due to policy rate limiting. + +2) Fix typo in interfaces file. + +3) Eliminate "bad variable" errors during stop/clear. + +4) Fix typo in tunnels file. + +Changes in 2.0.15 + +1) Increased port range for Traceroute. + +2) Corrected port of rate-limit logging change. + +Changes in 2.0.16 + +1) Backport DROPINVALID from 2.2.0. diff --git a/Shorewall/common.def b/Shorewall/common.def deleted file mode 100644 index ea3abeb35..000000000 --- a/Shorewall/common.def +++ /dev/null @@ -1,49 +0,0 @@ -############################################################################ -# Shorewall 1.4 -- /etc/shorewall/common.def -# -# This file defines the rules that are applied before a policy of -# DROP or REJECT is applied. In addition to the rules defined in this file, -# the firewall will also define a DROP rule for each subnet broadcast -# address defined in /etc/shorewall/interfaces (including "detect"). -# -# Do not modify this file -- if you wish to change these rules, create -# /etc/shorewall/common to replace it. It is suggested that you include -# the command ". /etc/shorewall/common.def" in your -# /etc/shorewall/common file so that you will continue to get the -# advantage of new releases of this file. -# -run_iptables -A common -p icmp -j icmpdef -############################################################################ -# NETBIOS chatter -# -run_iptables -A common -p udp --dport 135 -j DROP -run_iptables -A common -p udp --dport 137:139 -j DROP -run_iptables -A common -p udp --dport 445 -j DROP -run_iptables -A common -p tcp --dport 139 -j DROP -run_iptables -A common -p tcp --dport 445 -j DROP -run_iptables -A common -p tcp --dport 135 -j DROP -############################################################################ -# UPnP -# -run_iptables -A common -p udp --dport 1900 -j DROP -############################################################################ -# BROADCASTS -# -run_iptables -A common -d 255.255.255.255 -j DROP -run_iptables -A common -d 224.0.0.0/4 -j DROP -############################################################################ -# AUTH -- Silently reject it so that connections don't get delayed. -# -run_iptables -A common -p tcp --dport 113 -j reject -############################################################################ -# DNS -- Silenty drop late replies -# -run_iptables -A common -p udp --sport 53 -mstate --state NEW -j DROP -############################################################################ -# ICMP -- Silently drop null-address ICMPs -# -run_iptables -A common -p icmp -s 0.0.0.0 -j DROP -run_iptables -A common -p icmp -d 0.0.0.0 -j DROP - - - diff --git a/Shorewall/configpath b/Shorewall/configpath new file mode 100644 index 000000000..f676bd1b0 --- /dev/null +++ b/Shorewall/configpath @@ -0,0 +1,7 @@ +# +# Shorewall version 2.0 - Default Config Path +# +# /usr/share/shorewall/configpath +# + +CONFIG_PATH=/etc/shorewall:/usr/share/shorewall \ No newline at end of file diff --git a/Shorewall/default.debian b/Shorewall/default.debian new file mode 100644 index 000000000..f5eeaf87b --- /dev/null +++ b/Shorewall/default.debian @@ -0,0 +1,18 @@ +# prevent startup with default configuration +# set the following varible to 1 in order to allow Shorewall to start + +startup=0 + +# if your Shorewall configuration requires detection of the ip address of a ppp +# interface, you must list such interfaces in "wait_interface" to get Shorewall to +# wait until the interface is configured. Otherwise the script will fail because +# it won't be able to detect the IP address. +# +# Example: +# wait_interface="ppp0" +# or +# wait_interface="ppp0 ppp1" +# or, if you have defined in /etc/shorewall/params +# wait_interface= + +# EOF diff --git a/Shorewall/ecn b/Shorewall/ecn index 27c6e3005..644a63500 100644 --- a/Shorewall/ecn +++ b/Shorewall/ecn @@ -1,5 +1,5 @@ # -# Shorewall 1.4 - /etc/shorewall/ecn +# Shorewall 2.0 - /etc/shorewall/ecn # # Use this file to list the destinations for which you want to # disable ECN. diff --git a/Shorewall/fallback.sh b/Shorewall/fallback.sh index b067e0894..8fe84b6b6 100755 --- a/Shorewall/fallback.sh +++ b/Shorewall/fallback.sh @@ -5,7 +5,7 @@ # # This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] # -# (c) 2001,2002,2003 - Tom Eastep (teastep@shorewall.net) +# (c) 2001,2002,2003,2004 - Tom Eastep (teastep@shorewall.net) # # Shorewall documentation is available at http://seattlefirewall.dyndns.org # @@ -28,11 +28,11 @@ # shown below. Simply run this script to revert to your prior version of # Shoreline Firewall. -VERSION=1.4.10d +VERSION=2.0.16 usage() # $1 = exit status { - echo "usage: `basename $0`" + echo "usage: $(basename $0)" exit $1 } @@ -57,30 +57,19 @@ fi echo "Backing Out Installation of Shorewall $VERSION" if [ -L /usr/share/shorewall/init ]; then - FIREWALL=`ls -l /usr/share/shorewall/firewall | sed 's/^.*> //'` + FIREWALL=$(ls -l /usr/share/shorewall/firewall | sed 's/^.*> //') restore_file $FIREWALL - restore_file /usr/share/shorewall/firewall -elif [ -L /usr/lib/shorewall/firewall ]; then - FIREWALL=`ls -l /usr/lib/shorewall/firewall | sed 's/^.*> //'` - restore_file $FIREWALL -elif [ -L /var/lib/shorewall/firewall ]; then - FIREWALL=`ls -l /var/lib/shorewall/firewall | sed 's/^.*> //'` - restore_file $FIREWALL -elif [ -L /usr/lib/shorewall/init ]; then - FIREWALL=`ls -l /usr/lib/shorewall/init | sed 's/^.*> //'` - restore_file $FIREWALL - restore_file /usr/lib/shorewall/firewall +else + restore_file /etc/init.d/shorewall fi -restore_file /sbin/shorewall +restore_file /usr/share/shorewall/firewall -[ -f /etc/shorewall.conf.$VERSION ] && rm -f /etc/shorewall.conf.$VERSION +restore_file /sbin/shorewall restore_file /etc/shorewall/shorewall.conf restore_file /etc/shorewall/functions -restore_file /usr/share/shorewall/functions -restore_file /usr/share/shorewall/firewall restore_file /usr/lib/shorewall/functions restore_file /var/lib/shorewall/functions restore_file /usr/lib/shorewall/firewall @@ -102,6 +91,8 @@ restore_file /etc/shorewall/rules restore_file /etc/shorewall/nat +restore_file /etc/shorewall/netmap + restore_file /etc/shorewall/params restore_file /etc/shorewall/proxyarp @@ -125,9 +116,16 @@ restore_file /etc/shorewall/blacklist restore_file /etc/shorewall/whitelist restore_file /etc/shorewall/rfc1918 +restore_file /usr/share/shorewall/rfc1918 + +restore_file /usr/share/shorewall/bogons + +restore_file /usr/share/shorewall/configpath restore_file /etc/shorewall/init +restore_file /etc/shorewall/initdone + restore_file /etc/shorewall/start restore_file /etc/shorewall/stop @@ -138,27 +136,15 @@ restore_file /etc/shorewall/ecn restore_file /etc/shorewall/accounting -restore_file /etc/shorewall/usersets - -restore_file /etc/shorewall/users +restore_file /etc/shorewall/actions.std restore_file /etc/shorewall/actions -restore_file /etc/shorewall/action.template +for f in /usr/share/shorewall/action.*-${VERSION}.bkout; do + restore_file $(echo $f | sed "s/-${VERSION}.bkout//") +done -if [ -f /usr/share/shorewall/version-${VERSION}.bkout ]; then - restore_file /usr/share/shorewall/version - oldversion="`cat /usr/share/shorewall/version`" -elif [ -f /usr/lib/shorewall/version-${VERSION}.bkout ]; then - restore_file /usr/lib/shorewall/version - oldversion="`cat /usr/lib/shorewall/version`" -elif [ -f /var/lib/shorewall/version-${VERSION}.bkout ]; then - restore_file /var/lib/shorewall/version - oldversion="`cat /var/lib/shorewall/version`" -else - restore_file /etc/shorewall/version - oldversion="`cat /etc/shorewall/version`" -fi +restore_file /usr/share/shorewall/version echo "Shorewall Restored to Version $oldversion" diff --git a/Shorewall/firewall b/Shorewall/firewall index 9a423c396..ae564c8f4 100755 --- a/Shorewall/firewall +++ b/Shorewall/firewall @@ -1,14 +1,11 @@ #!/bin/sh # -# The Shoreline Firewall (Shorewall) Packet Filtering Firewall - V1.4 3/14/2003 +# The Shoreline Firewall (Shorewall) Packet Filtering Firewall - V2.0 3/14/2004 # # This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] # # (c) 1999,2000,2001,2002,2003 - Tom Eastep (teastep@shorewall.net) # -# On most distributions, this file should be called: -# /etc/rc.d/init.d/shorewall or /etc/init.d/shorewall -# # Complete documentation is available at http://shorewall.net # # This program is free software; you can redistribute it and/or modify @@ -40,37 +37,6 @@ # shorewall refresh . Rebuild the common chain # shorewall check Verify the more heavily-used # configuration files. -# -# Search a list looking for a match -- returns zero if a match found -# 1 otherwise -# -list_search() # $1 = element to search for , $2-$n = list -{ - local e=$1 - - while [ $# -gt 1 ]; do - shift - [ "x$e" = "x$1" ] && return 0 - done - - return 1 -} - -# -# Functions to count list elements -# - - - - - - - - - - - - - - - - -# Whitespace-separated list -# -list_count1() { - echo $# -} -# -# Comma-separated list -# -list_count() { - list_count1 `separate_list $1` -} - # # Mutual exclusion -- These functions are jackets for the mutual exclusion # routines in $FUNCTIONS. They invoke @@ -99,7 +65,7 @@ error_message() # $* = Error Message fatal_error() # $* = Error Message { echo " Error: $@" >&2 - if [ $command = check ]; then + if [ $COMMAND = check ]; then [ -n "$TMP_DIR" ] && rm -rf $TMP_DIR else stop_firewall @@ -116,6 +82,7 @@ startup_error() # $* = Error Message echo " Error: $@" >&2 my_mutex_off [ -n "$TMP_DIR" ] && rm -rf $TMP_DIR + [ -n "$RESTOREBASE" ] && rm -f $RESTOREBASE kill $$ exit 2 } @@ -129,44 +96,56 @@ report () { # $* = message } # -# Perform variable substitution on the passed argument and echo the result +# Write the passed args to $RESTOREBASE # -expand() # $1 = contents of variable which may be the name of another variable +save_command() { - eval echo \"$1\" + echo "$@" >> $RESTOREBASE } # -# Perform variable substitition on the values of the passed list of variables +# Write a progress_message command to $RESTOREBASE # -expandv() # $* = list of variable names +save_progress_message() { - local varval - - while [ $# -gt 0 ]; do - eval varval=\$${1} - eval $1=\"$varval\" - shift - done + + echo >> $RESTOREBASE + echo "progress_message \"$@\"" >> $RESTOREBASE + echo >> $RESTOREBASE } # -# Replace all leading "!" with "! " in the passed argument list +# Save the passed command in the restore script then run it -- returns the status of the command +# If the command involves file redirection then it must be enclosed in quotes as in: # +# run_and_save_command "echo 1 > /proc/sys/net/ipv4/ip_forward" +# +run_and_save_command() +{ + echo "$@" >> $RESTOREBASE + eval $* +} -fix_bang() { - local i; - - for i in $@; do - case $i in - !*) - echo "! ${i#!}" - ;; - *) - echo $i - ;; - esac - done +# +# Run the passed command and if it succeeds, save it in the restore script. If it fails, stop the firewall and die +# +ensure_and_save_command() +{ + if eval $* ; then + echo "$@" >> $RESTOREBASE + else + [ -z "$stopping" ] && { stop_firewall; exit 2; } + fi +} + +# +# Append a file in $STATEDIR to $RESTOREBASE +# +append_file() # $1 = File Name +{ + save_command "cat > $STATEDIR/$1 << __EOF__" + cat $STATEDIR/$1 >> $RESTOREBASE + save_command __EOF__ } # @@ -174,6 +153,8 @@ fix_bang() { # run_iptables() { + [ -n "$BRIDGING" ] && [ -f $TMP_DIR/physdev ] && rm -f $TMP_DIR/physdev + if ! iptables $@ ; then [ -z "$stopping" ] && { stop_firewall; exit 2; } fi @@ -194,7 +175,17 @@ run_iptables2() { # # Need to insert white space before each "!" # - run_iptables `fix_bang $@` + run_iptables $(fix_bang $@) +} + +# +# Quietly run iptables +# +qt_iptables() { + + [ -n "$BRIDGING" ] && [ -f $TMP_DIR/physdev ] && rm -f $TMP_DIR/physdev + + qt iptables $@ } # @@ -234,7 +225,7 @@ run_tc() { # createchain() # $1 = chain name, $2 = If "yes", create default rules { - local c=`chain_base $1` + local c=$(chain_base $1) run_iptables -N $1 @@ -249,7 +240,7 @@ createchain() # $1 = chain name, $2 = If "yes", create default rules createchain2() # $1 = chain name, $2 = If "yes", create default rules { - local c=`chain_base $1` + local c=$(chain_base $1) if iptables -N $1; then @@ -272,7 +263,7 @@ createchain2() # $1 = chain name, $2 = If "yes", create default rules # havechain() # $1 = name of chain { - local c=`chain_base $1` + local c=$(chain_base $1) eval test \"\$exists_${c}\" = Yes } @@ -301,13 +292,18 @@ ensurechain() # $1 = chain name havechain $1 || createchain $1 yes } +ensurechain1() # $1 = chain name +{ + havechain $1 || createchain $1 no +} + # # 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 $@ + run_iptables2 -A $@ } # @@ -414,7 +410,7 @@ find_interfaces() # $1 = interface zone local interface for interface in $all_interfaces; do - eval z=\$`chain_base ${interface}`_zone + eval z=\$$(chain_base $interface)_zone [ "x${z}" = x${zne} ] && echo $interface done } @@ -424,7 +420,7 @@ find_interfaces() # $1 = interface zone # forward_chain() # $1 = interface { - echo `chain_base $1`_fwd + echo $(chain_base $1)_fwd } # @@ -432,7 +428,7 @@ forward_chain() # $1 = interface # input_chain() # $1 = interface { - echo `chain_base $1`_in + echo $(chain_base $1)_in } # @@ -440,7 +436,7 @@ input_chain() # $1 = interface # output_chain() # $1 = interface { - echo `chain_base $1`_out + echo $(chain_base $1)_out } # @@ -448,7 +444,7 @@ output_chain() # $1 = interface # masq_chain() # $1 = interface { - echo `chain_base $1`_masq + echo $(chain_base $1)_masq } # @@ -456,7 +452,32 @@ masq_chain() # $1 = interface # mac_chain() # $1 = interface { - echo `chain_base $1`_mac + echo $(chain_base $1)_mac +} + +# +# Functions for creating dynamic zone rules +# +dynamic_fwd() # $1 = interface +{ + echo $(chain_base $1)_dynf +} + +dynamic_in() # $1 = interface +{ + echo $(chain_base $1)_dyni +} + +dynamic_out() # $1 = interface +{ + echo $(chain_base $1)_dyno +} + +dynamic_chains() #$1 = interface +{ + local c=$(chain_base $1) + + echo ${c}_dyni ${c}_dynf ${c}_dyno } # @@ -472,7 +493,7 @@ dnat_chain() # $1 = zone # snat_chain() # $1 = zone { - echo `chain_base $1`_snat + echo $(chain_base $1)_snat } # @@ -480,7 +501,7 @@ snat_chain() # $1 = zone # ecn_chain() # $1 = interface { - echo `chain_base $1`_ecn + echo $(chain_base $1)_ecn } # @@ -488,34 +509,111 @@ ecn_chain() # $1 = interface # first_chains() #$1 = interface { - local c=`chain_base $1` + local c=$(chain_base $1) echo ${c}_fwd ${c}_in } # -# ACCEPT chain for a userset +# Horrible hack to work around an iptables bug # -accept_chain() # $1 = userset +physdev_echo() { - echo ${1}_acc + if [ -f $TMP_DIR/physdev ]; then + echo $@ + else + echo -m physdev $@ + > $TMP_DIR/physdev + fi } # -# DROP chain for a userset +# We allow hosts to be specified by IP address or by physdev. These two functions +# are used to produce the proper match in a netfilter rule. # -drop_chain() # $1 = userset +match_source_hosts() { - echo ${1}_drp -} -# -# REJECT chain for a userset -# -reject_chain() # $1 = userset -{ - echo ${1}_rej + if [ -n "$BRIDGING" ]; then + case $1 in + *:*) + physdev_echo "--physdev-in ${1%:*} -s ${1#*:}" + ;; + *.*.*.*) + echo -s $1 + ;; + *) + physdev_echo "--physdev-in $1" + ;; + esac + else + echo -s $1 + fi } +match_dest_hosts() +{ + if [ -n "$BRIDGING" ]; then + case $1 in + *:*) + physdev_echo "--physdev-out ${1%:*} -d ${1#*:}" + ;; + *.*.*.*) + echo -d $1 + ;; + *) + physdev_echo "--physdev-out $1" + ;; + esac + else + echo -d $1 + fi +} + +# +# Similarly, the source or destination in a rule can be qualified by a device name. If +# the device is defined in /etc/shorewall/interfaces then a normal interface match is +# generated (-i or -o); otherwise, a physdev match is generated. +#------------------------------------------------------------------------------------- +# +# loosely match the passed interface with those in /etc/shorewall/interfaces. +# +known_interface() # $1 = interface name +{ + local iface + + for iface in $all_interfaces ; do + if if_match $iface $1 ; then + return 0 + fi + done + + return 1 +} + +match_source_dev() +{ + if [ -n "$BRIDGING" ]; then + list_search $1 $all_ports && physdev_echo "--physdev-in $1" || echo -i $1 + else + echo -i $1 + fi +} + +match_dest_dev() +{ + if [ -n "$BRIDGING" ]; then + list_search $1 $all_ports && physdev_echo "--physdev-out $1" || echo -o $1 + else + echo -o $1 + fi +} + +verify_interface() +{ + known_interface $1 || { [ -n $BRIDGING ] && list_search $1 $all_ports ; } +} + +# # # Find hosts in a given zone # @@ -527,11 +625,11 @@ find_hosts() # $1 = host zone local hosts interface address addresses while read z hosts options; do - if [ "x`expand $z`" = "x$1" ]; then + if [ "x$(expand $z)" = "x$1" ]; then expandv hosts - interface=${hosts%:*} + interface=${hosts%%:*} addresses=${hosts#*:} - for address in `separate_list $addresses`; do + for address in $(separate_list $addresses); do echo $interface:$address done fi @@ -546,37 +644,51 @@ find_hosts() # $1 = host zone # determine_interfaces() { for zone in $zones; do - interfaces=`find_interfaces $zone` - interfaces=`echo $interfaces` # Remove extra trash + interfaces=$(find_interfaces $zone) + interfaces=$(echo $interfaces) # Remove extra trash eval ${zone}_interfaces=\"\$interfaces\" done } +# +# Determine if an interface has a given option +# +interface_has_option() # $1 = interface, #2 = option +{ + local options + + eval options=\$$(chain_base $1)_options + + list_search $2 $options +} + # # Determine the defined hosts in each zone and generate report # determine_hosts() { for zone in $zones; do - hosts=`find_hosts $zone` - hosts=`echo $hosts` # Remove extra trash + hosts=$(find_hosts $zone) + hosts=$(echo $hosts) # Remove extra trash eval interfaces=\$${zone}_interfaces for interface in $interfaces; do - eval options=\$`chain_base ${interface}`_options - - if list_search detectnets $options; then - subnets=`get_routed_subnets $interface` + if interface_has_option $interface detectnets; then + networks=$(get_routed_networks $interface) else - subnets=0.0.0.0/0 + networks=0.0.0.0/0 fi - for subnet in $subnets; do + for network in $networks; do if [ -z "$hosts" ]; then - hosts=$interface:$subnet + hosts=$interface:$network else - hosts="$hosts $interface:$subnet" + hosts="$hosts $interface:$network" + fi + + if interface_has_option $interface routeback; then + eval ${zone}_routeback=\"$interface:$network \$${zone}_routeback\" fi done done @@ -585,16 +697,19 @@ determine_hosts() { for host in $hosts; do interface=${host%:*} - if ! list_search $interface $interfaces; then + if list_search $interface $interfaces; then + list_search $interface:0.0.0.0/0 $hosts && \ + startup_error "Invalid zone definition for zone $zone" + list_search $interface:0/0 $hosts && \ + startup_error "Invalid zone definition for zone $zone" + eval ${zone}_is_complex=Yes + else if [ -z "$interfaces" ]; then interfaces=$interface else interfaces="$interfaces $interface" fi fi - - [ "${host#*:}" = "0.0.0.0/0" ] || \ - eval ${zone}_is_complex=Yes done eval ${zone}_interfaces="\$interfaces" @@ -616,16 +731,25 @@ validate_zone() # $1 = zone { list_search $1 $zones $FW } +# +# Ensure that the passed zone is defined in the zones file. +# +validate_zone1() # $1 = zone +{ + list_search $1 $zones +} # # Validate the zone names and options in the interfaces file # validate_interfaces_file() { local wildcard + local found_obsolete_option= + local z interface networks options r iface option - while read z interface subnet options; do - expandv z interface subnet options - r="$z $interface $subnet $options" + while read z interface networks options; do + expandv z interface networks options + r="$z $interface $networks $options" [ "x$z" = "x-" ] && z= @@ -633,47 +757,51 @@ validate_interfaces_file() { validate_zone $z || startup_error "Invalid zone ($z) in record \"$r\"" fi - if [ -n "`ip link show $interface 2> /dev/null | grep LOOPBACK`" ]; then - startup_error "The loopback interface ($interface) may not be defined in /etc/shorewall/interfaces" - fi - list_search $interface $all_interfaces && \ startup_error "Duplicate Interface $interface" wildcard= case $interface in - *:*) + *:*|+) startup_error "Invalid Interface Name: $interface" ;; - *+*) + *+) wildcard=Yes ;; esac all_interfaces="$all_interfaces $interface" - options=`separate_list $options` - iface=`chain_base $interface` + options=$(separate_list $options) + iface=$(chain_base $interface) - eval ${iface}_broadcast="$subnet" + eval ${iface}_broadcast="$networks" eval ${iface}_zone="$z" eval ${iface}_options=\"$options\" for option in $options; do case $option in - dhcp|norfc1918|tcpflags|newnotsyn|arp_filter|routefilter|blacklist|proxyarp|maclist|-) + 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 ;; detectnets) [ -n "$wildcard" ] && \ startup_error "The \"detectnets\" option may not be used with a wild-card interface" ;; - dropunclean|logunclean) - error_message \ - "Warning: The 'dropunclean' and 'logunclean' options will be removed in a future release" - ;; routeback) [ -n "$z" ] || startup_error "The routeback option may not be specified on a multi-zone interface" - eval ${z}_routeback=\"$interface:0.0.0.0/0 \$${z}_routeback\" ;; *) error_message "Warning: Invalid option ($option) in record \"$r\"" @@ -690,25 +818,55 @@ validate_interfaces_file() { # Validate the zone names and options in the hosts file # validate_hosts_file() { + local z hosts options r interface host option port ports + + check_bridge_port() + { + list_search $1 $ports || ports="$ports $1" + list_search ${interface}:${1} $zports || zports="$zports ${interface}:${1}" + 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_zone $z || startup_error "Invalid zone ($z) in record \"$r\"" + validate_zone1 $z || startup_error "Invalid zone ($z) in record \"$r\"" - interface=${hosts%:*} + interface=${hosts%%:*} + iface=$(chain_base $interface) list_search $interface $all_interfaces || \ startup_error "Unknown interface ($interface) in record \"$r\"" hosts=${hosts#*:} - for host in `separate_list $hosts`; do - for option in `separate_list $options`; do + eval ports=\$${iface}_ports + eval zports=\$${z}_ports + + for host in $(separate_list $hosts); do + + [ -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|-) + maclist|norfc1918|nobogons|blacklist|tcpflags|nosmurfs|newnotsyn|-) ;; routeback) - eval ${z}_routeback=\"$interface:$host \$${z}_routeback\" + [ -z "$ports" ] && \ + eval ${z}_routeback=\"$interface:$host \$${z}_routeback\" ;; *) error_message "Warning: Invalid option ($option) in record \"$r\"" @@ -716,7 +874,15 @@ validate_hosts_file() { esac done done + + 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" } # @@ -726,7 +892,7 @@ validate_hosts_file() { # mac_match() # $1 = MAC address formated as described above { - echo "--match mac --mac-source `echo $1 | sed 's/~//;s/-/:/g'`" + echo "--match mac --mac-source $(echo $1 | sed 's/~//;s/-/:/g')" } # @@ -746,11 +912,11 @@ validate_policy() print_policy() # $1 = source zone, $2 = destination zone { - [ $command != check ] || \ + [ $COMMAND != check ] || \ [ $1 = $2 ] || \ [ $1 = all ] || \ [ $2 = all ] || \ - echo " Policy for $1 to $2 is $policy using chain $chain" + progress_message " Policy for $1 to $2 is $policy using chain $chain" } all_policy_chains= @@ -800,9 +966,6 @@ validate_policy() chain=${client}2${server} - [ "x$chain" = "x${FW}2${FW}" ] && \ - startup_error "fw->fw policy not allowed: $policy" - if is_policy_chain $chain ; then startup_error "Duplicate policy $policy" fi @@ -863,16 +1026,11 @@ validate_policy() # find_broadcasts() { for interface in $all_interfaces; do - eval bcast=\$`chain_base $interface`_broadcast + eval bcast=\$$(chain_base $interface)_broadcast if [ "x$bcast" = "xdetect" ]; then - addr="`ip -f inet addr show $interface 2> /dev/null`" - if [ -n "`echo "$addr" | grep 'inet.*brd '`" ]; then - addr="`echo "$addr" | \ - grep "inet " | sed 's/^.* inet.*brd //;s/scope.*//'`" - echo $addr | cut -d' ' -f 1 - fi + ip -f inet addr show $interface 2> /dev/null | grep 'inet.*brd' | sed 's/inet.*brd //; s/scope.*//;' | sort -u elif [ "x${bcast}" != "x-" ]; then - echo `separate_list $bcast` + echo $(separate_list $bcast) fi done } @@ -886,7 +1044,7 @@ find_interface_address() # $1 = interface # # get the line of output containing the first IP address # - addr=`ip -f inet addr show $1 2> /dev/null | grep inet | head -n1` + addr=$(ip -f inet addr show $1 2> /dev/null | grep inet | head -n1) # # If there wasn't one, bail out now # @@ -913,7 +1071,7 @@ find_interface_addresses() # $1 = interface find_interfaces_by_option() # $1 = option { for interface in $all_interfaces; do - eval options=\$`chain_base ${interface}`_options + eval options=\$$(chain_base $interface)_options list_search $1 $options && echo $interface done } @@ -927,19 +1085,18 @@ find_hosts_by_option() # $1 = option while read ignore hosts options; do expandv options - if list_search $1 `separate_list $options`; then + if list_search $1 $(separate_list $options); then expandv hosts - interface=${hosts%:*} + interface=${hosts%%:*} addresses=${hosts#*:} - for address in `separate_list $addresses`; do + for address in $(separate_list $addresses); do echo $interface:$address done fi done < $TMP_DIR/hosts for interface in $all_interfaces; do - eval options=\$`chain_base ${interface}`_options - list_search $1 $options && \ + interface_has_option $interface $1 && \ echo ${interface}:0.0.0.0/0 done } @@ -956,7 +1113,7 @@ have_interfaces_in_zone_with_option() # $1 = zone, $2 = option local interface for interface in $all_interfaces; do - eval z=\$`chain_base ${interface}`_zone + eval z=\$$(chain_base $interface)_zone [ "x$z" = "x$zne" ] && \ list_search $1 $options && \ @@ -979,10 +1136,10 @@ deleteallchains() { # run_user_exit() # $1 = file name { - local user_exit=`find_file $1` + local user_exit=$(find_file $1) if [ -f $user_exit ]; then - echo "Processing $user_exit ..." + progress_message "Processing $user_exit ..." . $user_exit fi } @@ -990,50 +1147,48 @@ run_user_exit() # $1 = file name # # Add a logging rule. # -log_rule_limit() # $1 = log level, $2 = chain, $3 = disposition , $4 = rate limit $... = predicates for the rule +log_rule_limit() # $1 = log level, $2 = chain, $3 = disposition , $4 = rate limit $5=log tag $... = predicates for the rule { local level=$1 local chain=$2 local disposition=$3 local rulenum= local limit="${4:-$LOGLIMIT}" + local tag=${5:+$5 } + local prefix + local base=$(chain_base $displayChain) - shift;shift;shift;shift + shift;shift;shift;shift;shift if [ -n "$LOGRULENUMBERS" ]; then - eval rulenum=\$${chain}_logrules + eval rulenum=\$${base}_logrules - [ -z "$rulenum" ] && rulenum=1 + rulenum=${rulenum:-1} - case $level in - ULOG) - eval iptables -A $chain $@ $limit -j ULOG $LOGPARMS --ulog-prefix '"`printf "$LOGFORMAT" $chain $rulenum $disposition`"' - ;; - *) - eval iptables -A $chain $@ $limit -j LOG $LOGPARMS --log-level $level --log-prefix '"`printf "$LOGFORMAT" $chain $rulenum $disposition`"' - ;; - esac - - if [ $? -ne 0 ] ; then - [ -z "$stopping" ] && { stop_firewall; exit 2; } - fi + prefix="$(printf "$LOGFORMAT" $chain $rulenum $disposition)${tag}" rulenum=$(($rulenum + 1)) - - eval ${chain}_logrules=$rulenum + eval ${base}_logrules=$rulenum else - case $level in - ULOG) - eval iptables -A $chain $@ $limit -j ULOG $LOGPARMS --ulog-prefix '"`printf "$LOGFORMAT" $chain $disposition`"' - ;; - *) - eval iptables -A $chain $@ $limit -j LOG $LOGPARMS --log-level $level --log-prefix '"`printf "$LOGFORMAT" $chain $disposition`"' - ;; - esac + prefix="$(printf "$LOGFORMAT" $chain $disposition)${tag}" + fi + + if [ ${#prefix} -gt 29 ]; then + prefix="$(echo $prefix | cut -b -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 -A $chain $@ $limit -j LOG $LOGPARMS --log-level $level --log-prefix "$prefix" + ;; + esac - if [ $? -ne 0 ] ; then - [ -z "$stopping" ] && { stop_firewall; exit 2; } - fi + if [ $? -ne 0 ] ; then + [ -z "$stopping" ] && { stop_firewall; exit 2; } fi } @@ -1045,25 +1200,61 @@ 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 $disposition "$LOGLIMIT" "" $@ } # # Set /proc/sys/net/ipv4/ip_forward based on $IP_FORWARDING # setup_forwarding() { + + save_progress_message "Restoring IP Forwarding..." + case "$IP_FORWARDING" in [Oo][Nn]) - echo 1 > /proc/sys/net/ipv4/ip_forward + run_and_save_command "echo 1 > /proc/sys/net/ipv4/ip_forward" echo "IP Forwarding Enabled" ;; [Oo][Ff][Ff]) - echo 0 > /proc/sys/net/ipv4/ip_forward + run_and_save_command "echo 0 > /proc/sys/net/ipv4/ip_forward" echo "IP Forwarding Disabled!" ;; esac } +# +# Disable IPV6 +# +disable_ipv6() { + local foo="$(ip -f inet6 addr ls 2> /dev/null)" + + if [ -n "$foo" ]; then + if qt which ip6tables; then + save_progress_message "Disabling IPV6..." + ip6tables -P FORWARD DROP && save_command ip6tables -P FORWARD DROP + ip6tables -P INPUT DROP && save_command ip6tables -P INPUT DROP + ip6tables -P OUTPUT DROP && save_command ip6tables -P OUTPUT DROP + else + error_message "WARNING: DISABLE_IPV6=Yes in shorewall.conf but this system does not appear to have ip6tables" + fi + fi +} + +disable_ipv6_1() { + local foo="$(ip -f inet6 addr ls 2> /dev/null)" + + if [ -n "$foo" ]; then + if qt which ip6tables; then + progress_message "Disabling IPV6..." + ip6tables -P FORWARD DROP + ip6tables -P INPUT DROP + ip6tables -P OUTPUT DROP + else + error_message "WARNING: DISABLE_IPV6=Yes in shorewall.conf but this system does not appear to have ip6tables" + fi + fi +} + # # Stop the Firewall # @@ -1071,7 +1262,10 @@ stop_firewall() { # # Turn off trace unless we were tracing "stop" or "clear" # - case $command in + + [ -n "$RESTOREBASE" ] && rm -f $RESTOREBASE + + case $COMMAND in stop|clear) ;; check) @@ -1080,6 +1274,19 @@ stop_firewall() { ;; *) set +x + + [ -z "$RESTOREFILE" ] && RESTOREFILE=restore + + RESTOREPATH=/var/lib/shorewall/$RESTOREFILE + + if [ -x $RESTOREPATH ]; then + echo Restoring Shorewall... + $RESTOREPATH + echo "Shorewall restored from $RESTOREPATH" + my_mutex_off + kill $$ + exit 2 + fi ;; esac @@ -1097,7 +1304,9 @@ stop_firewall() { [ -n "$NAT_ENABLED" ] && delete_nat delete_proxy_arp - [ -n "$CLEAR_TC" ] && delete_tc + [ -n "$CLEAR_TC" ] && delete_tc1 + + [ -n "$DISABLE_IPV6" ] && disable_ipv6_1 if [ -z "$ADMINISABSENTMINDED" ]; then for chain in INPUT OUTPUT FORWARD; do @@ -1123,25 +1332,46 @@ stop_firewall() { strip_file routestopped - while read interface host; do - expandv interface host + while read interface host options; do + expandv interface host options [ "x$host" = "x-" -o -z "$host" ] && host=0.0.0.0/0 - for h in `separate_list $host`; do + for h in $(separate_list $host); do hosts="$hosts $interface:$h" done + + routeback= + + if [ -n $options ]; then + for option in $(separate_list $options); do + case $option in + routeback) + if [ -n "$routeback" ]; then + error_message "Warning: Duplicate option ignored: routeback" + else + routeback=Yes + for h in $(separate_list $host); do + iptables -A FORWARD -i $interface -s $h -o $interface -d $h -j ACCEPT + done + fi + ;; + *) + error_message "Warning: Unknown option ignored: $option" + ;; + esac + done + fi + done < $TMP_DIR/routestopped for host in $hosts; do interface=${host%:*} - subnet=${host#*:} - iptables -A INPUT -i $interface -s $subnet -j ACCEPT + networks=${host#*:} + iptables -A INPUT -i $interface -s $networks -j ACCEPT [ -z "$ADMINISABSENTMINDED" ] && \ - iptables -A OUTPUT -o $interface -d $subnet -j ACCEPT + iptables -A OUTPUT -o $interface -d $networks -j ACCEPT for host1 in $hosts; do - [ "$host" != "$host1" ] && \ - iptables -A FORWARD -i $interface -s $subnet \ - -o ${host1%:*} -d ${host1#*:} -j ACCEPT + [ "$host" != "$host1" ] && iptables -A FORWARD -i $interface -s $networks -o ${host1%:*} -d ${host1#*:} -j ACCEPT done done @@ -1149,13 +1379,26 @@ stop_firewall() { [ -z "$ADMINISABSENTMINDED" ] && \ iptables -A OUTPUT -o lo -j ACCEPT - for interface in `find_interfaces_by_option dhcp`; do + for interface in $(find_interfaces_by_option dhcp); do 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 + # + # This might be a bridge + # + iptables -A FORWARD -p udp -i $interface -o $interface --dport 67:68 -j ACCEPT done - setup_forwarding + case "$IP_FORWARDING" in + [Oo][Nn]) + echo 1 > /proc/sys/net/ipv4/ip_forward + echo "IP Forwarding Enabled" + ;; + [Oo][Ff][Ff]) + echo 0 > /proc/sys/net/ipv4/ip_forward + echo "IP Forwarding Disabled!" + ;; + esac run_user_exit stopped @@ -1163,7 +1406,7 @@ stop_firewall() { rm -rf $TMP_DIR - case $command in + case $COMMAND in stop|clear) ;; *) @@ -1192,6 +1435,12 @@ clear_firewall() { setpolicy FORWARD ACCEPT setpolicy OUTPUT ACCEPT + if qt which ip6tables; then + ip6tables -P INPUT ACCEPT 2> /dev/null + ip6tables -P OUTPUT ACCEPT 2> /dev/null + ip6tables -P FORWARD ACCEPT 2> /dev/null + fi + run_user_exit clear logger "Shorewall Cleared" @@ -1207,25 +1456,39 @@ setup_tunnels() # $1 = name of tunnels file setup_one_ipsec() # $1 = gateway $2 = Tunnel Kind $3 = gateway zones { + local kind=$2 noah= + + case $kind in + *:*) + noah=${kind#*:} + [ $noah = noah -o $noah = NOAH ] || fatal_error "Invalid IPSEC modifier $noah in tunnel \"$tunnel\"" + kind=${kind%:*} + ;; + esac + + [ $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 - run_iptables -A $inchain -p 51 -s $1 -j ACCEPT - run_iptables -A $outchain -p 51 -d $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 + fi run_iptables -A $outchain -p udp -d $1 --dport 500 --sport 500 $options - if [ $2 = ipsec ]; then + if [ $kind = ipsec ]; then run_iptables -A $inchain -p udp -s $1 --sport 500 --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 fi - for z in `separate_list $3`; do + for z in $(separate_list $3); do if validate_zone $z; then addrule ${FW}2${z} -p udp --sport 500 --dport 500 $options - if [ $2 = ipsec ]; then + if [ $kind = ipsec ]; then addrule ${z}2${FW} -p udp --sport 500 --dport 500 $options else addrule ${z}2${FW} -p udp --dport 500 $options @@ -1237,7 +1500,7 @@ setup_tunnels() # $1 = name of tunnels file fi done - echo " IPSEC tunnel to $gateway defined." + progress_message " IPSEC tunnel to $gateway defined." } setup_one_other() # $1 = TYPE, $2 = gateway, $3 = protocol @@ -1245,7 +1508,7 @@ setup_tunnels() # $1 = name of tunnels file addrule $inchain -p $3 -s $2 -j ACCEPT addrule $outchain -p $3 -d $2 -j ACCEPT - echo " $1 tunnel to $2 defined." + progress_message " $1 tunnel to $2 defined." } setup_pptp_client() # $1 = gateway @@ -1254,16 +1517,16 @@ setup_tunnels() # $1 = name of tunnels file addrule $inchain -p 47 -j ACCEPT addrule $outchain -p tcp --dport 1723 -d $1 -j ACCEPT - echo " PPTP tunnel to $1 defined." + progress_message " PPTP tunnel to $1 defined." } - setup_pptp_server() + setup_pptp_server() # $1 = gateway { - addrule $inchain -p 47 -j ACCEPT - addrule $outchain -p 47 -j ACCEPT - addrule $inchain -p tcp --dport 1723 -j ACCEPT + 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 - echo " PPTP server defined." + progress_message " PPTP server defined." } setup_one_openvpn() # $1 = gateway, $2 = kind[:port] @@ -1280,12 +1543,12 @@ setup_tunnels() # $1 = name of tunnels file addrule $inchain -p udp -s $1 --sport $p --dport $p -j ACCEPT addrule $outchain -p udp -d $1 --sport $p --dport $p -j ACCEPT - echo " OPENVPN tunnel to $1:$p defined." + progress_message " OPENVPN tunnel to $1:$p defined." } setup_one_generic() # $1 = gateway, $2 = kind:protocol[:port], $3 = Gateway Zone { - local procotol + local protocol local p= case $2 in @@ -1308,7 +1571,7 @@ setup_tunnels() # $1 = name of tunnels file addrule $inchain -p $protocol -s $1 $p -j ACCEPT addrule $outchain -p $protocol -d $1 $p -j ACCEPT - for z in `separate_list $3`; do + for z in $(separate_list $3); do if validate_zone $z; then addrule ${FW}2${z} -p $protocol $p -j ACCEPT addrule ${z}2${FW} -p $protocol $p -j ACCEPT @@ -1318,23 +1581,24 @@ setup_tunnels() # $1 = name of tunnels file fi done - echo " GENERIC tunnel to $1:$p defined." + progress_message " GENERIC tunnel to $1:$p defined." } strip_file tunnels $1 while read kind z gateway z1; do expandv kind z gateway z1 - tunnel="`echo $kind $z $gateway $z1`" + tunnel="$(echo $kind $z $gateway $z1)" if validate_zone $z; then inchain=${z}2${FW} outchain=${FW}2${z} + gateway=${gateway:-0.0.0.0/0} case $kind in - ipsec|IPSEC) - setup_one_ipsec $gateway ipsec $z1 + ipsec|IPSEC|ipsec:*|IPSEC:*) + setup_one_ipsec $gateway $kind $z1 ;; - ipsecnat|IPSECNAT) - setup_one_ipsec $gateway ipsecnat $z1 + ipsecnat|IPSECNAT|ipsecnat:*|IPSECNAT:*) + setup_one_ipsec $gateway $kind $z1 ;; ipip|IPIP) setup_one_other IPIP $gateway 4 @@ -1349,7 +1613,7 @@ setup_tunnels() # $1 = name of tunnels file setup_pptp_client $gateway ;; pptpserver|PPTPSERVER) - setup_pptp_server + setup_pptp_server $gateway ;; openvpn|OPENVPN|openvpn:*|OPENVPN:*) setup_one_openvpn $gateway $kind @@ -1379,7 +1643,18 @@ setup_proxy_arp() { error_message "Entry \"$address $interface $external $haveroute\" ignored" } + print_error1() { + error_message "Invalid value for PERSISTENT - ($persistent)" + error_message "Entry \"$address $interface $external $haveroute $persistent\" ignored" + } + + print_warning() { + error_message "PERSISTENT setting ignored - ($persistent)" + error_message "Entry \"$address $interface $external $haveroute $persistent\"" + } + setup_one_proxy_arp() { + case $haveroute in [Nn][Oo]) haveroute= @@ -1394,30 +1669,51 @@ setup_proxy_arp() { ;; esac - [ -z "$haveroute" ] && run_ip route replace $address dev $interface + case $persistent in + [Nn][Oo]) + persistent= + ;; + [Yy][Ee][Ss]) + [ -z "$haveroute" ] || print_warning + ;; + *) + if [ -n "$persistent" ]; then + print_error1 + return + fi + ;; + esac - run_arp -i $external -Ds $address $external pub + if [ -z "$haveroute" ]; then + ensure_and_save_command ip route replace $address dev $interface + [ -n "$persistent" ] && haveroute=yes + fi - echo 1 > /proc/sys/net/ipv4/conf/$interface/proxy_arp - echo 0 > /proc/sys/net/ipv4/conf/$external/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 - echo " Host $address connected to $interface added to ARP on $external" + progress_message " Host $address connected to $interface added to ARP on $external" } > ${STATEDIR}/proxyarp - while read address interface external haveroute; do - expandv address interface external haveroute + save_progress_message "Restoring Proxy ARP..." + + while read address interface external haveroute persistent; do + expandv address interface external haveroute persistent setup_one_proxy_arp done < $TMP_DIR/proxyarp - interfaces=`find_interfaces_by_option proxyarp` + interfaces=$(find_interfaces_by_option proxyarp) for interface in $interfaces; do if echo 1 > /proc/sys/net/ipv4/conf/$interface/proxy_arp 2> /dev/null; then - echo " Enabled proxy ARP on $interface" + progress_message " Enabled proxy ARP on $interface" + save_command "echo 1 > /proc/sys/net/ipv4/conf/$interface/proxy_arp" else error_message "Warning: Unable to enable proxy ARP on $interface" fi @@ -1443,7 +1739,7 @@ setup_mac_lists() { maclist_interfaces= for hosts in $maclist_hosts; do - interface=${hosts%:*} + interface=${hosts%%:*} if ! list_search $interface $maclist_interfaces; then\ if [ -z "$maclist_interfaces" ]; then maclist_interfaces=$interface @@ -1453,7 +1749,7 @@ setup_mac_lists() { fi done - echo "Setting up MAC Verification on $maclist_interfaces..." + progress_message "Setting up MAC Verification on $maclist_interfaces..." # # Be sure that they are all ethernet interfaces # @@ -1466,7 +1762,7 @@ setup_mac_lists() { ;; esac - createchain `mac_chain $interface` no + createchain $(mac_chain $interface) no done # # Process the maclist file producing the verification rules @@ -1475,19 +1771,30 @@ setup_mac_lists() { while read interface mac addresses; do expandv interface mac addresses - chain=`mac_chain $interface` + physdev_part= + + if [ -n "$BRIDGING" ]; then + case $interface in + *:*) + physdev_part="-m physdev --physdev-in ${interface#*:}" + interface=${interface%:*} + ;; + esac + fi + + chain=$(mac_chain $interface) if ! havechain $chain ; then fatal_error "No hosts on $interface have the maclist option specified" fi - macpart=`mac_match $mac` + macpart=$(mac_match $mac) if [ -z "$addresses" ]; then - run_iptables -A $chain $macpart -j RETURN + run_iptables -A $chain $macpart $physdev_part -j RETURN else - for address in `separate_list $addresses` ; do - run_iptables2 -A $chain $macpart -s $address -j RETURN + for address in $(separate_list $addresses) ; do + run_iptables2 -A $chain $macpart -s $address $physdev_part -j RETURN done fi done < $TMP_DIR/maclist @@ -1496,14 +1803,14 @@ setup_mac_lists() { # chains # for interface in $maclist_interfaces; do - chain=`mac_chain $interface` + chain=$(mac_chain $interface) - blob=`ip link show $interface 2> /dev/null` + blob=$(ip link show $interface 2> /dev/null) [ -z "$blob" ] && \ fatal_error "Interface $interface must be up before Shorewall can start" - ip -f inet addr show $interface 2> /dev/null | grep inet | sed 's/inet //; s/brd //; s/scope.*//;' | while read address broadcast; do + ip -f inet addr show $interface 2> /dev/null | grep 'inet.*brd' | sed 's/inet //; s/brd //; s/scope.*//;' | while read address broadcast; do if [ -n "$broadcast" ]; then run_iptables -A $chain -s ${address%/*} -d $broadcast -j RETURN fi @@ -1522,11 +1829,11 @@ setup_mac_lists() { # Generate jumps from the input and forward chains # for hosts in $maclist_hosts; do - interface=${hosts%:*} + interface=${hosts%%:*} hosts=${hosts#*:} - for chain in `first_chains $interface` ; do - run_iptables -A $chain -s $hosts -m state --state NEW \ - -j `mac_chain $interface` + for chain in $(first_chains $interface) ; do + run_iptables -A $chain $(match_source_hosts $hosts) -m state --state NEW \ + -j $(mac_chain $interface) done done } @@ -1537,8 +1844,9 @@ setup_mac_lists() { setup_syn_flood_chain () # $1 = policy chain # $2 = synparams + # $3 = loglevel { - local chain=$1 + local chain=@$1 local limit=$2 local limit_burst= @@ -1549,9 +1857,11 @@ setup_syn_flood_chain () ;; esac - run_iptables -N @$chain - run_iptables -A @$chain -m limit --limit $limit $limit_burst -j RETURN - run_iptables -A @$chain -j DROP + 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" "" + run_iptables -A $chain -j DROP } # @@ -1563,7 +1873,7 @@ setup_syn_flood_chain () enable_syn_flood_protection() # $1 = chain, $2 = protection chain { run_iptables -I $1 2 -p tcp --syn -j @$2 - echo " Enabled SYN flood protection" + progress_message " Enabled SYN flood protection" } # @@ -1581,7 +1891,7 @@ delete_proxy_arp() { [ -d ${STATEDIR} ] && touch ${STATEDIR}/proxyarp - for f in `ls /proc/sys/net/ipv4/conf/*/proxy_arp`; do + for f in $(ls /proc/sys/net/ipv4/conf/*/proxy_arp); do echo 0 > $f done } @@ -1596,7 +1906,7 @@ setup_nat() { # > ${STATEDIR}/nat - echo "Setting up NAT..." + save_progress_message "Restoring one-to-one NAT..." while read external interface internal allints localnat; do expandv external interface internal allints localnat @@ -1604,31 +1914,35 @@ setup_nat() { iface=${interface%:*} if [ -n "$ADD_IP_ALIASES" ]; then - qt ip addr del $external dev $iface + run_and_save_command qt ip addr del $external dev $iface fi - if [ -z "$allints" -o "$allints" = "Yes" -o "$allints" = "yes" ] - then + 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 - if [ "$localnat" = "Yes" -o "$localnat" = "yes" ]; then - run_iptables2 -t nat -A OUTPUT -d $external \ - -j DNAT --to-destination $internal - fi - else - addnatrule `input_chain $iface` \ + 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` \ + 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 - echo " Host $internal NAT $external on $interface" + progress_message " Host $internal NAT $external on $interface" done < $TMP_DIR/nat } @@ -1650,6 +1964,34 @@ delete_nat() { [ -d ${STATEDIR} ] && touch ${STATEDIR}/nat } +# +# Setup Network Mapping (NETMAP) +# +setup_netmap() { + + while read type net1 interface net2 ; do + expandv type net1 interface net2 + + list_search $interface $all_interfaces || \ + fatal_error "Unknown interface $interface in entry \"$type $net1 $interface $net2\"" + + case $type in + DNAT) + addnatrule $(input_chain $interface) -d $net1 -j NETMAP --to $net2 + ;; + SNAT) + addnatrule $(output_chain $interface) -s $net1 -j NETMAP --to $net2 + ;; + *) + fatal_error "Invalid type $type in entry \"$type $net1 $interface $net2\"" + ;; + esac + + progress_message " Network $net1 on $interface mapped to $net2 ($type)" + + done < $TMP_DIR/netmap +} + # # Setup ECN disabling rules # @@ -1670,16 +2012,16 @@ setup_ecn() # $1 = file name list_search $interface $interfaces || \ interfaces="$interfaces $interface" [ "x$host" = "x-" ] && host= - for h in `separate_list ${host:-0.0.0.0/0}`; do + for h in $(separate_list ${host:-0.0.0.0/0}); do hosts="$hosts $interface:$h" done done < $TMP_DIR/ecn if [ -n "$interfaces" ]; then - echo "Setting up ECN control on${interfaces}..." + progress_message "Setting up ECN control on${interfaces}..." for interface in $interfaces; do - chain=`ecn_chain $interface` + chain=$(ecn_chain $interface) if mangle_chain_exists $chain; then flushmangle $chain else @@ -1692,8 +2034,8 @@ 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 - echo " ECN Disabled to $h through $interface" + run_iptables -t mangle -A $(ecn_chain $interface) -p tcp -d $h -j ECN --ecn-tcp-remove + progress_message " ECN Disabled to $h through $interface" done fi } @@ -1715,17 +2057,15 @@ process_tc_rule() r="-s $source " ;; ~*) - r="`mac_match $source` " + r="$(mac_match $source) " ;; $FW) chain=tcout ;; *) - if ! list_search $source $all_interfaces; then - fatal_error "Unknown interface $source in rule \"$rule\"" - fi - - r="-i $source " + + verify_interface $source || fatal_error "Unknown interface $source in rule \"$rule\"" + r="$(match_source_dev) $source " ;; esac fi @@ -1750,6 +2090,8 @@ process_tc_rule() 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 " [ "x$sport" = "x-" ] || r="${r}--sport $sport " @@ -1778,17 +2120,17 @@ process_tc_rule() mark="${mark%:*}" fi - for source in `separate_list ${sources:=-}`; do - for dest in `separate_list ${dests:=-}`; do - for port in `separate_list ${ports:=-}`; do - for sport in `separate_list ${sports:=-}`; do + for source in $(separate_list ${sources:=-}); do + for dest in $(separate_list ${dests:=-}); do + for port in $(separate_list ${ports:=-}); do + for sport in $(separate_list ${sports:=-}); do add_a_tc_rule done done done done - echo " TC Rule \"$rule\" added" + progress_message " TC Rule \"$rule\" added" } # @@ -1809,7 +2151,7 @@ setup_tc1() { 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"` + rule=$(echo "$mark $sources $dests $proto $ports $sports $user") process_tc_rule done < $TMP_DIR/tcrules # @@ -1822,6 +2164,9 @@ setup_tc1() { run_user_exit tcstart + save_progress_message "Restoring Traffic Control..." + save_command . $(find_file tcstart) + } setup_tc() { @@ -1838,8 +2183,34 @@ delete_tc() { clear_one_tc() { - tc qdisc del dev $1 root 2> /dev/null + run_and_save_command "tc qdisc del dev $1 root 2> /dev/null" + run_and_save_command "tc qdisc del dev $1 ingress 2> /dev/null" + + } + + save_progress_message "Clearing Traffic Control/QOS" + + run_user_exit tcclear + + run_ip link list | \ + while read inx interface details; do + case $inx in + [0-9]*) + clear_one_tc ${interface%:} + ;; + *) + ;; + esac + done +} + +delete_tc1() +{ + + clear_one_tc() { + tc qdisc del dev $1 root 2> /dev/null tc qdisc del dev $1 ingress 2> /dev/null + } run_user_exit tcclear @@ -1868,6 +2239,14 @@ process_accounting_rule() { error_message "Warning: Invalid Accounting rule" $action $chain $source $dest $proto $port $sport } + accounting_interface_error() { + error_message "Warning: Unknown interface $1 in " $action $chain $source $dest $proto $port $sport + } + + accounting_interface_verify() { + verify_interface $1 || accounting_interface_error $1 + } + jump_to_chain() { if ! havechain $jumpchain; then if ! createchain2 $jumpchain No; then @@ -1881,7 +2260,8 @@ process_accounting_rule() { case $source in *:*) - rule="-s ${source#*:} -i ${source%:*}" + accounting_interface_verify ${source%:*} + rule="-s ${source#*:} $(match_source_dev ${source%:*})" ;; *.*.*.*) rule="-s $source" @@ -1889,13 +2269,17 @@ process_accounting_rule() { -|all|any) ;; *) - [ -n "$source" ] && rule="-i $source" + if [ -n "$source" ]; then + accounting_interface_verify $source + rule="$(match_source_dev $source)" + fi ;; esac [ -n "$dest" ] && case $dest in *:*) - rule="$rule -d ${dest#*:} -o ${dest%:*}" + accounting_interface_verify ${dest%:*} + rule="$rule -d ${dest#*:} $(match_dest_dev ${dest%:*})" ;; *.*.*.*) rule="$rule -d $dest" @@ -1903,7 +2287,8 @@ process_accounting_rule() { -|all|any) ;; *) - rule="$rule -o $dest" + accounting_interface_verify $dest + rule="$rule $(match_dest_dev $dest)" ;; esac @@ -1955,11 +2340,11 @@ process_accounting_rule() { [ "x$chain" = "x-" ] && chain=accounting [ -z "$chain" ] && chain=accounting - havechain $chain || createchain $chain No + ensurechain1 $chain - if iptables -A $chain $rule ; then - [ "x$rule2" != x ] && run_iptables -A $jumpchain $rule2 - echo " Accounting rule" $action $chain $source $dest $proto $port $sport Added + 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 else accounting_error fi @@ -1988,82 +2373,6 @@ setup_accounting() # $1 = Name of accounting file } -process_user_set_entry() { - local acceptchain=`accept_chain $userset` - local dropchain=`drop_chain $userset` - local rejectchain=`reject_chain $userset` - - list_search $userset $usersets && \ - fatal_error "Duplicate Uset Set: $userset" - usersets="$usersets $userset" - - createchain $acceptchain No - createchain $dropchain No - createchain $rejectchain No - - [ "x$reject" = "x-" ] && reject="" - eval ${userset}_reject="$reject" - [ "x$accept" = "x-" ] && accept="" - eval ${userset}_accept="$accept" - [ "x$drop" = "x-" ] && drop="" - eval ${userset}_drop="$drop" -} - -process_user_entry() { - local acceptchain=`accept_chain $userset` - local dropchain=`drop_chain $userset` - local rejectchain=`reject_chain $userset` - local rule="-m owner" - local level= - - list_search $userset $usersets || \ - fatal_error "Unknown Uset Set: $userset" - - [ "x$user" = "x-" ] && user= - - [ -z "${user}${group}" ] && \ - fatal_error "Either user or group must be specified for user set $userset" - - [ -n "$user" ] && rule="$rule --uid-owner $user" || user='*' - [ -n "$group" ] && rule="$rule --gid-owner $group" || group='*' - - eval level=\$${userset}_accept - [ -n "$level" ] && \ - log_rule $level $acceptchain ACCEPT $rule - run_iptables -A $acceptchain $rule -j ACCEPT - - eval level=\$${userset}_drop - [ -n "$level" ] && \ - log_rule $level $dropchain DROP $rule - run_iptables -A $dropchain $rule -j DROP - - eval level=\$${userset}_reject - [ -n "$level" ] && \ - log_rule $level $rejectchain REJECT $rule - run_iptables -A $rejectchain $rule -j reject - - echo " User $user:$group added to user set $userset" -} - -setup_usersets() # $1 = Name of usersets file -{ - echo "Setting up User Sets..." - - strip_file usersets $1 - - while read userset reject accept drop; do - expandv userset reject accept drop - process_user_set_entry - done < $TMP_DIR/usersets - - strip_file users - - while read userset user group ; do - expandv userset user group - process_user_entry - done < $TMP_DIR/users -} - # # Check the configuration # @@ -2085,8 +2394,6 @@ check_config() { verify_os_version - load_kernel_modules - echo "Determining Zones..." determine_zones @@ -2112,17 +2419,22 @@ check_config() { validate_policy - echo "Validating Actions..." + echo "Pre-validating Actions..." - process_actions + process_actions1 echo "Validating rules file..." - rules=`find_file rules` + rules=$(find_file rules) strip_file rules $rules process_rules + echo "Validating Actions..." + + process_actions2 + rm -rf $TMP_DIR + [ -n "$RESTOREBASE" ] && rm -f $RESTOREBASE echo "Configuration Validated" @@ -2137,7 +2449,7 @@ refresh_tc() { echo "Refreshing Traffic Control Rules..." - [ -n "$CLEAR_TC" ] && delete_tc + [ -n "$CLEAR_TC" ] && delete_tc1 [ -n "$MARK_IN_FORWARD_CHAIN" ] && chain=tcfor || chain=tcpre @@ -2155,7 +2467,7 @@ refresh_tc() { while read mark sources dests proto ports sports; do expandv mark sources dests proto ports sports - rule=`echo "$mark $sources $dests $proto $ports $sports"` + rule=$(echo "$mark $sources $dests $proto $ports $sports") process_tc_rule done < $TMP_DIR/tcrules @@ -2170,17 +2482,19 @@ 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' -# which only goes through the motions. -# client = SOURCE IP or MAC -# server = DESTINATION IP or interface -# protocol = Protocol -# address = Original Destination Address -# port = Destination Port -# cport = Source Port -# multioption = String to invoke multiport match if appropriate -# action = The chain for this rule -# ratelimit = Optional rate limiting clause +# check = 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 +# protocol = Protocol +# address = Original Destination Address +# port = Destination Port +# cport = Source Port +# multioption = String to invoke multiport match if appropriate +# action = The chain for this rule +# ratelimit = Optional rate limiting clause +# userandgroup = owner match clause +# logtag = Log tag # add_an_action() { @@ -2204,6 +2518,16 @@ add_an_action() fi } + interface_error() + { + fatal_error "Unknown interface $1 in rule: \"$rule\"" + } + + action_interface_verify() + { + verify_interface $1 || interface_error $1 + } + # Set source variables. The 'cli' variable will hold the client match predicate(s). cli= @@ -2212,16 +2536,20 @@ add_an_action() -) ;; *:*) - cli="-i ${client%:*} -s ${client#*:}" + action_interface_verify ${client%:*} + cli="$(match_source_dev ${client%:*}) -s ${client#*:}" ;; *.*.*) cli="-s $client" ;; ~*) - cli=`mac_match $client` + cli=$(mac_match $client) ;; *) - [ -n "$client" ] && cli="-i $client" + if [ -n "$client" ]; then + action_interface_verify $client + cli="$(match_source_dev $client)" + fi ;; esac @@ -2240,7 +2568,10 @@ add_an_action() fatal_error "Rule \"$rule\" - Destination may not be specified by MAC Address" ;; *) - [ -n "$server" ] && dest_interface="-o $server" + if [ -n "$server" ]; then + action_interface_verify $server + dest_interface="$(match_dest_dev $server)" + fi ;; esac @@ -2248,7 +2579,6 @@ add_an_action() sports= dports= - state="-m state --state NEW" proto=$protocol servport=$serverport multiport= @@ -2266,15 +2596,8 @@ add_an_action() ;; icmp|ICMP|1) [ -n "$port" ] && dports="--icmp-type $port" - state= - ;; - all|ALL) - [ -n "$port" ] && \ - fatal_error "Port number not allowed with protocol \"all\"; rule: \"$rule\"" - proto= ;; *) - state= [ -n "$port" ] && \ fatal_error "Port number not allowed with protocol \"$proto\"; rule: \"$rule\"" ;; @@ -2290,27 +2613,27 @@ add_an_action() ;; esac - if [ $command != check ]; then + if [ $COMMAND != check ]; then if [ -n "${serv}" ]; then - for serv1 in `separate_list $serv`; do - for srv in `ip_range $serv1`; do + for serv1 in $(separate_list $serv); do + for srv in $(ip_range $serv1); do if [ -n "$loglevel" ]; then - log_rule_limit $loglevel $action $logtarget "$ratelimit" \ - `fix_bang $proto $sports $multiport $state $cli -d $srv $dports` + log_rule_limit $loglevel $action $logtarget "$ratelimit" "$logtag" $userandgroup \ + $(fix_bang $proto $sports $multiport $cli -d $srv $dports) fi - run_iptables2 -A $action $proto $multiport $state $cli $sports \ - -d $srv $dports $ratelimit -j $target + run_iptables2 -A $action $proto $multiport $cli $sports \ + -d $srv $dports $ratelimit $userandgroup -j $target done done else if [ -n "$loglevel" ]; then - log_rule_limit $loglevel $action $logtarget "$ratelimit" \ - `fix_bang $proto $sports $multiport $state $cli $dports` + log_rule_limit $loglevel $action $logtarget "$ratelimit" "$logtag" $userandgroup \ + $(fix_bang $proto $sports $multiport $cli $dest_interface $dports) fi - run_iptables2 -A $action $proto $multiport $state $cli $sports \ - $dports $ratelimit -j $target + run_iptables2 -A $action $proto $multiport $cli $dest_interface $sports \ + $dports $ratelimit $userandgroup -j $target fi fi } @@ -2319,13 +2642,14 @@ add_an_action() # Process a record from an action file for the 'start', 'restart' or 'check' commands # process_action() # $1 = action - # $1 = target - # $2 = clients - # $3 = servers - # $4 = protocol - # $5 = ports - # $6 = cports - # $7 = ratelimit + # $2 = target + # $3 = clients + # $4 = servers + # $5 = protocol + # $6 = ports + # $7 = cports + # $8 = ratelimit + # $9 = userspec { local action="$1" local target="$2" @@ -2335,7 +2659,10 @@ process_action() # $1 = action local ports="$6" local cports="$7" local ratelimit="$8" - local rule="`echo $target $clients $servers $protocol $ports $cports $ratelimit`" + local userspec="$9" + local rule="$(echo $target $clients $servers $protocol $ports $cports $ratelimit)" + local userandgroup= + local logtag= if [ -n "$ratelimit" ]; then case $ratelimit in @@ -2351,24 +2678,63 @@ process_action() # $1 = action esac fi + [ "x$userspec" = "x-" ] && userspec= + + if [ -n "$userspec" ]; then + case "$userspec" in + !*:*) + if [ "$userspec" != "!:" ]; then + userandgroup="-m owner" + temp="${userspec#!}" + temp="${temp%:*}" + [ -n "$temp" ] && userandgroup="$userandgroup ! --uid-owner $temp" + temp="${userspec#*:}" + [ -n "$temp" ] && userandgroup="$userandgroup ! --gid-owner $temp" + fi + ;; + *:*) + if [ "$userspec" != ":" ]; then + userandgroup="-m owner" + temp="${userspec%:*}" + [ -n "$temp" ] && userandgroup="$userandgroup --uid-owner $temp" + temp="${userspec#*:}" + [ -n "$temp" ] && userandgroup="$userandgroup --gid-owner $temp" + fi + ;; + !*) + userandgroup="-m owner ! --uid-owner ${userspec#!}" + ;; + *) + userandgroup="-m owner --uid-owner $userspec" + ;; + esac + fi + # Isolate log level if [ "$target" = "${target%:*}" ]; then loglevel= else loglevel="${target#*:}" - target="${target%:*}" + target="${target%%:*}" expandv loglevel + if [ "$loglevel" != "${loglevel%:*}" ]; then + logtag="${loglevel#*:}" + loglevel="${loglevel%:*}" + expandv logtag + fi + fi - + logtarget="$target" case $target in - ACCEPT|LOG) - ;; REJECT) target=reject ;; + CONTINUE) + target=RETURN + ;; *) ;; esac @@ -2381,18 +2747,18 @@ process_action() # $1 = action ! list_search $protocol "icmp" "ICMP" "1" && \ [ "$ports" = "${ports%:*}" -a \ "$cports" = "${cports%:*}" -a \ - `list_count $ports` -le 15 -a \ - `list_count $cports` -le 15 ] + $(list_count $ports) -le 15 -a \ + $(list_count $cports) -le 15 ] then # # MULTIPORT is enabled, there are no port ranges in the rule and less than # 16 ports are listed - use multiport match. # multioption="-m multiport" - for client in `separate_list ${clients:=-}`; do - for server in `separate_list ${servers:=-}`; do + for client in $(separate_list ${clients:=-}); do + for server in $(separate_list ${servers:=-}); do # - # add_a_rule() modifies these so we must set their values each time + # add_an_action() modifies these so we must set their values each time # port=${ports:=-} cport=${cports:=-} @@ -2404,10 +2770,10 @@ process_action() # $1 = action # MULTIPORT is disabled or the rule isn't compatible with multiport match # multioption= - for client in `separate_list ${clients:=-}`; do - for server in `separate_list ${servers:=-}`; do - for port in `separate_list ${ports:=-}`; do - for cport in `separate_list ${cports:=-}`; do + for client in $(separate_list ${clients:=-}); do + for server in $(separate_list ${servers:=-}); do + for port in $(separate_list ${ports:=-}); do + for cport in $(separate_list ${cports:=-}); do add_an_action done done @@ -2417,96 +2783,190 @@ process_action() # $1 = action # # Report Result # - if [ $command = check ]; then - echo " Rule \"$rule\" checked." + if [ $COMMAND = check ]; then + progress_message " Rule \"$rule\" checked." else - echo " Rule \"$rule\" added." + progress_message " Rule \"$rule\" added." fi } # -# Read /etc/shorewall/actions and for each defined , process +# Create an action chain and run it's associated user exit +# + +createactionchain() # $1 = chain name +{ + createchain $1 no + run_user_exit $1 +} + +# +# Read /etc/shorewall/actions and for each defined , pre-process # /etc/shorewall/action. # -process_actions() { - # - # Process a rule where the source or destination is "all" - # - process_wildcard_rule() { - local yclients yservers ysourcezone ydestzone ypolicy +process_actions1() { - for yclients in $xclients; do - for yservers in $xservers; do - ysourcezone=${yclients%%:*} - ydestzone=${yservers%%:*} - if [ "${ysourcezone}" != "${ydestzone}" ] ; then - eval ypolicy=\$${ysourcezone}2${ydestzone}_policy - if [ "$ypolicy" != NONE ] ; then - process_action $xaction $xtarget $yclients $yservers $xprotocol $xports $xcports $xratelimit - fi - fi - done - done - } - - do_it() { - expandv xclients xservers xprotocol xports xcports xratelimit - - if [ "x$xclients" = xall ]; then - xclients="$zones $FW" - if [ "x$xservers" = xall ]; then - xservers="$zones $FW" - fi - process_wildcard_rule - continue - fi - - if [ "x$xservers" = xall ]; then - xservers="$zones $FW" - process_wildcard_rule - continue - fi - - process_action $xaction $xtarget $xclients $xservers $xprotocol $xports $xcports $xratelimit - } + ACTIONS="dropBcast dropNonSyn dropNotSyn rejNotSyn logNotSyn rLogNotSyn dLogNotSyn dropInvalid allowInvalid" + USEDACTIONS= strip_file actions - while read xaction rest; do - [ "x$rest" = x ] || fatal_error "Invalid Action: $xaction $rest" - [ "$command" = check ] || createchain $xaction No + strip_file actions.std /usr/share/shorewall/actions.std - f=action.$xaction - fn=`find_file $f` + for inputfile in actions.std actions; do + while read xaction rest; do + [ "x$rest" = x ] || fatal_error "Invalid Action: $xaction $rest" - if [ -f $fn ]; then - echo "Processing $fn..." - strip_file $f $fn - while read xtarget xclients xservers xprotocol xports xcports xratelimit ; do - expandv xtarget - temp="${xtarget%:*}" - case "${temp%<*}" in - ACCEPT|DROP|REJECT|LOG|QUEUE) - do_it - ;; - *) - if list_search $temp $ACTIONS; then - do_it - else - rule="`echo $xtarget $xclients $xservers $xprotocol $xports $xcports $xratelimit`" - fatal_error "Invalid TARGET in rule \"$rule\"" + case $xaction in + *:*) + temp=${xaction#*:} + 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" + ;; + esac + esac + + [ -z "$xaction" ] && continue + + [ "$xaction" = "$(chain_base $xaction)" ] || fatal_error "Invalid Action Name: $xaction" + + if ! list_search $xaction $ACTIONS; then + f=action.$xaction + fn=$(find_file $f) + + eval requiredby_${action}= + + if [ -f $fn ]; then + echo " Pre-processing $fn..." + strip_file $f $fn + while read xtarget xclients xservers xprotocol xports xcports xratelimit $xuserspec; do + expandv xtarget + temp="${xtarget%%:*}" + case "${temp%<*}" in + ACCEPT|DROP|REJECT|LOG|QUEUE|CONTINUE) + ;; + *) + if list_search $temp $ACTIONS; then + eval requiredby_${xaction}=\"\$requiredby_${xaction} $temp\" + else + rule="$(echo $xtarget $xclients $xservers $xprotocol $xports $xcports $xratelimit $xuserspec)" + fatal_error "Invalid TARGET in rule \"$rule\"" + fi + ;; + + esac + done < $TMP_DIR/$f + else + fatal_error "Missing Action File: $f" + fi + + ACTIONS="$ACTIONS $xaction" + fi + 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 + } + + 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 + changed=Yes + fi + done + done + done + # + # Now process the relevant action files -- they were already stripped in process_actions1() above. + # + for xaction in $USEDACTIONS; do + case $xaction 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 - ;; - - esac - done < $TMP_DIR/$f - else - fatal_error "Missing Action File: $f" - fi - - ACTIONS="$ACTIONS $xaction" - done < $TMP_DIR/actions + else + drop_broadcasts + fi + fi + ;; + dropNonSyn) + error_message "WARNING: \"dropNonSyn\" has been replaced by \"dropNotSyn\"" + [ "$COMMAND" != check ] && run_iptables -A dropNonSyn -p tcp ! --syn -j DROP + ;; + + dropNotSyn) + [ "$COMMAND" != check ] && run_iptables -A dropNotSyn -p tcp ! --syn -j DROP + ;; + 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 + ;; + dropInvalid) + [ "$COMMAND" != check ] && run_iptables -A dropInvalid -m state --state INVALID -j DROP + ;; + allowInvalid) + [ "$COMMAND" != check ] && run_iptables -A dropInvalid -m state --state INVALID -j ACCEPT + ;; + *) + f=action.$xaction + fn=$(find_file $f) + + 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 + done < $TMP_DIR/$f + ;; + esac + done } # @@ -2526,6 +2986,8 @@ process_actions() { # cport = Source Port Specification # multiport = String to invoke multiport match if appropriate # ratelimit = Optional rate limiting clause +# userandgroup = -m owner match to limit the rule to a particular user and/or group +# logtag = Log tag # add_nat_rule() { local chain @@ -2557,13 +3019,13 @@ 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_interface_address $interface) done fi ;; !*) - if [ `list_count $addr` -gt 1 ]; then - excludedests="`separate_list ${addr#\!}`" + if [ $(list_count $addr) -gt 1 ]; then + excludedests="$(separate_list ${addr#\!})" addr= fi ;; @@ -2576,7 +3038,7 @@ add_nat_rule() { if [ -n "$serv" ]; then servport="${servport:+:$servport}" serv1= - for srv in `separate_list $serv`; do + for srv in $(separate_list $serv); do serv1="$serv1 --to-destination ${srv}${servport}" done target1="DNAT $serv1" @@ -2590,15 +3052,15 @@ add_nat_rule() { # Generate nat table rules - if [ $command != check ]; then + if [ $COMMAND != check ]; then if [ "$source" = "$FW" ]; then if [ -n "$excludedests" ]; then chain=nonat${nonat_seq} nonat_seq=$(($nonat_seq + 1)) createnatchain $chain - for adr in `separate_list $addr`; do - run_iptables2 -t nat -A OUTPUT $cli $proto $multiport $sports $dports -d $adr -j $chain + for adr in $(separate_list $addr); do + run_iptables2 -t nat -A OUTPUT $cli $proto $userandgroup $multiport $sports $dports -d $adr -j $chain done for adr in $excludedests; do @@ -2611,31 +3073,31 @@ add_nat_rule() { addnatrule $chain $ratelimit $proto -j $target1 # Protocol is necessary for port redirection else - for adr in `separate_list $addr`; do + for adr in $(separate_list $addr); do if [ -n "$loglevel" ]; then - log_rule_limit $loglevel $OUTPUT $logtarget "$ratelimit" -t nat \ - `fix_bang $proto $cli $sports -d $adr $multiport $dports` + log_rule_limit $loglevel OUTPUT $logtarget "$ratelimit" "$logtag" -t nat \ + $(fix_bang $proto $cli $sports $userandgroup -d $adr $multiport $dports) fi - run_iptables2 -t nat -A OUTPUT $ratelimit $proto $sports -d $adr $multiport $dports -j $target1 + run_iptables2 -t nat -A OUTPUT $ratelimit $proto $sports $userandgroup -d $adr $multiport $dports -j $target1 done fi else - chain=`dnat_chain $source` + chain=$(dnat_chain $source) if [ -n "${excludezones}${excludedests}" ]; then chain=nonat${nonat_seq} nonat_seq=$(($nonat_seq + 1)) createnatchain $chain - for adr in `separate_list $addr`; do - addnatrule `dnat_chain $source` $cli $proto $multiport $sports $dports -d $adr -j $chain + for adr in $(separate_list $addr); do + addnatrule $(dnat_chain $source) $cli $proto $multiport $sports $dports -d $adr -j $chain done for z in $(separate_list $excludezones); do eval hosts=\$${z}_hosts for host in $hosts; do - addnatrule $chain -s ${host#*:} -j RETURN + addnatrule $chain $(match_source_hosts ${host#*:}) -j RETURN done done @@ -2644,16 +3106,16 @@ add_nat_rule() { done if [ -n "$loglevel" ]; then - log_rule_limit $loglevel $chain $logtarget "$ratelimit" -t nat + log_rule_limit $loglevel $chain $logtarget "$ratelimit" "$logtag" -t nat fi addnatrule $chain $ratelimit $proto -j $target1 # Protocol is necessary for port redirection else - for adr in `separate_list $addr`; do + for adr in $(separate_list $addr); do if [ -n "$loglevel" ]; then ensurenatchain $chain - log_rule_limit $loglevel $chain $logtarget "$ratelimit" -t nat \ - `fix_bang $proto $cli $sports -d $adr $multiport $dports` + log_rule_limit $loglevel $chain $logtarget "$ratelimit" "$logtag" -t nat \ + $(fix_bang $proto $cli $sports -d $adr $multiport $dports) fi addnatrule $chain $proto $ratelimit $cli $sports \ @@ -2677,15 +3139,15 @@ add_nat_rule() { if [ -n "$snat" ]; then if [ -n "$cli" ]; then - [ $command = check ] || addnatrule `snat_chain $dest` $proto $cli $multiport \ + [ $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` \ - -s ${source_host#*:} $proto $sports $multiport \ + [ $COMMAND = check ] || addnatrule $(snat_chain $dest) \ + $(match_source_hosts ${source_host#*:}) $proto $sports $multiport \ -d $serv $dports -j SNAT --to-source $snat done fi @@ -2699,7 +3161,7 @@ add_nat_rule() { # Add one Filter Rule -- Helper function for the rules 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 @@ -2712,7 +3174,8 @@ add_nat_rule() { # chain = The canonical chain for this rule # ratelimit = Optional rate limiting clause # userandgroup= -m owner clause -# userset = User set name +# userspec = User name +# logtag = Log tag # add_a_rule() { @@ -2738,6 +3201,16 @@ add_a_rule() fi } + interface_error() + { + fatal_error "Unknown interface $1 in rule: \"$rule\"" + } + + rule_interface_verify() + { + verify_interface $1 || interface_error $1 + } + # Set source variables. The 'cli' variable will hold the client match predicate(s). cli= @@ -2746,16 +3219,20 @@ add_a_rule() -) ;; *:*) - cli="-i ${client%:*} -s ${client#*:}" + rule_interface_verify ${client%:*} + cli="$(match_source_dev ${client%:*}) -s ${client#*:}" ;; *.*.*) cli="-s $client" ;; ~*) - cli=`mac_match $client` + cli=$(mac_match $client) ;; *) - [ -n "$client" ] && cli="-i $client" + if [ -n "$client" ]; then + rule_interface_verify $client + cli="$(match_source_dev $client)" + fi ;; esac @@ -2774,7 +3251,11 @@ add_a_rule() fatal_error "Rule \"$rule\" - Destination may not be specified by MAC Address" ;; *) - [ -n "$server" ] && dest_interface="-o $server" + if [ -n "$server" ]; then + [ -n "$nonat" ] && fatal_error "Destination interface not allowed with $logtarget" + rule_interface_verify $server + dest_interface="$(match_dest_dev $server)" + fi ;; esac @@ -2782,7 +3263,6 @@ add_a_rule() sports= dports= - state="-m state --state NEW" proto=$protocol addr=$address servport=$serverport @@ -2801,7 +3281,6 @@ add_a_rule() ;; icmp|ICMP|1) [ -n "$port" ] && dports="--icmp-type $port" - state= ;; all|ALL) [ -n "$port" ] && \ @@ -2809,7 +3288,6 @@ add_a_rule() proto= ;; *) - state= [ -n "$port" ] && \ fatal_error "Port number not allowed with protocol \"$proto\"; rule: \"$rule\"" ;; @@ -2820,10 +3298,13 @@ add_a_rule() # Some misc. setup case "$logtarget" in - REJECT) - [ -n "$servport" ] && \ - fatal_error "Server port may not be specified in a REJECT rule;"\ - "rule: \"$rule\"" + 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"\ @@ -2841,19 +3322,8 @@ add_a_rule() ;; esac - # Complain if the rule is really a policy - - case $logtarget in - ACCEPT|DROP|REJECT) - 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 - ;; - esac - if [ -n "${serv}${servport}" ]; then - if [ $command != check ]; then + if [ $COMMAND != check ]; then # A specific server or server port given @@ -2863,39 +3333,49 @@ add_a_rule() fatal_error "Only DNAT and REDIRECT rules may specify destination mapping; rule \"$rule\"" fi - if [ -z "$dnat_only" -a $chain != ${FW}2${FW} ]; then + if [ -z "$dnat_only" ]; then if [ -n "$serv" ]; then - for serv1 in `separate_list $serv`; do - for srv in `ip_range $serv1`; do + for serv1 in $(separate_list $serv); do + for srv in $(ip_range $serv1); do if [ -n "$addr" -a -n "$CONNTRACK_MATCH" ]; then - for adr in `separate_list $addr`; do + for adr in $(separate_list $addr); do if [ -n "$loglevel" -a -z "$natrule" ]; then - log_rule_limit $loglevel $chain $logtarget "$ratelimit" -m conntrack --ctorigdst $adr \ - $userandgroup `fix_bang $proto $sports $multiport $state $cli -d $srv $dports` + log_rule_limit $loglevel $chain $logtarget "$ratelimit" "$logtag" -m conntrack --ctorigdst $adr \ + $userandgroup $(fix_bang $proto $sports $multiport $cli -d $srv $dports) fi - run_iptables2 -A $chain $proto $ratelimit $multiport $state $cli $sports \ + run_iptables2 -A $chain $proto $ratelimit $multiport $cli $sports \ -d $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" $userandgroup \ - `fix_bang $proto $sports $multiport $state $cli -d $srv $dports` + log_rule_limit $loglevel $chain $logtarget "$ratelimit" "$logtag" $userandgroup \ + $(fix_bang $proto $sports $multiport $cli -d $srv $dports) fi + + [ -n "$nonat" ] && \ + addnatrule $(dnat_chain $source) $proto $multiport \ + $cli $sports -d $srv $dports $ratelimit $userandgroup -j RETURN - run_iptables2 -A $chain $proto $multiport $state $cli $sports \ - -d $srv $dports $ratelimit $userandgroup -j $target + [ "$logtarget" != NONAT ] && \ + run_iptables2 -A $chain $proto $multiport $cli $sports \ + -d $srv $dports $ratelimit $userandgroup -j $target fi done done else if [ -n "$loglevel" -a -z "$natrule" ]; then - log_rule_limit $loglevel $chain $logtarget "$ratelimit" $userandgroup \ - `fix_bang $proto $sports $multiport $state $cli $dports` + log_rule_limit $loglevel $chain $logtarget "$ratelimit" "$logtag" $userandgroup \ + $(fix_bang $proto $sports $multiport $cli $dports) fi - run_iptables2 -A $chain $proto $multiport $state $cli $sports \ - $dports $ratelimit $userandgroup -j $target + [ -n "$nonat" ] && \ + addnatrule $(dnat_chain $source) $proto $multiport \ + $cli $sports $dports $ratelimit $userandgroup -j RETURN + + [ "$logtarget" != NONAT ] && \ + run_iptables2 -A $chain $proto $multiport $cli $sports \ + $dports $ratelimit $userandgroup -j $target fi fi fi @@ -2907,15 +3387,20 @@ add_a_rule() "An ORIGINAL DESTINATION ($addr) is only allowed in" \ " a DNAT or REDIRECT: \"$rule\"" - if [ $command != check ]; then + if [ $COMMAND != check ]; then if [ -n "$loglevel" ]; then - log_rule_limit $loglevel $chain $logtarget "$ratelimit" $userandgroup \ - `fix_bang $proto $multiport $dest_interface $state $cli $sports $dports` + log_rule_limit $loglevel $chain $logtarget "$ratelimit" "$logtag" $userandgroup \ + $(fix_bang $proto $multiport $cli $dest_interface $sports $dports) fi - if [ $logtarget != LOG ]; then - run_iptables2 -A $chain $proto $multiport $dest_interface $state \ - $cli $sports $dports $ratelimit $userandgroup -j $target + if [ "$logtarget" != LOG ]; then + [ -n "$nonat" ] && \ + addnatrule $(dnat_chain $source) $proto $multiport \ + $cli $sports $dports $ratelimit $userandgroup -j RETURN + + [ "$logtarget" != NONAT ] && \ + run_iptables2 -A $chain $proto $multiport $cli $dest_interface \ + $sports $dports $ratelimit $userandgroup -j $target fi fi fi @@ -2932,7 +3417,7 @@ process_rule() # $1 = target # $6 = cports # $7 = address # $8 = ratelimit - # $9 = userset + # $9 = userspec { local target="$1" local clients="$2" @@ -2942,23 +3427,16 @@ process_rule() # $1 = target local cports="$6" local address="$7" local ratelimit="$8" - local userset="$9" + local userspec="$9" local userandgroup= - local rule="`echo $target $clients $servers $protocol $ports $cports $address $ratelimit $userset`" + local rule="$(echo $target $clients $servers $protocol $ports $cports $address $ratelimit $userspec)" + local logtag= + local nonat= # Function Body - isolate rate limit [ "x$ratelimit" = "x-" ] && ratelimit= - if [ -z "$ratelimit" ]; then - if [ "$target" != "${target%<*}" ]; then - ratelimit="${target#*<}" - ratelimit="${ratelimit%>*}" - target="${target%<*}${target#*>}" - expandv ratelimit - fi - fi - if [ -n "$ratelimit" ]; then case $ratelimit in *:*) @@ -2976,126 +3454,96 @@ process_rule() # $1 = target loglevel= else loglevel="${target#*:}" - target="${target%:*}" + target="${target%%:*}" expandv loglevel + if [ "$loglevel" != "${loglevel%:*}" ]; then + logtag="${loglevel#*:}" + loglevel="${loglevel%:*}" + expandv logtag + fi + fi - - logtarget="$target" - dnat_only= + # + # Save the original target in 'logtarget' for logging rules + # + logtarget=${target%-} + # + # Targets ending in "-" only apply to the nat table + # + [ $target = $logtarget ] && dnat_only= || dnat_only=Yes # Tranform the rule: # - # - parse the user set specification + # - parse the user specification # - set 'target' to the filter table target. # - make $FW the destination for REDIRECT # - remove '-' suffix from logtargets while setting 'dnat_only' # - clear 'address' if it has been set to '-' - [ "x$userset" = x- ] && userset= + [ "x$userspec" = x- ] && userspec= [ "x$address" = "x-" ] && address= - if [ -n "$userset" ]; then - case "$userset" in - *:*) - case $target in - ACCEPT) - ;; - REJECT|DROP) - [ -n "$ratelimit" ] && fatal_error \ - "Rate Limiting only available with ACCEPT, DNAT[-], REDIRECT[-] and LOG" - ;; - *) - fatal_error ": may only be specified in ACCEPT, REJECT and DROP rules: rule \"$rule\"" - ;; - esac - - if [ "$userset" != ":" ]; then + if [ -n "$userspec" ]; then + case "$userspec" in + !*:*) + if [ "$userspec" != "!:" ]; then userandgroup="-m owner" - temp="${userset%:*}" + temp="${userspec#!}" + temp="${temp%:*}" + [ -n "$temp" ] && userandgroup="$userandgroup ! --uid-owner $temp" + temp="${userspec#*:}" + [ -n "$temp" ] && userandgroup="$userandgroup ! --gid-owner $temp" + fi + ;; + *:*) + if [ "$userspec" != ":" ]; then + userandgroup="-m owner" + temp="${userspec%:*}" [ -n "$temp" ] && userandgroup="$userandgroup --uid-owner $temp" - temp="${userset#*:}" + temp="${userspec#*:}" [ -n "$temp" ] && userandgroup="$userandgroup --gid-owner $temp" fi - userset= + ;; + !*) + userandgroup="-m owner ! --uid-owner ${userspec#!}" ;; *) - if ! havechain `accept_chain $userset`; then - fatal_error "Unknown user set $userset: rule \"$rule\"" - fi - - case $target in - ACCEPT) - target=`accept_chain $userset` - ;; - DROP) - [ -n "$ratelimit" ] && fatal_error \ - "Rate Limiting only available with ACCEPT, DNAT[-], REDIRECT[-] and LOG" - target=`drop_chain $userset` - ;; - REJECT) - [ -n "$ratelimit" ] && fatal_error \ - "Rate Limiting only available with ACCEPT, DNAT[-], REDIRECT[-] and LOG" - target=`reject_chain $userset` - ;; - *) - fatal_error "A user set may only be specified in ACCEPT, REJECT and DROP rules: rule \"$rule\"" - esac - - [ -n "$loglevel" ] && \ - fatal_error "Logging may not be specified on a rule with a User Set: rule \"$rule\"" - ;; - esac - else - case $target in - ACCEPT|LOG) - ;; - REJECT) - [ -n "$ratelimit" ] && fatal_error \ - "Rate Limiting only available with ACCEPT, DNAT[-], REDIRECT[-] and LOG" - target=reject - ;; - CONTINUE) - [ -n "$ratelimit" ] && fatal_error \ - "Rate Limiting only available with ACCEPT, DNAT[-], REDIRECT[-] and LOG" - target=RETURN - ;; - DNAT) - target=ACCEPT - address=${address:=detect} - ;; - DNAT-) - target=ACCEPT - address=${address:=detect} - dnat_only=Yes - logtarget=DNAT - ;; - REDIRECT) - target=ACCEPT - address=${address:=all} - if [ "x-" = "x$servers" ]; then - servers=$FW - else - servers="$FW::$servers" - fi - ;; - REDIRECT-) - target=ACCEPT - logtarget=REDIRECT - dnat_only=Yes - address=${address:=all} - if [ "x-" = "x$servers" ]; then - servers=$FW - else - servers="$FW::$servers" - fi - ;; - *) - [ -n "$ratelimit" ] && fatal_error \ - "Rate Limiting only available with ACCEPT, DNAT[-], REDIRECT[-] and LOG" + userandgroup="-m owner --uid-owner $userspec" ;; esac fi + case $target in + ACCEPT+|NONAT) + nonat=Yes + target=ACCEPT + ;; + ACCEPT|LOG) + ;; + DROP) + [ -n "$ratelimit" ] && fatal_error "Rate Limiting not available with DROP" + ;; + REJECT) + target=reject + ;; + CONTINUE) + target=RETURN + ;; + DNAT*) + target=ACCEPT + address=${address:=detect} + ;; + REDIRECT*) + target=ACCEPT + address=${address:=all} + if [ "x-" = "x$servers" ]; then + servers=$FW + else + servers="$FW::$servers" + fi + ;; + esac + # Parse and validate source if [ "$clients" = "${clients%:*}" ]; then @@ -3126,8 +3574,8 @@ process_rule() # $1 = target if [ $source = $FW ]; then source_hosts= - elif [ -n "$userset" ]; then - fatal_error "Invalid use of a user set: rule \"$rule\"" + elif [ -n "$userspec" ]; then + fatal_error "Invalid use of a user-qualification: rule \"$rule\"" else eval source_hosts=\"\$${source}_hosts\" fi @@ -3169,26 +3617,9 @@ process_rule() # $1 = target [ $policy = NONE ] && \ fatal_error "Rules may not override a NONE policy: rule \"$rule\"" - # Be sure that this isn't a fw->fw rule. - - if [ "x$chain" = x${FW}2${FW} ]; then - case $logtarget in - REDIRECT|DNAT) - # - # Redirect rules that have the firewall as the source are fw->fw rules - # - ;; - *) - error_message "WARNING: fw -> fw rules are not supported; rule \"$rule\" ignored" - return - ;; - esac - else - - # Create the canonical chain if it doesn't already exist + # Create the canonical chain if it doesn't already exist - [ $command = check ] || ensurechain $chain - fi + [ $COMMAND = check ] || ensurechain $chain # Generate Netfilter rule(s) @@ -3200,15 +3631,15 @@ process_rule() # $1 = target ! list_search $protocol "icmp" "ICMP" "1" && \ [ "$ports" = "${ports%:*}" -a \ "$cports" = "${cports%:*}" -a \ - `list_count $ports` -le 15 -a \ - `list_count $cports` -le 15 ] + $(list_count $ports) -le 15 -a \ + $(list_count $cports) -le 15 ] then # # MULTIPORT is enabled, there are no port ranges in the rule and less than # 16 ports are listed - use multiport match. # multioption="-m multiport" - for client in `separate_list ${clients:=-}`; do + for client in $(separate_list ${clients:=-}); do # # add_a_rule() modifies these so we must set their values each time # @@ -3222,9 +3653,9 @@ process_rule() # $1 = target # MULTIPORT is disabled or the rule isn't compatible with multiport match # multioption= - for client in `separate_list ${clients:=-}`; do - for port in `separate_list ${ports:=-}`; do - for cport in `separate_list ${cports:=-}`; do + for client in $(separate_list ${clients:=-}); do + for port in $(separate_list ${ports:=-}); do + for cport in $(separate_list ${cports:=-}); do server=${servers:=-} add_a_rule done @@ -3238,16 +3669,16 @@ process_rule() # $1 = target ! list_search $protocol "icmp" "ICMP" "1" && \ [ "$ports" = "${ports%:*}" -a \ "$cports" = "${cports%:*}" -a \ - `list_count $ports` -le 15 -a \ - `list_count $cports` -le 15 ] + $(list_count $ports) -le 15 -a \ + $(list_count $cports) -le 15 ] then # # MULTIPORT is enabled, there are no port ranges in the rule and less than # 16 ports are listed - use multiport match. # multioption="-m multiport" - for client in `separate_list ${clients:=-}`; do - for server in `separate_list ${servers:=-}`; do + for client in $(separate_list ${clients:=-}); do + for server in $(separate_list ${servers:=-}); do # # add_a_rule() modifies these so we must set their values each time # @@ -3261,10 +3692,10 @@ process_rule() # $1 = target # MULTIPORT is disabled or the rule isn't compatible with multiport match # multioption= - for client in `separate_list ${clients:=-}`; do - for server in `separate_list ${servers:=-}`; do - for port in `separate_list ${ports:=-}`; do - for cport in `separate_list ${cports:=-}`; do + for client in $(separate_list ${clients:=-}); do + for server in $(separate_list ${servers:=-}); do + for port in $(separate_list ${ports:=-}); do + for cport in $(separate_list ${cports:=-}); do add_a_rule done done @@ -3276,10 +3707,10 @@ process_rule() # $1 = target # # Report Result # - if [ $command = check ]; then - echo " Rule \"$rule\" checked." + if [ $COMMAND = check ]; then + progress_message " Rule \"$rule\" checked." else - echo " Rule \"$rule\" added." + progress_message " Rule \"$rule\" added." fi } @@ -3301,7 +3732,7 @@ process_rules() if [ "${ysourcezone}" != "${ydestzone}" ] ; then eval ypolicy=\$${ysourcezone}2${ydestzone}_policy if [ "$ypolicy" != NONE ] ; then - process_rule $xtarget $yclients $yservers $xprotocol $xports $xcports $xaddress $xratelimit $xuserset + process_rule $xtarget $yclients $yservers $xprotocol $xports $xcports $xaddress $xratelimit $xuserspec fi fi done @@ -3309,7 +3740,7 @@ process_rules() } do_it() { - expandv xclients xservers xprotocol xports xcports xaddress xratelimit xuserset + expandv xclients xservers xprotocol xports xcports xaddress xratelimit xuserspec if [ "x$xclients" = xall ]; then xclients="$zones $FW" @@ -3326,20 +3757,25 @@ process_rules() continue fi - process_rule $xtarget $xclients $xservers $xprotocol $xports $xcports $xaddress $xratelimit $xuserset + process_rule $xtarget $xclients $xservers $xprotocol $xports $xcports $xaddress $xratelimit $xuserspec } - while read xtarget xclients xservers xprotocol xports xcports xaddress xratelimit xuserset; do - temp="${xtarget%:*}" + while read xtarget xclients xservers xprotocol xports xcports xaddress xratelimit xuserspec; do + temp="${xtarget%%:*}" case "${temp%<*}" in - ACCEPT|DROP|REJECT|DNAT|DNAT-|REDIRECT|REDIRECT-|LOG|CONTINUE|QUEUE) + 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" + fi + do_it else - rule="`echo $xtarget $xclients $xservers $xprotocol $xports $xcports $xaddress $xratelimit $xuserset`" + rule="$(echo $xtarget $xclients $xservers $xprotocol $xports $xcports $xaddress $xratelimit $xuserspec)" fatal_error "Invalid Action in rule \"$rule\"" fi ;; @@ -3386,18 +3822,23 @@ process_tos_rule() { [ -n "$src" ] && case "$src" in *.*.*) # - # IP Address or subnet + # IP Address or networks # src="-s $src" ;; ~*) - src=`mac_match $src` + src=$(mac_match $src) ;; *) # # Assume that this is a device name # - src="-i $src" + if ! verify_interface $src ; then + error_message "Warning: Unknown Interface in rule \"$rule\" ignored" + return + fi + + src="$(match_source_dev $src)" ;; esac @@ -3429,7 +3870,7 @@ process_tos_rule() { [ -n "$dst" ] && case "$dst" in *.*.*) # - # IP Address or subnet + # IP Address or networks # ;; *) @@ -3509,7 +3950,7 @@ process_tos_rule() { esac done - echo " Rule \"$rule\" added." + progress_message " Rule \"$rule\" added." } # @@ -3526,7 +3967,7 @@ process_tos() # $1 = name of tos file while read src dst protocol sport dport tos; do expandv src dst protocol sport dport tos - rule="`echo $src $dst $protocol $sport $dport $tos`" + rule="$(echo $src $dst $protocol $sport $dport $tos)" process_tos_rule done < $TMP_DIR/tos @@ -3534,29 +3975,6 @@ process_tos() # $1 = name of tos file run_iptables -t mangle -A OUTPUT -j outtos } -# -# Load a Kernel Module -# -loadmodule() # $1 = module name, $2 - * arguments -{ - local modulename=$1 - local modulefile - local suffix - - if [ -z "`lsmod | grep $modulename`" ]; then - shift - - for suffix in $MODULE_SUFFIX ; do - modulefile=$MODULESDIR/${modulename}.${suffix} - - if [ -f $modulefile ]; then - insmod $modulefile $* - return - fi - done - fi -} - # # Display elements of a list with leading white space # @@ -3565,18 +3983,6 @@ display_list() # $1 = List Title, rest of $* = list to display [ $# -gt 1 ] && echo " $*" } -# -# Add rules to the "common" chain to silently drop packets addressed to any of -# the passed addresses -# -drop_broadcasts() # $* = broadcast addresses -{ - while [ $# -gt 0 ]; do - run_iptables -A common -d $1 -j DROP - shift - done -} - # # Add policy rule ( and possibly logging rule) to the passed chain # @@ -3587,23 +3993,22 @@ policy_rules() # $1 = chain to add rules to local target="$2" case "$target" in - ACCEPT) - ;; - - DROP) - run_iptables -A $1 -j common - ;; - REJECT) - run_iptables -A $1 -j common - target=reject - ;; - CONTINUE) - target= - ;; - *) - fatal_error "Invalid policy ($policy) for $1" - ;; - + ACCEPT) + [ -n "$ACCEPT_common" ] && run_iptables -A $1 -j $ACCEPT_common + ;; + DROP) + [ -n "$DROP_common" ] && run_iptables -A $1 -j $DROP_common + ;; + REJECT) + [ -n "$REJECT_common" ] && run_iptables -A $1 -j $REJECT_common + target=reject + ;; + CONTINUE) + target= + ;; + *) + fatal_error "Invalid policy ($policy) for $1" + ;; esac if [ $# -eq 3 -a "x${3}" != "x-" ]; then @@ -3700,7 +4105,7 @@ default_policy() # $1 = client $2 = server esac fi - echo " Policy $policy for $1 to $2 using chain $chain" + progress_message " Policy $policy for $1 to $2 using chain $chain" } eval chain1=\$${1}2${2}_policychain @@ -3764,9 +4169,9 @@ rules_chain() # $1 = source zone, $2 = destination zone } # -# echo the list of subnets routed out of a given interface +# echo the list of networks routed out of a given interface # -get_routed_subnets() # $1 = interface name +get_routed_networks() # $1 = interface name { local address local rest @@ -3792,15 +4197,15 @@ setup_masq() case $fullinterface in *:*:*) - # Both alias name and subnet + # Both alias name and networks destnets="${fullinterface##*:}" fullinterface="${fullinterface%:*}" ;; *:*) - # Alias name OR subnet + # Alias name OR networks case ${fullinterface#*:} in *.*) - # It's a subnet + # It's a networks destnets="${fullinterface#*:}" fullinterface="${fullinterface%:*}" ;; @@ -3821,32 +4226,35 @@ setup_masq() fatal_error "Unknown interface $interface" fi - if [ "$subnet" = "${subnet%!*}" ]; then + if [ "$networks" = "${networks%!*}" ]; then nomasq= else - nomasq="${subnet#*!}" - subnet="${subnet%!*}" + nomasq="${networks#*!}" + networks="${networks%!*}" fi - source="$subnet" + source="$networks" - case $subnet in + case $networks in *.*.*) ;; *) - subnets=`get_routed_subnets $subnet` - [ -z "$subnets" ] && fatal_error "Unable to determine the routes through interface $subnet" - subnet="$subnets" + networks=$(get_routed_networks $networks) + [ -z "$networks" ] && fatal_error "Unable to determine the routes through interface \"$source\"" + networks="$networks" ;; esac + [ "x$addresses" = x- ] && addresses= + if [ -n "$addresses" -a -n "$ADD_SNAT_ALIASES" ]; then - for address in `separate_list $addresses`; do - for addr in `ip_range_explicit $address` ; do + 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 + case $fullinterface in *:*) fullinterface=${fullinterface%:*}:$((${fullinterface#*:} + 1 )) ;; @@ -3856,9 +4264,53 @@ setup_masq() done fi + [ "x$proto" = x- ] && proto= + [ "x$ports" = x- ] && ports= + + if [ -n "$proto" ]; then + + displayproto="($proto)" + + case $proto in + tcp|TCP|udp|UDP|6|17) + if [ -n "$ports" ]; then + displayproto="($proto $ports)" + + listcount=$(list_count $ports) + + if [ $listcount -gt 1 ]; then + case $ports in + *:*) + fatal_error "Port Range not allowed in list ($ports)" + ;; + *) + if [ -n "$MULTIPORT" ]; then + [ $listcount -gt 15 ] && fatal_error "Too many entries in port list ($ports)" + ports="-m multiport --dports $ports" + else + fatal_error "Port Ranges require multiport match support in your kernel ($ports)" + fi + ;; + esac + else + ports="--dport $ports" + fi + fi + ;; + *) + [ -n "$ports" ] && fatal_error "Ports only allowed with UDP or TCP ($ports)" + ;; + esac + + proto="-p $proto" + else + displayproto="(all)" + [ -n "$ports" ] && fatal_error "Ports only allowed with UDP or TCP ($ports)" + fi + destination=$destnets - chain=`masq_chain $interface` + chain=$(masq_chain $interface) case $destnets in !*) @@ -3870,11 +4322,11 @@ setup_masq() addnatrule $newchain -d $destnet -j RETURN done - if [ -n "$subnet" ]; then - for s in $subnet; do - addnatrule $chain -s $s -j $newchain + if [ -n "$networks" ]; then + for s in $networks; do + addnatrule $chain -s $s $proto $ports -j $newchain done - subnet= + networks= else addnatrule $chain -j $newchain fi @@ -3882,9 +4334,11 @@ setup_masq() masq_seq=$(($masq_seq + 1)) chain=$newchain destnets=0.0.0.0/0 + proto= + ports= if [ -n "$nomasq" ]; then - for addr in `separate_list $nomasq`; do + for addr in $(separate_list $nomasq); do addnatrule $chain -s $addr -j RETURN done source="$source except $nomasq" @@ -3895,24 +4349,26 @@ setup_masq() newchain=masq${masq_seq} createnatchain $newchain - if [ -n "$subnet" ]; then - for s in $subnet; do + if [ -n "$networks" ]; then + for s in $networks; do for destnet in $(separate_list $destnets); do - addnatrule $chain -d $destnet -s $s -j $newchain + addnatrule $chain -d $destnet -s $s $proto $ports -j $newchain done done else for destnet in $(separate_list $destnets); do - addnatrule $chain -d $destnet -j $newchain + addnatrule $chain -d $destnet $proto $ports -j $newchain done fi masq_seq=$(($masq_seq + 1)) chain=$newchain - subnet= + networks= destnets=0.0.0.0/0 + proto= + ports= - for addr in `separate_list $nomasq`; do + for addr in $(separate_list $nomasq); do addnatrule $chain -s $addr -j RETURN done @@ -3921,47 +4377,48 @@ setup_masq() ;; esac - temp= + addrlist= + if [ -n "$addresses" ]; then - for address in `separate_list $addresses`; do - temp="$temp --to-source $address" + for address in $(separate_list $addresses); do + addrlist="$addrlist --to-source $address" done fi - if [ -n "$subnet" ]; then - for s in $subnet; do + if [ -n "$networks" ]; then + for s in $networks; do if [ -n "$addresses" ]; then for destnet in $(separate_list $destnets); do - addnatrule $chain -s $s -d $destnet -j SNAT $temp + addnatrule $chain -s $s -d $destnet $proto $ports -j SNAT $addrlist done - echo " To $destination from $s through ${interface} using $addresses" + progress_message " To $destination $displayproto from $s through ${interface} using $addresses" else for destnet in $(separate_list $destnets); do - addnatrule $chain -s $s -d $destnet -j MASQUERADE + addnatrule $chain -s $s -d $destnet $proto $ports -j MASQUERADE done - echo " To $destination from $s through ${interface}" + progress_message " To $destination $displayproto from $s through ${interface}" fi done elif [ -n "$addresses" ]; then for destnet in $(separate_list $destnets); do - addnatrule $chain -d $destnet -j SNAT $temp + addnatrule $chain -d $destnet $proto $ports -j SNAT $addrlist done - echo " To $destination from $source through ${interface} using $addresses" + echo " To $destination $displayproto from $source through ${interface} using $addresses" else for destnet in $(separate_list $destnets); do - addnatrule $chain -d $destnet -j MASQUERADE + addnatrule $chain -d $destnet $proto $ports -j MASQUERADE done - echo " To $destination from $source through ${interface}" + progress_message " To $destination $displayproto from $source through ${interface}" fi } strip_file masq $1 - [ -n "$NAT_ENABLED" ] && echo "Masqueraded Subnets and Hosts:" + [ -n "$NAT_ENABLED" ] && echo "Masqueraded Networks and Hosts:" && save_progress_message "Restoring Masquerading/SNAT..." - while read fullinterface subnet addresses; do - expandv fullinterface subnet addresses + while read fullinterface networks addresses proto ports; do + expandv fullinterface networks addresses proto ports [ -n "$NAT_ENABLED" ] && setup_one || \ error_message "Warning: NAT disabled; masq rule ignored" done < $TMP_DIR/masq @@ -3976,7 +4433,7 @@ setup_masq() # add_blacklist_rule() { if [ -n "$BLACKLIST_LOGLEVEL" ]; then - log_rule $BLACKLIST_LOGLEVEL blacklst $BLACKLIST_DISPOSITION `fix_bang $source $proto $dport` + log_rule $BLACKLIST_LOGLEVEL blacklst $BLACKLIST_DISPOSITION $(fix_bang $source $proto $dport) fi run_iptables2 -A blacklst $source $proto $dport -j $disposition @@ -3985,7 +4442,7 @@ add_blacklist_rule() { # # Process a record from the blacklist file # -# $subnet = address/subnet +# $networks = address/networks # $protocol = Protocol Number/Name # $port = Port Number/Name # @@ -3995,10 +4452,10 @@ process_blacklist_rec() { local proto local dport - for addr in `separate_list $subnet`; do + for addr in $(separate_list $networks); do case $addr in ~*) - addr=`echo $addr | sed 's/~//;s/-/:/g'` + addr=$(echo $addr | sed 's/~//;s/-/:/g') source="--match mac --mac-source $addr" ;; *) @@ -4015,12 +4472,12 @@ process_blacklist_rec() { if [ -n "$MULTIPORT" -a \ "$ports" != "${ports%,*}" -a \ "$ports" = "${ports%:*}" -a \ - `list_count $ports` -le 15 ] + $(list_count $ports) -le 15 ] then dport="-m multiport --dports $ports" add_blacklist_rule else - for dport in `separate_list $ports`; do + for dport in $(separate_list $ports); do dport="--dport $dport" add_blacklist_rule done @@ -4031,7 +4488,7 @@ process_blacklist_rec() { ;; icmp|ICMP|0) if [ -n "$ports" ]; then - for dport in `separate_list $ports`; do + for dport in $(separate_list $ports); do dport="--icmp-type $dport" add_blacklist_rule done @@ -4053,7 +4510,7 @@ process_blacklist_rec() { addr="$addr $protocol" fi - echo " $addr added to Black List" + progress_message " $addr added to Black List" done } @@ -4061,31 +4518,36 @@ process_blacklist_rec() { # Setup the Black List # setup_blacklist() { - local interfaces=`find_interfaces_by_option blacklist` - local f=`find_file blacklist` + local hosts="$(find_hosts_by_option blacklist)" + local f=$(find_file blacklist) local disposition=$BLACKLIST_DISPOSITION - if [ -n "$interfaces" -a -f $f ]; then + if [ -n "$hosts" -a -f $f ]; then echo "Setting up Blacklisting..." strip_file blacklist $f createchain blacklst no - [ -n "$BLACKLISTNEWONLY" ] && state="-m state --state NEW" || state= + [ -n "$BLACKLISTNEWONLY" ] && state="-m state --state NEW,INVALID" || state= - for interface in $interfaces; do - for chain in `first_chains $interface`; do - run_iptables -A $chain $state -j blacklst - done + for host in $hosts; do + interface=${host%%:*} + network=${host#*:} - echo " Blacklisting enabled on $interface" + for chain in $(first_chains $interface); do + run_iptables -A $chain $state $(match_source_hosts $network) -j blacklst + done + + [ $network = 0/0.0.0.0 ] && network= || network=":$network" + + progress_message " Blacklisting enabled on ${interface}${network}" done [ "$disposition" = REJECT ] && disposition=reject - while read subnet protocol ports; do - expandv subnet protocol ports + while read networks protocol ports; do + expandv networks protocol ports process_blacklist_rec done < $TMP_DIR/blacklist @@ -4096,7 +4558,7 @@ setup_blacklist() { # Refresh the Black List # refresh_blacklist() { - local f=`find_file blacklist` + local f=$(find_file blacklist) local disposition=$BLACKLIST_DISPOSITION if qt iptables -L blacklst -n ; then @@ -4108,8 +4570,8 @@ refresh_blacklist() { run_iptables -F blacklst - while read subnet protocol ports; do - expandv subnet protocol ports + while read networks protocol ports; do + expandv networks protocol ports process_blacklist_rec done < $TMP_DIR/blacklist fi @@ -4120,7 +4582,7 @@ refresh_blacklist() { # verify_os_version() { - osversion=`uname -r` + osversion=$(uname -r) case $osversion in 2.4.*|2.5.*|2.6.*) @@ -4130,7 +4592,7 @@ verify_os_version() { ;; esac - [ $command = start -a -n "`lsmod 2> /dev/null | grep '^ipchains'`" ] && \ + [ $COMMAND = start -a -n "$(lsmod 2> /dev/null | grep '^ipchains')" ] && \ startup_error "Shorewall can't start with the ipchains kernel module loaded - see FAQ #8" } @@ -4148,15 +4610,15 @@ add_ip_aliases() # decoration on these IP addresses that they see when their # distro's net config tool adds them. In an attempt to reduce # the anxiety level, we have the following code which sets - # the VLSM and BRD from an existing address in the same subnet + # the VLSM and BRD from an existing address in the same networks # - # Get all of the lines that contain inet addresses + # Get all of the lines that contain inet addresses with broadcast # - ip -f inet addr show $interface 2> /dev/null | grep 'inet' | while read inet cidr rest ; do + ip -f inet addr show $interface 2> /dev/null | grep 'inet.*brd' | while read inet cidr rest ; do case $cidr in */*) - if in_subnet $external $cidr; then - echo "/${cidr#*/} brd `broadcastaddress $cidr`" + if in_network $external $cidr; then + echo "/${cidr#*/} brd $(broadcastaddress $cidr)" break fi ;; @@ -4166,15 +4628,17 @@ add_ip_aliases() do_one() { - val=`address_details` - run_ip addr add ${external}${val} dev $interface $label + val=$(address_details) + ensure_and_save_command ip addr add ${external}${val} dev $interface $label echo "$external $interface" >> ${STATEDIR}/nat [ -n "$label" ] && label="with $label" - echo " IP Address $external added to interface $interface $label" + progress_message " IP Address $external added to interface $interface $label" } set -- $aliases_to_add + save_progress_message "Restoring IP Addresses..." + while [ $# -gt 0 ]; do external=$1 interface=$2 @@ -4188,24 +4652,48 @@ add_ip_aliases() shift;shift - list_search $external `find_interface_addresses $interface` || do_one + list_search $external $(find_interface_addresses $interface) || do_one done } # # Load kernel modules required for Shorewall # -load_kernel_modules() { +load_kernel_modules() +{ + save_modules_dir=$MODULESDIR [ -z "$MODULESDIR" ] && \ - MODULESDIR=/lib/modules/$osversion/kernel/net/ipv4/netfilter + MODULESDIR=/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter - modules=`find_file modules` + modules=$(find_file modules) if [ -f $modules -a -d $MODULESDIR ]; then - echo "Loading Modules..." + progress_message "Loading Modules..." . $modules fi + + MODULESDIR=$save_modules_dir +} + +save_load_kernel_modules() +{ + + modules=$(find_file modules) + + save_progress_message "Loading kernel modules..." + save_command "reload_kernel_modules <<__EOF__" + + while read command; do + case "$command" in + loadmodule*) + save_command $command + ;; + esac + done < $modules + + save_command __EOF__ + } # Verify that the 'ip' program is installed @@ -4300,6 +4788,7 @@ initialize_netfilter () { strip_file proxyarp strip_file maclist strip_file nat + strip_file netmap terminator=fatal_error @@ -4327,13 +4816,15 @@ initialize_netfilter () { setcontinue INPUT setcontinue OUTPUT + [ -n "$DISABLE_IPV6" ] && disable_ipv6 + # - # Enable the Loopback interface + # Enable the Loopback interface for now # run_iptables -A INPUT -i lo -j ACCEPT run_iptables -A OUTPUT -o lo -j ACCEPT - accounting_file=`find_file accounting` + accounting_file=$(find_file accounting) [ -f $accounting_file ] && setup_accounting $accounting_file @@ -4343,7 +4834,8 @@ initialize_netfilter () { for chain in INPUT OUTPUT FORWARD; do run_iptables -A $chain -p udp --dport 53 -j ACCEPT - run_iptables -A $chain -p ! icmp -m state --state INVALID -j DROP + [ -n "$DROPINVALID" ] && \ + run_iptables -A $chain -p ! icmp -m state --state INVALID -j DROP done [ -n "$CLAMPMSS" ] && \ @@ -4354,11 +4846,13 @@ initialize_netfilter () { if [ -z "$NEWNOTSYN" ]; then createchain newnotsyn no - for interface in `find_interfaces_by_option newnotsyn`; do - run_iptables -A newnotsyn -i $interface -p tcp --tcp-flags ACK ACK -j ACCEPT - run_iptables -A newnotsyn -i $interface -p tcp --tcp-flags RST RST -j ACCEPT - run_iptables -A newnotsyn -i $interface -p tcp --tcp-flags FIN FIN -j ACCEPT - run_iptables -A newnotsyn -i $interface -j RETURN + for host in $(find_hosts_by_option newnotsyn); do + 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 done run_user_exit newnotsyn @@ -4371,13 +4865,9 @@ initialize_netfilter () { fi createchain icmpdef no - createchain common no createchain reject no createchain dynamic no - - usersets_file=`find_file usersets` - - [ -f $usersets_file ] && setup_usersets $usersets_file + createchain smurfs no if [ -f /var/lib/shorewall/save ]; then echo "Restoring dynamic rules..." @@ -4395,78 +4885,59 @@ initialize_netfilter () { fi fi - [ -n "$BLACKLISTNEWONLY" ] && state="-m state --state NEW" || state= + [ -n "$BLACKLISTNEWONLY" ] && state="-m state --state NEW,INVALID" || state= echo "Creating Interface Chains..." 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 - run_iptables -A `input_chain $interface` $state -j dynamic + createchain $(forward_chain $interface) no + run_iptables -A $(forward_chain $interface) $state -j dynamic + createchain $(input_chain $interface) no + run_iptables -A $(input_chain $interface) $state -j dynamic done } -# -# Build the common chain -- called during [re]start and refresh -# -build_common_chain() { - - # - # Common ICMP rules - # - run_user_exit icmpdef - # - # Common rules in each chain - # - common=`find_file common` - - if [ -f $common ]; then - . $common - elif [ -f /etc/shorewall/common.def ]; then - . /etc/shorewall/common.def - else - fatal_error "/etc/shorewall/common.def does not exist" - fi - # - # New Not Syn Stuff - # - if [ -n "$NEWNOTSYN" ]; then - run_iptables -A common -p tcp --tcp-flags ACK ACK -j ACCEPT - run_iptables -A common -p tcp --tcp-flags RST RST -j ACCEPT - run_iptables -A common -p tcp --tcp-flags FIN FIN -j ACCEPT - fi - # - # BROADCASTS - # - drop_broadcasts `find_broadcasts` -} - # # Construct zone-independent rules # add_common_rules() { local savelogparms="$LOGPARMS" local broadcasts="$(find_broadcasts) 255.255.255.255 224.0.0.0/4" - # - # Reject Rules -- Don't respond to broadcasts with an ICMP - # - 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 - # + + drop_broadcasts() { for address in $broadcasts ; do run_iptables -A reject -d $address -j DROP done + } + + # + # Populate the smurf chain + # + 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 + 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 + # + # No pkttype support -- do it the hard way + # + drop_broadcasts + fi + else + drop_broadcasts fi # # Don't feed the smurfs # for address in $broadcasts ; do run_iptables -A reject -s $address -j DROP - done - + done + run_iptables -A reject -p tcp -j REJECT --reject-with tcp-reset run_iptables -A reject -p udp -j REJECT # @@ -4479,94 +4950,57 @@ add_common_rules() { # run_iptables -A reject -j REJECT fi - # - # dropunclean rules - # - interfaces="`find_interfaces_by_option dropunclean`" - if [ -n "$interfaces" ]; then - createchain badpkt no - - if [ -n "$LOGUNCLEAN" ]; then - - LOGPARMS="$LOGPARMS --log-ip-options" - - log_rule $LOGUNCLEAN badpkt DROP -p ! tcp - - LOGPARMS="$LOGPARMS --log-tcp-options" - - log_rule $LOGUNCLEAN badpkt DROP -p tcp - - LOGPARMS="$savelogparms" - fi - - run_iptables -A badpkt -j DROP - echo "Mangled/Invalid Packet filtering enabled on:" - - for interface in $interfaces; do - for chain in `first_chains $interface`; do - run_iptables -A $chain --match unclean -j badpkt - done - echo " $interface" - done - fi - # - # logunclean rules - # - interfaces="`find_interfaces_by_option logunclean`" - - if [ -n "$interfaces" ]; then - createchain logpkt no - - [ -z "$LOGUNCLEAN" ] && LOGUNCLEAN=info - - LOGPARMS="$LOGPARMS --log-ip-options" - - log_rule $LOGUNCLEAN logpkt LOG -p ! tcp - - LOGPARMS="$LOGPARMS --log-tcp-options" - - log_rule $LOGUNCLEAN logpkt LOG -p tcp - - LOGPARMS="$savelogparms" - - echo "Mangled/Invalid Packet Logging enabled on:" - - for interface in $interfaces; do - for chain in `first_chains $interface`; do - run_iptables -A $chain --match unclean -j logpkt - done - echo " $interface" - done - fi - - build_common_chain + run_user_exit initdone # # Process Black List # setup_blacklist + # + # SMURFS + # + hosts=$(find_hosts_by_option nosmurfs) + + if [ -n "$hosts" ]; then + + echo "Adding Anti-smurf Rules" + + for host in $hosts; do + 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 + done + done + fi # # DHCP # - interfaces=`find_interfaces_by_option dhcp` + interfaces=$(find_interfaces_by_option dhcp) if [ -n "$interfaces" ]; then echo "Adding rules for DHCP" for interface in $interfaces; do - run_iptables -A `input_chain $interface` -p udp --dport 67:68 -j ACCEPT + 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 + 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 done fi # # RFC 1918 # - norfc1918_interfaces="`find_interfaces_by_option norfc1918`" + hosts="$(find_hosts_by_option norfc1918)" - if [ -n "$norfc1918_interfaces" ]; then + if [ -n "$hosts" ]; then echo "Enabling RFC1918 Filtering" strip_file rfc1918 @@ -4594,7 +5028,7 @@ add_common_rules() { run_iptables -t mangle -A rfc1918 -j DROP fi - while read subnet target; do + while read networks target; do case $target in logdrop) target=rfc1918 @@ -4602,40 +5036,86 @@ add_common_rules() { DROP|RETURN) ;; *) - fatal_error "Invalid target ($target) for $subnet" + fatal_error "Invalid target ($target) for $networks" ;; esac - run_iptables2 -A norfc1918 -s $subnet -j $target + 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 $subnet -j $target + 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 $subnet -j $target + run_iptables2 -t mangle -A man1918 -d $networks -j $target fi done < $TMP_DIR/rfc1918 - for interface in $norfc1918_interfaces; do - for chain in `first_chains $interface`; do - run_iptables -A $chain -m state --state NEW -j norfc1918 + for host in $hosts; do + 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 done [ -n "$MANGLE_ENABLED" -a -z "$CONNTRACK_MATCH" ] && \ - run_iptables -t mangle -A PREROUTING -m state --state NEW -i $interface -j man1918 + run_iptables -t mangle -A PREROUTING -m state --state NEW -i $interface $(match_source_hosts $networks) -j man1918 + done + fi + # + # Bogons + # + hosts="$(find_hosts_by_option nobogons)" + + if [ -n "$hosts" ]; then + echo "Enabling Bogon Filtering" + + strip_file bogons + + createchain nobogons no + + createchain bogons no + + log_rule $BOGON_LOG_LEVEL bogons DROP + + run_iptables -A bogons -j DROP + + while read networks target; do + case $target in + logdrop) + target=bogons + ;; + DROP|RETURN) + ;; + *) + fatal_error "Invalid target ($target) for $networks" + ;; + esac + + run_iptables2 -A nobogons -s $networks -j $target + + done < $TMP_DIR/bogons + + for host in $hosts; do + interface=${host%%:*} + network=${host#*:} + + for chain in $(first_chains $interface); do + run_iptables -A $chain -m state --state NEW $(match_source_hosts $network) -j nobogons + done done fi - interfaces=`find_interfaces_by_option tcpflags` + hosts=$(find_hosts_by_option tcpflags) - if [ -n "$interfaces" ]; then + if [ -n "$hosts" ]; then echo "Setting up TCP Flags checking..." createchain tcpflags no @@ -4676,20 +5156,25 @@ add_common_rules() { # run_iptables -A tcpflags -p tcp --syn --sport 0 $disposition - for interface in $interfaces; do - for chain in `first_chains $interface`; do - run_iptables -A $chain -p tcp -j tcpflags + for host in $hosts; do + interface=${host%%:*} + network=${host#*:} + + for chain in $(first_chains $interface); do + run_iptables -A $chain -p tcp $(match_source_hosts $network) -j tcpflags done done fi # # ARP Filtering # + save_progress_message "Restoring ARP filtering..." + for f in /proc/sys/net/ipv4/conf/*/arp_filter; do - echo 0 > $f + run_and_save_command "echo 0 > $f" done - interfaces=`find_interfaces_by_option arp_filter` + interfaces=$(find_interfaces_by_option arp_filter) if [ -n "$interfaces" ]; then echo "Setting up ARP Filtering..." @@ -4697,7 +5182,7 @@ add_common_rules() { for interface in $interfaces; do file=/proc/sys/net/ipv4/conf/$interface/arp_filter if [ -f $file ]; then - echo 1 > $file + run_and_save_command "echo 1 > $file" else error_message \ "Warning: Cannot set ARP filtering on $interface" @@ -4707,28 +5192,51 @@ add_common_rules() { # # Route Filtering # - interfaces="`find_interfaces_by_option routefilter`" + interfaces="$(find_interfaces_by_option routefilter)" if [ -n "$interfaces" -o -n "$ROUTE_FILTER" ]; then echo "Setting up Kernel Route Filtering..." + save_progress_message "Restoring Route Filtering..." + for f in /proc/sys/net/ipv4/conf/*/rp_filter; do - echo 0 > $f + run_and_save_command "echo 0 > $f" done for interface in $interfaces; do file=/proc/sys/net/ipv4/conf/$interface/rp_filter if [ -f $file ]; then - echo 1 > $file + run_and_save_command "echo 1 > $file" else error_message \ "Warning: Cannot set route filtering on $interface" fi done - echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter - [ -n "$ROUTE_FILTER" ] && echo 1 > /proc/sys/net/ipv4/conf/default/rp_filter - run_ip route flush cache + run_and_save_command "echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter" + + if [ -n "$ROUTE_FILTER" ]; then + run_and_save_command "echo 1 > /proc/sys/net/ipv4/conf/default/rp_filter" + fi + + run_and_save_command ip route flush cache + fi + + if [ -n "$DYNAMIC_ZONES" ]; then + echo "Setting up Dynamic Zone Chains..." + + for interface in $all_interfaces; do + for chain in $(dynamic_chains $interface); do + createchain $chain no + done + + chain=$(dynamic_in $interface) + createnatchain $chain + + run_iptables -A $(input_chain $interface) -j $chain + run_iptables -A $(forward_chain $interface) -j $(dynamic_fwd $interface) + run_iptables -A OUTPUT -o $interface -j $(dynamic_out $interface) + done fi setup_forwarding @@ -4747,7 +5255,7 @@ apply_policy_rules() { eval loglevel=\$${chain}_loglevel eval synparams=\$${chain}_synparams - [ -n "$synparams" ] && setup_syn_flood_chain $chain $synparams + [ -n "$synparams" ] && setup_syn_flood_chain $chain $synparams $loglevel if havechain $chain; then [ -n "$synparams" ] && \ @@ -4814,15 +5322,16 @@ activate_rules() shift shift - havenatchain $destchain && \ + 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 + fi } # - # Jump to a RULES chain from one of the builtin nat chains - # - # If NAT_BEFORE_RULES then append the rule to the chain; otherwise, insert - # the jump near the front of the builtin chain + # Jump to a RULES chain from one of the builtin nat chains. These jumps are + # are inserted before jumps to static NAT chains. # addrulejump() # $1 = BUILTIN chain, $2 = user chain, $3 - * other arguments { @@ -4831,16 +5340,20 @@ activate_rules() shift if havenatchain $destchain; then - if [ -n "$NAT_BEFORE_RULES" ]; then - run_iptables -t nat -A $sourcechain $@ -j $destchain - else - eval run_iptables -t nat -I $sourcechain \ - \$${sourcechain}_rule $@ -j $destchain - eval ${sourcechain}_rule=\$\(\(\$${sourcechain}_rule + 1\)\) - fi + 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 fi } + # + # Add jumps for dynamic nat chains + # + [ -n "$DYNAMIC_ZONES" ] && for interface in $all_interfaces ; do + addrulejump PREROUTING $(dynamic_in $interface) -i $interface + done # # Add jumps from the builtin chains to the nat chains # @@ -4848,8 +5361,8 @@ activate_rules() addnatjump POSTROUTING nat_out for interface in $all_interfaces; do - addnatjump PREROUTING `input_chain $interface` -i $interface - addnatjump POSTROUTING `output_chain $interface` -o $interface + addnatjump PREROUTING $(input_chain $interface) -i $interface + addnatjump POSTROUTING $(output_chain $interface) -o $interface done > ${STATEDIR}/chains @@ -4858,10 +5371,8 @@ activate_rules() for zone in $zones; do eval source_hosts=\$${zone}_hosts - echo $zone $source_hosts >> ${STATEDIR}/zones - - chain1=`rules_chain $FW $zone` - chain2=`rules_chain $zone $FW` + chain1=$(rules_chain $FW $zone) + chain2=$(rules_chain $zone $FW) eval complex=\$${zone}_is_complex @@ -4870,36 +5381,43 @@ activate_rules() createchain $frwd_chain No fi - echo "$FW $zone $chain1" >> ${STATEDIR}/chains - echo "$zone $FW $chain2" >> ${STATEDIR}/chains + if [ -n "$DYNAMIC_ZONES" ]; then + echo $zone $source_hosts >> ${STATEDIR}/zones + echo "$FW $zone $chain1" >> ${STATEDIR}/chains + echo "$zone $FW $chain2" >> ${STATEDIR}/chains + fi need_broadcast= for host in $source_hosts; do - interface=${host%:*} - subnet=${host#*:} + interface=${host%%:*} + networks=${host#*:} - run_iptables -A OUTPUT -o $interface -d $subnet -j $chain1 + run_iptables -A OUTPUT -o $interface $(match_dest_hosts $networks) -j $chain1 # # Add jumps from the builtin chains for DNAT and SNAT rules # - addrulejump PREROUTING `dnat_chain $zone` -i $interface -s $subnet - addrulejump POSTROUTING `snat_chain $zone` -o $interface -d $subnet + addrulejump PREROUTING $(dnat_chain $zone) -i $interface $(match_source_hosts $networks) + addrulejump POSTROUTING $(snat_chain $zone) -o $interface $(match_dest_hosts $networks) - run_iptables -A `input_chain $interface` -s $subnet -j $chain2 + run_iptables -A $(input_chain $interface) $(match_source_hosts $networks) -j $chain2 [ -n "$complex" ] && \ - run_iptables -A `forward_chain $interface` -s $subnet -j $frwd_chain + run_iptables -A $(forward_chain $interface) $(match_source_hosts $networks) -j $frwd_chain - if [ "$subnet" != 0.0.0.0/0 ]; then - if ! list_search $interface $need_broadcast ; then - eval options=\$`chain_base ${interface}`_options - list_search detectnets $options && need_broadcast="$need_broadcast $interface" - fi - fi + case $networks in + *.*.*.*) + if [ "$networks" != 0.0.0.0/0 ]; then + if ! list_search $interface $need_broadcast ; then + interface_has_option $interface detectnets && need_broadcast="$need_broadcast $interface" + fi + fi + ;; + 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 @@ -4913,53 +5431,96 @@ activate_rules() eval dest_hosts=\$${zone1}_hosts - chain="`rules_chain $zone $zone1`" + chain="$(rules_chain $zone $zone1)" - echo "$zone $zone1 $chain" >> ${STATEDIR}/chains + [ -n "$DYNAMIC_ZONES" ] && echo "$zone $zone1 $chain" >> ${STATEDIR}/chains if [ $zone = $zone1 ]; then + # + # Try not to generate superfluous intra-zone rules + # eval routeback=\"\$${zone}_routeback\" + eval interfaces=\"\$${zone}_interfaces\" + eval ports="\$${zone}_ports" + + num_ifaces=$(list_count1 $interfaces) + # + # If the zone has a single interface then what matters is how many ports it has + # + [ $num_ifaces -eq 1 -a -n "$ports" ] && num_ifaces=$(list_count1 $ports) + # + # If we don't need to route back and if we have only one interface or one port to + # the zone then assume that hosts in the zone can communicate directly. + # + if [ $num_ifaces -lt 2 -a -z "$routeback" ] ; then + continue + fi else routeback= + num_ifaces=0 fi if [ -n "$complex" ]; then for host1 in $dest_hosts; do - interface1=${host1%:*} - subnet1=${host1#*:} - if [ `list_count1 $source_hosts` -eq 1 -a "$source_hosts" = "$host1" ]; then - if list_search $host1 $routeback; then - run_iptables -A $frwd_chain -o $interface1 -d $subnet1 -j $chain - fi - else - run_iptables -A $frwd_chain -o $interface1 -d $subnet1 -j $chain + interface1=${host1%%:*} + networks1=${host1#*:} + # + # Only generate an intrazone rule if the zone has more than one interface (port) or if + # 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 fi done else for host in $source_hosts; do - interface=${host%:*} + interface=${host%%:*} + networks=${host#*:} - chain1=`forward_chain $interface` + chain1=$(forward_chain $interface) for host1 in $dest_hosts; do - interface1=${host1%:*} - subnet1=${host1#*:} + interface1=${host1%%:*} + networks1=${host1#*:} if [ "$host" != "$host1" ] || list_search $host $routeback; then - run_iptables -A $chain1 -o $interface1 -d $subnet1 -j $chain + run_iptables -A $chain1 $(match_source_hosts $networks) -o $interface1 $(match_dest_hosts $networks1) -j $chain fi done done fi done done - - 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 + + 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 + # + # Bridges under the 2.4 kernel have the wierd property that REJECTS have the physdev-in and physdev-out set to the input physdev. + # To accomodate this feature/bug, we effectively set 'routeback' on bridge ports. + # + eval ports=\$$(chain_base $interface)_ports + for port in $ports; do + run_iptables -A $(forward_chain $interface) -o $interface -m physdev --physdev-in $port --physdev-out $port -j ACCEPT + done done + chain=${FW}2${FW} + + if havechain $chain; then + # + # There is a fw->fw chain. Send loopback output through that chain + # + run_ip link ls | grep LOOPBACK | while read ordinal interface rest ; do + run_iptables -A OUTPUT -o ${interface%:*} -j $chain + done + # + # And delete the unconditional ACCEPT rule + # + run_iptables -D OUTPUT -o lo -j ACCEPT + fi + complete_standard_chain INPUT all $FW complete_standard_chain OUTPUT $FW all complete_standard_chain FORWARD all all @@ -4970,7 +5531,6 @@ activate_rules() run_iptables -D $chain -m state --state ESTABLISHED,RELATED -j ACCEPT run_iptables -D $chain -p udp --dport 53 -j ACCEPT done - } # @@ -4998,74 +5558,78 @@ define_firewall() # $1 = Command (Start or Restart) echo "${1}ing Shorewall..." verify_os_version - verify_ip - load_kernel_modules + [ -d /var/lib/shorewall ] || { mkdir -p /var/lib/shorewall ; chmod 700 /var/lib/shorewall; } - echo "Initializing..." + RESTOREBASE=$(mktempfile /var/lib/shorewall) - initialize_netfilter + [ -n "$RESTOREBASE" ] || startup_error "Cannot create temporary file in /var/lib/shorewall" - echo "Configuring Proxy ARP" + echo '#bin/sh' >> $RESTOREBASE + save_command "#" + save_command "# Restore base file generated by Shorewall $version - $(date)" + save_command "#" + save_command ". /usr/share/shorewall/functions" - setup_proxy_arp + save_command "MODULESDIR=\"$MODULESDIR\"" + save_command "MODULE_SUFFIX=\"$MODULE_SUFFIX\"" - setup_nat + save_load_kernel_modules - echo "Adding Common Rules" - - add_common_rules - - tunnels=`find_file tunnels` + echo "Initializing..."; initialize_netfilter + echo "Configuring Proxy ARP"; setup_proxy_arp + echo "Setting up NAT..."; setup_nat + echo "Setting up NETMAP..."; setup_netmap + echo "Adding Common Rules"; add_common_rules + tunnels=$(find_file tunnels) [ -f $tunnels ] && \ - echo "Processing $tunnels..." && setup_tunnels $tunnels + echo "Processing $tunnels..." && setup_tunnels $tunnels - maclist_hosts=`find_hosts_by_option maclist` + maclist_hosts=$(find_hosts_by_option maclist) + [ -n "$maclist_hosts" ] && setup_mac_lists - if [ -n "$maclist_hosts" ] ; then - setup_mac_lists - fi + echo "Pre-processing Actions..."; process_actions1 + echo "Processing $(find_file rules)..."; process_rules + echo "Processing Actions..."; process_actions2 + echo "Processing $(find_file policy)..."; apply_policy_rules - rules=`find_file rules` - - echo "Processing Actions..." - - process_actions - - echo "Processing $rules..." - - process_rules - - policy=`find_file policy` - - echo "Processing $policy..." - - apply_policy_rules - - masq=`find_file masq` - - [ -f $masq ] && setup_masq $masq - - tos=`find_file tos` + masq=$(find_file masq) + [ -f $masq ] && setup_masq $masq + tos=$(find_file tos) [ -f $tos ] && [ -n "$MANGLE_ENABLED" ] && process_tos $tos - ecn=`find_file ecn` - + ecn=$(find_file ecn) [ -f $ecn ] && [ -n "$MANGLE_ENABLED" ] && setup_ecn $ecn - [ -n "$TC_ENABLED" ] && setup_tc + [ -n "$TC_ENABLED" ] && setup_tc - echo "Activating Rules..." - - activate_rules + echo "Activating Rules..."; activate_rules [ -n "$aliases_to_add" ] && \ - echo "Adding IP Addresses..." && \ - add_ip_aliases + echo "Adding IP Addresses..." && add_ip_aliases + for file in chains nat proxyarp zones; do + append_file $file + 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 createchain shorewall no @@ -5075,10 +5639,14 @@ define_firewall() # $1 = Command (Start or Restart) report "Shorewall ${1}ed" rm -rf $TMP_DIR + + mv -f /var/lib/shorewall/restore-base-$$ /var/lib/shorewall/restore-base + mv -f $RESTOREBASE /var/lib/shorewall/restore-tail + } # -# Rebuild the common chain +# Refresh the firewall # refresh_firewall() { @@ -5096,18 +5664,12 @@ refresh_firewall() run_user_exit refresh - run_iptables -F common - - echo "Adding Common Rules" - - build_common_chain - # # Blacklist # refresh_blacklist - ecn=`find_file ecn` + ecn=$(find_file ecn) [ -f $ecn ] && [ -n "$MANGLE_ENABLED" ] && setup_ecn $ecn # @@ -5121,11 +5683,13 @@ refresh_firewall() } # -# Add a host or subnet to a zone +# Add a host or networks to a zone # add_to_zone() # $1 = [:] $2 = zone { - local base + local base interface host newhost zone z h z1 z2 chain terminator + local dhcp_interfaces blacklist_interfaces maclist_interfaces tcpflags_interfaces + local rulenum source_chain dest_hosts iface hosts nat_chain_exists() # $1 = chain name { @@ -5134,20 +5698,16 @@ add_to_zone() # $1 = [:] $2 = zone 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" fi } - output_rule_num() { - local num=`iptables -L OUTPUT -n --line-numbers | grep icmp | cut -d' ' -f1 | head -n1` - - [ -n "$num" ] && echo $(($num+1)) - } # # Isolate interface and host parts # - interface=${1%:*} + interface=${1%%:*} host=${1#*:} [ -z "$host" ] && host="0.0.0.0/0" @@ -5156,6 +5716,10 @@ add_to_zone() # $1 = [:] $2 = zone # determine_zones # + # Validate Interfaces File + # + validate_interfaces_file + # # Validate Zone # zone=$2 @@ -5163,24 +5727,22 @@ add_to_zone() # $1 = [:] $2 = zone 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 present at last [re]start + # Be sure that the interface was dynamic at last [re]start # - if ! chain_exists `input_chain $interface` ; then + if ! chain_exists $(input_chain $interface) ; then startup_error "Unknown interface $interface" fi - # - # Build lists of interfaces with special rules - # - dhcp_interfaces=`find_interfaces_by_option dhcp` - blacklist_interfaces=`find_interfaces_by_option blacklist` - maclist_interfaces=`find_interfaces_by_option maclist` - tcpflags_interfaces=`find_interfaces_by_option tcpflags` + + 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 # @@ -5220,111 +5782,44 @@ add_to_zone() # $1 = [:] $2 = zone chain=${zone}_dnat if nat_chain_exists $chain; then - do_iptables -t nat -I PREROUTING -i $interface -s $host -j $chain + do_iptables -t nat -A $(dynamic_in $interface) $(match_source_hosts $host) -j $chain fi # - # Insert new rules into the input chains for the passed interface + # 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 - # - # We will insert the rule right after the DHCP, 'ping' and - # MAC rules (if any) - # - if list_search $interface $dhcp_interfaces; then - rulenum=3 - else - rulenum=2 - fi - - if list_search $interface $maclist_interfaces; then - rulenum=$(($rulenum + 1)) - fi - - if list_search $interface $tcpflags_interfaces; then - rulenum=$(($rulenum + 1)) - fi - - do_iptables -I `input_chain $interface` $rulenum -s $host -j $chain + do_iptables -A $(dynamic_in $interface) $(match_source_hosts $host) -j $chain else - # - # Insert rules into the passed interface's forward chain - # - # We insert them after any blacklist/MAC verification rules - # - source_chain=`forward_chain $interface` + source_chain=$(dynamic_fwd $interface) eval dest_hosts=\"\$${z2}_hosts\" - base=`chain_base $interface` - - eval rulenum=\$${base}_rulenum - - if [ -z "$rulenum" ]; then - if list_search $interface $blacklist_interfaces; then - rulenum=3 - else - rulenum=2 - fi - - if list_search $interface $maclist_interfaces; then - rulenum=$(($rulenum + 1)) - fi - - if list_search $interface $tcpflags_interfaces; then - rulenum=$(($rulenum + 1)) - fi - fi - for h in $dest_hosts; do - iface=${h%:*} + iface=${h%%:*} hosts=${h#*:} if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then - do_iptables -I $source_chain $rulenum -s $host -o $iface -d $hosts -j $chain - rulenum=$(($rulenum + 1)) + do_iptables -A $source_chain $(match_source_hosts $host) -o $iface $(match_dest_hosts $hosts) -j $chain fi done - - eval ${base}_rulenum=$rulenum - fi elif [ "$z2" = "$zone" ]; then if [ "$z1" = "$FW" ]; then # - # Add a rule to the OUTPUT chain -- always after the icmp * ACCEPT rule + # Add a rule to the dynamic out chain for the interface # - do_iptables -I OUTPUT `output_rule_num` -o $interface -d $host -j $chain + do_iptables -A $(dynamic_out $interface) $(match_dest_hosts $host) -j $chain else - # - # Insert rules into the source interface's forward chain - # - # We insert them after any blacklist rules - # eval source_hosts=\"\$${z1}_hosts\" for h in $source_hosts; do - iface=${h%:*} + iface=${h%%:*} hosts=${h#*:} - base=`chain_base $iface` - - eval rulenum=\$${base}_rulenum - - if [ -z "$rulenum" ]; then - if list_search $iface $blacklist_interfaces; then - rulenum=3 - else - rulenum=2 - fi - fi - if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then - do_iptables -I `forward_chain $iface` $rulenum -s $hosts -o $interface -d $host -j $chain - rulenum=$(($rulenum + 1)) + do_iptables -A $(dynamic_fwd $iface) $rulenum $(match_source_hosts $hosts) -o $interface $(match_dest_hosts $host) -j $chain fi - - eval ${base}_rulenum=$rulenum done fi fi @@ -5332,16 +5827,16 @@ add_to_zone() # $1 = [:] $2 = zone rm -rf $TMP_DIR - echo "$1 added to zone $2" + progress_message "$1 added to zone $2" } # -# Delete a host or subnet from a zone +# Delete a host or networks from a zone # delete_from_zone() # $1 = [:] $2 = zone { # - # Delete the subnect host(s) from the zone state file + # Delete the subject host(s) from the zone state file # delete_from_zones_file() { @@ -5369,7 +5864,7 @@ delete_from_zone() # $1 = [:] $2 = zone # # Isolate interface and host parts # - interface=${1%:*} + interface=${1%%:*} host=${1#*:} [ -z "$host" ] && host="0.0.0.0/0" @@ -5391,9 +5886,13 @@ delete_from_zone() # $1 = [:] $2 = zone # # Be sure that the interface was present at last [re]start # - if ! chain_exists `input_chain $interface` ; then + 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 # @@ -5401,7 +5900,7 @@ delete_from_zone() # $1 = [:] $2 = zone # # Delete the passed hosts from the zone state file # - [ -z "`delete_from_zones_file`" ] && \ + [ -z "$(delete_from_zones_file)" ] && \ error_message "Warning: $1 does not appear to be in zone $2" # # Construct the zone host maps @@ -5414,39 +5913,39 @@ delete_from_zone() # $1 = [:] $2 = zone # # Delete any nat table entries for the host(s) # - qt iptables -t nat -D PREROUTING -i $interface -s $host -j ${zone}_dnat + 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 `input_chain $interface` -s $host -j $chain + qt_iptables -D $(dynamic_in $interface) $(match_source_hosts $host) -j $chain else - source_chain=`forward_chain $interface` + source_chain=$(dynamic_fwd $interface) eval dest_hosts=\"\$${z2}_hosts\" for h in $dest_hosts $delhost; do - iface=${h%:*} + iface=${h%%:*} hosts=${h#*:} if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then - qt iptables -D $source_chain -s $host -o $iface -d $hosts -j $chain + qt_iptables -D $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 - qt iptables -D OUTPUT -o $interface -d $host -j $chain + 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%:*} + iface=${h%%:*} hosts=${h#*:} if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then - qt iptables -D `forward_chain $iface` -s $hosts -o $interface -d $host -j $chain + qt_iptables -D $(dynamic_fwd $iface) $(match_source_hosts $hosts) -o $interface $(match_dest_hosts $host) -j $chain fi done fi @@ -5455,7 +5954,7 @@ delete_from_zone() # $1 = [:] $2 = zone rm -rf $TMP_DIR - echo "$1 removed from zone $2" + progress_message "$1 removed from zone $2" } # @@ -5535,12 +6034,10 @@ do_initialize() { ADD_IP_ALIASES= ADD_SNAT_ALIASES= TC_ENABLED= - LOGUNCLEAN= BLACKLIST_DISPOSITION= BLACKLIST_LOGLEVEL= CLAMPMSS= ROUTE_FILTER= - NAT_BEFORE_RULES= DETECT_DNAT_IPADDRS= MUTEX_TIMEOUT= NEWNOTSYN= @@ -5551,6 +6048,7 @@ do_initialize() { TCP_FLAGS_DISPOSITION= TCP_FLAGS_LOG_LEVEL= RFC1918_LOG_LEVEL= + BOGON_LOG_LEVEL= MARK_IN_FORWARD_CHAIN= SHARED_DIR=/usr/share/shorewall FUNCTIONS= @@ -5561,6 +6059,15 @@ do_initialize() { BLACKLISTNEWONLY= MODULE_SUFFIX= ACTIONS= + USEDACTIONS= + SMURF_LOG_LEVEL= + DISABLE_IPV6= + BRIDGING= + DYNAMIC_ZONES= + PKTTYPE= + DROPINVALID= + RESTOREBASE= + TMP_DIR= stopping= have_mutex= @@ -5568,53 +6075,69 @@ do_initialize() { nonat_seq=1 aliases_to_add= - TMP_DIR=/tmp/shorewall-$$ - rm -rf $TMP_DIR - mkdir -p $TMP_DIR && chmod 700 $TMP_DIR || \ - startup_error "Can't create $TMP_DIR" - - trap "rm -rf $TMP_DIR; my_mutex_off; exit 2" 1 2 3 4 5 6 9 - FUNCTIONS=$SHARED_DIR/functions if [ -f $FUNCTIONS ]; then - echo "Loading $FUNCTIONS..." + [ -n "$QUIET" ] || echo "Loading $FUNCTIONS..." . $FUNCTIONS else startup_error "$FUNCTIONS does not exist!" fi + TMP_DIR=$(mktempdir) + + [ -n "$TMP_DIR" ] && chmod 700 $TMP_DIR || \ + startup_error "Can't create a temporary directory" + + trap "rm -rf $TMP_DIR; my_mutex_off; exit 2" 1 2 3 4 5 6 9 + + ensure_config_path + VERSION_FILE=$SHARED_DIR/version - [ -f $VERSION_FILE ] && version=`cat $VERSION_FILE` + [ -f $VERSION_FILE ] && version=$(cat $VERSION_FILE) run_user_exit params - config=`find_file shorewall.conf` + config=$(find_file shorewall.conf) if [ -f $config ]; then - echo "Processing $config..." - . $config + if [ -r $config ]; then + [ -n "$QUIET" ] || echo "Processing $config..." + . $config + else + echo " ERROR: Cannot read $config (Hint: Are you root?)" + exit 2 + fi else echo "$config does not exist!" >&2 exit 2 fi # - # Determine the capabilities of the installed iptables/netfilter + # Restore CONFIG_PATH if the shorewall.conf file cleared it # + ensure_config_path + # + # Determine the capabilities of the installed iptables/netfilter + # We load the kernel modules here to acurately determine + # capabilities when module autoloading isn't enabled. + # + + [ -n "$MODULE_SUFFIX" ] || MODULE_SUFFIX="o gz ko o.gz ko.gz" + load_kernel_modules determine_capabilities [ -z "${STATEDIR}" ] && STATEDIR=/var/state/shorewall - + [ -d $STATEDIR ] || mkdir -p $STATEDIR [ -z "$FW" ] && FW=fw - ALLOWRELATED="`added_param_value_yes ALLOWRELATED $ALLOWRELATED`" + ALLOWRELATED="$(added_param_value_yes ALLOWRELATED $ALLOWRELATED)" [ -n "$ALLOWRELATED" ] || \ startup_error "ALLOWRELATED=No is not supported" - ADD_IP_ALIASES="`added_param_value_yes ADD_IP_ALIASES $ADD_IP_ALIASES`" - TC_ENABLED="`added_param_value_yes TC_ENABLED $TC_ENABLED`" + ADD_IP_ALIASES="$(added_param_value_yes ADD_IP_ALIASES $ADD_IP_ALIASES)" + TC_ENABLED="$(added_param_value_yes TC_ENABLED $TC_ENABLED)" if [ -n "${LOGRATE}${LOGBURST}" ]; then LOGLIMIT="--match limit" @@ -5640,16 +6163,15 @@ do_initialize() { [ -z "$BLACKLIST_DISPOSITION" ] && BLACKLIST_DISPOSITION=DROP - CLAMPMSS=`added_param_value_no CLAMPMSS $CLAMPMSS` - ADD_SNAT_ALIASES=`added_param_value_no ADD_SNAT_ALIASES $ADD_SNAT_ALIASES` - ROUTE_FILTER=`added_param_value_no ROUTE_FILTER $ROUTE_FILTER` - NAT_BEFORE_RULES=`added_param_value_yes NAT_BEFORE_RULES $NAT_BEFORE_RULES` - DETECT_DNAT_IPADDRS=`added_param_value_no DETECT_DNAT_IPADDRS $DETECT_DNAT_IPADDRS` - FORWARDPING=`added_param_value_no FORWARDPING $FORWARDPING` + CLAMPMSS=$(added_param_value_no CLAMPMSS $CLAMPMSS) + ADD_SNAT_ALIASES=$(added_param_value_no ADD_SNAT_ALIASES $ADD_SNAT_ALIASES) + ROUTE_FILTER=$(added_param_value_no ROUTE_FILTER $ROUTE_FILTER) + DETECT_DNAT_IPADDRS=$(added_param_value_no DETECT_DNAT_IPADDRS $DETECT_DNAT_IPADDRS) + FORWARDPING=$(added_param_value_no FORWARDPING $FORWARDPING) [ -n "$FORWARDPING" ] && \ startup_error "FORWARDPING=Yes is no longer supported" - NEWNOTSYN=`added_param_value_yes NEWNOTSYN $NEWNOTSYN` + NEWNOTSYN=$(added_param_value_yes NEWNOTSYN $NEWNOTSYN) maclist_target=reject @@ -5681,23 +6203,25 @@ do_initialize() { fi [ -z "$RFC1918_LOG_LEVEL" ] && RFC1918_LOG_LEVEL=info - MARK_IN_FORWARD_CHAIN=`added_param_value_no MARK_IN_FORWARD_CHAIN $MARK_IN_FORWARD_CHAIN` + [ -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 if [ -n "$TC_ENABLED" ]; then - CLEAR_TC=`added_param_value_yes CLEAR_TC $CLEAR_TC` + CLEAR_TC=$(added_param_value_yes CLEAR_TC $CLEAR_TC) else CLEAR_TC= fi if [ -n "$LOGFORMAT" ]; then - if [ -n "`echo $LOGFORMAT | grep '%d'`" ]; then + if [ -n "$(echo $LOGFORMAT | grep '%d')" ]; then LOGRULENUMBERS=Yes - temp=`printf "$LOGFORMAT" fooxx 1 barxx 2> /dev/null` + temp=$(printf "$LOGFORMAT" fooxx 1 barxx 2> /dev/null) if [ $? -ne 0 ]; then startup_error "Invalid LOGFORMAT string: \"$LOGFORMAT\"" fi else - temp=`printf "$LOGFORMAT" fooxx barxx 2> /dev/null` + temp=$(printf "$LOGFORMAT" fooxx barxx 2> /dev/null) if [ $? -ne 0 ]; then startup_error "Invalid LOGFORMAT string: \"$LOGFORMAT\"" fi @@ -5709,10 +6233,13 @@ do_initialize() { else LOGFORMAT="Shorewall:%s:%s:" fi - ADMINISABSENTMINDED=`added_param_value_no ADMINISABSENTMINDED $ADMINISABSENTMINDED` - BLACKLISTNEWONLY=`added_param_value_no BLACKLISTNEWONLY $BLACKLISTNEWONLY` - [ -n "$MODULE_SUFFIX" ] || MODULE_SUFFIX="o gz ko o.gz" - + ADMINISABSENTMINDED=$(added_param_value_no ADMINISABSENTMINDED $ADMINISABSENTMINDED) + BLACKLISTNEWONLY=$(added_param_value_no BLACKLISTNEWONLY $BLACKLISTNEWONLY) + 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) + DROPINVALID=$(added_param_value_yes DROPINVALID $DROPINVALID) # # Strip the files that we use often # @@ -5723,10 +6250,13 @@ do_initialize() { # [ -n "$SHOREWALL_SHELL" ] || SHOREWALL_SHELL=/bin/sh - temp=`decodeaddr 192.168.1.1` - if [ `encodeaddr $temp` != 192.168.1.1 ]; then + temp=$(decodeaddr 192.168.1.1) + if [ $(encodeaddr $temp) != 192.168.1.1 ]; then startup_error "Shell $SHOREWALL_SHELL is broken and may not be used with Shorewall" fi + + rm -f $TMP_DIR/physdev + } # @@ -5751,9 +6281,9 @@ nolock= trap "my_mutex_off; exit 2" 1 2 3 4 5 6 9 -command="$1" +COMMAND="$1" -case "$command" in +case "$COMMAND" in stop) [ $# -ne 1 ] && usage do_initialize @@ -5801,7 +6331,7 @@ case "$command" in status) [ $# -ne 1 ] && usage - echo "Shorewall-$version Status at $HOSTNAME - `date`" + echo "Shorewall-$version Status at $HOSTNAME - $(date)" echo iptables -L -n -v ;; diff --git a/Shorewall/functions b/Shorewall/functions index 657762330..152b10e91 100755 --- a/Shorewall/functions +++ b/Shorewall/functions @@ -1,6 +1,45 @@ #!/bin/sh # -# Shorewall 1.4 -- /usr/lib/shorewall/functions +# Shorewall 2.0 -- /usr/share/shorewall/functions + +# +# Search a list looking for a match -- returns zero if a match found +# 1 otherwise +# +list_search() # $1 = element to search for , $2-$n = list +{ + local e=$1 + + while [ $# -gt 1 ]; do + shift + [ "x$e" = "x$1" ] && return 0 + done + + return 1 +} + +# +# Functions to count list elements +# - - - - - - - - - - - - - - - - +# Whitespace-separated list +# +list_count1() { + echo $# +} +# +# Comma-separated list +# +list_count() { + list_count1 $(separate_list $1) +} + +# +# Conditionally produce message +# +progress_message() # $* = Message +{ + [ -n "$QUIET" ] || echo "$@" +} # # Suppress all output for a command @@ -11,15 +50,88 @@ qt() } # -# Find a File -- Look first in $SHOREWALL_DIR then in /etc/shorewall +# Perform variable substitution on the passed argument and echo the result +# +expand() # $@ = contents of variable which may be the name of another variable +{ + eval echo \"$@\" +} + +# +# Perform variable substitition on the values of the passed list of variables +# +expandv() # $* = list of variable names +{ + local varval + + while [ $# -gt 0 ]; do + eval varval=\$${1} + eval $1=\"$varval\" + shift + done +} + +# +# Replace all leading "!" with "! " in the passed argument list +# + +fix_bang() { + local i; + + for i in $@; do + case $i in + !*) + echo "! ${i#!}" + ;; + *) + echo $i + ;; + esac + done +} + +# +# Set default config path +# +ensure_config_path() { + local F=/usr/share/shorewall/configpath + if [ -z "$CONFIG_PATH" ]; then + [ -f $F ] || { echo " ERROR: $F does not exist"; exit 2; } + . $F + fi +} + +# +# Find a File -- For relative file name, look first in $SHOREWALL_DIR then in /etc/shorewall # find_file() { - if [ -n "$SHOREWALL_DIR" -a -f $SHOREWALL_DIR/$1 ]; then - echo $SHOREWALL_DIR/$1 - else - echo /etc/shorewall/$1 - fi + local saveifs= directory + + case $1 in + /*) + echo $1 + ;; + *) + if [ -n "$SHOREWALL_DIR" -a -f $SHOREWALL_DIR/$1 ]; then + echo $SHOREWALL_DIR/$1 + else + saveifs=$IFS + IFS=: + for directory in $CONFIG_PATH; do + if [ -f $directory/$1 ]; then + echo $directory/$1 + IFS=$saveifs + return + fi + done + + IFS=$saveifs + + echo /etc/shorewall/$1 + fi + ;; + esac } # @@ -58,6 +170,55 @@ separate_list() { echo "$newlist" } +# +# Load a Kernel Module +# +loadmodule() # $1 = module name, $2 - * arguments +{ + local modulename=$1 + local modulefile + local suffix + moduleloader=modprobe + + if ! qt which modprobe; then + moduleloader=insmod + fi + + if [ -z "$(lsmod | grep $modulename)" ]; then + shift + + for suffix in $MODULE_SUFFIX ; do + modulefile=$MODULESDIR/${modulename}.${suffix} + + if [ -f $modulefile ]; then + case $moduleloader in + insmod) + insmod $modulefile $* + ;; + *) + modprobe $modulename $* + ;; + esac + + return + fi + done + fi +} + +# +# Reload the Modules +# +reload_kernel_modules() { + + [ -z "$MODULESDIR" ] && MODULESDIR=/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter + + while read command; do + eval $command + done + +} + # # Find the zones # @@ -67,7 +228,7 @@ find_zones() # $1 = name of the zone file [ -n "$zone" ] && case "$zone" in \#*) ;; - $FW|multi) + $FW) echo "Reserved zone name \"$zone\" in zones file ignored" >&2 ;; *) @@ -89,15 +250,15 @@ find_display() # $1 = zone, $2 = name of the zone file # determine_zones() { - local zonefile=`find_file zones` + local zonefile=$(find_file zones) multi_display=Multi-zone strip_file zones $zonefile - zones=`find_zones $TMP_DIR/zones` - zones=`echo $zones` # Remove extra trash + zones=$(find_zones $TMP_DIR/zones) + zones=$(echo $zones) # Remove extra trash for zone in $zones; do - dsply=`find_display $zone $TMP_DIR/zones` + dsply=$(find_display $zone $TMP_DIR/zones) eval ${zone}_display=\$dsply done } @@ -117,7 +278,7 @@ get_statedir() { MUTEX_TIMEOUT= - local config=`find_file shorewall.conf` + local config=$(find_file shorewall.conf) if [ -f $config ]; then . $config @@ -175,6 +336,92 @@ mutex_off() rm -f $STATEDIR/lock } +# +# Determine which version of mktemp is present (if any) and set MKTEMP accortingly: +# +# None - No mktemp +# BSD - BSD mktemp (Mandrake) +# STD - mktemp.org mktemp +# +find_mktemp() { + local mktemp=`which mktemp 2> /dev/null` + + if [ -n "$mktemp" ]; then + if qt mktemp -V ; then + MKTEMP=STD + else + MKTEMP=BSD + fi + else + MKTEMP=None + fi +} + +# +# create a temporary file. If a directory name is passed, the file will be created in +# that directory. Otherwise, it will be created in a temporary directory. +# +mktempfile() { + + [ -z "$MKTEMP" ] && find_mktemp + + if [ $# -gt 0 ]; then + case "$MKTEMP" in + BSD) + mktemp $1/shorewall.XXXXXX + ;; + STD) + mktemp -p $1 shorewall.XXXXXX + ;; + None) + > $1/shorewall-$$ && echo $1/shorewall-$$ + ;; + *) + echo " ERROR:Internal error in mktempfile" + ;; + esac + else + case "$MKTEMP" in + BSD) + mktemp /tmp/shorewall.XXXXXX + ;; + STD) + mktemp -t shorewall.XXXXXX + ;; + None) + rm -f /tmp/shorewall-$$ + > /tmp/shorewall-$$ && echo /tmp/shorewall-$$ + ;; + *) + echo " ERROR:Internal error in mktempfile" + ;; + esac + fi +} + +# +# create a temporary directory +# +mktempdir() { + + [ -z "$MKTEMP" ] && find_mktemp + + case "$MKTEMP" in + STD) + mktemp -td shorewall.XXXXXX + ;; + None|BSD) + # + # Not all versions of the BSD mktemp support the -d option under Linux + # + mkdir /tmp/shorewall-$$ && chmod 700 /tmp/shorewall-$$ && echo /tmp/shorewall-$$ + ;; + *) + echo " ERROR:Internal error in mktempdir" + ;; + esac +} + # # Read a file and handle "INCLUDE" directives # @@ -183,24 +430,29 @@ read_file() # $1 = file name, $2 = nest count { local first rest - while read first rest; do - if [ "x$first" = "xINCLUDE" ]; then - if [ $2 -lt 4 ]; then - read_file `find_file ${rest%#*}` $(($2 + 1)) + if [ -f $1 ]; then + while read first rest; do + if [ "x$first" = "xINCLUDE" ]; then + if [ $2 -lt 4 ]; then + read_file $(find_file $(expand ${rest%#*})) $(($2 + 1)) + else + echo " WARNING: INCLUDE in $1 ignored (nested too deeply)" >&2 + fi else - echo " WARNING: INCLUDE in $1 ignored (nested too deeply)" >&2 + echo "$first $rest" fi - else - echo "$first $rest" - fi - done < $1 + done < $1 + else + [ -n "$terminator" ] && $terminator "No such file: $1" + echo "Warning -- No such file: $1" + fi } # # Function for including one file into another # INCLUDE() { - . `find_file $@` + . $(find_file $(expand $@)) } # @@ -211,7 +463,7 @@ strip_file() # $1 = Base Name of the file, $2 = Full Name of File (optional) { local fname - [ $# = 1 ] && fname=`find_file $1` || fname=$2 + [ $# = 1 ] && fname=$(find_file $1) || fname=$2 if [ -f $fname ]; then read_file $fname 0 | cut -d'#' -f1 | grep -v '^[[:space:]]*$' > $TMP_DIR/$1 @@ -288,8 +540,8 @@ ip_range() { ;; esac - first=`decodeaddr ${1%-*}` - last=`decodeaddr ${1#*-}` + first=$(decodeaddr ${1%-*}) + last=$(decodeaddr ${1#*-}) if [ $first -gt $last ]; then fatal_error "Invalid IP address range: $1" @@ -310,7 +562,7 @@ ip_range() { y=$(( $y * 2 )) done - echo `encodeaddr $first`$vlsm + echo $(encodeaddr $first)$vlsm first=$(($first + $z)) done } @@ -327,15 +579,15 @@ ip_range_explicit() { ;; esac - first=`decodeaddr ${1%-*}` - last=`decodeaddr ${1#*-}` + first=$(decodeaddr ${1%-*}) + last=$(decodeaddr ${1#*-}) if [ $first -gt $last ]; then fatal_error "Invalid IP address range: $1" fi while [ $first -le $last ]; do - echo `encodeaddr $first` + echo $(encodeaddr $first) first=$(($first + 1)) done } @@ -353,10 +605,10 @@ ip_netmask() { # Network address from CIDR # ip_network() { - local decodedaddr=`decodeaddr ${1%/*}` - local netmask=`ip_netmask $1` + local decodedaddr=$(decodeaddr ${1%/*}) + local netmask=$(ip_netmask $1) - echo `encodeaddr $(($decodedaddr & $netmask))` + echo $(encodeaddr $(($decodedaddr & $netmask))) } # @@ -374,37 +626,37 @@ ip_broadcast() { # Calculate broadcast address from CIDR # broadcastaddress() { - local decodedaddr=`decodeaddr ${1%/*}` - local netmask=`ip_netmask $1` - local broadcast=`ip_broadcast $1` + local decodedaddr=$(decodeaddr ${1%/*}) + local netmask=$(ip_netmask $1) + local broadcast=$(ip_broadcast $1) - echo `encodeaddr $(( $(($decodedaddr & $netmask)) | $broadcast ))` + echo $(encodeaddr $(( $(($decodedaddr & $netmask)) | $broadcast ))) } # -# Test for subnet membership +# Test for network membership # -in_subnet() # $1 = IP address, $2 = CIDR network +in_network() # $1 = IP address, $2 = CIDR network { - local netmask=`ip_netmask $2` + local netmask=$(ip_netmask $2) - test $(( `decodeaddr $1` & $netmask)) -eq $(( `decodeaddr ${2%/*}` & $netmask )) + test $(( $(decodeaddr $1) & $netmask)) -eq $(( $(decodeaddr ${2%/*}) & $netmask )) } # # Netmask to VLSM # ip_vlsm() { - local mask=`decodeaddr $1` + local mask=$(decodeaddr $1) local vlsm=0 - local x=$(( 128 $LEFTSHIFT 24 )) + local x=$(( 128 $LEFTSHIFT 24 )) # 0x80000000 while [ $(( $x & $mask )) -ne 0 ]; do - [ $mask -eq $x ] && mask=0 || mask=$(( $mask $LEFTSHIFT 1 )) # Don't Ask... + [ $mask -eq $x ] && mask=0 || mask=$(( $mask $LEFTSHIFT 1 )) # Not all shells shift 0x80000000 left properly. vlsm=$(($vlsm + 1)) done - if [ $(( $mask & 2147483647)) -ne 0 ]; then + if [ $(( $mask & 2147483647 )) -ne 0 ]; then # 2147483647 = 0x7fffffff echo "Invalid net mask: $1" >&2 else echo $vlsm @@ -414,11 +666,11 @@ ip_vlsm() { # # Chain name base for an interface -- replace all periods with underscores in the passed name. -# The result is echoed (less "+" and anything following). +# The result is echoed (less trailing "+"). # chain_base() #$1 = interface { - local c=${1%%+*} + local c=${1%%+} while true; do case $c in @@ -436,29 +688,25 @@ chain_base() #$1 = interface done } -# -# Remove trailing digits from a name -# -strip_trailing_digits() { - echo $1 | sed s'/[0-9].*$//' -} - # # Loosly Match the name of an interface # if_match() # $1 = Name in interfaces file - may end in "+" - # $2 = Name from routing table + # $2 = Full interface name - may also end in "+" { - local if_file=$1 - local rt_table=$2 - - case $if_file in + local pattern=${1%+} + + case $1 in *+) - test "`strip_trailing_digits $rt_table`" = "${if_file%+}" + # + # 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 "$rt_table" = "$if_file" + test "x$1" = "x$2" ;; esac } @@ -483,13 +731,13 @@ find_rt_interface() { ip route ls | while read addr rest; do case $addr in */*) - in_subnet ${1%/*} $addr && echo `find_device $rest` + in_network ${1%/*} $addr && echo $(find_device $rest) ;; default) ;; *) if [ "$addr" = "$1" -o "$addr/32" = "$1" ]; then - echo `find_device $rest` + echo $(find_device $rest) fi ;; esac @@ -501,7 +749,7 @@ find_rt_interface() { # find_default_interface() { ip route ls | while read first rest; do - [ "$first" = default ] && echo `find_device $rest` && return + [ "$first" = default ] && echo $(find_device $rest) && return done } @@ -511,10 +759,10 @@ find_default_interface() { # find_interface_by_address() { - local dev="`find_rt_interface $1`" + local dev="$(find_rt_interface $1)" local first rest - [ -z "$dev" ] && dev=`find_default_interface` + [ -z "$dev" ] && dev=$(find_default_interface) [ -n "$dev" ] && echo $dev } diff --git a/Shorewall/help b/Shorewall/help index f3a0c8927..7343d2f43 100755 --- a/Shorewall/help +++ b/Shorewall/help @@ -1,12 +1,12 @@ #!/bin/sh # -# Shorewall help subsystem - V1.4 - 3/14/2003 +# Shorewall help subsystem - V2.0 - 2/14/2004 # # # This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] # -# (c) 2003 - Tom Eastep (teastep@shorewall.net) -# Steve Herber (herber@thing.com) +# (c) 2003-2004 - Tom Eastep (teastep@shorewall.net) +# Steve Herber (herber@thing.com) # # This file should be placed in /usr/share/shorewall/help # @@ -29,11 +29,11 @@ case $1 in add) - echo "add: add [:] + echo "add: add [:][:] Adds a host or subnet to a dynamic zone usually used with VPN's. - shorewall add interface[:host] zone - Adds the specified interface - (and host if included) to the specified zone. + shorewall add interface[:port][:host] zone - Adds the specified interface + (and bridge port/host if included) to the specified zone. Example: @@ -87,15 +87,17 @@ debug) shorewall debug start 2> /tmp/trace The above command would trace the 'start' command and - place the trace information in the file /tmp/trace." + place the trace information in the file /tmp/trace. + + The word 'trace' is a synonym for 'debug'." ;; delete) - echo "delete: delete [:] + echo "delete: delete [:][:] Deletes a host or subnet from a dynamic zone usually used with VPN's. - shorewall delete interface[:host] zone - Deletes the specified - interface (and host if included) from the specified zone. + shorewall delete interface[:port][:host] zone - Deletes the specified + interface (and bridge port/host if included) from the specified zone. Example: @@ -114,6 +116,14 @@ drop) See also \"help address\"" ;; +forget) + echo "forget: forget [ ] + Deletes /var/lib/shorewall/. If no is given then + the file specified by RESTOREFILE in shorewall.conf is removed. + + See also \"help save\"" + ;; + help) echo "help: help [ | host | address ] Display helpful information about the shorewall commands." @@ -145,15 +155,21 @@ logwatch) monitor) echo "monitor: monitor [] + + shorewall [-x] monitor [] + Continuously display the firewall status, last 20 log entries and nat. - When the log entry display changes, an audible alarm is sounded." + When the log entry display changes, an audible alarm is sounded. + + When -x is given, that option is also passed to iptables to display actual packet and byte counts." ;; refresh) - echo "refresh: refresh + echo "refresh: [ -q ] refresh The rules involving the broadcast addresses of firewall interfaces, the black list, traffic control rules and ECN control rules are recreated - to reflect any changes made. Existing connections are untouched" + to reflect any changes made. Existing connections are untouched + If \"-q\" is specified, less detain is displayed making it easier to spot warnings" ;; reject) @@ -171,26 +187,45 @@ reset) ;; restart) - echo "restart: restart [ -c ] + echo "restart: restart [ -q ] [ -c ] Restart is the same as a shorewall stop && shorewall start. - Existing connections are dropped." + Existing connections are maintained. + If \"-q\" is specified, less detain is displayed making it easier to spot warnings" + ;; + +restore) + echo "restore: restore [ ] + Restore Shorewall to a state saved using the 'save' command + Existing connections are maintained. The names a restore file in + /var/lib/shorewall created using "shorewall save"; if no is given + then Shorewall will be restored from the file specified by the RESTOREFILE + option in shorewall.conf. + + See also \"help save\" and \"help forget\"" ;; save) - echo "save: save - The dynamic data is stored in /var/lib/shorewall/save - Shorewall allow, drop, rejct and save implement dynamic blacklisting." + echo "save: save [ ] + The dynamic data is stored in /var/lib/shorewall/save. The state of the + firewall is stored in /var/lib/shorewall/ for use by the 'shorewall restore' + and 'shorewall -f start' commands. If is not given then the state is saved + in the file specified by the RESTOREFILE option in shorewall.conf. + + Shorewall allow, drop, rejct and save implement dynamic blacklisting. + + See also \"help restore\" and \"help forget\"" ;; show) - echo "show: show [ [ ...] |classifiers|connections|log|nat|tc|tos] - shorewall show [ ... ] - produce a verbose report about the IPtable chain(s). + echo "show: show [ [ ...] |classifiers|connections|log|nat|tc|tos] + + shorewall [-x] show [ ... ] - produce a verbose report about the IPtable chain(s). (iptables -L chain -n -v) - shorewall show nat - produce a verbose report about the nat table. + shorewall [-x] show nat - produce a verbose report about the nat table. (iptables -t nat -L -n -v) - shorewall show tos - produce a verbose report about the mangle table. + shorewall [-x] show tos - produce a verbose report about the mangle table. (iptables -t mangle -L -n -v) shorewall show log - display the last 20 packet log entries. @@ -199,14 +234,19 @@ show) being tracked by the firewall. shorewall show tc - displays information about the traffic - control/shaping configuration." + control/shaping configuration. + + When -x is given, that option is also passed to iptables to display actual packet and byte counts." ;; start) - echo "start: start [ -c ] + echo "start: [ -q ] [ -f ] [ -c ] 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 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" ;; stop) @@ -219,9 +259,31 @@ stop) status) echo "status: status + + shorewall [-x] status + Produce a verbose report about the firewall. - (iptables -L -n -v)" + (iptables -L -n -) + + When -x is given, that option is also passed to iptables to display actual packet and byte counts." + ;; + +trace) + echo "trace: trace + If you include the keyword trace as the first argument to any + of these commands: + + start|stop|restart|reset|clear|refresh|check|add|delete + + then a shell trace of the command is produced. For example: + + shorewall trace start 2> /tmp/trace + + The above command would trace the 'start' command and + place the trace information in the file /tmp/trace. + + The word 'debug' is a synonym for 'trace'." ;; try) diff --git a/Shorewall/hosts b/Shorewall/hosts index a60b16bee..49e322adb 100644 --- a/Shorewall/hosts +++ b/Shorewall/hosts @@ -1,39 +1,48 @@ # -# Shorewall 1.4 - /etc/shorewall/hosts +# Shorewall 2.0 - /etc/shorewall/hosts # -# THERE ARE TWO CASES WHERE YOU NEED THIS FILE: -# -# 1) YOU HAVE MULTIPLE NETWORKS IN THE SAME ZONE CONNECTED TO -# A SINGLE INTERFACE AND YOU WANT THE SHOREWALL BOX TO ROUTE -# BETWEEN THESE NETWORKS. -# -# 2) YOU HAVE MORE THAN ONE ZONE CONNECTED THROUGH A SINGLE -# INTERFACE. -# -# IF YOU DON'T HAVE EITHER OF THESE SITUATIONS THEN DON'T TOUCH -# THIS FILE. +# THE ONLY TIME YOU NEED THIS FILE IS WHERE YOU HAVE MORE THAN +# ONE ZONE CONNECTED THROUGH A SINGLE INTERFACE. # +# IF YOU DON'T HAVE THAT SITUATION THEN DON'T TOUCH THIS FILE. +#------------------------------------------------------------------------------ +# IF YOU HAVE AN ENTRY FOR A ZONE AND INTERFACE IN +# /etc/shorewall/interfaces THEN DO NOT ADD ANY ENTRIES FOR THAT +# ZONE AND INTERFACE IN THIS FILE. +#------------------------------------------------------------------------------ # This file is used to define zones in terms of subnets and/or # individual IP addresses. Most simple setups don't need to # (should not) place anything in this file. # +# The order of entries in this file is not significant in +# determining zone composition. Rather, the order that the zones +# are defined in /etc/shorewall/zones determines the order in +# which the records in this file are interpreted. +# # ZONE - The name of a zone defined in /etc/shorewall/zones # -# HOST(S) - The name of an interface followed by a colon (":") and +# HOST(S) - The name of an interface defined in the +# /etc/shorewall/interfaces file followed by a colon (":") and # a comma-separated list whose elements are either: # # a) The IP address of a host # b) A subnetwork in the form # / -# -# The interface must be defined in the -# /etc/shorewall/interfaces file. +# c) 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. +# See http://www.shorewall.net/Bridge.html for details. # # Examples: # # eth1:192.168.1.3 # eth2:192.168.2.0/24 # eth3:192.168.2.0/24,192.168.3.1 +# br0:eth4 +# br0:eth0:192.168.1.16/28 # # OPTIONS - A comma-separated list of options. Currently-defined # options are: @@ -45,15 +54,75 @@ # an ethernet NIC and must be up before # Shorewall is started. # -# routeback - Shorewall show set up the infrastructure +# routeback - Shorewall should set up the infrastructure # to pass packets from this/these # address(es) back to themselves. This is -# necessary of hosts in this group use the +# necessary if hosts in this group use the # services of a transparent proxy that is # a member of the group or if DNAT is used # to send requests originating from this # group to a server in the group. # +# norfc1918 - This option only makes sense for ports +# on a bridge. +# +# The port should not accept +# any packets whose source is in one +# of the ranges reserved by RFC 1918 +# (i.e., private or "non-routable" +# addresses. If packet mangling or +# connection-tracking match is enabled in +# your kernel, packets whose destination +# addresses are reserved by RFC 1918 are +# also rejected. +# +# nobogons - This option only makes sense for ports +# on a bridge. +# +# This port should not accept +# any packets whose source is in one +# of the ranges reserved by IANA (this +# option does not cover those ranges +# reserved by RFC 1918 -- see +# 'norfc1918' above). +# +# blacklist - This option only makes sense for ports +# on a bridge. +# +# Check packets arriving on this port +# against the /etc/shorewall/blacklist +# file. +# +# tcpflags - Packets arriving from these hosts are +# checked for certain illegal combinations +# of TCP flags. Packets found to have +# such a combination of flags are handled +# according to the setting of +# TCP_FLAGS_DISPOSITION after having been +# logged according to the setting of +# TCP_FLAGS_LOG_LEVEL. +# +# nosmurfs - This option only makes sense for ports +# on a bridge. +# +# Filter packets for smurfs +# (packets with a broadcast +# address as the source). +# +# Smurfs will be optionally logged based +# on the setting of SMURF_LOG_LEVEL in +# shorewall.conf. After logging, the +# packets are dropped. +# +# newnotsyn - TCP packets that don't have the SYN +# flag set and which are not part of an +# established connection will be accepted +# from these hosts, even if +# NEWNOTSYN=No has been specified in +# /etc/shorewall/shorewall.conf. +# +# This option has no effect if +# NEWNOTSYN=Yes. # #ZONE HOST(S) OPTIONS #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS LINE -- DO NOT REMOVE diff --git a/Shorewall/init b/Shorewall/init index 0d4564439..cdd21c79b 100644 --- a/Shorewall/init +++ b/Shorewall/init @@ -1,5 +1,5 @@ ############################################################################ -# Shorewall 1.4 -- /etc/shorewall/init +# Shorewall 2.0 -- /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/Shorewall/init.debian.sh b/Shorewall/init.debian.sh new file mode 100755 index 000000000..a0a9f18d5 --- /dev/null +++ b/Shorewall/init.debian.sh @@ -0,0 +1,129 @@ +#!/bin/sh + +SRWL=/sbin/shorewall +WAIT_FOR_IFUP=/usr/share/shorewall/wait4ifup +# Note, set INITLOG to /dev/null if you do not want to +# keep logs of the firewall (not recommended) +INITLOG=/var/log/shorewall-init.log + +test -x $SRWL || exit 0 +test -n $INITLOG || { + echo "INITLOG cannot be empty, please configure $0" ; + exit 1; +} + +if [ "$(id -u)" != "0" ] +then + echo "You must be root to start, stop or restart \"Shorewall firewall\"." + exit 1 +fi + +echo_notdone () { + + if [ "$INITLOG" = "/dev/null" ] ; then + "not done." + else + "not done (check $INITLOG)." + fi + +} + +not_configured () { + echo "#### WARNING ####" + echo "the firewall won't be started/stopped unless it is configured" + if [ "$1" != "stop" ] + then + echo "" + echo "please configure it and then edit /etc/default/shorewall" + echo "and set the \"startup\" variable to 1 in order to allow " + echo "shorewall to start" + fi + echo "#################" + exit 0 +} + +# parse the shorewall params file in order to use params in +# /etc/default/shorewall +if [ -f "/etc/shorewall/params" ] +then + . /etc/shorewall/params +fi + +# check if shorewall is configured or not +if [ -f "/etc/default/shorewall" ] +then + . /etc/default/shorewall + if [ "$startup" != "1" ] + then + not_configured + fi +else + not_configured +fi + +# wait an unconfigured interface +wait_for_pppd () { + if [ "$wait_interface" != "" ] + then + if [ -f $WAIT_FOR_IFUP ] + then + for i in $wait_interface + do + $WAIT_FOR_IFUP $i 90 + done + else + echo "$WAIT_FOR_IFUP: File not found" >> $INITLOG + echo_notdone + exit 2 + fi + fi +} + +# start the firewall +shorewall_start () { + echo -n "Starting \"Shorewall firewall\": " + wait_for_pppd + $SRWL -f start >> $INITLOG 2>&1 && echo "done." || echo_notdone + return 0 +} + +# stop the firewall +shorewall_stop () { + echo -n "Stopping \"Shorewall firewall\": " + $SRWL stop >> $INITLOG 2>&1 && echo "done." || echo_notdone + return 0 +} + +# restart the firewall +shorewall_restart () { + echo -n "Restarting \"Shorewall firewall\": " + $SRWL restart >> $INITLOG 2>&1 && echo "done." || echo_notdone + return 0 +} + +# refresh the firewall +shorewall_refresh () { + echo -n "Refreshing \"Shorewall firewall\": " + $SRWL refresh >> $INITLOG 2>&1 && echo "done." || echo_notdone + return 0 +} + +case "$1" in + start) + shorewall_start + ;; + stop) + shorewall_stop + ;; + refresh) + shorewall_refresh + ;; + force-reload|restart) + shorewall_restart + ;; + *) + echo "Usage: /etc/init.d/shorewall {start|stop|refresh|restart|force-reload}" + exit 1 +esac + +exit 0 diff --git a/Shorewall/init.sh b/Shorewall/init.sh index 70d6ff32e..c5ef93d27 100644 --- a/Shorewall/init.sh +++ b/Shorewall/init.sh @@ -1,14 +1,13 @@ #!/bin/sh RCDLINKS="2,S41 3,S41 6,K41" # -# The Shoreline Firewall (Shorewall) Packet Filtering Firewall - V1.4 3/14/2003 +# The Shoreline Firewall (Shorewall) Packet Filtering Firewall - V2.0 3/14/2003 # # 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 - Tom Eastep (teastep@shorewall.net) # -# On most distributions, this file should be called: -# /etc/rc.d/init.d/shorewall or /etc/init.d/shorewall +# On most distributions, this file should be called /etc/init.d/shorewall. # # Complete documentation is available at http://shorewall.net # @@ -63,7 +62,12 @@ command="$1" case "$command" in - stop|start|restart|status) + start) + + exec /sbin/shorewall -f start + ;; + + stop|restart|status) exec /sbin/shorewall $@ ;; diff --git a/Shorewall/initdone b/Shorewall/initdone new file mode 100755 index 000000000..35148d94a --- /dev/null +++ b/Shorewall/initdone @@ -0,0 +1,7 @@ +############################################################################ +# Shorewall 2.0 -- /etc/shorewall/initdone +# +# Add commands below that you want to be executed during +# "shorewall start" or "shorewall restart" commands at the point where +# Shorewall has not yet added any perminent rules to the builtin chains. +# diff --git a/Shorewall/install.sh b/Shorewall/install.sh index f55ec13b2..eab116a69 100755 --- a/Shorewall/install.sh +++ b/Shorewall/install.sh @@ -4,9 +4,9 @@ # # This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] # -# (c) 2000,2001,2002,2003 - Tom Eastep (teastep@shorewall.net) +# (c) 2000,2001,2002,2003,2004 - Tom Eastep (teastep@shorewall.net) # -# Seawall documentation is available at http://seawall.sourceforge.net +# Shorewall documentation is available at http://shorewall.net # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License @@ -21,47 +21,15 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA # -# Usage: -# -# If you are running a distribution that has a directory called /etc/rc.d/init.d or one -# called /etc/init.d or you are running Slackware then simply cd to the directory -# containing this script and run it. -# -# ./install.sh -# -# If you don't have either of those directories, you will need to determine where the -# SysVInit scripts are kept on your system and pass the name of that directory. -# -# ./install.sh /etc/rc.d/scripts -# -# The default is that the firewall will be started in run levels 2-5 starting at -# position 15 and stopping at position 90. This is correct RedHat/Mandrake, Debian, -# Caldera and Corel. -# -# If you wish to change that, you can pass -r "". -# -# Example 1: You wish to start your firewall in runlevels 2 and three, start at position -# 15 and stop at position 90 -# -# ./install.sh -r "23 15 90" -# -# Example 2: You wish to start your firewall only in run level 3, start at position 5 -# and stop at position 95. -# -# ./install.sh -r "3 5 95" /etc/rc.d/scripts -# -# For distributions that don't include chkconfig (Slackware, for example), the -# /etc/rc.d/rc.local file is modified to start the firewall. -# -VERSION=1.4.10d +VERSION=2.0.16 usage() # $1 = exit status { - ME=`basename $0` - echo "usage: $ME [ -r \"\" ] [ ]" - echo " $ME [ -v ]" - echo " $ME [ -h ]" + ME=$(basename $0) + echo "usage: $ME" + echo " $ME -v" + echo " $ME -h" exit $1 } @@ -77,7 +45,7 @@ run_install() cant_autostart() { echo - echo "WARNING: Unable to configure Shorewall to start" + echo "WARNING: Unable to configure shorewall to start" echo " automatically at boot" } @@ -105,20 +73,6 @@ delete_file() # $1 = file to delete fi } -modify_rclocal() -{ - if [ -f /etc/rc.d/rc.local ]; then - if [ -z "`grep shorewall /etc/rc.d/rc.local`" ]; then - cp -f /etc/rc.d/rc.local /etc/rc.d/rc.local-shorewall.bkout - echo >> /etc/rc.d/rc.local - echo "/sbin/shorewall start" >> /etc/rc.d/rc.local - echo "/etc/rc.d/rc.local modified to start Shorewall" - fi - else - cant_autostart - fi -} - install_file_with_backup() # $1 = source $2 = target $3 = mode { backup_file $2 @@ -129,13 +83,24 @@ install_file_with_backup() # $1 = source $2 = target $3 = mode # Parse the run line # # DEST is the SysVInit script directory +# INIT is the name of the script in the $DEST directory # RUNLEVELS is the chkconfig parmeters for firewall # ARGS is "yes" if we've already parsed an argument # -DEST="" -RUNLEVELS="" ARGS="" +if [ -z "$DEST" ] ; then + DEST="/etc/init.d" +fi + +if [ -z "$INIT" ] ; then + INIT="shorewall" +fi + +if [ -z "$RUNLEVELS" ] ; then + RUNLEVELS="" +fi + if [ -z "$OWNER" ] ; then OWNER=root fi @@ -147,34 +112,14 @@ fi while [ $# -gt 0 ] ; do case "$1" in -h|help|?) - if [ -n "$ARGS" ]; then - usage 1 - fi - usage 0 ;; - -r) - if [ -n "$RUNLEVELS" -o $# -eq 1 ]; then - usage 1 - fi - - RUNLEVELS="$2"; - shift - ;; -v) - if [ -n "$ARGS" ]; then - usage 1 - fi - echo "Shorewall Firewall Installer Version $VERSION" exit 0 ;; *) - if [ -n "$DEST" ]; then - usage 1 - fi - - DEST="$1" + usage 1 ;; esac shift @@ -186,44 +131,19 @@ PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin # # Determine where to install the firewall script # +DEBIAN= + if [ -n "$PREFIX" ]; then install -d -o $OWNER -g $GROUP -m 755 ${PREFIX}/sbin install -d -o $OWNER -g $GROUP -m 755 ${PREFIX}${DEST} -fi - -FIREWALL="shorewall" - -if [ -z "$DEST" ]; then - # - # We make this first test so that on RedHat systems that have Seawall installed, - # we can still use PREFIX (the code that reads the existing symbolic link - # fails dreadfully if the link is relative and PREFIX is non-null). - # - if [ -x /etc/rc.d/init.d/firewall ]; then - DEST=/etc/rc.d/init.d - elif [ -L /etc/shorewall/firewall ]; then - TEMP=`ls -l /etc/shorewall/firewall | sed 's/^.*> //'` - DEST=`dirname $TEMP` - FIREWALL=`basename $TEMP` - elif [ -d /etc/rc.d/init.d ]; then - DEST=/etc/rc.d/init.d - elif [ -d /etc/init.d ]; then - DEST=/etc/init.d - elif [ -f /etc/rc.d/rc.local ]; then - DEST=/etc/rc.d - FIREWALL="rc.shorewall" - else - echo "ERROR: Can't determine where to install the firewall script" - echo " Rerun $0 passing the name of the SysVInit script directory" - echo " on your system" - exit 1 - fi +elif [ -d /etc/apt -a -e /usr/bin/dpkg ]; then + DEBIAN=yes fi # # Change to the directory containing this script # -cd "`dirname $0`" +cd "$(dirname $0)" echo "Installing Shorewall Version $VERSION" @@ -239,52 +159,33 @@ fi install_file_with_backup shorewall ${PREFIX}/sbin/shorewall 0544 echo -echo "Shorewall control program installed in ${PREFIX}/sbin/shorewall" +echo "shorewall control program installed in ${PREFIX}/sbin/shorewall" # # Install the Firewall Script # -if [ -n "$RUNLEVELS" ]; then - # - # User specified chkconfig parameters -- build an awk script to install them - # in the firewall script - # - echo "/# chkconfig/ { print \"# chkconfig: $RUNLEVELS\" ; next }" > awk.temp - echo "{ print }" >> awk.temp - - awk -f awk.temp init.sh > init.temp - - if [ $? -ne 0 ]; then - echo - echo "ERROR: Error running awk." - echo " You must run `basename $0` without the "-r" option then edit" - echo " $DEST/$FIREWALL manually (line beginning '# chkconfig:')" - exit 1 - fi - - install_file_with_backup init.temp ${PREFIX}${DEST}/$FIREWALL 0544 - - rm -f init.temp awk.tmp +if [ -n "$DEBIAN" ]; then + install_file_with_backup init.debian.sh /etc/init.d/shorewall 0544 else - install_file_with_backup init.sh ${PREFIX}${DEST}/$FIREWALL 0544 + install_file_with_backup init.sh ${PREFIX}${DEST}/$INIT 0544 fi echo -echo "Shorewall script installed in ${PREFIX}${DEST}/$FIREWALL" +echo "Shorewall script installed in ${PREFIX}${DEST}/$INIT" # # Create /etc/shorewall, /usr/share/shorewall and /var/shorewall if needed # -mkdir -p ${PREFIX}/etc/shorewall -mkdir -p ${PREFIX}/usr/share/shorewall -mkdir -p ${PREFIX}/var/lib/shorewall +mkdir -p ${PREFIX}/etc/shorewall && chmod 700 ${PREFIX}/etc/shorewall +mkdir -p ${PREFIX}/usr/share/shorewall && chmod 700 ${PREFIX}/usr/share/shorewall +mkdir -p ${PREFIX}/var/lib/shorewall && chmod 700 ${PREFIX}/var/lib/shorewall # # Install the config file # if [ -f ${PREFIX}/etc/shorewall/shorewall.conf ]; then backup_file /etc/shorewall/shorewall.conf else - run_install -o $OWNER -g $GROUP -m 0744 shorewall.conf ${PREFIX}/etc/shorewall/shorewall.conf + run_install -o $OWNER -g $GROUP -m 0600 shorewall.conf ${PREFIX}/etc/shorewall/shorewall.conf echo echo "Config file installed as ${PREFIX}/etc/shorewall/shorewall.conf" fi @@ -294,7 +195,7 @@ fi if [ -f ${PREFIX}/etc/shorewall/zones ]; then backup_file /etc/shorewall/zones else - run_install -o $OWNER -g $GROUP -m 0744 zones ${PREFIX}/etc/shorewall/zones + run_install -o $OWNER -g $GROUP -m 0600 zones ${PREFIX}/etc/shorewall/zones echo echo "Zones file installed as ${PREFIX}/etc/shorewall/zones" fi @@ -307,11 +208,6 @@ if [ -f ${PREFIX}/etc/shorewall/functions ]; then rm -f ${PREFIX}/etc/shorewall/functions fi -if [ -f ${PREFIX}/var/lib/shorewall/functions ]; then - backup_file ${PREFIX}/var/lib/shorewall/functions - rm -f ${PREFIX}/var/lib/shorewall/functions -fi - install_file_with_backup functions ${PREFIX}/usr/share/shorewall/functions 0444 echo @@ -324,13 +220,6 @@ install_file_with_backup help ${PREFIX}/usr/share/shorewall/help 0544 echo echo "Help command executor installed in ${PREFIX}/usr/share/shorewall/help" -# -# Install the common.def file -# -install_file_with_backup common.def ${PREFIX}/etc/shorewall/common.def 0444 - -echo -echo "Common rules installed in ${PREFIX}/etc/shorewall/common.def" # # Delete the icmp.def file @@ -388,6 +277,16 @@ else echo "NAT file installed as ${PREFIX}/etc/shorewall/nat" fi # +# Install the NETMAP file +# +if [ -f ${PREFIX}/etc/shorewall/netmap ]; then + backup_file /etc/shorewall/netmap +else + run_install -o $OWNER -g $GROUP -m 0600 netmap ${PREFIX}/etc/shorewall/netmap + echo + echo "NETMAP file installed as ${PREFIX}/etc/shorewall/netmap" +fi +# # Install the Parameters file # if [ -f ${PREFIX}/etc/shorewall/params ]; then @@ -498,13 +397,21 @@ fi # # Install the rfc1918 file # -if [ -f ${PREFIX}/etc/shorewall/rfc1918 ]; then - backup_file /etc/shorewall/rfc1918 -else - run_install -o $OWNER -g $GROUP -m 0600 rfc1918 ${PREFIX}/etc/shorewall/rfc1918 - echo - echo "RFC 1918 file installed as ${PREFIX}/etc/shorewall/rfc1918" -fi +install_file_with_backup rfc1918 ${PREFIX}/usr/share/shorewall/rfc1918 0600 +echo +echo "RFC 1918 file installed as ${PREFIX}/usr/share/shorewall/rfc1918" +# +# Install the bogons file +# +install_file_with_backup bogons ${PREFIX}/usr/share/shorewall/bogons 0600 +echo +echo "Bogon file installed as ${PREFIX}/usr/share/shorewall/bogons" +# +# Install the default config path file +# +install_file_with_backup configpath ${PREFIX}/usr/share/shorewall/configpath 0600 +echo +echo " Default config path file installed as ${PREFIX}/usr/share/shorewall/configpath" # # Install the init file # @@ -516,6 +423,16 @@ else echo "Init file installed as ${PREFIX}/etc/shorewall/init" fi # +# Install the initdone file +# +if [ -f ${PREFIX}/etc/shorewall/initdone ]; then + backup_file /etc/shorewall/initdone +else + run_install -o $OWNER -g $GROUP -m 0600 initdone ${PREFIX}/etc/shorewall/initdone + echo + echo "Initdone file installed as ${PREFIX}/etc/shorewall/initdone" +fi +# # Install the start file # if [ -f ${PREFIX}/etc/shorewall/start ]; then @@ -566,25 +483,13 @@ else echo "Accounting file installed as ${PREFIX}/etc/shorewall/accounting" fi # -# Install the User Sets file # -if [ -f ${PREFIX}/etc/shorewall/usersets ]; then - backup_file /etc/shorewall/usersets -else - run_install -o $OWNER -g $GROUP -m 0600 usersets ${PREFIX}/etc/shorewall/usersets - echo - echo "User Sets file installed as ${PREFIX}/etc/shorewall/usersets" -fi +# Install the Standard Actions file # -# Install the User file -# -if [ -f ${PREFIX}/etc/shorewall/users ]; then - backup_file /etc/shorewall/users -else - run_install -o $OWNER -g $GROUP -m 0600 users ${PREFIX}/etc/shorewall/users - echo - echo "Users file installed as ${PREFIX}/etc/shorewall/users" -fi +install_file_with_backup actions.std ${PREFIX}/usr/share/shorewall/actions.std 0600 +echo +echo "Standard actions file installed as ${PREFIX}/etc/shorewall/actions.std" + # # Install the Actions file # @@ -596,27 +501,23 @@ else echo "Actions file installed as ${PREFIX}/etc/shorewall/actions" fi # -# Install the Action Template file +# Install the Action files # -if [ -f ${PREFIX}/etc/shorewall/action.template ]; then - backup_file /etc/shorewall/action.template -else - run_install -o $OWNER -g $GROUP -m 0600 action.template ${PREFIX}/etc/shorewall/action.template - echo - echo "Action Template file installed as ${PREFIX}/etc/shorewall/action.template" -fi +for f in action.* ; do + if [ -f ${PREFIX}/usr/share/shorewall/$f ]; then + backup_file /usr/share/shorewall/$f + else + run_install -o $OWNER -g $GROUP -m 0600 $f ${PREFIX}/usr/share/shorewall/$f + echo + echo "Action ${f#*.} file installed as ${PREFIX}/usr/share/shorewall/$f" + fi +done # # Backup the version file # if [ -z "$PREFIX" ]; then if [ -f /usr/share/shorewall/version ]; then backup_file /usr/share/shorewall/version - elif [ -f /usr/lib/shorewall/version ]; then - backup_file /usr/lib/shorewall/version - elif [ -n "$oldversion" ]; then - echo $oldversion > /usr/lib/shorewall/version-${VERSION}.bkout - else - echo "Unknown" > /usr/lib/shorewall/version-${VERSION}.bkout fi fi # @@ -629,54 +530,64 @@ chmod 644 ${PREFIX}/usr/share/shorewall/version # if [ -z "$PREFIX" ]; then - rm -f /etc/shorewall/firewall - rm -f /var/lib/shorewall/firewall - [ -L /usr/lib/shorewall/firewall ] && \ - mv -f /usr/lib/shorewall/firewall /usr/lib/shorewall/firewall-${VERSION}.bkout - rm -f /usr/lib/shorewall/init rm -f /usr/share/shorewall/init - ln -s ${DEST}/${FIREWALL} /usr/share/shorewall/init + ln -s ${DEST}/${INIT} /usr/share/shorewall/init fi + # # Install the firewall script # install_file_with_backup firewall ${PREFIX}/usr/share/shorewall/firewall 0544 -if [ -z "$PREFIX" -a -n "$first_install" ]; then - if [ -x /sbin/insserv -o -x /usr/sbin/insserv ]; then - if insserv /etc/init.d/shorewall ; then +if [ -z "$PREFIX" ]; then + if [ -n "$first_install" ]; then + if [ -n "$DEBIAN" ]; then + run_install -o $OWNER -g $GROUP -m 0644 default.debian /etc/default/shorewall + ln -s ../init.d/shorewall /etc/rcS.d/S40shorewall echo - echo "Firewall will start automatically at boot" + echo "shorewall will start automatically at boot" + echo "Set startup=1 in /etc/default/shorewall to enable" else - cant_autostart - fi - elif [ -x /sbin/chkconfig -o -x /usr/sbin/chkconfig ]; then - if chkconfig --add $FIREWALL ; then - echo - echo "Firewall will start automatically in run levels as follows:" - chkconfig --list $FIREWALL - else - cant_autostart - fi - elif [ -x /sbin/rc-update ]; then - if rc-update add shorewall default; then - echo - echo "Firewall will start automatically at boot" - else - cant_autostart - fi - else - modify_rclocal - fi - - echo \ + if [ -x /sbin/insserv -o -x /usr/sbin/insserv ]; then + if insserv /etc/init.d/shorewall ; then + echo + echo "shorewall will start automatically at boot" + echo "Remove /etc/shorewall/startup_disabled in /etc/default/shorewall to enable" + else + cant_autostart + fi + elif [ -x /sbin/chkconfig -o -x /usr/sbin/chkconfig ]; then + if chkconfig --add shorewall ; then + echo + echo "shorewall will start automatically in run levels as follows:" + echo "Remove /etc/shorewall/startup_disabled in /etc/default/shorewall to enable" + chkconfig --list shorewall + else + cant_autostart + fi + elif [ -x /sbin/rc-update ]; then + if rc-update add shorewall default; then + echo + echo "shorewall will start automatically at boot" + echo "Remove /etc/shorewall/startup_disabled in /etc/default/shorewall to enable" + else + cant_autostart + fi + elif [ "$INIT" != rc.firewall ]; then #Slackware starts this automatically + cant_autostart + fi + + echo \ "######################################################################## # REMOVE THIS FILE AFTER YOU HAVE CONFIGURED SHOREWALL # ########################################################################" > /etc/shorewall/startup_disabled -fi - + fi + elif [ -n "$DEBIAN" -a ! -f /etc/default/shorewall ]; then + run_install -o $OWNER -g $GROUP -m 0644 default.debian /etc/default/shorewall + fi +fi # # Report Success # echo -echo "Shorewall Version $VERSION Installed" +echo "shorewall Version $VERSION Installed" diff --git a/Shorewall/interfaces b/Shorewall/interfaces index d60544a0d..01ed6f353 100644 --- a/Shorewall/interfaces +++ b/Shorewall/interfaces @@ -1,5 +1,5 @@ # -# Shorewall 1.4 -- Interfaces File +# Shorewall 2.0 -- Interfaces File # # /etc/shorewall/interfaces # @@ -24,11 +24,12 @@ # want to make an entry that applies to all PPP # interfaces, use 'ppp+'. # -# DO NOT DEFINE THE LOOPBACK INTERFACE (lo) IN THIS FILE. +# There is no need to define the loopback interface (lo) +# in this file. # # BROADCAST The broadcast address for the subnetwork to which the # interface belongs. For P-T-P interfaces, this -# column is left black.If the interface has multiple +# column is left blank.If the interface has multiple # addresses on multiple subnets then list the broadcast # addresses as a comma-separated list. # @@ -36,8 +37,7 @@ # will detect the broadcast address for you. If you # select this option, the interface must be up before # the firewall is started, you must have iproute -# installed and the interface must only be associated -# with a single subnet. +# installed. # # If you don't want to give a value for this column but # you want to enter a value in the OPTIONS column, enter @@ -46,38 +46,51 @@ # OPTIONS A comma-separated list of options including the # following: # -# dhcp - interface is managed by DHCP or used by -# a DHCP server running on the firewall or -# you have a static IP but are on a LAN -# segment with lots of Laptop DHCP clients. +# dhcp - Specify this option when any of +# the following are true: +# 1. the interface gets its IP address +# via DHCP +# 2. the interface is used by +# a DHCP server running on the firewall +# 3. you have a static IP but are on a LAN +# segment with lots of Laptop DHCP +# clients. +# 4. the interface is a bridge with +# a DHCP server on one port and DHCP +# clients on another port. +# # norfc1918 - This interface should not receive # any packets whose source is in one # of the ranges reserved by RFC 1918 # (i.e., private or "non-routable" -# addresses. If packet mangling is -# enabled in shorewall.conf, packets -# whose destination addresses are -# reserved by RFC 1918 are also rejected. +# addresses. If packet mangling or +# connection-tracking match is enabled in +# your kernel, packets whose destination +# addresses are reserved by RFC 1918 are +# also rejected. +# +# nobogons - This interface should not receive +# any packets whose source is in one +# of the ranges reserved by IANA (this +# option does not cover those ranges +# reserved by RFC 1918 -- see above). +# # 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. -# dropunclean - Logs and drops mangled/invalid -# packets. USE OF THIS OPTION IS -# NOT RECOMMENDED. It will be removed in -# Shorewall 2.0. -# logunclean - Logs mangled/invalid packets but does -# not drop them. This option will be -# removed in Shorewall 2.0. +# # . . blacklist - Check packets arriving on this interface # against the /etc/shorewall/blacklist # file. +# # maclist - Connection requests from this interface # are compared against the contents of # /etc/shorewall/maclist. If this option # is specified, the interface must be # an ethernet NIC and must be up before # Shorewall is started. +# # tcpflags - Packets arriving on this interface are # checked for certain illegal combinations # of TCP flags. Packets found to have @@ -86,6 +99,7 @@ # TCP_FLAGS_DISPOSITION after having been # logged according to the setting of # TCP_FLAGS_LOG_LEVEL. +# # proxyarp - # Sets # /proc/sys/net/ipv4/conf//proxy_arp. @@ -101,11 +115,21 @@ # established connection will be accepted # from this interface, even if # NEWNOTSYN=No has been specified in -# /etc/shorewall/shorewall.conf. +# /etc/shorewall/shorewall.conf. In other +# words, packets coming in on this interface +# are processed as if NEWNOTSYN=Yes had been +# specified in /etc/shorewall/shorewall.conf. # # This option has no effect if # NEWNOTSYN=Yes. # +# It is the opinion of the author that +# NEWNOTSYN=No creates more problems than +# it solves and I recommend against using +# that setting in shorewall.conf (hence +# making the use of the 'newnotsyn' +# interface option unnecessary). +# # routeback - If specified, indicates that Shorewall # should include rules that allow filtering # traffic arriving on this interface back @@ -120,12 +144,21 @@ # interface. The interface must be up # when Shorewall is started. # +# nosmurfs - Filter packets for smurfs +# (packets with a broadcast +# address as the source). +# +# Smurfs will be optionally logged based +# on the setting of SMURF_LOG_LEVEL in +# shorewall.conf. After logging, the +# packets are dropped. +# # detectnets - Automatically taylors the zone named # in the ZONE column to include only those # hosts routed through the interface. # # WARNING: DO NOT SET THE detectnets OPTION ON YOUR -# INTERNET INTERFACE! +# INTERNET INTERFACE. # # The order in which you list the options is not # significant but the list should have no embedded white @@ -157,4 +190,5 @@ # net ppp0 - ############################################################################## #ZONE INTERFACE BROADCAST OPTIONS +# #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/maclist b/Shorewall/maclist index 91b5e0f35..3374fd83c 100644 --- a/Shorewall/maclist +++ b/Shorewall/maclist @@ -1,11 +1,14 @@ # -# Shorewall 1.4 - MAC list file +# Shorewall 2.0 - MAC list file # # /etc/shorewall/maclist # # Columns are: # -# INTERFACE Network interface to a host +# INTERFACE Network interface to a host. If the interface +# names a bridge, it may be optionally followed by +# a colon (":") and a physical port name (e.g., +# br0:eth4). # # MAC MAC address of the host -- you do not need to use # the Shorewall format for MAC addresses here diff --git a/Shorewall/masq b/Shorewall/masq index 4dd27564f..45bac35b6 100755 --- a/Shorewall/masq +++ b/Shorewall/masq @@ -1,5 +1,5 @@ # -# Shorewall 1.4 - Masquerade file +# Shorewall 2.0 - Masquerade file # # /etc/shorewall/masq # @@ -18,12 +18,7 @@ # PLACE IN YOUR SHOREWALL CONFIGURATION. # # This may be qualified by adding the character -# ":" followed by a comma-separed list of -# destination hosts or subnets. If this list begins with -# "!" then masquerading will occur if and only if the -# connection destination is NOT included in the list. -# Otherwise, the masquerading will occur if and only if -# the destination IS included in the list. +# ":" followed by a destination host or subnet. # # # SUBNET -- Subnet that you wish to masquerade. You can specify this as @@ -47,6 +42,13 @@ # 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 @@ -60,6 +62,27 @@ # # This column may not contain DNS Names. # +# If you want to leave this column empty +# but you need to specify the next column then +# place a hyphen ("-") here. +# +# PROTO -- (Optional) If you wish to restrict this entry to a +# particular protocol then enter the protocol +# name (from /etc/protocols) or number here. +# +# PORT(S) -- (Optional) If the PROTO column specifies TCP (protocol 6) +# or UDP (protocol 17) then you may list one +# or more port numbers (or names from +# /etc/services) separated by commas or you +# may list a single port range +# (:). +# +# Where a comma-separated list is given, your +# kernel and iptables must have multiport match +# support and a maximum of 15 ports may be +# listed. +# +# # Example 1: # # You have a simple masquerading setup where eth0 connects to @@ -94,11 +117,24 @@ # # You want all outgoing traffic from 192.168.1.0/24 through # eth0 to use source address 206.124.146.176 which is NOT the -# primary address of eth0. You want 206.124.146.176 to +# primary address of eth0. You want 206.124.146.176 added to # be added to eth0 with name eth0:0. # # eth0:0 192.168.1.0/24 206.124.146.176 # -############################################################################## -#INTERFACE SUBNET ADDRESS +# Example 5: +# +# You want all outgoing SMTP traffic entering the firewall +# on eth1 to be sent from eth0 with source IP address +# 206.124.146.177. You want all other outgoing traffic +# from eth1 to be sent from eth0 with source IP address +# 206.124.146.176. +# +# eth0 eth1 206.124.146.177 tcp smtp +# eth0 eth1 206.124.146.176 +# +# THE ORDER OF THE ABOVE TWO RULES IS SIGNIFICANT!!!!! +# +############################################################################### +#INTERFACE SUBNET ADDRESS PROTO PORT(S) #LAST LINE -- ADD YOUR ENTRIES ABOVE THIS LINE -- DO NOT REMOVE diff --git a/Shorewall/modules b/Shorewall/modules index 45db4e93c..6621f36b3 100644 --- a/Shorewall/modules +++ b/Shorewall/modules @@ -1,5 +1,5 @@ ############################################################################## -# Shorewall 1.4 /etc/shorewall/modules +# Shorewall 2.0 /etc/shorewall/modules # # This file loads the modules needed by the firewall. # diff --git a/Shorewall/nat b/Shorewall/nat index 7bbbcd54d..dbd44c4f0 100755 --- a/Shorewall/nat +++ b/Shorewall/nat @@ -1,6 +1,6 @@ ############################################################################## # -# Shorewall 1.4 -- Network Address Translation Table +# Shorewall 2.0 -- Network Address Translation Table # # /etc/shorewall/nat # @@ -16,7 +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 we want to EXTERNAL address to appear +# 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 # indicate that you want Shorewall to add the alias @@ -25,12 +25,11 @@ # THAT THIS NAME IS GOOD FOR -- YOU CANNOT USE IT # ANYWHERE ELSE IN YOUR SHORWALL CONFIGURATION. # INTERNAL Internal Address (must not be a DNS Name). -# ALL INTERFACES If Yes or yes (or left empty), NAT will be effective -# from all hosts. If No or no then NAT will be effective +# 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 and the ALL INTERFACES column contains -# Yes or yes, NAT will be effective from the firewall +# LOCAL If Yes or yes, NAT will be effective from the firewall # system ############################################################################## #EXTERNAL INTERFACE INTERNAL ALL LOCAL diff --git a/Shorewall/netmap b/Shorewall/netmap new file mode 100644 index 000000000..8b57af253 --- /dev/null +++ b/Shorewall/netmap @@ -0,0 +1,38 @@ +############################################################################## +# +# Shorewall 2.0 -- Network Mapping Table +# +# /etc/shorewall/netmap +# +# This file is used to map addresses in one network to corresponding +# addresses in a second network. +# +# WARNING: To use this file, your kernel and iptables must have +# NETMAP support included. +# +# Columns must be separated by white space and are: +# +# TYPE Must be DNAT or SNAT. +# +# If DNAT, traffic entering INTERFACE and addressed to +# NET1 has it's destination address rewritten to the +# corresponding address in NET2. +# +# If SNAT, traffic leaving INTERFACE with a source +# address in NET1 has it's source address rewritten to +# the corresponding address in NET2. +# +# NET1 Network in CIDR format (e.g., 192.168.1.0/24) +# +# INTERFACE The name of a network interface. The interface must +# be defined in /etc/shorewall/interfaces. +# +# NET2 Network in CIDR format +# +# See http://shorewall.net/netmap.html for an example and usage +# information. +# +############################################################################## +#TYPE NET1 INTERFACE NET2 +# +#LAST LINE -- ADD YOUR ENTRIES ABOVE THIS LINE -- DO NOT REMOVE diff --git a/Shorewall/params b/Shorewall/params index ba53d6446..5873bf90a 100644 --- a/Shorewall/params +++ b/Shorewall/params @@ -1,5 +1,5 @@ # -# Shorewall 1.4 /etc/shorewall/params +# Shorewall 2.0 /etc/shorewall/params # # Assign any variables that you need here. # diff --git a/Shorewall/policy b/Shorewall/policy index a32d6ba4e..d56b67ea7 100644 --- a/Shorewall/policy +++ b/Shorewall/policy @@ -1,15 +1,14 @@ # -# Shorewall 1.4 -- Policy File +# Shorewall 2.0 -- Policy File # # /etc/shorewall/policy # # THE ORDER OF ENTRIES IN THIS FILE IS IMPORTANT # # This file determines what to do with a new connection request if we -# don't get a match from the /etc/shorewall/rules file or from the -# /etc/shorewall/common[.def] file. For each source/destination pair, the -# file is processed in order until a match is found ("all" will match -# any client or server). +# don't get a match from the /etc/shorewall/rules file . For each +# source/destination pair, the file is processed in order until a +# match is found ("all" will match any client or server). # # Columns are: # @@ -19,10 +18,6 @@ # DEST Destination zone. Must be the name of a zone defined # in /etc/shorewall/zones, $FW or "all" # -# WARNING: Firewall->Firewall policies are not allowed; if -# you have a policy where both SOURCE and DEST are $FW, -# Shorewall will not start! -# # POLICY Policy if no match from the rules file is found. Must # be "ACCEPT", "DROP", "REJECT", "CONTINUE" or "NONE". # @@ -47,6 +42,12 @@ # SOURCE or DEST columns contain the # firewall zone ($FW) or "all". # +# If this column contains ACCEPT, DROP or REJECT and a +# corresponding common action is defined in +# /etc/shorewall/actions (or /usr/share/shorewall/actions.std) +# then that action will be invoked before the policy named in +# this column is inforced. +# # LOG LEVEL If supplied, each connection handled under the default # POLICY is logged at that level. If not supplied, no # log message is generated. See syslog.conf(5) for a @@ -59,7 +60,7 @@ # (http://www.gnumonks.org/projects/ulogd). # # If you don't want to log but need to specify the -# following column, place "_" here. +# following column, place "-" here. # # LIMIT:BURST If passed, specifies the maximum TCP connection rate # and the size of an acceptable burst. If not specified, diff --git a/Shorewall/proxyarp b/Shorewall/proxyarp index 81c88a512..b21a4f432 100644 --- a/Shorewall/proxyarp +++ b/Shorewall/proxyarp @@ -1,6 +1,6 @@ ############################################################################## # -# Shorewall 1.4 -- Proxy ARP +# Shorewall 2.0 -- Proxy ARP # # /etc/shorewall/proxyarp # @@ -9,22 +9,36 @@ # Columns must be separated by white space and are: # # ADDRESS IP Address +# # INTERFACE Local interface where system is connected. If the # local interface is obvious from the subnetting, # you may enter "-" in this column. +# # EXTERNAL External Interface to be used to access this system # # HAVEROUTE If there is already a route from the firewall to # the host whose address is given, enter "Yes" or "yes" # in this column. Otherwise, entry "no", "No" or leave -# the column empty. +# the column empty and Shorewall will add the route for +# you. If Shorewall adds the route,the route will be +# persistent if the PERSISTENT column contains Yes; +# otherwise, "shorewall stop" or "shorewall clear" will +# delete the route. +# +# PERSISTENT If HAVEROUTE is No or "no", then the value of this +# column determines if the route added by Shorewall +# persists after a "shorewall stop" or a "shorewall +# clear". If this column contains "Yes" or "yes" then +# the route persists; If the column is empty or contains +# "No"or "no" then the route is deleted at "shorewall +# stop" or "shorewall clear". # # Example: Host with IP 155.186.235.6 is connected to # interface eth1 and we want hosts attached via eth0 # to be able to access it using that address. # -# #ADDRESS INTERFACE EXTERNAL HAVEROUTE -# 155.186.235.6 eth1 eth0 No +# #ADDRESS INTERFACE EXTERNAL +# 155.186.235.6 eth1 eth0 ############################################################################## -#ADDRESS INTERFACE EXTERNAL HAVEROUTE +#ADDRESS INTERFACE EXTERNAL HAVEROUTE PERSISTENT #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/releasenotes.txt b/Shorewall/releasenotes.txt index fc095b45c..4642131c2 100755 --- a/Shorewall/releasenotes.txt +++ b/Shorewall/releasenotes.txt @@ -1,89 +1,301 @@ -This is a minor release of Shorewall. +Shorewall 2.0.16 -Problems Corrected since version 1.4.9: +---------------------------------------------------------------------- +Problems Corrected in version 2.0.4 -1. The column descriptions in the action.template file did not match - the column headings. That has been corrected. +1) A DNAT rule with 'fw' as the source that specified logging caused + "shorewall start" to fail. -2. The presence of IPV6 addresses on devices generates error messages - during [re]start if ADD_IP_ALIASES=Yes or ADD_SNAT_ALIASES=Yes are - specified in /etc/shorewall/shorewall.conf. +---------------------------------------------------------------------- +Problems Corrected in version 2.0.5 -3. The CONTINUE action in /etc/shorewall/rules now works correctly. A - couple of problems involving rate limiting have been - corrected. These bug fixes courtesy of Steven Jan Springl. +1) Eliminated "$RESTOREBASE: ambiguous redirect" messages during + "shorewll stop" in the case where DISABLE_IPV6=Yes in + shorewall.conf. -4. Shorewall now tries to avoid sending an ICMP response to broadcasts - and smurfs. +2) An anachronistic reference to the mangle option was removed from + shorewall.conf. -5. Specifying "-" or "all" in the PROTO column of an action no longer - causes a startup error. +---------------------------------------------------------------------- +Problems Corrected in version 2.0.6 -6. Fixed a problem in which the firewall would encounter an error - during startup while processing the /etc/shorewall/masq file. +1) Some users have reported the pkttype match option in iptables/ + Netfilter failing to match certain broadcast packets. The result + is that the firewall log shows a lot of broadcast packets. -7. Atheros WiFi cards were previously excluded from use with the - "maclist" interface option. + Other users have complained of the following message when + starting Shorewall: -8. (Fix from Steven Jan Springl) In the /etc/shorewall/masq entry + modprobe: cant locate module ipt_pkttype - eth0:!10.1.1.150  0.0.0.0/0!10.1.0.0/16     10.1.2.16 + Users experiencing either of these problems can use PKTTYPE=No in + shorewall.conf to cause Shorewall to use IP address filtering of + broadcasts rather than packet type. - the !10.1.0.0/16 is ignored. +2) The shorewall.conf and zones file are no longer given execute + permission by the installer script. -9. A startup error occurs if the USER/GROUP column of the tcrules file - is empty. +3) ICMP packets that are in the INVALID state are now dropped by the + Reject and Drop default actions. They do so using the new + 'dropInvalid' builtin action. +----------------------------------------------------------------------- +Problems Corrected in version 2.0.7 -10. The following syntax previously produced a startup error: +1) The PKTTYPE option introduced in version 2.0.6 is now used when + generating rules to REJECT packets. Broadcast packets are silently + dropped rather than being rejected with an ICMP (which is a protocol + violation) and users whose kernels have broken packet type match + support are likely to see messages reporting this violation. + Setting PKTTYPE=No should cause these messages to cease. - DNAT z1!z2,z3 z4:... +2) Multiple interfaces with the 'blacklist' option no longer result in + an error message at startup. - That has been corrected so that multiple excluded zones may now be - listed in a DNAT or REDIRECT rule. +3) The following has been added to /etc/shorewall/bogons: -11. Use of user-defined actions frequently resulted in a WARNING that - the rule was a policy. + 0.0.0.0 RETURN -12. Thanks to Sean Mathews, a long-standing problem with proxy ARP and - IPSEC has been corrected!! + This prevents the 'nobogons' option from logging DHCP 'DISCOVER' + broadcasts. +----------------------------------------------------------------------- +New Features in version 2.0.7 -Migration Issues: - -None. - -New Features: - -1) The INTERFACE column in the /etc/shorewall/masq file may now - specify a destination list. +1) To improve supportability, the "shorewall status" command now + includes IP and Route configuration information. Example: - #INTERFACE SUBNET ADDRESS - eth0:192.0.2.3,192.0.2.16/28 eth1 + IP Configuration - If the list begins with "!" then SNAT will occur only if the - destination IP address is NOT included in the list. + 1: lo: mtu 16436 qdisc noqueue + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + inet 127.0.0.1/8 brd 127.255.255.255 scope host lo + inet6 ::1/128 scope host + 2: eth0: mtu 1500 qdisc pfifo_fast qlen 1000 + link/ether 00:a0:c9:15:39:78 brd ff:ff:ff:ff:ff:ff + inet6 fe80::2a0:c9ff:fe15:3978/64 scope link + 3: eth1: mtu 1500 qdisc pfifo_fast qlen 1000 + link/ether 00:a0:c9:a7:d7:bf brd ff:ff:ff:ff:ff:ff + inet6 fe80::2a0:c9ff:fea7:d7bf/64 scope link + 5: sit0@NONE: mtu 1480 qdisc noop + link/sit 0.0.0.0 brd 0.0.0.0 + 6: eth2: mtu 1500 qdisc pfifo_fast qlen 1000 + link/ether 00:40:d0:07:3a:1b brd ff:ff:ff:ff:ff:ff + inet6 fe80::240:d0ff:fe07:3a1b/64 scope link + 7: br0: mtu 1500 qdisc noqueue + link/ether 00:40:d0:07:3a:1b brd ff:ff:ff:ff:ff:ff + inet 192.168.1.3/24 brd 192.168.1.255 scope global br0 + inet6 fe80::240:d0ff:fe07:3a1b/64 scope link -2) Output traffic control rules (those with the firewall as the source) - may now be qualified by the effective userid and/or effective group - id of the program generating the output. This feature is courtesy of - Frédéric LESPEZ. + Routing Rules - A new USER column has been added to /etc/shorewall/tcrules. + 0: from all lookup local + 32765: from all fwmark ca lookup www.out + 32766: from all lookup main + 32767: from all lookup default - It may contain : + Table local: - []:[] + broadcast 192.168.1.0 dev br0 proto kernel scope link src 192.168.1.3 + broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1 + local 192.168.1.3 dev br0 proto kernel scope host src 192.168.1.3 + broadcast 192.168.1.255 dev br0 proto kernel scope link src 192.168.1.3 + broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1 + local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1 + local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1 - The colon is optionnal when specifying only a user. + Table www.out: - Examples : john: / john / :users / john:users + default via 192.168.1.3 dev br0 -3) A "detectnets" interface option has been added for entries in - /etc/shorewall/interfaces. This option automatically taylors the - definition of the zone named in the ZONE column to include just - those hosts that have routes through the interface named in the - INTERFACE column. The named interface must be UP when - Shorewall is [re]started. + Table main: - WARNING: DO NOT SET THIS OPTION ON YOUR INTERNET INTERFACE! + 192.168.1.0/24 dev br0 proto kernel scope link src 192.168.1.3 + default via 192.168.1.254 dev br0 + + Table default: +----------------------------------------------------------------------- +Problems Corrected in version 2.0.8 + +1) User/group restricted rules now work in actions. + +----------------------------------------------------------------------- +Problems Corrected in version 2.0.9 + +1) Previously, an empty PROTO column or a value of "all" in that column + would cause errors when processing the /etc/shorewall/tcrules file. + +New Fewatures in version 2.0.9 + +1) The "shorewall status" command now includes the output of "brctl + show" if the bridge tools are installed. +----------------------------------------------------------------------- +Problems corrected in version 2.0.10 + +1) The GATEWAY column was previously ignored in 'pptpserver' entries in + /etc/shorewall/tunnels. + +2) When log rule numbers are included in the LOGFORMAT, duplicate + rule numbers could previously be generated. + +3) The /etc/shorewall/tcrules file now includes a note to the effect + that rule evaluation continues after a match. + +4) The error message produced if Shorewall couldn't obtain the routes + through an interface named in the SUBNET column of + /etc/shorewall/masq was less than helpful since it didn't include + the interface name. +----------------------------------------------------------------------- +New Features in 2.0.10 + +The "shorewall status" command has been enhanced to include the values +of key /proc settings: + +Example from a two-interface firewall: + +/proc + + /proc/sys/net/ipv4/ip_forward = 1 + /proc/sys/net/ipv4/conf/all/proxy_arp = 0 + /proc/sys/net/ipv4/conf/all/arp_filter = 0 + /proc/sys/net/ipv4/conf/all/rp_filter = 0 + /proc/sys/net/ipv4/conf/default/proxy_arp = 0 + /proc/sys/net/ipv4/conf/default/arp_filter = 0 + /proc/sys/net/ipv4/conf/default/rp_filter = 0 + /proc/sys/net/ipv4/conf/eth0/proxy_arp = 0 + /proc/sys/net/ipv4/conf/eth0/arp_filter = 0 + /proc/sys/net/ipv4/conf/eth0/rp_filter = 0 + /proc/sys/net/ipv4/conf/eth1/proxy_arp = 0 + /proc/sys/net/ipv4/conf/eth1/arp_filter = 0 + /proc/sys/net/ipv4/conf/eth1/rp_filter = 0 + /proc/sys/net/ipv4/conf/lo/proxy_arp = 0 + /proc/sys/net/ipv4/conf/lo/arp_filter = 0 + /proc/sys/net/ipv4/conf/lo/rp_filter = 0 + +----------------------------------------------------------------------- +Problems corrected in 2.0.11 + +1) The INSTALL file now include special instructions for Slackware + users. + +2) The bogons file has been updated. + +3) Service names are replaced by port numbers in /etc/shorewall/tos. + +4) A typo in the install.sh file that caused an error during a new +install has been corrected. +----------------------------------------------------------------------- +New Features in 2.0.11 + +1) The AllowNNTP action now allows NNTP over SSL/TLS (NTTPS). + +----------------------------------------------------------------------- +Problems corrected in 2.0.12 + +1) A typo in shorewall.conf (NETNOTSYN) has been corrected. + +2) The "shorewall add" and "shorewall delete" commands now work in a + bridged environment. The syntax is: + + shorewall add [:]:
+ shorewall delete [:]:
+ + Examples: + + shorewall add br0:eth2:192.168.1.3 OK + shorewall delete br0:eth2:192.168.1.3 OK + +3) Previously, "shorewall save" created an out-of-sequence restore + script. The commands saved in the user's /etc/shorewall/start script + were executed prior to the Netfilter configuration being + restored. This has been corrected so that "shorewall save" now + places those commands at the end of the script. + + To accomplish this change, the "restore base" file + (/var/lib/shorewall/restore-base) has been split into two files: + + /var/lib/shorewall/restore-base -- commands to be executed before + Netfilter the configuration is restored. + + /var/lib/shorewall/restore-tail -- commands to be executed after the + Netfilter configuration is restored. + +4) Previously, traffic from the firewall to a dynamic zone member host + did not need to match the interface specified when the host was + added to the zone. For example, if eth0:1.2.3.4 is added to dynamic + zone Z then traffic out of any firewall interface to 1.2.3.4 will + obey the fw->Z policies and rules. This has been corrected. + +----------------------------------------------------------------------- +New Features in 2.0.12 + +1) Variable expansion may now be used with the INCLUDE directive. + + Example: + + /etc/shorewall/params + + FILE=/etc/foo/bar + + Any other config file: + + INCLUDE $FILE +----------------------------------------------------------------------- +Problems corrected in 2.0.13 + +1) A typo in /usr/share/shorewall/firewall caused the following: + + /usr/share/shorewall/firewall: line 1: match_destination_hosts: command + not found +----------------------------------------------------------------------- +New Features in 2.0.14 + +1) Previously, when rate-limiting was specified in + /etc/shorewall/policy (LIMIT:BURST column), any traffic which + exceeded the specified rate was silently dropped. Now, if a log + level is given in the entry (LEVEL column) then drops are logged at + that level at a rate of 5/min with a burst of 5. +----------------------------------------------------------------------- +Problems corrected in 2.0.14 + +1) A typo in the /etc/shorewall/interfaces file has been fixed. + +2) "bad variable" error messages occurring during "shorewall stop" and + "shorewall clear" have been eliminated. + +3) A misleading typo in /etc/shorewall/tunnels has been corrected. +----------------------------------------------------------------------- +Problems corrected in 2.0.15 + +1) The range of ports opened by the AllowTrcrt action has been + expanded to 33434:33524. + +2) Code mis-ported from 2.2.0 caused the following error during + "shorewall start" where SYN rate-limiting is present in + /etc/shorewall/policy: + + Bad argument `DROP' + Try `iptables -h' or 'iptables --help' for more information. +----------------------------------------------------------------------- +New Features in 2.0.16 + +1) Recent 2.6 kernels include code that evaluates TCP packets based on + TCP Window analysis. This can cause packets that were previously + classified as NEW or ESTABLISHED to be classified as INVALID. + + The new kernel code can be disabled by including this command in + your /etc/shorewall/init file: + + echo 1 > /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_be_liberal + + Additional kernel logging about INVALID TCP packets may be + obtained by adding this command to /etc/shorewall/init: + + echo 1 > /proc/sys/net/ipv4/netfilter/ip_conntrack_log_invalid + + Traditionally, Shorewall has dropped INVALID TCP packets early. The + new DROPINVALID option allows INVALID packets to be passed through + the normal rules chains by setting DROPINVALID=No. + + If not specified or if specified as empty (e.g., DROPINVALID="") + then DROPINVALID=Yes is assumed. diff --git a/Shorewall/rfc1918 b/Shorewall/rfc1918 index ae9010d9c..42bd82e3d 100644 --- a/Shorewall/rfc1918 +++ b/Shorewall/rfc1918 @@ -1,13 +1,14 @@ # -# Shorewall 1.4 -- RFC1918 File +# Shorewall 2.0-- RFC1918 File # # /etc/shorewall/rfc1918 # # Lists the subnetworks that are blocked by the 'norfc1918' interface option. # -# The default list includes those IP addresses listed in RFC 1918, those listed -# as 'reserved' by the IANA, the DHCP Autoconfig class B, and the class C -# reserved for use in documentation and examples. +# The default list includes those IP addresses listed in RFC 1918. +# +# DO NOT MODIFY THIS FILE. IF YOU NEED TO MAKE CHANGES, COPY THE FILE +# TO /etc/shorewall AND MODIFY THE COPY. # # Columns are: # @@ -19,45 +20,7 @@ # ############################################################################### #SUBNET TARGET -255.255.255.255 RETURN # We need to allow limited broadcast -169.254.0.0/16 DROP # DHCP autoconfig 172.16.0.0/12 logdrop # RFC 1918 -192.0.2.0/24 logdrop # Example addresses (RFC 3330) 192.168.0.0/16 logdrop # RFC 1918 -# -# The following are generated with the help of the Python program found at: -# -# http://www.shorewall.net/pub/shorewall/contrib/iana_reserved/ -# -# The program was contributed by Andy Wiggin -# -0.0.0.0/7 logdrop # Reserved -2.0.0.0/8 logdrop # Reserved -5.0.0.0/8 logdrop # Reserved -7.0.0.0/8 logdrop # Reserved -10.0.0.0/8 logdrop # Reserved -23.0.0.0/8 logdrop # Reserved -27.0.0.0/8 logdrop # Reserved -31.0.0.0/8 logdrop # Reserved -36.0.0.0/7 logdrop # Reserved -39.0.0.0/8 logdrop # Reserved -41.0.0.0/8 logdrop # Reserved -42.0.0.0/8 logdrop # Reserved -49.0.0.0/8 logdrop # JTC - Returned to IANA Mar 98 -50.0.0.0/8 logdrop # JTC - Returned to IANA Mar 98 -58.0.0.0/7 logdrop # Reserved -71.0.0.0/8 logdrop # Reserved -72.0.0.0/5 logdrop # Reserved -85.0.0.0/8 logdrop # Reserved -86.0.0.0/7 logdrop # Reserved -88.0.0.0/5 logdrop # Reserved -96.0.0.0/3 logdrop # Reserved -127.0.0.0/8 logdrop # Loopback -197.0.0.0/8 logdrop # Reserved -198.18.0.0/15 logdrop # Reserved -223.0.0.0/8 logdrop # Reserved - Returned by APNIC in 2003 -240.0.0.0/4 logdrop # Reserved -# -# End of generated entries -# +10.0.0.0/8 logdrop # RFC 1918 #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/routestopped b/Shorewall/routestopped index 55698c986..8d5a0b41c 100644 --- a/Shorewall/routestopped +++ b/Shorewall/routestopped @@ -1,6 +1,6 @@ ############################################################################## # -# Shorewall 1.4 -- Hosts Accessible when the Firewall is Stopped +# Shorewall 2.0 -- Hosts Accessible when the Firewall is Stopped # # /etc/shorewall/routestopped # @@ -14,12 +14,18 @@ # HOST(S) - (Optional) Comma-separated list of IP/subnet # If left empty or supplied as "-", # 0.0.0.0/0 is assumed. +# OPTIONS - (Optional) A comma-separated list of +# options. The currently-supported options are: +# +# routeback - Set up a rule to ACCEPT traffic from +# these hosts back to themselves. # # Example: # -# INTERFACE HOST(S) +# INTERFACE HOST(S) OPTIONS # eth2 192.168.1.0/24 # eth0 192.0.2.44 +# br0 - routeback ############################################################################## -#INTERFACE HOST(S) +#INTERFACE HOST(S) OPTIONS #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/rules b/Shorewall/rules index 77ced5bb1..7a2f452a6 100755 --- a/Shorewall/rules +++ b/Shorewall/rules @@ -1,24 +1,37 @@ # -# Shorewall version 1.4 - Rules File +# Shorewall version 2.0 - Rules File # # /etc/shorewall/rules # # Rules in this file govern connection establishment. Requests and -# responses are automatically allowed using connection tracking. +# responses are automatically allowed using connection tracking. For any +# particular (source,dest) pair of zones, the rules are evaluated in the +# order in which they appear in this file and the first match is the one +# that determines the disposition of the request. # # In most places where an IP address or subnet is allowed, you # can preceed the address/subnet with "!" (e.g., !192.168.1.0/24) to # indicate that the rule matches all addresses except the address/subnet # given. Notice that no white space is permitted between "!" and the # address/subnet. -# +#------------------------------------------------------------------------------ +# WARNING: If you masquerade or use SNAT from a local system to the internet, +# you cannot use an ACCEPT rule to allow traffic from the internet to +# that system. You *must* use a DNAT rule instead. +#-------------------------------------------------------------------------------# # Columns are: # -# # ACTION ACCEPT, DROP, REJECT, DNAT, DNAT-, REDIRECT, CONTINUE, -# LOG or an . +# LOG, QUEUE or an . # # ACCEPT -- allow the connection request +# ACCEPT+ -- like ACCEPT but also excludes the +# connection from any subsequent +# DNAT[-] or REDIRECT[-] rules +# NONAT -- Excludes the connection from any +# subsequent DNAT[-] or REDIRECT[-] +# rules but doesn't generate a rule +# to accept the traffic. # DROP -- ignore the request # REJECT -- disallow the request and return an # icmp-unreachable or an RST packet. @@ -36,6 +49,7 @@ # Like REDIRET but only generates the # REDIRECT iptables rule and not # the companion ACCEPT rule. +# # CONTINUE -- (For experts only). Do not process # any of the following rules for this # (source zone,destination zone). If @@ -47,38 +61,31 @@ # (those) zone(s). # LOG -- Simply log the packet and continue. # QUEUE -- Queue the packet to a user-space -# application such as p2pwall. +# application such as ftwall +# (http://p2pwall.sf.net). # -- The name of an action defined in -# /etc/shorewall/actions. +# /etc/shorewall/actions or in +# /usr/share/shorewall/actions.std. # -# You may rate-limit the rule by optionally -# following ACCEPT, DNAT[-], REDIRECT[-] or LOG with -# -# < /[:] > -# -# where is the number of connections per -# ("sec" or "min") and is the -# largest burst permitted. If no is given, -# a value of 5 is assumed. There may be no -# no whitespace embedded in the specification. -# -# Example: ACCEPT<10/sec:20> -# -# The ACTION (and rate limit) may optionally be followed +# The ACTION may optionally be followed # by ":" and a syslog log level (e.g, REJECT:info or -# DNAT<4/sec:8>:debugging). This causes the packet to be +# DNAT:debug). This causes the packet to be # logged at the specified level. # -# NOTE: For those of you who prefer to place the -# rate limit in a separate column, see the RATE LIMIT -# column below. If you specify a value in that column, -# you must not include a rate limit in the ACTION column -# # 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 # (http://www.gnumonks.org/projects/ulogd). # +# Actions specifying logging may be followed by a +# log tag (a string of alphanumeric characters) +# are appended to the string generated by the +# LOGPREFIX (in /etc/shorewall/shorewall.conf). +# +# Example: ACCEPT:info:ftp would include 'ftp ' +# at the end of the log prefix generated by the +# LOGPREFIX setting. +# # SOURCE Source hosts to which the rule applies. May be a zone # defined in /etc/shorewall/zones, $FW to indicate the # firewall itself, or "all" If the ACTION is DNAT or @@ -86,6 +93,10 @@ # excluded from the rule by following the zone name with # "!' and a comma-separated list of sub-zone names. # +# When "all" is used either in the SOURCE or DEST column +# intra-zone traffic is not affected. You must add +# separate rules to handle that traffic. +# # Except when "all" is specified, clients may be further # restricted to a list of subnets and/or hosts by # appending ":" and a comma-separated list of subnets @@ -116,6 +127,10 @@ # /etc/shorewall/zones, $FW to indicate the firewall # itself or "all" # +# When "all" is used either in the SOURCE or DEST column +# intra-zone traffic is not affected. You must add +# separate rules to handle that traffic. +# # Except when "all" is specified, the server may be # further restricted to a particular subnet, host or # interface by appending ":" and the subnet, host or @@ -180,8 +195,8 @@ # ranges. # # If you don't want to restrict client ports but need to -# specify an ADDRESS in the next column, then place "-" -# in this column. +# specify an ORIGINAL DEST in the next column, then +# place "-" in this column. # # If your kernel contains multi-port match support, then # only a single Netfilter rule will be generated if in @@ -229,25 +244,25 @@ # # Example: 10/sec:20 # -# If you place a rate limit in this column, you may not -# place a similar limit in the ACTION column. -# -# USER SET This column may only be non-empty if the SOURCE is -# the firewall itself and the ACTION is ACCEPT, DROP or -# REJECT. +# USER/GROUP This column may only be non-empty if the SOURCE is +# the firewall itself. # -# The column may contain a user set name defined in the -# /etc/shorewall/usersets file or it may contain: +# 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 (s) and/or (s) specified. -# When a user set name is given, a log level may not be -# present in the ACTION column; logging for such rules is -# controlled by the user set's entry in -# /etc/shorewall/usersets. +# 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 # # Example: Accept SMTP requests from the DMZ to the internet # @@ -293,6 +308,6 @@ # ACCEPT net:130.252.100.69,130.252.100.70 fw \ # tcp 22 #################################################################################################### -#ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE USER -# PORT PORT(S) DEST LIMIT +#ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE USER/ +# PORT PORT(S) DEST LIMIT GROUP #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/shorewall b/Shorewall/shorewall index a3f78332c..d0d9ca1a2 100755 --- a/Shorewall/shorewall +++ b/Shorewall/shorewall @@ -1,11 +1,10 @@ #!/bin/sh # -# Shorewall Packet Filtering Firewall Control Program - V1.4 - 3/14/2003 +# Shorewall Packet Filtering Firewall Control Program - V2.0 - 3/14/2004 # # 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 - Tom Eastep (teastep@shorewall.net) # # This file should be placed in /sbin/shorewall. # @@ -77,10 +76,17 @@ # listed address(es) # shorewall allow
... Reenable address(es) previously # disabled with "drop" or "reject" -# shorewall save Save the list of "rejected" and +# shorewall save [ ] Save the list of "rejected" and # "dropped" addresses so that it will # be automatically reinstated the # next time that Shorewall starts. +# Save the current state so that 'shorewall +# restore' can be used. +# +# shorewall forget [ ] Discard the data saved by 'shorewall save' +# +# shorewall restore [ ] Restore the state of the firewall from +# previously saved information. # # shorewall ipaddr [
/ |
] # @@ -109,7 +115,7 @@ showfirstchain() # $1 = name of chain /^Chain/ {if ( prnt == 1 ) { rslt=0; exit 0; }; };\ /Chain '$1'/ { prnt=1; }; \ { if (prnt == 1) print; };\ - END { exit rslt; }' /tmp/chains-$$ + END { exit rslt; }' $TMPFILE } showchain() # $1 = name of chain @@ -124,10 +130,23 @@ showchain() # $1 = name of chain /^$|^ pkts/ { next; };\ /^Chain/ {if ( prnt == 1 ) exit; };\ /Chain '$1'/ { prnt=1; };\ - { if (prnt == 1) print; }' /tmp/chains-$$ + { if (prnt == 1) print; }' $TMPFILE fi } +# +# Validate the value of RESTOREFILE +# +validate_restorefile() # $* = label +{ + case $RESTOREFILE in + */*) + echo " ERROR: $@ must specify a simple file name: $RESTOREFILE" >&2 + exit 2 + ;; + esac +} + # # Set the configuration variables from shorewall.conf # @@ -157,10 +176,17 @@ get_config() { if [ -n "$SHOREWALL_SHELL" ]; then if [ ! -e "$SHOREWALL_SHELL" ]; then - echo "The program specified in SHOREWALL_SHELL does not exist or is not executable" >&2 + echo " ERROR: The program specified in SHOREWALL_SHELL does not exist or is not executable" >&2 exit 2 fi fi + + [ -n "$RESTOREFILE" ] || RESTOREFILE=restore + + validate_restorefile RESTOREFILE + + export RESTOREFILE + } # @@ -176,10 +202,13 @@ display_chains() # Send the output to a temporary file since ash craps if we try to store # the output in a variable. # - iptables -L -n -v > /tmp/chains-$$ + TMPFILE=$(mktempfile) + [ -n "$TMPFILE" ] || { echo " ERROR:Cannot create temporary file" >&2; exit 1; } + + iptables -L $IPT_OPTIONS >> $TMPFILE clear - echo "$banner `date`" + echo "$banner $(date)" echo echo "Standard Chains" echo @@ -191,13 +220,13 @@ display_chains() timed_read clear - echo "$banner `date`" + echo "$banner $(date)" echo firstchain=Yes echo "Input Chains" echo - chains=`grep '^Chain.*_[in|fwd]' /tmp/chains-$$ | cut -d' ' -f 2` + chains=$(grep '^Chain.*_[in|fwd]' $TMPFILE | cut -d' ' -f 2) for chain in $chains; do showchain $chain @@ -207,9 +236,9 @@ display_chains() for zone in $zones; do - if [ -n "`grep "^Chain \.*${zone}" /tmp/chains-$$`" ] ; then + if [ -n "$(grep "^Chain \.*${zone}" $TMPFILE)" ] ; then clear - echo "$banner `date`" + echo "$banner $(date)" echo firstchain=Yes eval display=\$${zone}_display @@ -228,7 +257,7 @@ display_chains() done clear - echo "$banner `date`" + echo "$banner $(date)" echo firstchain=Yes echo "Policy Chains" @@ -249,7 +278,7 @@ display_chains() timed_read clear - echo "$banner `date`" + echo "$banner $(date)" echo firstchain=Yes echo "Dynamic Chain" @@ -257,7 +286,7 @@ display_chains() showchain dynamic timed_read - qt rm -f /tmp/chains-$$ + qt rm -f $TMPFILE else iptables -L -n -v timed_read @@ -290,7 +319,7 @@ packet_log() # $1 = number of messages sed s/" kernel:"// | \ sed s/" $host $LOGFORMAT"/" "/ | \ sed s/" $host kernel: ipt_unclean: "/" "/ | \ - sed 's/MAC=.*SRC=/SRC=/' | \ + sed 's/MAC=.* SRC=/SRC=/' | \ tail $options } @@ -301,7 +330,7 @@ show_tc() { show_one_tc() { local device=${1%@*} - qdisc=`tc qdisc list dev $device` + qdisc=$(tc qdisc list dev $device) if [ -n "$qdisc" ]; then echo Device $device: @@ -331,7 +360,7 @@ show_classifiers() { show_one_classifier() { local device=${1%@*} - qdisc=`tc qdisc list dev $device` + qdisc=$(tc qdisc list dev $device) if [ -n "$qdisc" ]; then echo Device $device: @@ -360,8 +389,8 @@ monitor_firewall() # $1 = timeout -- if negative, prompt each time that { get_config - host=`echo $HOSTNAME | sed 's/\..*$//'` - oldrejects=`iptables -L -v -n | grep 'LOG'` + host=$(echo $HOSTNAME | sed 's/\..*$//') + oldrejects=$(iptables -L -v -n | grep 'LOG') if [ $1 -lt 0 ]; then let "timeout=- $1" @@ -373,8 +402,8 @@ monitor_firewall() # $1 = timeout -- if negative, prompt each time that if qt which awk; then - TMP_DIR=/tmp/shorewall-$$ - mkdir $TMP_DIR + TMP_DIR=$(mktempdir) + [ -n "$TMP_DIR" ] || { echo " ERROR:Cannot create temporary directory" >&2; exit 1; } haveawk=Yes determine_zones rm -rf $TMP_DIR @@ -386,7 +415,7 @@ monitor_firewall() # $1 = timeout -- if negative, prompt each time that display_chains clear - echo "$banner `date`" + echo "$banner $(date)" echo echo "Dropped/Rejected Packet Log" @@ -394,7 +423,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" @@ -417,24 +446,24 @@ monitor_firewall() # $1 = timeout -- if negative, prompt each time that fi clear - echo "$banner `date`" + echo "$banner $(date)" echo echo "NAT Status" echo - iptables -t nat -L -n -v + iptables -t nat -L $IPT_OPTIONS timed_read clear - echo "$banner `date`" + echo "$banner $(date)" echo echo echo "TOS/MARK Status" echo - iptables -t mangle -L -n -v + iptables -t mangle -L $IPT_OPTIONS timed_read clear - echo "$banner `date`" + echo "$banner $(date)" echo echo echo "Tracked Connections" @@ -443,7 +472,7 @@ monitor_firewall() # $1 = timeout -- if negative, prompt each time that timed_read clear - echo "$banner `date`" + echo "$banner $(date)" echo echo echo "Traffic Shaping/Control" @@ -452,7 +481,7 @@ monitor_firewall() # $1 = timeout -- if negative, prompt each time that timed_read clear - echo "$banner `date`" + echo "$banner $(date)" echo echo echo "Packet Classifiers" @@ -470,8 +499,8 @@ logwatch() # $1 = timeout -- if negative, prompt each time that { get_config - host=`echo $HOSTNAME | sed 's/\..*$//'` - oldrejects=`iptables -L -v -n | grep 'LOG'` + host=$(echo $HOSTNAME | sed 's/\..*$//') + oldrejects=$(iptables -L -v -n | grep 'LOG') if [ $1 -lt 0 ]; then timeout=$((- $1)) @@ -485,7 +514,7 @@ logwatch() # $1 = timeout -- if negative, prompt each time that while true; do clear - echo "$banner `date`" + echo "$banner $(date)" echo echo "Dropped/Rejected Packet Log" @@ -493,7 +522,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" @@ -531,7 +560,7 @@ help() # usage() # $1 = exit status { - echo "Usage: `basename $0` [debug] [nolock] [-c ] " + echo "Usage: $(basename $0) [debug|trace] [nolock] [-c ] [ -x ] [ -q ] [ -f ] " echo "where is one of:" echo " add [:] " echo " allow
..." @@ -539,6 +568,7 @@ usage() # $1 = exit status echo " clear" echo " delete [:] " echo " drop
..." + echo " forget [ ]" echo " help [ | host | address ]" echo " hits" echo " ipcalc [
/ |
]" @@ -549,7 +579,8 @@ usage() # $1 = exit status echo " reject
..." echo " reset" echo " restart" - echo " save" + echo " restore [ ]" + echo " save [ ]" echo " show [ [ ... ]|classifiers|connections|log|nat|tc|tos]" echo " start" echo " stop" @@ -564,16 +595,20 @@ usage() # $1 = exit status # show_reset() { [ -f $STATEDIR/restarted ] && \ - echo "Counters reset `cat $STATEDIR/restarted`" && \ + echo "Counters reset $(cat $STATEDIR/restarted)" && \ echo } +show_proc() { + [ -f $1 ] && echo " $1 = $(cat $1)" +} + # # Execution begins here # debugging= -if [ $# -gt 0 ] && [ "$1" = "debug" ]; then +if [ $# -gt 0 ] && [ "$1" = "debug" -o "$1" = "trace" ]; then debugging=debug shift fi @@ -586,29 +621,60 @@ if [ $# -gt 0 ] && [ "$1" = "nolock" ]; then fi SHOREWALL_DIR= +QUIET= +IPT_OPTIONS="-nv" +FAST= + done=0 while [ $done -eq 0 ]; do [ $# -eq 0 ] && usage 1 - case $1 in - -c) - [ $# -eq 1 ] && usage 1 + option=$1 + case $option in + -*) + option=${option#-} - 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 + [ -z "$option" ] && usage 1 + + while [ -n "$option" ]; do + case $option in + c) + [ $# -eq 1 ] && usage 1 - SHOREWALL_DIR=$2 - shift - shift - ;; - *) - done=1 - ;; + 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 + option= + shift + ;; + x*) + IPT_OPTIONS="-xnv" + option=${option#x} + ;; + q*) + QUIET=Yes + option=${option#q} + ;; + f*) + FAST=Yes + option=${option#f} + ;; + *) + usage 1 + ;; + esac + done + shift + ;; + *) + done=1 + ;; esac done @@ -617,6 +683,7 @@ if [ $# -eq 0 ]; then fi [ -n "$SHOREWALL_DIR" ] && export SHOREWALL_DIR +[ -n "$QUIET" ] && export QUIET PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin MUTEX_TIMEOUT= @@ -634,15 +701,26 @@ else exit 2 fi -config=`find_file shorewall.conf` +ensure_config_path + +config=$(find_file shorewall.conf) if [ -f $config ]; then - . $config + if [ -r $config ]; then + . $config + else + echo "Cannot read $config! (Hint: Are you root?)" >&2 + exit 1 + fi else echo "$config does not exist!" >&2 exit 2 fi +ensure_config_path + +export CONFIG_PATH + [ -z "${STATEDIR}" ] && STATEDIR=/var/state/shorewall if [ ! -f $FIREWALL ]; then @@ -658,7 +736,7 @@ if [ ! -f $FIREWALL ]; then fi if [ -f $VERSION_FILE ]; then - version=`cat $VERSION_FILE` + version=$(cat $VERSION_FILE) else echo "ERROR: Shorewall is not properly installed" echo " The file $VERSION_FILE does not exist" @@ -667,8 +745,7 @@ fi banner="Shorewall-$version Status at $HOSTNAME -" - -case `echo -e` in +case $(echo -e) in -e*) RING_BELL="echo \a" ;; @@ -677,7 +754,7 @@ case `echo -e` in ;; esac -case `echo -n "Testing"` in +case $(echo -n "Testing") in -n*) ECHO_N= ;; @@ -687,7 +764,26 @@ case `echo -n "Testing"` in esac case "$1" in - start|stop|restart|reset|clear|refresh|check) + start) + [ $# -ne 1 ] && usage 1 + get_config + if [ -n "$FAST" ]; then + + RESTOREPATH=/var/lib/shorewall/$RESTOREFILE + + if [ -x $RESTOREPATH ]; then + echo Restoring Shorewall... + $RESTOREPATH + date > $STATEDIR/restarted + echo Shorewall restored from $RESTOREPATH + else + exec $SHOREWALL_SHELL $FIREWALL $debugging $nolock start + fi + else + exec $SHOREWALL_SHELL $FIREWALL $debugging $nolock start + fi + ;; + stop|restart|reset|clear|refresh|check) [ $# -ne 1 ] && usage 1 get_config exec $SHOREWALL_SHELL $FIREWALL $debugging $nolock $1 @@ -698,65 +794,67 @@ case "$1" in exec $SHOREWALL_SHELL $FIREWALL $debugging $nolock $1 $2 $3 ;; show|list) + [ -n "$debugging" ] && set -x case "$2" in connections) [ $# -gt 2 ] && usage 1 - echo "Shorewall-$version Connections at $HOSTNAME - `date`" + echo "Shorewall-$version Connections at $HOSTNAME - $(date)" echo cat /proc/net/ip_conntrack ;; nat) [ $# -gt 2 ] && usage 1 - echo "Shorewall-$version NAT at $HOSTNAME - `date`" + echo "Shorewall-$version NAT at $HOSTNAME - $(date)" echo show_reset - iptables -t nat -L -n -v + iptables -t nat -L $IPT_OPTIONS ;; tos|mangle) [ $# -gt 2 ] && usage 1 - echo "Shorewall-$version TOS at $HOSTNAME - `date`" + echo "Shorewall-$version TOS at $HOSTNAME - $(date)" echo show_reset - iptables -t mangle -L -n -v + iptables -t mangle -L $IPT_OPTIONS ;; log) [ $# -gt 2 ] && usage 1 get_config - echo "Shorewall-$version Log at $HOSTNAME - `date`" + echo "Shorewall-$version Log at $HOSTNAME - $(date)" echo show_reset - host=`echo $HOSTNAME | sed 's/\..*$//'` + host=$(echo $HOSTNAME | sed 's/\..*$//') packet_log 20 ;; tc) [ $# -gt 2 ] && usage 1 - echo "Shorewall-$version Traffic Control at $HOSTNAME - `date`" + echo "Shorewall-$version Traffic Control at $HOSTNAME - $(date)" echo show_tc ;; classifiers) [ $# -gt 2 ] && usage 1 - echo "Shorewall-$version Clasifiers at $HOSTNAME - `date`" + echo "Shorewall-$version Clasifiers at $HOSTNAME - $(date)" echo show_classifiers ;; *) shift - echo "Shorewall-$version `[ $# -gt 1 ] && echo Chains || echo Chain` $* at $HOSTNAME - `date`" + echo "Shorewall-$version $([ $# -gt 1 ] && echo Chains || echo Chain) $* at $HOSTNAME - $(date)" echo show_reset if [ $# -gt 0 ]; then for chain in $*; do - iptables -L $chain -n -v + iptables -L $chain $IPT_OPTIONS done else - iptables -L -n -v + iptables -L $IPT_OPTIONS fi ;; esac ;; monitor) + [ -n "$debugging" ] && set -x if [ $# -eq 2 ]; then monitor_firewall $2 elif [ $# -eq 1 ]; then @@ -766,37 +864,74 @@ case "$1" in fi ;; status) + [ -n "$debugging" ] && set -x [ $# -eq 1 ] || usage 1 get_config clear - echo "Shorewall-$version Status at $HOSTNAME - `date`" + echo "Shorewall-$version Status at $HOSTNAME - $(date)" echo show_reset - host=`echo $HOSTNAME | sed 's/\..*$//'` - iptables -L -n -v + host=$(echo $HOSTNAME | sed 's/\..*$//') + iptables -L $IPT_OPTIONS echo packet_log 20 echo echo "NAT Table" echo - iptables -t nat -L -n -v + iptables -t nat -L $IPT_OPTIONS echo echo "Mangle Table" echo - iptables -t mangle -L -n -v + iptables -t mangle -L $IPT_OPTIONS echo cat /proc/net/ip_conntrack + echo + echo "IP Configuration" + echo + ip addr ls + + if qt which brctl; then + echo + echo "Bridges" + echo + brctl show + fi + + echo + echo "/proc" + echo + + show_proc /proc/sys/net/ipv4/ip_forward + + for directory in /proc/sys/net/ipv4/conf/*; do + for file in proxy_arp arp_filter rp_filter; do + show_proc $directory/$file + done + done + + echo + echo "Routing Rules" + echo + ip rule ls + ip rule ls | while read rule; do + table=${rule##* } + echo + echo "Table $table:" + echo + ip route ls table $table + done ;; hits) + [ -n "$debugging" ] && set -x [ $# -eq 1 ] || usage 1 get_config clear - echo "Shorewall-$version Hits at $HOSTNAME - `date`" + echo "Shorewall-$version Hits at $HOSTNAME - $(date)" echo timeout=30 - if [ `grep -c "$LOGFORMAT" $LOGFILE ` -gt 0 ] ; then + if [ $(grep -c "$LOGFORMAT" $LOGFILE ) -gt 0 ] ; then echo " HITS IP DATE" echo " ---- --------------- ------" grep "$LOGFORMAT" $LOGFILE | sed 's/\(.\{6\}\)\(.*SRC=\)\(.*\)\( DST=.*\)/\3 \1/' | sort | uniq -c | sort -rn @@ -819,8 +954,8 @@ case "$1" in grep "$LOGFORMAT.*DPT" $LOGFILE | sed 's/\(.*DPT=\)\([0-9]\{1,5\}\)\(.*\)/\2/' | sort | uniq -c | sort -rn | \ while read count port ; do # List all services defined for the given port - srv=`grep "^[^#].*\\b$port/" /etc/services | cut -f 1 | sort -u` - srv=`echo $srv | sed 's/ /,/g'` + srv=$(grep "^[^#].*\\b$port/" /etc/services | cut -f 1 | sort -u) + srv=$(echo $srv | sed 's/ /,/g') if [ -n "$srv" ] ; then printf '%7d %5d %s\n' $count $port $srv @@ -848,6 +983,7 @@ case "$1" in fi ;; logwatch) + [ -n "$debugging" ] && set -x if [ $# -eq 2 ]; then logwatch $2 elif [ $# -eq 1 ]; then @@ -857,6 +993,7 @@ case "$1" in fi ;; drop) + [ -n "$debugging" ] && set -x [ $# -eq 1 ] && usage 1 mutex_on while [ $# -gt 1 ]; do @@ -869,6 +1006,7 @@ case "$1" in mutex_off ;; reject) + [ -n "$debugging" ] && set -x [ $# -eq 1 ] && usage 1 mutex_on while [ $# -gt 1 ]; do @@ -881,6 +1019,7 @@ case "$1" in mutex_off ;; allow) + [ -n "$debugging" ] && set -x [ $# -eq 1 ] && usage 1 mutex_on while [ $# -gt 1 ]; do @@ -894,28 +1033,98 @@ case "$1" in mutex_off ;; save) - [ $# -ne 1 ] && usage 1 - mutex_on - if qt iptables -L shorewall -n; then - [ -d /var/lib/shorewall ] || mkdir /var/lib/shorewall + [ -n "$debugging" ] && set -x - if iptables -L dynamic -n > /var/lib/shorewall/save; then - echo "Dynamic Rules Saved" + get_config + + case $# in + 1) + ;; + 2) + RESTOREFILE="$2" + validate_restorefile '' + ;; + *) + usage 1 + ;; + esac + + RESTOREPATH=/var/lib/shorewall/$RESTOREFILE + + mutex_on + + if qt iptables -L shorewall -n; then + [ -d /var/lib/shorewall ] || mkdir -p /var/lib/shorewall + + if [ -f $RESTOREPATH -a ! -x $RESTOREPATH ]; then + echo " ERROR: $RESTOREPATH exists and is not a saved Shorewall configuration" else - echo "Error Saving the Dynamic Rules" + case $RESTOREFILE in + save|restore-base) + echo " ERROR: Reserved file name: $RESTOREFILE" + ;; + *) + 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 + echo __EOF__ >> /var/lib/shorewall/restore-$$ + [ -f /var/lib/shorewall/restore-tail ] && \ + cat /var/lib/shorewall/restore-tail >> /var/lib/shorewall/restore-$$ + mv -f /var/lib/shorewall/restore-$$ $RESTOREPATH + chmod +x $RESTOREPATH + echo " Currently-running Configuration Saved to $RESTOREPATH" + else + rm -f /var/lib/shorewall/restore-$$ + echo " ERROR: Currently-running Configuration Not Saved" + fi + else + echo " ERROR: /var/lib/shorewall/restore-base does not exist" + fi + else + echo "Error Saving the Dynamic Rules" + fi + ;; + esac fi else echo "Shorewall isn't started" fi mutex_off ;; + forget) + get_config + case $# in + 1) + ;; + 2) + RESTOREFILE="$2" + validate_restorefile '' + ;; + *) + usage 1 + ;; + esac + + + RESTOREPATH=/var/lib/shorewall/$RESTOREFILE + + if [ -x $RESTOREPATH ]; then + rm -f $RESTOREPATH + echo " $RESTOREPATH removed" + elif [ -f $RESTOREPATH ]; then + echo " ERROR: $RESTOREPATH exists and is not a saved Shorewall configuration" + fi + ;; ipcalc) + [ -n "$debugging" ] && set -x if [ $# -eq 2 ]; then address=${2%/*} vlsm=${2#*/} elif [ $# -eq 3 ]; then address=$2 - vlsm=`ip_vlsm $3` + vlsm=$(ip_vlsm $3) else usage 1 fi @@ -926,13 +1135,14 @@ case "$1" in address=$address/$vlsm - echo " CIDR=$address" - temp=`ip_netmask $address`; echo " NETMASK=`encodeaddr $temp`" - temp=`ip_network $address`; echo " NETWORK=$temp" - temp=`broadcastaddress $address`; echo " BROADCAST=$temp" + echo " CIDR=$address" + temp=$(ip_netmask $address); echo " NETMASK=$(encodeaddr $temp)" + temp=$(ip_network $address); echo " NETWORK=$temp" + temp=$(broadcastaddress $address); echo " BROADCAST=$temp" ;; iprange) + [ -n "$debugging" ] && set -x case $2 in *.*.*.*-*.*.*.*) ip_range $2 @@ -942,7 +1152,32 @@ case "$1" in ;; esac ;; + restore) + get_config + case $# in + 1) + ;; + 2) + RESTOREFILE="$2" + validate_restorefile '' + ;; + *) + usage 1 + ;; + esac + + RESTOREPATH=/var/lib/shorewall/$RESTOREFILE + + if [ -x $RESTOREPATH ]; then + echo Restoring Shorewall... + $RESTOREPATH && echo "Shorewall restored from /var/lib/shorewall/$RESTOREFILE" + else + echo "File /var/lib/shorewall/$RESTOREFILE: file not found" + exit 2 + fi + ;; call) + [ -n "$debugging" ] && set -x # # Undocumented way to call functions in /usr/share/shorewall/functions directly # diff --git a/Shorewall/shorewall.conf b/Shorewall/shorewall.conf index a2ad3995c..c5b4a0656 100755 --- a/Shorewall/shorewall.conf +++ b/Shorewall/shorewall.conf @@ -1,12 +1,12 @@ ############################################################################## -# /etc/shorewall/shorewall.conf V1.4 - Change the following variables to +# /etc/shorewall/shorewall.conf V2.0 - Change the following variables to # match your setup # # This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] # # This file should be placed in /etc/shorewall # -# (c) 1999,2000,2001,2002,2003 - Tom Eastep (teastep@shorewall.net) +# (c) 1999,2000,2001,2002,2003,2004 - Tom Eastep (teastep@shorewall.net) ############################################################################## # L O G G I N G ############################################################################## @@ -32,7 +32,7 @@ # to choose, 6 (info) is a safe bet. You may specify levels by name or by # number. # -# If you have build your kernel with ULOG target support, you may also +# If you have built your kernel with ULOG target support, you may also # specify a log level of ULOG (must be all caps). Rather than log its # messages to syslogd, Shorewall will direct netfilter to log the messages # via the ULOG target which will send them to a process called 'ulogd'. @@ -90,34 +90,26 @@ LOGFORMAT="Shorewall:%s:%s:" # maximum initial burst size that will be logged. If set empty, the default # value of 5 will be used. # +# If BOTH variables are set empty then logging will not be rate-limited. +# # Example: # # LOGRATE=10/minute # LOGBURST=5 # -# If BOTH variables are set empty then logging will not be rate-limited. +# For each logging rule, the first time the rule is reached, the packet +# will be logged; in fact, since the burst is 5, the first five packets +# will be logged. After this, it will be 6 seconds (1 minute divided by +# the rate of 10) before a message will be logged from the rule, regardless +# of how many packets reach it. Also, every 6 seconds which passes without +# matching a packet, one of the bursts will be regained; if no packets hit +# the rule for 30 seconds, the burst will be fully recharged; back where +# we started. # LOGRATE= LOGBURST= -# -# LEVEL AT WHICH TO LOG 'UNCLEAN' PACKETS -# -# This variable determines the level at which Mangled/Invalid packets are logged -# under the 'dropunclean' interface option. If you set this variable to an -# empty value (e.g., LOGUNCLEAN= ), Mangled/Invalid packets will be dropped -# silently. -# -# The value of this variable also determines the level at which Mangled/Invalid -# packets are logged under the 'logunclean' interface option. If the variable -# is empty, these packets will still be logged at the 'info' level. -# -# See the comment at the top of this section for a description of log levels -# - -LOGUNCLEAN=info - # # BLACKLIST LOG LEVEL # @@ -182,6 +174,33 @@ TCP_FLAGS_LOG_LEVEL=info RFC1918_LOG_LEVEL=info +# +# SMURF Log Level +# +# Specifies the logging level for smurf packets dropped by the +#'nosmurfs' interface option in /etc/shorewall/interfaces and in +# /etc/shorewall/hosts. If set to the empty value ( SMURF_LOG_LEVEL="" +# ) then dropped smurfs are not logged. + +# +# See the comment at the top of this section for a description of log levels +# + +SMURF_LOG_LEVEL=info + +# +# BOGON Log Level +# +# Specifies the logging level for bogon packets dropped by the +#'nobogons' interface option in /etc/shorewall/interfaces and in +# /etc/shorewall/hosts. If set to the empty value +# ( BOGON_LOG_LEVEL="" ) then packets whose TARGET is 'logdrop' +# in /usr/share/shorewall/bogons are logged at the 'info' level. +# +# See the comment at the top of this section for a description of log levels +# + +BOGON_LOG_LEVEL=info ################################################################################ # 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 ################################################################################ @@ -226,6 +245,37 @@ STATEDIR=/var/lib/shorewall MODULESDIR= +# +# CONFIGURATION SEARCH PATH +# +# This option holds a list of directory names separated by colons +# (":"). Shorewall will search each directory in turn when looking for a +# configuration file. When processing a 'try' command or a command +# containing the "-c" option, Shorewall will automatically add the +# directory specified in the command to the front of this list. +# +# If not specified or specified as null ("CONFIG_PATH=""), +# CONFIG_PATH=/etc/shorewall:/usr/share/shorewall is assumed. + +CONFIG_PATH=/etc/shorewall:/usr/share/shorewall + +# +# RESTORE SCRIPT +# +# This option determines the script to be run in the following cases: +# +# shorewall -f start +# shorewall restore +# shorewall save +# shorewall forget +# Failure of shorewall start or shorewall restart +# +# The value of the option must be the name of an executable file in the +# directory /var/lib/shorewall. If this option is not set or if it is +# set to the empty value (RESTOREFILE="") then RESTOREFILE=restore is +# assumed. + +RESTOREFILE= ################################################################################ # F I R E W A L L O P T I O N S ################################################################################ @@ -275,9 +325,8 @@ ADD_SNAT_ALIASES=No # # 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 # @@ -358,16 +407,6 @@ CLAMPMSS=No ROUTE_FILTER=No -# -# NAT BEFORE RULES -# -# Shorewall has traditionally processed static NAT rules before port forwarding -# rules. If you would like to reverse the order, set this variable to "No". -# -# If this variable is not set or is set to the empty value, "Yes" is assumed. - -NAT_BEFORE_RULES=Yes - # DNAT IP ADDRESS DETECTION # # Normally when Shorewall encounters the following rule: @@ -430,12 +469,12 @@ MUTEX_TIMEOUT=60 # A packet is said to be NEW if it is not part of or related to an already # established connection. # -# The NETNOTSYN option determines the handling of non-SYN packets (those with +# The NEWNOTSYN 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. # # If NEWNOTSYN is set to "No" or "no", then non-SYN packets that are not -# part of an already established connection, it will be dropped by the +# part of an already established connection will be dropped by the # firewall. The setting of LOGNEWNOTSYN above determines if these packets are # logged before they are dropped. # @@ -447,7 +486,9 @@ MUTEX_TIMEOUT=60 # also need to select NEWNOTSYN=Yes. # # The behavior of NEWNOTSYN=Yes may also be enabled on a per-interface basis -# using the 'newnotsyn' option in /etc/shorewall/interfaces. +# using the 'newnotsyn' option in /etc/shorewall/interfaces and on a +# network or host basis using the same option in /etc/shorewall/hosts. + # # I find that NEWNOTSYN=No tends to result in lots of "stuck" # connections because any network timeout during TCP session tear down @@ -513,9 +554,9 @@ BLACKLISTNEWONLY=Yes # # When loading a module named in /etc/shorewall/modules, Shorewall normally # looks in the MODULES DIRECTORY (see MODULESDIR above) for files whose names -# end in ".o", ".ko", ".gz" or "o.gz". If your distribution uses a different -# naming convention then you can specify the suffix (extension) for module -# names in this variable. +# end in ".o", ".ko", ".gz", "o.gz" or "ko.gz" . If your distribution uses a +# different naming convention then you can specify the suffix (extension) for +# module names in this variable. # # To see what suffix is used by your distribution: # @@ -532,6 +573,88 @@ BLACKLISTNEWONLY=Yes MODULE_SUFFIX= +# +# DISABLE IPV6 +# +# Distributions (notably SuSE) are beginning to ship with IPV6 +# enabled. If you are not using IPV6, you are at risk of being +# exploited by users who do. Setting DISABLE_IPV6=Yes will cause +# Shorewall to disable IPV6 traffic to/from and through your +# firewall system. This requires that you have ip6tables installed. + +DISABLE_IPV6=Yes + +# +# BRIDGING +# +# If you wish to control traffic through a bridge (see http://bridge.sf.net), +# then set BRIDGING=Yes. Your kernel must have the physdev match option +# enabled; that option is available at the above URL for 2.4 kernels and +# is included as a standard part of the 2.6 series kernels. If not +# specified or specified as empty (BRIDGING="") then "No" is assumed. +# + +BRIDGING=No + +# +# DYNAMIC ZONES +# +# If you need to be able to add and delete hosts from zones dynamically then +# set DYNAMIC_ZONES=Yes. Otherwise, set DYNAMIC_ZONES=No. + +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. + +PKTTYPE=Yes + +# +# DROP INVALID PACKETS +# +# Netfilter classifies packets relative to its connection tracking table into +# four states: +# +# NEW - thes packet initiates a new connection +# ESTABLISHED - thes packet is part of an established connection +# RELATED - thes packet is related to an established connection; it may +# establish a new connection +# INVALID - the packet does not related to the table in any sensible way. +# +# Recent 2.6 kernels include code that evaluates TCP packets based on TCP +# Window analysis. This can cause packets that were previously classified as +# NEW or ESTABLISHED to be classified as INVALID. +# +# The new kernel code can be disabled by including this command in your +# /etc/shorewall/init file: +# +# echo 1 > /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_be_liberal +# +# Additional kernel logging about INVALID TCP packets may be obtained by +# adding this command to /etc/shorewall/init: +# +# echo 1 > /proc/sys/net/ipv4/netfilter/ip_conntrack_log_invalid +# +# Traditionally, Shorewall has dropped INVALID TCP packets early. The DROPINVALID +# option allows INVALID packets to be passed through the normal rules chains by +# setting DROPINVALID=No. +# +# If not specified or if specified as empty (e.g., DROPINVALID="") then +# DROPINVALID=Yes is assumed. + +DROPINVALID=No ################################################################################ # P A C K E T D I S P O S I T I O N ################################################################################ @@ -542,6 +665,7 @@ MODULE_SUFFIX= # Blacklisted systems. Must be DROP or REJECT. If not set or set to empty, # DROP is assumed. # + BLACKLIST_DISPOSITION=DROP # @@ -560,8 +684,9 @@ MACLIST_DISPOSITION=REJECT # # This variable determins the disposition of packets having an invalid # combination of TCP flags that are received on interfaces having the -# 'tcpflags' option specified in /etc/shorewall/interfaces. If not specified -# or specified as empty (TCP_FLAGS_DISPOSITION="") then DROP is assumed. +# 'tcpflags' option specified in /etc/shorewall/interfaces or in +# /etc/shorewall/hosts. If not specified or specified as empty +# (TCP_FLAGS_DISPOSITION="") then DROP is assumed. TCP_FLAGS_DISPOSITION=DROP diff --git a/Shorewall/shorewall.spec b/Shorewall/shorewall.spec index 98973f4ec..4babd73e2 100644 --- a/Shorewall/shorewall.spec +++ b/Shorewall/shorewall.spec @@ -1,5 +1,5 @@ %define name shorewall -%define version 1.4.10d +%define version 2.0.16 %define release 1 %define prefix /usr @@ -33,7 +33,7 @@ a multi-function gateway/ router/server or on a standalone GNU/Linux system. export PREFIX=$RPM_BUILD_ROOT ; \ export OWNER=`id -n -u` ; \ export GROUP=`id -n -g` ;\ -./install.sh /etc/init.d +./install.sh %clean rm -rf $RPM_BUILD_ROOT @@ -68,18 +68,17 @@ if [ $1 = 0 ]; then fi %files -/etc/init.d/shorewall +%attr(0544,root,root) /etc/init.d/shorewall %attr(0700,root,root) %dir /etc/shorewall %attr(0700,root,root) %dir /usr/share/shorewall %attr(0700,root,root) %dir /var/lib/shorewall -%attr(0600,root,root) /usr/share/shorewall/version -%attr(0600,root,root) /etc/shorewall/common.def %attr(0600,root,root) %config(noreplace) /etc/shorewall/shorewall.conf %attr(0600,root,root) %config(noreplace) /etc/shorewall/zones %attr(0600,root,root) %config(noreplace) /etc/shorewall/policy %attr(0600,root,root) %config(noreplace) /etc/shorewall/interfaces %attr(0600,root,root) %config(noreplace) /etc/shorewall/rules %attr(0600,root,root) %config(noreplace) /etc/shorewall/nat +%attr(0600,root,root) %config(noreplace) /etc/shorewall/netmap %attr(0600,root,root) %config(noreplace) /etc/shorewall/params %attr(0600,root,root) %config(noreplace) /etc/shorewall/proxyarp %attr(0600,root,root) %config(noreplace) /etc/shorewall/routestopped @@ -91,42 +90,146 @@ fi %attr(0600,root,root) %config(noreplace) /etc/shorewall/tunnels %attr(0600,root,root) %config(noreplace) /etc/shorewall/hosts %attr(0600,root,root) %config(noreplace) /etc/shorewall/blacklist -%attr(0600,root,root) %config(noreplace) /etc/shorewall/rfc1918 %attr(0600,root,root) %config(noreplace) /etc/shorewall/init +%attr(0600,root,root) %config(noreplace) /etc/shorewall/initdone %attr(0600,root,root) %config(noreplace) /etc/shorewall/start %attr(0600,root,root) %config(noreplace) /etc/shorewall/stop %attr(0600,root,root) %config(noreplace) /etc/shorewall/stopped %attr(0600,root,root) %config(noreplace) /etc/shorewall/ecn %attr(0600,root,root) %config(noreplace) /etc/shorewall/accounting -%attr(0600,root,root) %config(noreplace) /etc/shorewall/usersets -%attr(0600,root,root) %config(noreplace) /etc/shorewall/users %attr(0600,root,root) %config(noreplace) /etc/shorewall/actions -%attr(0600,root,root) %config(noreplace) /etc/shorewall/action.template + %attr(0544,root,root) /sbin/shorewall + +%attr(0600,root,root) /usr/share/shorewall/version +%attr(0600,root,root) /usr/share/shorewall/actions.std +%attr(0600,root,root) /usr/share/shorewall/action.AllowAuth +%attr(0600,root,root) /usr/share/shorewall/action.AllowDNS +%attr(0600,root,root) /usr/share/shorewall/action.AllowFTP +%attr(0600,root,root) /usr/share/shorewall/action.AllowIMAP +%attr(0600,root,root) /usr/share/shorewall/action.AllowNNTP +%attr(0600,root,root) /usr/share/shorewall/action.AllowNTP +%attr(0600,root,root) /usr/share/shorewall/action.AllowPCA +%attr(0600,root,root) /usr/share/shorewall/action.AllowPing +%attr(0600,root,root) /usr/share/shorewall/action.AllowPOP3 +%attr(0600,root,root) /usr/share/shorewall/action.AllowRdate +%attr(0600,root,root) /usr/share/shorewall/action.AllowSMB +%attr(0600,root,root) /usr/share/shorewall/action.AllowSMTP +%attr(0600,root,root) /usr/share/shorewall/action.AllowSNMP +%attr(0600,root,root) /usr/share/shorewall/action.AllowSSH +%attr(0600,root,root) /usr/share/shorewall/action.AllowTelnet +%attr(0600,root,root) /usr/share/shorewall/action.AllowTrcrt +%attr(0600,root,root) /usr/share/shorewall/action.AllowVNC +%attr(0600,root,root) /usr/share/shorewall/action.AllowVNCL +%attr(0600,root,root) /usr/share/shorewall/action.AllowWeb +%attr(0600,root,root) /usr/share/shorewall/action.Drop +%attr(0600,root,root) /usr/share/shorewall/action.DropDNSrep +%attr(0600,root,root) /usr/share/shorewall/action.DropPing +%attr(0600,root,root) /usr/share/shorewall/action.DropSMB +%attr(0600,root,root) /usr/share/shorewall/action.DropUPnP +%attr(0600,root,root) /usr/share/shorewall/action.Reject +%attr(0600,root,root) /usr/share/shorewall/action.RejectAuth +%attr(0600,root,root) /usr/share/shorewall/action.RejectSMB +%attr(0600,root,root) /usr/share/shorewall/action.template %attr(0444,root,root) /usr/share/shorewall/functions %attr(0544,root,root) /usr/share/shorewall/firewall %attr(0544,root,root) /usr/share/shorewall/help +%attr(0600,root,root) /usr/share/shorewall/rfc1918 +%attr(0600,root,root) /usr/share/shorewall/bogons +%attr(0600,root,root) /usr/share/shorewall/configpath + %doc COPYING INSTALL changelog.txt releasenotes.txt tunnel %changelog -* Tue Mar 16 2004 Tom Eastep -- Changed version to 1.4.10d-1 -* Sun Feb 15 2004 Tom Eastep -- Changed version to 1.4.10c-1 +* Tue Feb 01 2005 Tom Eastep tom@shorewall.net +- Updated to 2.0.16-1 +* Wed Jan 12 2005 Tom Eastep tom@shorewall.net +- Updated to 2.0.15-1 +* Mon Jan 03 2005 Tom Eastep tom@shorewall.net +- Updated to 2.0.14-1 +* Thu Dec 02 2004 Tom Eastep tom@shorewall.net +- Updated to 2.0.13-1 +* Wed Dec 01 2004 Tom Eastep tom@shorewall.net +- Updated to 2.0.12-1 +* Mon Nov 22 2004 Tom Eastep tom@shorewall.net +- Updated to 2.0.11-1 +* Mon Oct 25 2004 Tom Eastep tom@shorewall.net +- Updated to 2.0.10-1 +* Thu Sep 23 2004 Tom Eastep tom@shorewall.net +- Updated to 2.0.9-1 +* Sun Aug 22 2004 Tom Eastep tom@shorewall.net +- Updated to 2.0.8-1 +* Tue Jul 20 2004 Tom Eastep tom@shorewall.net +- Updated to 2.0.7-1 +* Sun Jul 11 2004 Tom Eastep tom@shorewall.net +- Updated to 2.0.6-1 +* Fri Jul 09 2004 Tom Eastep tom@shorewall.net +- Updated to 2.0.5-1 +* Tue Jul 06 2004 Tom Eastep tom@shorewall.net +- Updated to 2.0.4-1 +* Fri Jul 02 2004 Tom Eastep tom@shorewall.net +- Updated to 2.0.3c-1 +* Wed Jun 30 2004 Tom Eastep tom@shorewall.net +- Updated to 2.0.3b-1 +* Mon Jun 28 2004 Tom Eastep tom@shorewall.net +- Updated to 2.0.3a-1 +* Wed Jun 23 2004 Tom Eastep tom@shorewall.net +- Updated to 2.0.3-1 +* Sat Jun 19 2004 Tom Eastep tom@shorewall.net +- Updated to 2.0.2-0RC2 +* Tue Jun 15 2004 Tom Eastep tom@shorewall.net +- Updated to 2.0.2-0RC1 +* Mon Jun 14 2004 Tom Eastep tom@shorewall.net +- Added %attr spec for /etc/init.d/shorewall +* Sat May 15 2004 Tom Eastep tom@shorewall.net +- Updated for 2.0.2a-1 +* Thu May 13 2004 Tom Eastep tom@shorewall.net +- Updated for 2.0.2-1 +* Mon May 10 2004 Tom Eastep tom@shorewall.net +- Add /etc/shorewall/initdone +* Fri May 07 2004 Tom Eastep tom@shorewall.net +- Shorewall 2.0.2-RC1 +* Tue May 04 2004 Tom Eastep tom@shorewall.net +- Shorewall 2.0.2-Beta2 +* Tue Apr 13 2004 Tom Eastep tom@shorewall.net +- Add /usr/share/shorewall/configpath +* Mon Apr 05 2004 Tom Eastep tom@shorewall.net +- Updated for 2.0.1-1 +* Thu Apr 02 2004 Tom Eastep tom@shorewall.net +- Updated for 2.0.1 RC5 +* Thu Apr 01 2004 Tom Eastep tom@shorewall.net +- Updated for 2.0.1 RC4 +* Sun Mar 28 2004 Tom Eastep tom@shorewall.net +- Updated for 2.0.1 RC3 +* Thu Mar 25 2004 Tom Eastep tom@shorewall.net +- Updated for 2.0.1 RC2 +* Wed Mar 24 2004 Tom Eastep tom@shorewall.net +- Updated for 2.0.1 RC1 +* Fri Mar 19 2004 Tom Eastep tom@shorewall.net +- Updated for 2.0.1 Beta 2 +* Thu Mar 18 2004 Tom Eastep tom@shorewall.net +- Added netmap file +* Wed Mar 17 2004 Tom Eastep +- Update for 2.0.1 Beta 1 +* Wed Mar 17 2004 Tom Eastep +- Add bogons file +* Sat Mar 13 2004 Tom Eastep +- Update for 2.0.0 Final +* Sat Mar 06 2004 Tom Eastep +- Update for RC2 +* Fri Feb 27 2004 Tom Eastep +- Update for RC1 +* Mon Feb 16 2004 Tom Eastep +- Moved rfc1918 to /usr/share/shorewall +- Update for Beta 3 +* Sat Feb 14 2004 Tom Eastep +- Removed common.def +- Unconditionally replace actions.std +- Update for Beta 2 * Thu Feb 12 2004 Tom Eastep -- Changed version to 1.4.10b-1 +- Added action.AllowPCA * Sun Feb 08 2004 Tom Eastep -- Changed version to 1.4.10a-1 -* Fri Jan 30 2004 Tom Eastep -- Changed version to 1.4.10-1 -* Tue Jan 27 2004 Tom Eastep -- Changed version to 1.4.10-RC3 -* Sat Jan 24 2004 Tom Eastep -- Changed version to 1.4.10-RC2 -* Thu Jan 22 2004 Tom Eastep -- Changed version to 1.4.10-RC1 -* Tue Jan 13 2004 Tom Eastep -- Changed version to 1.4.9 +- Updates for Shorewall 2.0.0. * Mon Dec 29 2003 Tom Eastep - Remove Documentation from this RPM * Sun Dec 28 2003 Tom Eastep diff --git a/Shorewall/start b/Shorewall/start index 7b46073f8..c3b48057e 100644 --- a/Shorewall/start +++ b/Shorewall/start @@ -1,5 +1,5 @@ ############################################################################ -# Shorewall 1.4 -- /etc/shorewall/start +# Shorewall 2.0 -- /etc/shorewall/start # # Add commands below that you want to be executed after shorewall has # been started or restarted. diff --git a/Shorewall/stop b/Shorewall/stop index 6f402cfa6..78c5fa97b 100644 --- a/Shorewall/stop +++ b/Shorewall/stop @@ -1,5 +1,5 @@ ############################################################################ -# Shorewall 1.4 -- /etc/shorewall/stop +# Shorewall 2.0 -- /etc/shorewall/stop # # Add commands below that you want to be executed at the beginning of a # "shorewall stop" command. diff --git a/Shorewall/stopped b/Shorewall/stopped index 2b5840691..16feb827b 100644 --- a/Shorewall/stopped +++ b/Shorewall/stopped @@ -1,5 +1,5 @@ ############################################################################ -# Shorewall 1.4 -- /etc/shorewall/stopped +# Shorewall 2.0 -- /etc/shorewall/stopped # # Add commands below that you want to be executed at the completion of a # "shorewall stop" command. diff --git a/Shorewall/tcrules b/Shorewall/tcrules index e15a68d80..d2ff68ba5 100755 --- a/Shorewall/tcrules +++ b/Shorewall/tcrules @@ -1,5 +1,5 @@ # -# Shorewall version 1.4 - Traffic Control Rules File +# Shorewall version 2.0 - Traffic Control Rules File # # /etc/shorewall/tcrules # @@ -11,6 +11,11 @@ # FOR ENTRIES IN THIS FILE TO HAVE ANY EFFECT, YOU MUST SET # TC_ENABLED=Yes in /etc/shorewall/shorewall.conf # +# Unlike rules in the /etc/shorewall/rules file, evaluation +# of rules in this file will continue after a match. So the +# final mark for each packet will be the one assigned by the +# LAST tcrule that matches. +# # Columns are: # # diff --git a/Shorewall/tos b/Shorewall/tos index 60245554e..9f9d2bd91 100755 --- a/Shorewall/tos +++ b/Shorewall/tos @@ -1,5 +1,5 @@ # -# Shorewall 1.4 -- /etc/shorewall/tos +# Shorewall 2.0 -- /etc/shorewall/tos # # This file defines rules for setting Type Of Service (TOS) # @@ -43,10 +43,10 @@ # ############################################################################## #SOURCE DEST PROTOCOL SOURCE PORTS DEST PORTS TOS -all all tcp - ssh 16 -all all tcp ssh - 16 -all all tcp - ftp 16 -all all tcp ftp - 16 -all all tcp ftp-data - 8 -all all tcp - ftp-data 8 +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/Shorewall/tunnel b/Shorewall/tunnel index 2cb20ca36..1397e7463 100755 --- a/Shorewall/tunnel +++ b/Shorewall/tunnel @@ -2,14 +2,14 @@ RCDLINKS="2,S45 3,S45 6,K45" ################################################################################ -# Script to create a gre or ipip tunnel -- Shorewall 1.4 +# Script to create a gre or ipip tunnel -- Shorewall 2.0 # # Modified - Steve Cowles 5/9/2000 # Incorporated init {start|stop} syntax and iproute2 usage # # This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] # -# (c) 2000,2001,2002,2003 - Tom Eastep (teastep@shorewall.net) +# (c) 2000,2001,2002,2003,2004 - Tom Eastep (teastep@shorewall.net) # # Modify the following variables to match your configuration # @@ -59,6 +59,13 @@ gateway="x.x.x.x" subnet="192.168.9.0/24" +# GRE Key -- set this to a number or to a dotted quad if you want +# a keyed GRE tunnel. You must specify a KEY if you +# intend to load ip_conntrack_proto_gre on either +# gateway system + +key= + PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin load_modules () { @@ -101,7 +108,7 @@ do_start() { case $tunnel_type in gre) - ip tunnel add $tunnel mode gre remote $gateway local $myrealip ttl 255 + ip tunnel add $tunnel mode gre remote $gateway local $myrealip ttl 255 ${key:+key $key) ;; *) ip tunnel add $tunnel mode ipip remote $gateway diff --git a/Shorewall/tunnels b/Shorewall/tunnels index 742a2246a..0069daad8 100644 --- a/Shorewall/tunnels +++ b/Shorewall/tunnels @@ -1,5 +1,5 @@ # -# Shorewall 1.4 - /etc/shorewall/tunnels +# Shorewall 2.0 - /etc/shorewall/tunnels # # This file defines IPSEC, GRE, IPIP and OPENVPN tunnels. # @@ -9,10 +9,14 @@ # # 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" # +# If the type is "ipsec" or "ipsecnat", it may be followed +# by ":noah" to indicate that the Authentication Header +# protocol (51) is not used by the tunnel. +# # If type is "openvpn", it may optionally be followed # by ":" and the port number used by the tunnel. if no # ":" and port number are included, then the default port @@ -42,9 +46,10 @@ # Example 1: # # IPSec tunnel. The remote gateway is 4.33.99.124 and -# the remote subnet is 192.168.9.0/24 +# the remote subnet is 192.168.9.0/24. The tunnel does +# not use the AH protocol # -# ipsec net 4.33.99.124 +# ipsec:noah net 4.33.99.124 # # Example 2: # diff --git a/Shorewall/uninstall.sh b/Shorewall/uninstall.sh index 32fec8486..fa30c12fa 100755 --- a/Shorewall/uninstall.sh +++ b/Shorewall/uninstall.sh @@ -4,7 +4,7 @@ # # This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] # -# (c) 2000,2001,2002,2003 - Tom Eastep (teastep@shorewall.net) +# (c) 2000,2001,2002,2003,2004 - Tom Eastep (teastep@shorewall.net) # # Shorewall documentation is available at http://shorewall.sourceforge.net # @@ -26,11 +26,11 @@ # You may only use this script to uninstall the version # shown below. Simply run this script to remove Seattle Firewall -VERSION=1.4.10d +VERSION=2.0.16 usage() # $1 = exit status { - ME=`basename $0` + ME=$(basename $0) echo "usage: $ME" exit $1 } @@ -61,7 +61,7 @@ remove_file() # $1 = file to restore } if [ -f /usr/share/shorewall/version ]; then - INSTALLED_VERSION="`cat /usr/share/shorewall/version`" + INSTALLED_VERSION="$(cat /usr/share/shorewall/version)" if [ "$INSTALLED_VERSION" != "$VERSION" ]; then echo "WARNING: Shorewall Version $INSTALLED_VERSION is installed" echo " and this is the $VERSION uninstaller." @@ -72,27 +72,25 @@ else VERSION="" fi -echo "Uninstalling Shorewall $VERSION" +echo "Uninstalling shorewall $VERSION" if qt iptables -L shorewall -n; then /sbin/shorewall clear fi -if [ -L /usr/lib/shorewall/firewall ]; then - FIREWALL=`ls -l /usr/lib/shorewall/firewall | sed 's/^.*> //'` -elif [ -L /var/lib/shorewall/firewall ]; then - FIREWALL=`ls -l /var/lib/shorewall/firewall | sed 's/^.*> //'` -elif [ -L /usr/lib/shorewall/init ]; then - FIREWALL=`ls -l /usr/lib/shorewall/init | sed 's/^.*> //'` +if [ -L /usr/share/shorewall/init ]; then + FIREWALL=$(ls -l /usr/share/shorewall/init | sed 's/^.*> //') else - FIREWALL= + FIREWALL=/etc/init.d/shorewall fi if [ -n "$FIREWALL" ]; then if [ -x /sbin/insserv -o -x /usr/sbin/insserv ]; then insserv -r $FIREWALL elif [ -x /sbin/chkconfig -o -x /usr/sbin/chkconfig ]; then - chkconfig --del `basename $FIREWALL` + chkconfig --del $(basename $FIREWALL) + else + rm -f /etc/rc*.d/*$(basename $FIREWALL) fi remove_file $FIREWALL @@ -102,12 +100,7 @@ fi rm -f /sbin/shorewall rm -f /sbin/shorewall-*.bkout -if [ -n "$VERSION" ]; then - restore_file /etc/rc.d/rc.local -fi - rm -rf /etc/shorewall -rm -rf /usr/lib/shorewall rm -rf /var/lib/shorewall rm -rf /usr/share/shorewall diff --git a/Shorewall/users b/Shorewall/users deleted file mode 100644 index 8e82f3d8a..000000000 --- a/Shorewall/users +++ /dev/null @@ -1,25 +0,0 @@ -# -# Shorewall version 1.4 - Users File -# -# /etc/shorewall/users -# -# This file is used to associate local users and/or groups to Shorewall -# "User Sets". -# Columns are: -# -# USERSET The name of a user set defined in -# /etc/shorewall/usersets. -# -# USER A Linux user name or number defined in /etc/passwd. -# -# GROUP A linux group name or number defined in /etc/groups. -# -# The GROUP may be omitted. If it is supplied, then the USER may be -# entered as "-" in which case all members of the specified group are -# included in the USERSET. -# -################################################################################ -#USERSET USER GROUP -# -#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE - diff --git a/Shorewall/usersets b/Shorewall/usersets deleted file mode 100644 index f147d01c3..000000000 --- a/Shorewall/usersets +++ /dev/null @@ -1,29 +0,0 @@ -# -# Shorewall version 1.4 - Users Sets File -# -# /etc/shorewall/usersets -# -# A user set is a list of , or names and can -# be used to control access by individual users to other network hosts -# from the firewall system. -# -# Columns are: -# -# USERSET The name of a user set. May be up to 6 characters in -# length and must be a valid shell identifier. -# -# REJECT The log level for REJECT rules that match a user in this -# userset. -# -# ACCEPT The log level for ACCEPT rules that match a user in this -# userset. -# -# DROP The log level for DROP rules that match a user in this -# userset. -# -# To omit one of the last three columns yet supply a value to one of the -# following ones, enter "-". -# -#USERSET REJECT ACCEPT DROP -# -#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/zones b/Shorewall/zones index 993080b5e..5c13ce6cc 100644 --- a/Shorewall/zones +++ b/Shorewall/zones @@ -1,5 +1,5 @@ # -# Shorewall 1.4 /etc/shorewall/zones +# Shorewall 2.0 /etc/shorewall/zones # # This file determines your network zones. Columns are: #