From 7c78bb16a73de8064ed36f3b95c7d63d1b998498 Mon Sep 17 00:00:00 2001 From: teastep Date: Tue, 30 Apr 2002 23:13:15 +0000 Subject: [PATCH] Initial revision git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@10 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb --- Shorewall/COPYING | 340 ++++ Shorewall/INSTALL | 43 + Shorewall/blacklist | 19 + Shorewall/changelog.txt | 17 + Shorewall/common.def | 34 + Shorewall/fallback.sh | 112 ++ Shorewall/firewall | 3074 ++++++++++++++++++++++++++++++++++++ Shorewall/functions | 167 ++ Shorewall/hosts | 36 + Shorewall/icmp.def | 17 + Shorewall/install.sh | 478 ++++++ Shorewall/interfaces | 94 ++ Shorewall/masq | 81 + Shorewall/modules | 14 + Shorewall/nat | 30 + Shorewall/params | 43 + Shorewall/policy | 47 + Shorewall/proxyarp | 30 + Shorewall/releasenotes.txt | 16 + Shorewall/rules | 151 ++ Shorewall/shorewall | 561 +++++++ Shorewall/shorewall.conf | 189 +++ Shorewall/shorewall.spec | 215 +++ Shorewall/tcrules | 47 + Shorewall/tos | 52 + Shorewall/tunnel | 159 ++ Shorewall/tunnels | 51 + Shorewall/uninstall.sh | 155 ++ Shorewall/whitelist | 18 + Shorewall/zones | 14 + 30 files changed, 6304 insertions(+) create mode 100644 Shorewall/COPYING create mode 100644 Shorewall/INSTALL create mode 100755 Shorewall/blacklist create mode 100755 Shorewall/changelog.txt create mode 100644 Shorewall/common.def create mode 100755 Shorewall/fallback.sh create mode 100755 Shorewall/firewall create mode 100755 Shorewall/functions create mode 100644 Shorewall/hosts create mode 100644 Shorewall/icmp.def create mode 100755 Shorewall/install.sh create mode 100644 Shorewall/interfaces create mode 100755 Shorewall/masq create mode 100644 Shorewall/modules create mode 100755 Shorewall/nat create mode 100644 Shorewall/params create mode 100644 Shorewall/policy create mode 100644 Shorewall/proxyarp create mode 100755 Shorewall/releasenotes.txt create mode 100755 Shorewall/rules create mode 100755 Shorewall/shorewall create mode 100755 Shorewall/shorewall.conf create mode 100644 Shorewall/shorewall.spec create mode 100755 Shorewall/tcrules create mode 100755 Shorewall/tos create mode 100755 Shorewall/tunnel create mode 100644 Shorewall/tunnels create mode 100755 Shorewall/uninstall.sh create mode 100644 Shorewall/whitelist create mode 100644 Shorewall/zones diff --git a/Shorewall/COPYING b/Shorewall/COPYING new file mode 100644 index 000000000..2ba72d57f --- /dev/null +++ b/Shorewall/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Shorewall/INSTALL b/Shorewall/INSTALL new file mode 100644 index 000000000..99e98a3a7 --- /dev/null +++ b/Shorewall/INSTALL @@ -0,0 +1,43 @@ +Shoreline Firewall (Shorewall) Version 1.2 - 12/21/2001 +----- ---- + +----------------------------------------------------------------------------- + + This program is free software; you can redistribute it and/or modify + it under the terms of Version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA + +--------------------------------------------------------------------------- +If your system supports rpm, I recommend that you install the Shorewall +.rpm. If you want to install from the tarball: + +o Unpack the tarball +o cd to the shorewall- directory +o If you have an earlier version of Shoreline Firewall installed,see the + upgrade instructions below +o Edit the files policy, interfaces, rules, nat, proxyarp and masq to + fit your environment. +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 Start the firewall by typing "shorewall start" +o If the install script was unable to configure Shoreline Firewall to + start audomatically at boot, see the HTML documentation contains in the + "documentation" directory. + +Upgrade: + +o run the install script as described above. +o shorewall restart + + diff --git a/Shorewall/blacklist b/Shorewall/blacklist new file mode 100755 index 000000000..24b08c9a9 --- /dev/null +++ b/Shorewall/blacklist @@ -0,0 +1,19 @@ +# +# Shorewall 1.2 -- Blacklist File +# +# /etc/shorewall/blacklist +# +# This file contains a list of IP addresses, MAC addresses and/or subnetworks. +# When a packet arrives on in interface that has the 'blacklist' option +# specified, its source IP address is checked against this file and disposed of +# according to the BLACKLIST_DISPOSITION and BLACKLIST_LOGLEVEL variables in +# /etc/shorewall/shorewall.conf +# +# MAC addresses must be prefixed with "~" and use "-" as a separator. +# +# Example: ~00-A0-C9-15-39-78 +############################################################################### +#ADDRESS/SUBNET +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE + + diff --git a/Shorewall/changelog.txt b/Shorewall/changelog.txt new file mode 100755 index 000000000..438530bbd --- /dev/null +++ b/Shorewall/changelog.txt @@ -0,0 +1,17 @@ +Changes since 1.2.12 + +1. Added whitelist support +2. Added SYN Flood Protection + + + + + + + + + + + + + diff --git a/Shorewall/common.def b/Shorewall/common.def new file mode 100644 index 000000000..f5119665f --- /dev/null +++ b/Shorewall/common.def @@ -0,0 +1,34 @@ +############################################################################ +# Shorewall 1.1 -- /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, copy this +# file to /etc/shorewall/common and modify that file. +# +run_iptables -A common -p icmp -j icmpdef +############################################################################ +# accept ACKs and RSTs that aren't related to any session so that the +# protocol stack can handle them +# +run_iptables -A common -p tcp --tcp-flags ACK ACK -j ACCEPT +run_iptables -A common -p tcp --tcp-flags RST RST -j ACCEPT +############################################################################ +# NETBIOS chatter +# +run_iptables -A common -p udp --dport 137:139 -j REJECT +run_iptables -A common -p udp --dport 445 -j REJECT +run_iptables -A common -p tcp --dport 135 -j reject +############################################################################ +# 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 + diff --git a/Shorewall/fallback.sh b/Shorewall/fallback.sh new file mode 100755 index 000000000..a0e078f7e --- /dev/null +++ b/Shorewall/fallback.sh @@ -0,0 +1,112 @@ +#!/bin/sh +# +# Script to back out the installation of Shoreline Firewall and to restore the previous version of +# the program +# +# This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] +# +# (c) 2001,2002 - Tom Eastep (teastep@shorewall.net) +# +# Shorewall documentation is available at http://seattlefirewall.dyndns.org +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of Version 2 of the GNU General Public License +# as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA +# +# Usage: +# +# You may only use this script to back out the installation of the version +# shown below. Simply run this script to revert to your prior version of +# Shoreline Firewall. + +VERSION=1.2.13 + +usage() # $1 = exit status +{ + echo "usage: `basename $0`" + exit $1 +} + +restore_file() # $1 = file to restore +{ + if [ -f ${1}-${VERSION}.bkout ]; then + if (mv -f ${1}-${VERSION}.bkout $1); then + echo + echo "$1 restored" + else + echo "ERROR: Could not restore $1" + exit 1 + fi + fi +} + +if [ ! -f /etc/shorewall/version-${VERSION}.bkout ]; then + echo "Seattle Firewall Version $VERSION is not installed" + exit 1 +fi + +echo "Backing Out Installation of Shorewall $VERSION" + +if [ -L /etc/shorewall/firewall ]; then + FIREWALL=`ls -l /etc/shorewall/firewall | sed 's/^.*> //'` + restore_file $FIREWALL +fi + +restore_file /sbin/shorewall + +[ -f /etc/shorewall.conf.$VERSION ] && rm -f /etc/shorewall.conf.$VERSION + +restore_file /etc/shorewall/shorewall.conf + +restore_file /etc/shorewall/functions + +restore_file /etc/shorewall/common.def + +restore_file /etc/shorewall/icmp.def + +restore_file /etc/shorewall/zones + +restore_file /etc/shorewall/policy + +restore_file /etc/shorewall/interfaces + +restore_file /etc/shorewall/hosts + +restore_file /etc/shorewall/rules + +restore_file /etc/shorewall/nat + +restore_file /etc/shorewall/params + +restore_file /etc/shorewall/proxyarp + +restore_file /etc/shorewall/masq + +restore_file /etc/shorewall/modules + +restore_file /etc/shorewall/tcrules + +restore_file /etc/shorewall/tos + +restore_file /etc/shorewall/tunnels + +restore_file /etc/shorewall/blacklist + +restore_file /etc/shorewall/whitelist + +restore_file /etc/shorewall/version + +oldversion="`cat /etc/shorewall/version`" + +echo "Shorewall Restored to Version $oldversion" + + diff --git a/Shorewall/firewall b/Shorewall/firewall new file mode 100755 index 000000000..5f0e37f79 --- /dev/null +++ b/Shorewall/firewall @@ -0,0 +1,3074 @@ +#!/bin/sh +RCDLINKS="2,S41 3,S41 6,K41" +# +# The Shoreline Firewall (Shorewall) Packet Filtering Firewall - V1.2 12/21/2001 +# +# This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] +# +# (c) 1999,2000,2001,2002 - 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 +# it under the terms of Version 2 of the GNU General Public License +# as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA +# +# If an error occurs while starting or restarting the firewall, the +# firewall is automatically stopped. +# +# Commands are: +# +# shorewall start Starts the firewall +# shorewall restart Restarts the firewall +# shorewall stop Stops the firewall +# shorewall status Displays firewall status +# shorewall reset Resets iptabless packet and +# byte counts +# shorewall clear Remove all Shorewall chains +# and rules/policies. +# shorewall refresh . Rebuild the common chain +# shorewall check Verify the more heavily-used +# configuration files. + +#### BEGIN INIT INFO +# Provides: shorewall +# Required-Start: $network +# Required-Stop: +# Default-Start: 2 3 5 +# Default-Stop: 0 1 6 +# Description: starts and stops the shorewall firewall +### END INIT INFO + +# chkconfig: 2345 25 90 +# description: Packet filtering firewall +# + +############################################################################### +# Mutual exclusion -- These functions are jackets for the mutual exclusion # +# routines in /etc/shorewall/functions. They invoke the # +# corresponding function in that file if the user did not # +# specify "nolock" on the runeline. # +############################################################################### +my_mutex_on() { + [ -n "$nolock" ] || { mutex_on; have_mutex=Yes; } +} + +my_mutex_off() { + [ -n "$have_mutex" ] && { mutex_off; have_mutex=; } +} + +############################################################################### +# Message to stderr # +############################################################################### +error_message() # $* = Error Message +{ + echo "$@" >&2 +} + +############################################################################### +# Fatal error -- stops the firewall after issuing the error message # +############################################################################### +fatal_error() # $* = Error Message +{ + echo "$@" >&2 + stop_firewall + exit 2 +} + +############################################################################### +# Fatal error during startup -- generate an error message and abend with # +# altering the state of the firewall # +############################################################################### +startup_error() # $* = Error Message +{ + echo "$@" >&2 + my_mutex_off + [ -n "$TMP_DIR" ] && rm -rf $TMP_DIR + kill $$ + exit 2 +} + +############################################################################### +# Perform variable substitution on the passed argument and echo the result # +############################################################################### +expand() # $1 = contents of variable which may be the name of another variable +{ + eval echo \"$1\" +} + +############################################################################### +# 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 +} + +################################################################################ +# Run iptables and if an error occurs, stop the firewall and quit # +################################################################################ +run_iptables() { + if ! iptables `echo $@ | sed 's/!/! /g'`; then + [ -z "$stopping" ] && { stop_firewall; exit 2; } + fi +} + +################################################################################ +# Run ip and if an error occurs, stop the firewall and quit # +################################################################################ +run_ip() { + if ! ip $@ ; then + [ -z "$stopping" ] && { stop_firewall; exit 2; } + fi +} + +################################################################################ +# Run arp and if an error occurs, stop the firewall and quit # +################################################################################ +run_arp() { + if ! arp $@ ; then + [ -z "$stopping" ] && { stop_firewall; exit 2; } + fi +} + +################################################################################ +# Run tc and if an error occurs, stop the firewall and quit # +################################################################################ +run_tc() { + if ! tc $@ ; then + [ -z "$stopping" ] && { stop_firewall; exit 2; } + fi +} + +################################################################################ +# Create a filter chain # +# # +# If the chain isn't one of the common chains then add a rule to the chain # +# allowing packets that are part of an established connection. Create a # +# variable ${1}_exists and set its value to Yes to indicate that the chain now # +# exists. # +################################################################################ +createchain() # $1 = chain name, $2 = If non-null, don't create default rules +{ + run_iptables -N $1 + + if [ $# -eq 1 ]; then + state="ESTABLISHED" + [ -n "$ALLOWRELATED" ] && state="$state,RELATED" + run_iptables -A $1 -m state --state $state -j ACCEPT + fi + + eval ${1}_exists=Yes +} + +################################################################################ +# Determine if a chain exists # +# # +# When we create a chain "chain", we create a variable named chain_exists and # +# set its value to Yes. This function tests for the "_exists" variable # +# corresponding to the passed chain having the value of "Yes". # +################################################################################ +havechain() # $1 = name of chain +{ + eval test \"\$${1}_exists\" = Yes +} + +################################################################################ +# Ensure that a chain exists (create it if it doesn't) # +################################################################################ +ensurechain() # $1 = chain name +{ + havechain $1 || createchain $1 +} + +################################################################################ +# 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 $@ +} + +################################################################################ +# Delete a chain if it exists # +################################################################################ +deletechain() # $1 = name of chain +{ + qt iptables -L $1 -n && qt iptables -F $1 && qt iptables -X $1 +} + +################################################################################ +# Set a standard chain's policy # +################################################################################ +setpolicy() # $1 = name of chain, $2 = policy +{ + run_iptables -P $1 $2 +} + +################################################################################ +# Set a standard chain to enable established connections # +################################################################################ +setcontinue() # $1 = name of chain +{ + run_iptables -A $1 -m state --state ESTABLISHED -j ACCEPT +} + +################################################################################ +# Flush one of the NAT table chains # +################################################################################ +flushnat() # $1 = name of chain +{ + run_iptables -t nat -F $1 +} + +################################################################################ +# Find interfaces to a given zone # +# # +# Read the interfaces file and for each record matching the passed ZONE, # +# echo the expanded contents of the "INTERFACE" column # +################################################################################ +find_interfaces() # $1 = interface zone +{ + local zne=$1 + + [ $zne = multi ] && zne="-" + + while read z interface subnet options; do + [ "x`expand $z`" = "x$zne" ] && echo `expand $interface` + done < $TMP_DIR/interfaces +} + +################################################################################ +# Find hosts in a given zone # +# # +# Read hosts file and for each record matching the passed ZONE, # +# echo the expanded contents of the "HOST(S)" column # +################################################################################ +find_hosts() # $1 = host zone +{ + local hosts + + while read z hosts options; do + [ "x`expand $z`" = "x$1" ] && expandv hosts && echo `separate_list $hosts` + done < $TMP_DIR/hosts +} + +################################################################################ +# Determine the interfaces on the firewall # +# # +# For each zone, create a variable called ${zone}_interfaces. This # +# variable contains a space-separated list of interfaces to the zone # +################################################################################ +determine_interfaces() { + local all_interfaces + + for zone in $zones multi; do + interfaces=`find_interfaces $zone` + interfaces=`echo $interfaces` # Remove extra trash + eval ${zone}_interfaces="\$interfaces" + all_interfaces=${all_interfaces:-$interfaces} + done + + [ -n "$all_interfaces" ] || startup_error "Error: No interfaces defined" +} + +################################################################################ +# Determine the defined hosts in each zone and generate report # +################################################################################ +determine_hosts() { + do_a_zone() # $1 = zone name + { + eval interfaces=\$${zone}_interfaces + + for interface in $interfaces; do + if [ -z "$hosts" ]; then + hosts=$interface:0.0.0.0/0 + else + hosts="$hosts $interface:0.0.0.0/0" + fi + done + } + + for zone in $zones multi; do + hosts=`find_hosts $zone` + hosts=`echo $hosts` # Remove extra trash + + if [ -z "$hosts" ]; then + #################################################################### + # If no hosts are defined for a zone then the zone consists of any + # host that can send us messages via the interfaces to the zone + # + do_a_zone $zone + fi + + eval ${zone}_hosts="\$hosts" + + if [ -n "$hosts" ]; then + eval display=\$${zone}_display + display_list "$display Zone:" $hosts + elif [ "$zone" != "multi" ]; then + error_message " Warning: Zone $zone is empty" + fi + done +} + +################################################################################ +# Ensure that the passed zone is defined in the zones file or is the firewall # +################################################################################ +validate_zone() # $1 = zone +{ + local zone + for zone in $zones $FW; do + [ "$zone" = "$1" ] && return 0 + done + return 1 +} + +################################################################################ +# Validate the zone names and options in the interfaces file # +################################################################################ +validate_interfaces_file() { + while read z interface subnet options; do + expandv z interface subnet options + r="$z $interface $subnet $options" + [ "x$z" = "x-" ] || validate_zone $z || startup_error "Invalid zone ($z) in record \"$r\"" + + for option in `separate_list $options`; do + case $option in + dhcp|noping|routestopped|norfc1918|multi|routefilter|dropunclean|logunclean|blacklist|-) + ;; + *) + error_message " Warning: Invalid option ($option) in record \"$r\"" + ;; + esac + done + done < $TMP_DIR/interfaces +} + +################################################################################ +# Validate the zone names and options in the hosts file # +################################################################################ +validate_hosts_file() { + 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\"" + + for option in `separate_list $options`; do + case $option in + routestopped|-) + ;; + *) + error_message " Warning: Invalid option ($option) in record \"$r\"" + ;; + esac + done + done < $TMP_DIR/hosts +} + +################################################################################ +# Format a match by the passed MAC address # +# The passed address begins with "~" and uses "-" as a separator between bytes # +# Example: ~01-02-03-04-05-06 # +################################################################################ +mac_match() # $1 = MAC address formated as described above +{ + echo "--match mac --mac-source `echo $1 | sed 's/~//;s/-/:/g'`" +} + +################################################################################ +# validate a record from the rules file # +# # +# The caller has loaded the column contents from the record into the following # +# variables: # +# # +# target clients servers protocol ports cports address # +# # +# and has loaded a space-separated list of their values in "rule". # +################################################################################ +validate_rule() { + ############################################################################ + # validate one rule + # + validate_a_rule() { + ######################################################################## + # Determine the format of the client + # + cli= + + [ -n "$client" ] && case "$client" in + -) + ;; + ~*) + cli=`mac_match $client` + ;; + [0-9]*|![0-9]*) + # + # IP Address, address or subnet + # + cli="-s $client" + ;; + *) + # + # Assume that this is a device name + # + cli="-i $client" + ;; + esac + + dest_interface= + + [ -n "$server" ] && case "$server" in + -) + serv= + ;; + [0-9]*|![0-9]*) + serv=$server + ;; + ~*) + fatal_error "Error: Rule \"$rule\" - Server may not be specified by MAC Address" + ;; + *) + dest_interface="-o $server" + serv= + ;; + esac + ################################################################ + # Setup PROTOCOL, PORT and STATE variables + # + sports="" + dports="" + state="-m state --state NEW" + proto=$protocol + addr=$address + servport=$serverport + + case $proto in + tcp|udp|TCP|UDP|6|17) + [ -n "$port" ] && [ "x${port}" != "x-" ] && \ + dports="--dport $port" + [ -n "$cport" ] && [ "x${cport}" != "x-" ] && \ + sports="--sport $cport" + ;; + icmp|ICMP|0) + [ -n "$port" ] && dports="--icmp-type $port" + state="" + ;; + all|ALL) + proto= + ;; + related|RELATED) + proto= + state="-m state --state RELATED" + ;; + *) + ;; + esac + + proto="${proto:+-p $proto}" + + if [ -z "$proto" -a -z "$cli" -a -z "$serv" -a -z "$servport" ]; then + error_message " Warning -- Rule \"$rule\" is a POLICY" + error_message " -- and should be moved to the policy file" + fi + + if [ -n "${serv}${servport}" ]; then + ################################################################## + # Destination is a Specific Server or we're redirecting a port + # + if [ -n "$addr" -a "$addr" != "$serv" ]; then + ############################################################## + # Must use Prerouting DNAT + # + if [ -z "$NAT_ENABLED" ]; then + startup_error \ + " Error - Rule \"$rule\" requires NAT which is disabled" + fi + + if [ "$target" != "ACCEPT" ]; then + startup_error " Error - Only ACCEPT rules may specify " \ + "port mapping; rule \"$rule\"" + fi + fi + else + [ -n "$addr" ] && startup_error \ + " Error: An ADDRESS ($addr) is only allowed in" \ + " a port mapping rule: \"$rule\"" + fi + } + ############################################################################ + # V a l i d a t e _ R u l e S t a r t s H e r e + ############################################################################ + # Parse the Target and Clients columns + # + if [ "$target" = "${target%:*}" ]; then + loglevel= + else + loglevel="${target#*:}" + target="${target%:*}" + expandv loglevel + fi + + logtarget="$target" + + if [ "$clients" = "${clients%:*}" ]; then + clientzone="$clients" + clients= + else + clientzone="${clients%:*}" + clients="${clients#*:}" + fi + ############################################################################ + # Validate the Source Zone + + if ! validate_zone $clientzone; then + startup_error " Error: Undefined Client Zone in rule \"$rule\"" + fi + + source=$clientzone + + [ $source = $FW ] && source_hosts= || eval source_hosts=\"\$${source}_hosts\" + + ############################################################################ + # Parse the servers column + # + if [ "$servers" = "${servers%:*}" ] ; then + serverzone="$servers" + servers= + serverport= + else + serverzone="${servers%%:*}" + servers="${servers#*:}" + if [ "$servers" != "${servers%:*}" ] ; then + serverport="${servers#*:}" + servers="${servers%:*}" + else + serverport= + fi + fi + ############################################################################ + # Validate the destination zone + # + if ! validate_zone $serverzone; then + startup_error " Error: Undefined Server Zone in rule \"$rule\"" + fi + + dest=$serverzone + ############################################################################ + # Iterate through the various lists validating individual rules + # + [ "$ports" = "none" -o "$ports" = "None" -o \ + "$cports" = "none" -o "$cports" = "None" -o \ + "$clients" = "none" -o "$clients" = "None" -o \ + "$servers" = "none" -o "$servers" = "None" ] || \ + { + 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 + validate_a_rule + done + done + done + done + + echo " Rule \"$rule\" validated." + } +} + +################################################################################ +# validate the rules file # +################################################################################ +validate_rules() # $1 = name of rules file +{ + strip_file rules + + while read target clients servers protocol ports cports address; do + expandv clients servers protocol ports cports address + case "$target" in + + ACCEPT*|DROP*|REJECT*) + rule="`echo $target $clients $servers $protocol $ports $cports $address`" + validate_rule + ;; + *) + rule="`echo $target $clients $servers $protocol $ports $cports $address`" + startup_error "Error: Invalid Target - rule \"$rule\" ignored" + ;; + esac + done < $TMP_DIR/rules +} + +################################################################################ +# validate the policy file # +################################################################################ +validate_policy() +{ + strip_file policy $policy + + while read client server policy loglevel synparams; do + expandv client server policy loglevel synparams + case "$client" in + all|ALL) + ;; + *) + if ! validate_zone $client; then + startup_error " Error: Undefined zone $client" + fi + esac + + case "$server" in + all|ALL) + ;; + *) + if ! validate_zone $server; then + startup_error " Error: Undefined zone $server" + fi + esac + + case $policy in + ACCEPT|REJECT|DROP|CONTINUE) + ;; + *) + startup_error " Error: Invalid policy $policy" + ;; + esac + + echo " Policy \"$client $server $policy $loglevel\" Validated" + + done < $TMP_DIR/policy +} + +################################################################################ +# Find broadcast addresses corresponding to interfaces to a given zone # +################################################################################ +find_broadcast() # $1 = zone +{ + local zne=$1 + + [ $zne = multi ] && zne="-" + + while read z interface bcast options; do + expandv z interface bcast + if [ "x$z" = "x$zne" -a -n "$bcast" ]; then + if [ "x$bcast" = "xdetect" ]; then + addr="`ip 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 + elif [ "x${bcast}" != "x-" ]; then + echo `separate_list $bcast` + fi + fi + done < $TMP_DIR/interfaces +} + +################################################################################ +# Find interfaces that have the passed option specified # +################################################################################ +find_interfaces_by_option() # $1 = option +{ + while read ignore interface subnet options; do + expandv options + for option in `separate_list $options`; do + [ "$option" = "$1" ] && echo `expand $interface` && break 1 + done + done < $TMP_DIR/interfaces +} + +################################################################################ +# Find hosts with the passed option # +################################################################################ +find_hosts_by_option() # $1 = option +{ + while read ignore hosts options; do + expandv options + for option in `separate_list $options`; do + [ "$option" = "$1" ] && echo `expand $hosts` + done + done < $TMP_DIR/hosts + + while read ignore interface ignore1 options; do + expandv options + for option in `separate_list $options`; do + [ "$option" = "$1" ] && \ + echo `expand $interface`:0.0.0.0/0 && break 1 + done + done < $TMP_DIR/interfaces +} + +################################################################################ +# Determine if there are interfaces of the given zone and option # +# # +# Returns zero if any such interfaces are found and returns one otherwise. # +################################################################################ +have_interfaces_in_zone_with_option() # $1 = zone, $2 = option +{ + local zne=$1 + + [ $zne = multi ] && zne="-" + + while read z interface broadcast options; do + [ "x`expand $z`" = "x$zne" ] && \ + expandv options && \ + for option in `separate_list $options`; do + [ "$option" = "$2" ] && return 0 + done + done < $TMP_DIR/interfaces + return 1 +} + +################################################################################ +# Flush and delete all user-defined chains in the filter table # +################################################################################ +deleteallchains() { + run_iptables -F + run_iptables -X +} + +################################################################################ +# Source a user exit file if it exists # +################################################################################ +run_user_exit() # $1 = file name +{ + local user_exit=`find_file $1` + + if [ -f $user_exit ]; then + echo "Processing $user_exit ..." + . $user_exit + fi +} + +################################################################################ +# Stop the Firewall - # +################################################################################ +stop_firewall() { + stopping="Yes" + + deletechain shorewall + + run_user_exit stop + + [ -n "$MANGLE_ENABLED" ] && \ + run_iptables -t mangle -F && \ + run_iptables -t mangle -X + + [ -n "$NAT_ENABLED" ] && delete_nat + delete_proxy_arp + [ -n "$TC_ENABLED" ] && delete_tc + + setpolicy INPUT DROP + setpolicy OUTPUT DROP + setpolicy FORWARD DROP + + deleteallchains + + hosts="`find_hosts_by_option routestopped`" + + for host in $hosts; do + interface=${host%:*} + subnet=${host#*:} + iptables -A INPUT -i $interface -s $subnet -j ACCEPT + iptables -A OUTPUT -o $interface -d $subnet -j ACCEPT + + for host1 in $hosts; do + [ "$host" != "$host1" ] && \ + iptables -A FORWARD -i $interface -s $subnet \ + -o ${host1%:*} -d ${host1#*:} -j ACCEPT + done + done + + iptables -A INPUT -i lo -j ACCEPT + iptables -A OUTPUT -o lo -j ACCEPT + + + for interface in `find_interfaces_by_option dhcp`; do + iptables -A INPUT -p udp -i $interface --dport 67:68 -j ACCEPT + iptables -A OUTPUT -p udp -o $interface --dport 67:68 -j ACCEPT + done + + case "$IP_FORWARDING" in + [Oo][Nn]) + echo 1 > /proc/sys/net/ipv4/ip_forward + ;; + [Oo][Ff][Ff]) + echo 0 > /proc/sys/net/ipv4/ip_forward + ;; + esac + + logger "Shorewall Stopped" + + rm -rf $TMP_DIR + + case $command in + stop|clear) + ;; + *) + # + # The firewall is being stopped when we were trying to do something + # else. Remove the lock file and Kill the shell in case we're in a + # subshell + # + my_mutex_off + kill $$ + ;; + esac +} + +################################################################################ +# Remove all rules and remove all user-defined chains # +################################################################################ +clear_firewall() { + stop_firewall + + setpolicy INPUT ACCEPT + setpolicy FORWARD ACCEPT + setpolicy OUTPUT ACCEPT + + run_user_exit clear + + logger "Shorewall Cleared" +} + +################################################################################ +# Set up ipsec tunnels # +################################################################################ +setup_tunnels() # $1 = name of tunnels file +{ + local inchain + local outchain + + setup_one_ipsec() # $1 = zone, $2 = gateway $3 = gateway zone + { + if ! validate_zone $1; then + + error_message "Invalid gateway zone ($3)" \ + " -- Tunnel \"$tunnel\" Ignored" + return 1 + fi + + options="-mstate --state NEW -j ACCEPT" + inchain=${1}2${FW} + outchain=${FW}2${1} + addrule $inchain -p 50 -s $2 $options + addrule $outchain -p 50 -d $2 $options + run_iptables -A $inchain -p 51 -s $2 $options + run_iptables -A $outchain -p 51 -d $2 $options + run_iptables -A $inchain -p udp -s $2 --sport 500 --dport 500 $options + run_iptables -A $outchain -p udp -d $2 --dport 500 --sport 500 $options + + if [ -n "$3" ]; then + if validate_zone $3; then + addrule ${FW}2${3} -p udp --sport 500 --dport 500 $options + else + error_message "Warning: Invalid gateway zone ($3)" \ + " -- Tunnel \"$tunnel\" may encounter keying problems" + fi + fi + + return 0 + } + + setup_one_other() # $1 = zone, $2 = gateway, $3 = protocol + { + if ! validate_zone $1; then + error_message "Invalid gateway zone ($3)" \ + " -- Tunnel \"$tunnel\" Ignored" + return 1 + fi + + options="-mstate --state NEW -j ACCEPT" + inchain=${1}2${FW} + outchain=${FW}2${1} + addrule $inchain -p $3 -s $2 $options + addrule $outchain -p $3 -d $2 $options + + return 0 + } + + strip_file tunnels $1 + + while read kind z gateway z1; do + expandv kind z gateway z1 + tunnel="`echo $kind $z $gateway $z1`" + case $kind in + ipsec|IPSEC) + setup_one_ipsec $z $gateway $z1 && \ + echo " IPSEC tunnel to $gateway defined." + ;; + ipip|IPIP) + setup_one_other $z $gateway 4 && \ + echo " IPIP tunnel to $gateway defined." + ;; + gre|GRE) + setup_one_other $z $gateway 47 $z1 \ + echo " GRE tunnel to $gateway defined." + ;; + *) + error_message "Tunnels of type $kind are not supported:" \ + "Tunnel \"$tunnel\" Ignored" + ;; + esac + done < $TMP_DIR/tunnels +} + +################################################################################ +# Setup Proxy ARP # +################################################################################ +setup_proxy_arp() { + + print_error() { + error_message "Invalid value for HAVEROUTE - ($haveroute)" + error_message "Entry \"$address $interface $external $haveroute\" ignored" + } + + setup_one_proxy_arp() { + case $haveroute in + [Nn][Oo]) + haveroute= + ;; + [Yy][Ee][Ss]) + ;; + *) + if [ -n "$haveroute" ]; then + print_error + return + fi + ;; + esac + + [ -z "$haveroute" ] && run_ip route add $address dev $interface + + run_arp -Ds $address $external pub + + echo 1 > /proc/sys/net/ipv4/conf/$interface/proxy_arp + 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" + } + + > ${STATEDIR}/proxyarp + + strip_file proxyarp + + while read address interface external haveroute; do + expandv address interface external haveroute + setup_one_proxy_arp + done < $TMP_DIR/proxyarp +} + +############################################################################### +# Set up SYN flood protection # +############################################################################### +setup_syn_flood_chain () + # $1 = policy chain + # $2 = synparams +{ + local chain=$1 + local limit=${2%:*} + local limit_burst=${2#*:} + + run_iptables -N @$chain + run_iptables -A @$chain \ + -m limit --limit $limit --limit-burst $limit_burst \ + -j RETURN + run_iptables -A @$chain -j DROP +} + +################################################################################ +# Enable SYN flood protection on a chain # +# -----------------------------------------------------------------------------# +# Insert a jump rule to the protection chain from the first chain. Inserted # +# as the second rule and restrict the jump to SYN packets # +################################################################################ +enable_syn_flood_protection() # $1 = chain, $2 = protection chain +{ + run_iptables -I $1 2 -p tcp --syn -j @$2 + echo " Enabled SYN flood protection" +} + +################################################################################ +# Delete existing Proxy ARP # +################################################################################ +delete_proxy_arp() { + if [ -f ${STATEDIR}/proxyarp ]; then + while read address interface external haveroute; do + qt arp -i $external -d $address pub + [ -z "$haveroute" ] && qt ip route del $address dev $interface + + echo 0 > /proc/sys/net/ipv4/conf/$external/proxy_arp + echo 0 > /proc/sys/net/ipv4/conf/$interface/proxy_arp + done < ${STATEDIR}/proxyarp + + rm -f ${STATEDIR}/proxyarp + fi + + [ -d ${STATEDIR} ] && touch ${STATEDIR}/proxyarp +} + +################################################################################ +# Setup Static Network Address Translation (NAT) # +################################################################################ +setup_nat() { + local allints + # + # At this point, we're just interested in the network translation + # + > ${STATEDIR}/nat + + strip_file nat + + echo "Setting up NAT..." + + while read external interface internal allints localnat; do + expandv external interface internal allints localnat + if [ -n "$ADD_IP_ALIASES" ]; then + qt ip addr del $external dev $interface + fi + + if [ -z "$allints" -o "$allints" = "Yes" \ + -o "$allints" = "yes" ] + then + run_iptables -t nat -A PREROUTING -d $external \ + -j DNAT --to-destination $internal + run_iptables -t nat -A POSTROUTING -s $internal \ + -j SNAT --to-source $external + if [ "$localnat" = "Yes" -o "$localnat" = "yes" ]; then + run_iptables -t nat -A OUTPUT -d $external \ + -j DNAT --to-destination $internal + fi + else + run_iptables -t nat -A PREROUTING -i $interface \ + -d $external -j DNAT --to-destination $internal + run_iptables -t nat -A POSTROUTING -o $interface \ + -s $internal -j SNAT --to-source $external + fi + + if [ -n "$ADD_IP_ALIASES" ]; then + run_ip addr add $external dev $interface + echo "$external $interface" >> ${STATEDIR}/nat + fi + + echo " Host $internal NAT $external on $interface" + done < $TMP_DIR/nat +} + +################################################################################ +# Delete existing Static NAT and Port Forwarding # +################################################################################ +delete_nat() { + run_iptables -t nat -F + run_iptables -t nat -X + + if [ -f ${STATEDIR}/nat ]; then + while read external interface; do + qt ip addr del $external dev $interface + done < ${STATEDIR}/nat + + rm -f {$STATEDIR}/nat + fi + + [ -d ${STATEDIR} ] && touch ${STATEDIR}/nat +} + +################################################################################ +# Process TC Rule # +################################################################################ +process_tc_rule() +{ + add_a_tc_rule() { + r= + chain=tcpre + + if [ "x$source" != "x-" ]; then + case $source in + [0-9]*) + r="-s $source " + ;; + ~*) + r=`mac_match $source` + ;; + $FW) + chain=tcout + ;; + *) + r="-i $source " + ;; + esac + fi + [ "x$dest" = "x-" ] || r="${r}-d $dest " + [ "$proto" = "all" ] || r="${r}-p $proto " + [ "x$port" = "x-" ] || r="${r}--dport $port " + [ "x$sport" = "x-" ] || r="${r}--sport $sport " + + run_iptables -t mangle -A $chain $r -j MARK --set-mark $mark + + } + + 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" +} + +################################################################################ +# Setup queuing and classes # +################################################################################ +setup_tc() { + + echo "Setting up Traffic Control Rules..." + + # + # Create the TC mangle chains + # + run_iptables -t mangle -N tcpre + run_iptables -t mangle -N tcout + # + # Process the TC Rules File + # + strip_file tcrules + + while read mark sources dests proto ports sports; do + expandv mark sources dests proto ports sports + rule=`echo "$mark $sources $dests $proto $ports $sports"` + process_tc_rule + done < $TMP_DIR/tcrules + # + # Link to the TC mangle chains from the main chains + # + run_iptables -t mangle -A PREROUTING -j tcpre + run_iptables -t mangle -A OUTPUT -j tcout + + run_user_exit tcstart + +} + +################################################################################ +# Clear Traffic Shaping # +################################################################################ +delete_tc() +{ + 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 + + run_ip link list | \ + while read inx interface details; do + case $inx in + [0-9]*) + clear_one_tc ${interface%:} + ;; + *) + ;; + esac + done +} + +################################################################################ +# Process a record from the rules file # +# # +# The caller has loaded the column contents from the record into the following # +# variables: # +# # +# target clients servers protocol ports cports address # +# # +# and has loaded a space-separated list of their values in "rule". # +################################################################################ +process_rule() { + ############################################################################ + # Add one rule + # + add_a_rule() { + ######################################################################## + # Determine the format of the client + # + cli= + + [ -n "$client" ] && case "$client" in + -) + ;; + [0-9]*|![0-9]*) + # + # IP Address or subnet + # + cli="-s $client" + ;; + ~*) + cli=`mac_match $client` + ;; + *) + # + # Assume that this is a device name + # + cli="-i $client" + ;; + esac + + dest_interface= + + [ -n "$server" ] && case "$server" in + -) + serv= + ;; + [0-9]*|![0-9]*) + serv=$server + ;; + *) + dest_interface="-o $server" + serv= + ;; + esac + ################################################################ + # Setup PROTOCOL, PORT and STATE variables + # + sports="" + dports="" + state="-m state --state NEW" + proto=$protocol + addr=$address + servport=$serverport + + case $proto in + tcp|udp|TCP|UDP|6|17) + [ -n "$port" ] && [ "x${port}" != "x-" ] && \ + dports="--dport $port" + [ -n "$cport" ] && [ "x${cport}" != "x-" ] && \ + sports="--sport $cport" + ;; + icmp|ICMP|0) + [ -n "$port" ] && [ "x${port}" != "x-" ] && \ + dports="--icmp-type $port" + state="" + ;; + all|ALL) + proto= + ;; + related|RELATED) + proto= + state="-m state --state RELATED" + ;; + *) + ;; + esac + + proto="${proto:+-p $proto}" + + [ "$target" = REJECT ] && target=reject + + if [ -z "$proto" -a -z "$cli" -a -z "$serv" -a -z "$servport" ]; then + error_message " Warning -- Rule \"$rule\" is a POLICY" + error_message " -- and should be moved to the policy file" + fi + + if [ -n "${serv}${servport}" ]; then + ################################################################## + # Destination is a Specific Server or we're redirecting a port + # + if [ -n "$addr" -a "$addr" != "$serv" ]; then + ############################################################## + # Must use Prerouting DNAT + # + if [ -z "$NAT_ENABLED" ]; then + fatal_error \ + " Error - Rule \"$rule\" requires NAT which is disabled" + fi + + if [ "$target" != "ACCEPT" ]; then + fatal_error " Error - Only ACCEPT rules may specify " \ + "port mapping; rule \"$rule\"" + fi + + if [ "$addr" != "${addr%:*}" ]; then + snat="${addr#*:}" + addr="${addr%:*}" + else + snat="" + fi + + [ "$addr" = "all" ] && addr= || addr="-d $addr" + + if [ -n "$serv" ]; then + servport="${servport:+:$servport}" + target1="DNAT --to-destination ${serv}${servport}" + else + target1="REDIRECT --to-port $servport" + fi + + if [ "$source" = "$FW" ]; then + run_iptables -t nat -A OUTPUT $proto $sports $addr \ + $dports -j $target1 + elif [ -n "$cli" ]; then + run_iptables -t nat -A PREROUTING $proto $cli $sports \ + $addr $dports -j $target1 + else + for source_host in $source_hosts; do + run_iptables -t nat -A PREROUTING \ + -i ${source_host%:*} \ + -s ${source_host#*:} $proto $sports \ + $addr $dports -j $target1 + done + fi + + [ -n "$servport" ] && dports="--dport ${servport#*:}" + + if [ -n "$snat" ]; then + if [ -n "$cli" ]; then + run_iptables -t nat -A POSTROUTING $proto $cli \ + $sports -d $serv $dports -j SNAT --to-source $snat + else + for source_host in $source_hosts; do + run_iptables -t nat -A POSTROUTING \ + -s ${source_host#*:} $proto $sports \ + -d $serv $dports -j SNAT --to-source $snat + done + fi + fi + fi + + serv="${serv:+-d $serv}" + + [ -n "$loglevel" ] && run_iptables -A $chain $proto $state $cli \ + $sports $serv $dports -j LOG $LOGPARMS --log-prefix \ + "Shorewall:$chain:$logtarget:" --log-level $loglevel + run_iptables -A $chain $proto $state $cli $sports \ + $serv $dports -j $target + else + #################################################################### + # Destination is just a zone or an interface + # + [ -n "$addr" ] && fatal_error \ + " Error: An ADDRESS ($addr) is only allowed in" \ + " a port mapping rule: \"$rule\"" + + [ -n "$loglevel" ] && run_iptables -A $chain $proto \ + $dest_interface $state $cli $sports $dports -j LOG \ + $LOGPARMS --log-prefix "Shorewall:$chain:$logtarget:" \ + --log-level $loglevel + + run_iptables -A $chain $proto $dest_interface $state \ + $cli $sports $dports -j $target + fi + } + ############################################################################ + # P r o c e s s _ R u l e S t a r t s H e r e + ############################################################################ + # Parse the Target and Clients columns + # + if [ "$target" = "${target%:*}" ]; then + loglevel= + else + loglevel="${target#*:}" + target="${target%:*}" + expandv loglevel + fi + + logtarget="$target" + + if [ "$clients" = "${clients%:*}" ]; then + clientzone="$clients" + clients= + else + clientzone="${clients%:*}" + clients="${clients#*:}" + fi + + ############################################################################ + # Validate the Source Zone + + if ! validate_zone $clientzone; then + fatal_error " Error: Undefined Client Zone in rule \"$rule\"" + fi + + source=$clientzone + + [ $source = $FW ] && source_hosts= || eval source_hosts=\"\$${source}_hosts\" + + ############################################################################ + # Parse the servers column + # + if [ "$servers" = "${servers%:*}" ] ; then + serverzone="$servers" + servers= + serverport= + else + serverzone="${servers%%:*}" + servers="${servers#*:}" + if [ "$servers" != "${servers%:*}" ] ; then + serverport="${servers#*:}" + servers="${servers%:*}" + else + serverport= + fi + fi + ############################################################################ + # Validate the destination zone + # + if ! validate_zone $serverzone; then + fatal_error " Error: Undefined Server Zone in rule \"$rule\"" + fi + + dest=$serverzone + ############################################################################ + # Create the canonlcal chain if it doesn't exist + # + chain=${source}2${dest} + ensurechain $chain + ############################################################################ + # Iterate through the various lists creating individual rules + # + [ "$ports" = "none" -o "$ports" = "None" -o \ + "$cports" = "none" -o "$cports" = "None" -o \ + "$clients" = "none" -o "$clients" = "None" -o \ + "$servers" = "none" -o "$servers" = "None" ] || \ + { + 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 + done + done + + echo " Rule \"$rule\" added." + } +} + +################################################################################ +# Process the rules file # +################################################################################ +process_rules() # $1 = name of rules file +{ + strip_file rules + + while read target clients servers protocol ports cports address; do + case "$target" in + + ACCEPT*|DROP*|REJECT*) + expandv clients servers protocol ports cports address + rule="`echo $target $clients $servers $protocol $ports $cports $address`" + process_rule + ;; + *) + rule="`echo $target $clients $servers $protocol $ports $cports $address`" + fatal_error "Error: Invalid Target in rule \"$rule\"" + ;; + esac + done < $TMP_DIR/rules +} + +################################################################################ +# Process a record from the tos file # +# # +# The caller has loaded the column contents from the record into the following # +# variables: # +# # +# src dst protocol sport dport tos # +# # +# and has loaded a space-separated list of their values in "rule". # +################################################################################ +process_tos_rule() { + ############################################################################ + # Parse the contents of the 'src' variable + # + if [ "$src" = "${src%:*}" ]; then + srczone="$src" + src= + else + srczone="${src%:*}" + src="${src#*:}" + fi + + source= + # + # Validate the source zone + # + if validate_zone $srczone; then + source=$srczone + elif [ "$srczone" = "all" ]; then + source="all" + else + error_message "Warning: Undefined Source Zone - rule \"$rule\" ignored" + return + fi + + [ -n "$src" ] && case "$src" in + [0-9]*|![0-9]*) + # + # IP Address or subnet + # + src="-s $src" + ;; + ~*) + src=`mac_match $src` + ;; + *) + # + # Assume that this is a device name + # + src="-i $src" + ;; + esac + + ############################################################################ + # Parse the contents of the 'dst' variable + # + if [ "$dst" = "${dst%:*}" ]; then + dstzone="$dst" + dst= + else + dstzone="${dst%:*}" + dst="${dst#*:}" + fi + + dest= + # + # Validate the destination zone + # + if validate_zone $dstzone; then + dest=$dstzone + elif [ "$dstzone" = "all" ]; then + dest="all" + else + error_message \ + "Warning: Undefined Destination Zone - rule \"$rule\" ignored" + return + fi + + [ -n "$dst" ] && case "$dst" in + [0-9]*|![0-9]*) + # + # IP Address or subnet + # + ;; + *) + # + # Assume that this is a device name + # + error_message \ + "Warning: Invalid Destination - rule \"$rule\" ignored" + return + ;; + esac + + ############################################################################ + # Setup PROTOCOL and PORT variables + # + sports="" + dports="" + + case $protocol in + tcp|udp|TCP|UDP|6|17) + [ -n "$sport" ] && [ "x${sport}" != "x-" ] && \ + sports="--sport $sport" + [ -n "$dport" ] && [ "x${dport}" != "x-" ] && \ + dports="--dport $dport" + ;; + icmp|ICMP|0) + [ -n "$dport" ] && [ "x${dport}" != "x-" ] && \ + dports="--icmp-type $dport" + ;; + all|ALL) + protocol= + ;; + *) + ;; + esac + + protocol="${protocol:+-p $protocol}" + + tos="-j TOS --set-tos $tos" + + case "$dstzone" in + all|ALL) + dst=0.0.0.0/0 + ;; + *) + [ -z "$dst" ] && eval dst=\$${dstzone}_hosts + ;; + esac + + for dest in $dst; do + dest="-d $dest" + + case $srczone in + $FW) + run_iptables -t mangle -A outtos \ + $protocol $dest $dports $sports $tos + ;; + all|ALL) + run_iptables -t mangle -A outtos \ + $protocol $dest $dports $sports $tos + run_iptables -t mangle -A pretos \ + $protocol $dest $dports $sports $tos + ;; + *) + if [ -n "$src" ]; then + run_iptables -t mangle -A pretos $src \ + $protocol $dest $dports $sports $tos + else + eval interfaces=\$${srczone}_interfaces + + for interface in $interfaces; do + run_iptables -t mangle -A pretos -i $interface \ + $protocol $dest $dports $sports $tos + done + fi + ;; + esac + done + + echo " Rule \"$rule\" added." +} + +################################################################################ +# Process the tos file # +################################################################################ +process_tos() # $1 = name of tos file +{ + echo "Processing $1..." + + run_iptables -t mangle -N pretos + run_iptables -t mangle -N outtos + + strip_file tos $1 + + while read src dst protocol sport dport tos; do + expandv src dst protocol sport dport tos + rule="`echo $src $dst $protocol $sport $dport $tos`" + process_tos_rule + done < $TMP_DIR/tos + + run_iptables -t mangle -A PREROUTING -j pretos + run_iptables -t mangle -A OUTPUT -j outtos +} + +################################################################################ +# Load a Kernel Module # +################################################################################ +loadmodule() # $1 = module name, $2 - * arguments +{ + local modulename=$1 + local modulefile + + if [ -z "`lsmod | grep $modulename`" ]; then + shift + modulefile=$MODULESDIR/${modulename}.o + + if [ -f $modulefile ]; then + insmod $modulefile $* + return + fi + # + # If the modules directory contains compressed modules then we'll + # assume that insmod can load them + # + modulefile=${modulefile}.gz + + if [ -f $modulefile ]; then + insmod $modulefile $* + fi + fi +} + +################################################################################ +# Display elements of a list with leading white space # +################################################################################ +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 # +################################################################################ +policy_rules() # $1 = chain to add rules to + # $2 = policy + # $3 = loglevel +{ + local target="$2" + + case "$target" in + ACCEPT) + ;; + + DROP) + run_iptables -A $1 -j common + ;; + REJECT) + run_iptables -A $1 -j common + target=reject + ;; + *) + fatal_error "Invalid policy ($policy) for $1 to $2" + ;; + + esac + + [ $# -eq 3 ] && [ "x${3}" != "x-" ] && run_iptables -A $1 -j LOG $LOGPARMS \ + --log-prefix "Shorewall:$chain:$policy:" --log-level $3 + run_iptables -A $1 -j $target +} + +################################################################################ +# Generate default policy & log level rules for the passed client & server # +# zones # +#------------------------------------------------------------------------------# +# This function is only called when the canonical chain for this client/server # +# pair is known to exist. If the default policy for this pair specifies the # +# same chain then we add the policy (and logging) rule to the canonical chain; # +# otherwise add a rule to the canonical chain to jump to the appropriate # +# policy chain. # +################################################################################ +default_policy() # $1 = client $2 = server +{ + local chain="${1}2${2}" + local policy= + local loglevel= + + apply_default() + { + ######################################################################## + # Construct policy chain name + # + chain1=${client}2${server} + + echo " Policy $policy for $1 to $2 using chain $chain1" + + if [ "$policy" = CONTINUE ]; then + #################################################################### + # The policy is CONTINUE -- simply add any logging and syn flood + # jump rules to the canonical chain + # + [ -n "$loglevel" ] && run_iptables -A $chain -j LOG $LOGPARMS \ + --log-prefix "Shorewall:$chain:$policy:" --log-level $loglevel + [ -n "$synparams" ] && \ + enable_syn_flood_protection $chain $chain1 + + elif [ "$chain" = "$chain1" ]; then + #################################################################### + # The policy chain is the canonical chain; add policy rule to it + # The syn flood jump has already been added if required. + # + policy_rules $chain $policy $loglevel + else + #################################################################### + # Policy chain is different; add a rule to jump from the canonical + # chain to the policy chain and optionally, insert a jump to the + # policy chain's syn flood chain. + # + run_iptables -A $chain -j $chain1 + + [ -n "$synparams" ] && \ + enable_syn_flood_protection $chain $chain1 + + fi + } + + while read client server policy loglevel synparams; do + expandv client server policy loglevel synparams + case "$client" in + all|ALL) + if [ "$server" = "$2" -o "$server" = "all" ]; then + apply_default $1 $2 + return + fi + ;; + *) + if [ "$client" = "$1" ] && \ + [ "$server" = "all" -o "$server" = "$2" ] + then + apply_default $1 $2 + return + fi + ;; + esac + done < $TMP_DIR/policy + + fatal_error "Error: No default policy for zone $1 to zone $2" +} + +################################################################################ +# Complete a standard chain +# +# - run any supplied user exit +# - search the policy file for an applicable policy and add rules as +# appropriate +# - If no applicable policy is found, add rules for an assummed +# policy of DROP INFO +################################################################################ +complete_standard_chain() # $1 = chain, $2 = source zone, $3 = destination zone +{ + local policy= + local loglevel= + + run_user_exit $1 + + while read client server policy loglevel synparams; do + expandv client server policy loglevelsynparams + case "$client" in + all|ALL) + if [ "$server" = "$3" -o "$server" = "all" ]; then + policy_rules $1 $policy $loglevel + return + fi + ;; + *) + if [ "$client" = "$2" ] && \ + [ "$server" = "all" -o "$server" = "$3" ] + then + policy_rules $1 $policy $loglevel + return + fi + ;; + esac + done < $TMP_DIR/policy + + policy_rules $1 DROP INFO +} + +################################################################################ +# Find the appropriate chain to pass packets from a source zone to a # +# destination zone # +# # +# If the canonical chain for this zone pair exists, echo it's name; otherwise # +# locate and echo the name of the appropriate policy chain # +# # +# The routine skips policy chains that don't exist. These chains correspond # +# to wild-card CONTINUE policies. # +################################################################################ +rules_chain() # $1 = source zone, $2 = destination zone +{ + local chain=${1}2${2} + + havechain $chain && { echo $chain; return; } + + while read client server policy loglevel ; do + expandv client server policy loglevel + case "$client" in + all|ALL) + if [ "$server" = "$2" -o "$server" = "all" ]; then + chain=all2${server} + if havechain $chain; then + echo $chain + return + fi + fi + ;; + *) + if [ "$client" = "$1" ] && \ + [ "$server" = "all" -o "$server" = "$2" ]; then + chain=${client}2${server} + if havechain $chain; then + echo $chain + return + fi + fi + ;; + esac + done < $TMP_DIR/policy + + fatal_error "Error: No appropriate chain for zone $1 to zone $2" +} + +################################################################################ +# Set up Source NAT (including masquerading) # +################################################################################ +setup_masq() +{ + setup_one() { + local using + + if [ "$interface" = "${interface%:*}" ]; then + destnet="0.0.0.0/0" + else + destnet="${interface#*:}" + interface="${interface%:*}" + fi + + if [ "$subnet" = "${subnet%!*}" ]; then + nomasq= + else + nomasq="${subnet#*!}" + subnet="${subnet%!*}" + fi + + chain=POSTROUTING + + case $subnet in + [0-9]*|![0-9]*) + source="$subnet" + subnet="-s $subnet" + ;; + -) + # + # Note: This only works if you have the LOCAL NAT patches in the + # kernel and in the iptables utility + # + chain=OUTPUT + subnet= + source=$FW + ;; + *) + ipaddr="`run_ip addr show $subnet | grep 'inet '`" + source="$subnet" + if [ -z "$ipaddr" ]; then + fatal_error \ + "Interface $subnet must be up before Shorewall starts" + fi + + subnet="`echo $ipaddr | sed s/" "// | cut -d' ' -f2`" + [ -z "`echo "$subnet" | grep '/'`" ] && subnet="${subnet}/32" + subnet="-s $subnet" + ;; + esac + + if [ -n "$address" -a -n "$ADD_SNAT_ALIASES" ]; then + qt ip addr del $address dev $interface + run_ip addr add $address dev $interface + echo "$address $interface" >> ${STATEDIR}/nat + fi + + destination=$destnet + iface=$interface + + if [ -n "$nomasq" ]; then + newchain=masq${masq_seq} + run_iptables -t nat -N $newchain + run_iptables -t nat -A $chain -d $destnet -o $interface \ + $subnet -j $newchain + masq_seq=$(($masq_seq + 1)) + chain=$newchain + subnet= + interface= + destnet= + + for addr in `separate_list $nomasq`; do + run_iptables -t nat -A $chain -s $addr -j RETURN + done + else + interface="-o $interface" + destnet="-d $destnet" + fi + + if [ -n "$address" ]; then + run_iptables -t nat -A $chain $subnet $destnet \ + $interface -j SNAT --to-source $address + using=" using $address" + else + run_iptables -t nat -A $chain $subnet $destnet \ + $interface -j MASQUERADE + using= + fi + + [ -n "$nomasq" ] && source="$source except $nomasq" + echo " To $destination from $source through ${iface}${using}" + } + + strip_file masq $1 + + [ -n "$NAT_ENABLED" ] && echo "Masqueraded Subnets and Hosts:" + + while read interface subnet address; do + expandv interface subnet address + [ -n "$NAT_ENABLED" ] && setup_one || \ + error_message "Warning: NAT disabled; masq rule ignored" + done < $TMP_DIR/masq +} + +################################################################################ +# Setup Intrazone chain if appropriate # +################################################################################ +setup_intrazone() # $1 = zone +{ + eval hosts=\$${1}_hosts + + if [ "$hosts" != "${hosts% *}" ] || \ + have_interfaces_in_zone_with_option $1 multi + then + ensurechain ${1}2${1} + fi +} + +############################################################################### +# Process a record from the blacklist file # +# # +# $subnet = address/subnet # +############################################################################### +process_blacklist_rec() { + local source + local addr + + for addr in `separate_list $subnet`; do + case $addr in + ~*) + addr=`echo $addr | sed 's/~//;s/-/:/g'` + source="--match mac --mac-source $addr" + ;; + *) + source="-s $addr" + ;; + esac + + [ -n "$BLACKLIST_LOGLEVEL" ] && \ + run_iptables -A blacklst $source -j LOG $LOGPARMS --log-prefix \ + "Shorewall:blacklst:$BLACKLIST_DISPOSITION:" \ + --log-level $BLACKLIST_LOGLEVEL + run_iptables -A blacklst $source -j $disposition + + echo " $addr added to Black List" + done +} + +############################################################################### +# Process a record from the whilelist file # +# # +# $subnet = address/subnet # +############################################################################### +process_whitelist_rec() { + local source + local addr + + for addr in `separate_list $subnet`; do + case $addr in + ~*) + addr=`echo $addr | sed 's/~//;s/-/:/g'` + source="--match mac --mac-source $addr" + ;; + *) + source="-s $addr" + ;; + esac + + run_iptables -A common $source -j ACCEPT + + echo " $addr added to White List" + done +} + +############################################################################### +# Setup the Black List # +############################################################################### +setup_blacklist() { + local interfaces=`find_interfaces_by_option blacklist` + local f=`find_file blacklist` + local disposition=$BLACKLIST_DISPOSITION + + if [ -n "$interfaces" -a -f $f ]; then + echo "Setting up Blacklisting..." + + strip_file blacklist $f + + createchain blacklst no + + for interface in $interfaces; do + run_iptables -A INPUT -i $interface -j blacklst + run_iptables -A FORWARD -i $interface -j blacklst + echo " Blacklisting enabled on $interface" + done + + [ "$disposition" = REJECT ] && disposition=reject + + while read subnet; do + expandv subnet + process_blacklist_rec + done < $TMP_DIR/blacklist + + fi +} + +############################################################################### +# Setup the White List # +############################################################################### +setup_whitelist() { + local f=`find_file whitelist` + + if [ -f $f ]; then + echo "Setting up Whitelisting..." + + strip_file whitelist $f + + while read subnet; do + expandv subnet + process_whitelist_rec + done < $TMP_DIR/whitelist + + fi +} + +############################################################################### +# Refresh the Black List # +############################################################################### +refresh_blacklist() { + local f=`find_file blacklist` + local disposition=$BLACKLIST_DISPOSITION + + if qt iptables -L blacklst -n ; then + echo "Refreshing Black List..." + + strip_file blacklist $f + + [ "$disposition" = REJECT ] && disposition=reject + + run_iptables -F blacklst + + while read subnet; do + expandv subnet + process_blacklist_rec + done < $TMP_DIR/blacklist + + fi +} + +############################################################################### +# Refresh the White List # +############################################################################### +refresh_whitelist() { + local f=`find_file whitelist` + + if [ -f $f ]; then + echo "Refreshing White List..." + + strip_file whitelist $f + + while read subnet; do + expandv subnet + process_whitelist_rec + done < $TMP_DIR/whitelist + + fi +} + +############################################################################### +# Verify that kernel has netfilter support # +############################################################################### +verify_os_version() { + + osversion=`uname -r` + + case $osversion in + 2.4.*|2.5.*) + ;; + *) + startup_error "Shorewall version $version does not work with kernel version $osversion" + ;; + esac +} + +################################################################################ +# Load kernel modules required for Shorewall # +################################################################################ +load_kernel_modules() { + + [ -z "$MODULESDIR" ] && + MODULESDIR=/lib/modules/$osversion/kernel/net/ipv4/netfilter + + modules=`find_file modules` + + if [ -f $modules -a -d $MODULESDIR ]; then + echo "Loading Modules..." + . $modules + fi +} + +################################################################################ +# Perform Initialization # +# - Delete all old rules # +# - Delete all user chains # +# - Set the POLICY on all standard chains and add a rule to allow packets# +# that are part of established connections. # +# - Determine the zones +################################################################################ +initialize_netfilter () { + + echo "Determining Zones..." + + determine_zones + + [ -z "$zones" ] && startup_error "ERROR: No Zones Defined" + + display_list "Zones:" $zones + + echo "Validating interfaces file..." + + validate_interfaces_file + + echo "Validating hosts file..." + + validate_hosts_file + + echo "Determining Hosts in Zones..." + + determine_interfaces + determine_hosts + + deletechain shorewall + + [ -n "$NAT_ENABLED" ] && delete_nat + + delete_proxy_arp + + [ -n "$MANGLE_ENABLED" ] && \ + run_iptables -t mangle -F && \ + run_iptables -t mangle -X + + [ -n "$TC_ENABLED" ] && delete_tc + + run_user_exit init + + echo "Deleting user chains..." + + setpolicy INPUT DROP + setpolicy OUTPUT DROP + setpolicy FORWARD DROP + + deleteallchains + + setcontinue FORWARD + setcontinue INPUT + setcontinue OUTPUT + + [ -n "$CLAMPMSS" ] && \ + run_iptables -A FORWARD -p tcp \ + --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu + + createchain icmpdef no + createchain common no + createchain reject no +} + +################################################################################ +# Construct zone-independent rules # +################################################################################ +add_common_rules() { + ############################################################################ + # Reject Rules + # + run_iptables -A reject -p tcp -j REJECT --reject-with tcp-reset + run_iptables -A reject -j REJECT + ############################################################################ + # dropunclean rules + # + interfaces="`find_interfaces_by_option dropunclean`" + + if [ -n "$interfaces" ]; then + createchain badpkt no + + if [ -n "$LOGUNCLEAN" ]; then + logoptions="$LOGPARAMS --log-prefix Shorewall:badpkt:DROP:" + logoptions="$logoptions --log-level $LOGUNCLEAN --log-ip-options" + run_iptables -A badpkt -p tcp -j LOG $logoptions --log-tcp-options + run_iptables -A badpkt -p !tcp -j LOG $logoptions + fi + + run_iptables -A badpkt -j DROP + echo "Mangled/Invalid Packet filtering enabled on:" + + for interface in $interfaces; do + for chain in INPUT FORWARD; do + run_iptables -A $chain -i $interface --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 + logoptions="$LOGPARAMS --log-prefix Shorewall:logpkt:LOG:" + logoptions="$logoptions --log-level $LOGUNCLEAN --log-ip-options" + run_iptables -A logpkt -p tcp -j LOG $logoptions --log-tcp-options + run_iptables -A logpkt -p !tcp -j LOG $logoptions + + echo "Mangled/Invalid Packet Logging enabled on:" + + for interface in $interfaces; do + for chain in INPUT FORWARD; do + run_iptables -A $chain -i $interface --match unclean -j logpkt + done + echo " $interface" + done + fi + ############################################################################ + # White List + # + setup_whitelist + + ############################################################################ + # Common ICMP rules + # + icmpdef=`find_file icmpdef` + + if [ -f $icmpdef ]; then + . $icmpdef + else + . `find_file icmp.def` + fi + ############################################################################ + # Common rules in each chain + # + common=`find_file common` + + if [ -f $common ]; then + . $common + else + . `find_file common.def` + fi + ########################################################################### + # BROADCASTS + # + for zone in $zones multi; do + eval interfaces=\$${zone}_interfaces + + [ -n "$interfaces" ] && drop_broadcasts `find_broadcast $zone` + setup_intrazone $zone + done + + norfc1918_interfaces="`find_interfaces_by_option norfc1918`" + + if [ -n "$norfc1918_interfaces" ]; then + echo "Enabling RFC1918 Filtering" + + disp="LOG --log-prefix "Shorewall:rfc1918:DROP:" --log-level info" + ######################################################################## + # Since the limited broadcast address falls into 240.0.0.0/4 which we + # filter, we must make a special case. Also, we drop the autoconfig + # class B but don't log since too many folks on cable/dsl screw up + # their Windows Networking config and end up with an autoconfiged IP. + # + createchain rfc1918 no + run_iptables -A rfc1918 -d 255.255.255.255 -j RETURN + run_iptables -A rfc1918 -s 169.254.0.0/16 -j DROP + + createchain logdrop no + run_iptables -A logdrop -j $disp + run_iptables -A logdrop -j DROP + + if [ -n "$MANGLE_ENABLED" ]; then + #################################################################### + # Mangling is enabled -- create a chain in the mangle table to + # filter RFC1918 destination addresses. This must be done in the + # mangle table before we apply any DNAT rules in the nat table + # + # Also add a chain to log and drop any RFC1918 packets that we find + # + run_iptables -t mangle -N rfc1918 + run_iptables -t mangle -A rfc1918 -d 255.255.255.255 -j RETURN + run_iptables -t mangle -A rfc1918 -d 169.254.0.0/16 -j DROP + run_iptables -t mangle -N logdrop + run_iptables -t mangle -A logdrop -j $disp + run_iptables -t mangle -A logdrop -j DROP + fi + ######################################################################## + # 240.0.0.0/4 isn't mentioned in RFC 1918 but since it is reserved, we + # include it here. Same with 0.0.0.0/8, 127.0.0.0/8 and 192.0.2.0/24 + # + for subnet in '0.0.0.0/8' '10.0.0.0/8' '127.0.0.0/8' '192.0.2.0/24' \ + '192.168.0.0/16' '172.16.0.0/12' '240.0.0.0/4'; do + run_iptables -A rfc1918 -s $subnet -j logdrop + #################################################################### + # If packet mangling is enabled, log and drop packets with an + # RFC1918 destination + # + if [ -n "$MANGLE_ENABLED" ]; then + run_iptables -t mangle -A rfc1918 -d $subnet -j logdrop + fi + done + + for interface in $norfc1918_interfaces; do + run_iptables -A INPUT -i $interface -j rfc1918 + run_iptables -A FORWARD -i $interface -j rfc1918 + [ -n "$MANGLE_ENABLED" ] && \ + run_iptables -t mangle -A PREROUTING -i $interface -j rfc1918 + done + + fi + ############################################################################ + # Process Black List + # + setup_blacklist + + ############################################################################ + # Enable the Loopback interface + # + run_iptables -A INPUT -i lo -j ACCEPT + run_iptables -A OUTPUT -o lo -j ACCEPT + ############################################################################ + # Enable icmp output + # + run_iptables -A OUTPUT -p icmp -j ACCEPT + + for f in /proc/sys/net/ipv4/conf/*/rp_filter; do + echo 0 > $f + done + + interfaces="`find_interfaces_by_option routefilter`" + + if [ -n "$interfaces" -o -n "$ROUTE_FILTER" ]; then + echo "Setting up Kernel Route Filtering..." + + if [ -n "$ROUTE_FILTER" ]; then + echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter + else + echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter + + for interface in $interfaces; do + file=/proc/sys/net/ipv4/conf/$interface/rp_filter + if [ -f $file ]; then + echo 1 > $file + else + error_message \ + "Warning: Cannot set route filtering on $interface" + fi + done + fi + fi + + 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 +} + +################################################################################ +# Scan the policy file defining the necessary chains # +# Add the appropriate policy rule(s) to the end of each canonical chain # +################################################################################ +apply_policy_rules() { + + while read client server policy loglevel synparams; do + expandv client server policy loglevel synparams + validate_zone $client + validate_zone $server + + chain=${client}2${server} + + [ -n "$synparams" ] && setup_syn_flood_chain $chain $synparams + + if havechain $chain; then + [ -n "$synparams" ] && enable_syn_flood_protection $chain $chain + elif [ "$client" = "all" -o "$server" = "all" ]; then + # + # A wild-card rule. Create the chain and add policy + # rules if the policy isn't CONTINUE + # + if [ "$policy" != CONTINUE ]; then + # + # We must include the ESTABLISHED and RELATED state + # rule here to account for replys and reverse + # related sessions associated with sessions going + # in the other direction + # + createchain $chain + policy_rules $chain $policy $loglevel + + [ -n "$synparams" ] && \ + [ $policy = ACCEPT ] && \ + run_iptables -I $chain 2 -p tcp --syn -j @$chain + fi + else + # + # This policy chain is also a canonical chain -- create it + # + createchain $chain + + [ -n "$synparams" ] && \ + [ $policy = ACCEPT ] && \ + run_iptables -I $chain 2 -p tcp --syn -j @$chain + fi + + done < $TMP_DIR/policy + + for zone in $FW $zones; do + for zone1 in $FW $zones; do + chain=${zone}2${zone1} + if havechain $chain; then + run_user_exit $chain + default_policy $zone $zone1 + fi + done + done +} + +################################################################################ +# Activate the rules # +################################################################################ +activate_rules() { + + for zone in multi $zones; do + eval source_hosts=\$${zone}_hosts + + for host in $source_hosts; do + interface=${host%:*} + subnet=${host#*:} + chain=INPUT + + if [ "$zone" != "multi" ]; then + # + # If we have a 'multi2fw' chain and the current interface is + # in the 'multi' pseudo-zone, then we will add the rule to + # multi2fw rather than to INPUT + # + if havechain multi2fw; then + for interface1 in $multi_interfaces; do + [ "$interface" = "$interface1" ] && \ + chain=multi2fw && break + done + fi + + run_iptables -A OUTPUT -o \ + $interface -d $subnet -j `rules_chain $FW $zone` + fi + + run_iptables -A $chain -i $interface -s $subnet \ + -j `rules_chain $zone $FW` + done + + [ "$zone" != multi ] && for zone1 in $zones; do + eval dest_hosts=\$${zone1}_hosts + + chain="`rules_chain $zone $zone1`" + + for host in $source_hosts; do + interface=${host%:*} + subnet=${host#*:} + + for host1 in $dest_hosts; do + interface1=${host1%:*} + subnet1=${host1#*:} + + [ $interface = $interface1 -a "x$subnet" = "x$subnet1" ] ||\ + run_iptables -A FORWARD -i $interface -s $subnet \ + -o $interface1 -d $subnet1 -j $chain + done + done + done + done + + while read zone interface broadcast options; do + [ "x`expand $zone`" = "x-" ] && zone=multi + for z in $zones; do + [ "x$z" = "x$zone" ] && \ + expandv interface options && \ + for option in `separate_list $options`; do + [ "$option" = "multi" ] && \ + run_iptables -A FORWARD -i $interface \ + -o $interface -j ${zone}2${zone} && \ + break 1 + done + done + done < $TMP_DIR/interfaces + + complete_standard_chain INPUT all $FW + complete_standard_chain OUTPUT $FW all + complete_standard_chain FORWARD all all + + run_iptables -D INPUT 1 + run_iptables -D OUTPUT 1 + run_iptables -D FORWARD 1 +} + +################################################################################ +# Start/Restart the Firewall # +################################################################################ +define_firewall() # $1 = Command (Start or Restart) +{ + echo "${1}ing Shorewall..." + + verify_os_version + + load_kernel_modules + + echo "Initializing..." + + initialize_netfilter + + echo "Configuring Proxy ARP" + + setup_proxy_arp + + [ -n "$NAT_BEFORE_RULES" ] && setup_nat + + echo "Adding Common Rules" + + add_common_rules + + tunnels=`find_file tunnels` + + [ -f $tunnels ] && \ + echo "Processing $tunnels..." && setup_tunnels $tunnels + + chains="`run_iptables -L -n | grep ^Chain | cut -d' ' -f2`" + chains=`echo $chains` + + rules=`find_file rules` + + echo "Processing $rules..." + + process_rules $rules + + echo "Adding rules for DHCP" + + for interface in `find_interfaces_by_option dhcp`; do + iptables -A INPUT -p udp -i $interface --dport 67:68 -j ACCEPT + iptables -A OUTPUT -p udp -o $interface --dport 67:68 -j ACCEPT + done + + echo "Setting up ICMP Echo handling..." + + noping_interfaces="`find_interfaces_by_option noping`" + + for zone in $zones multi; do + eval interfaces=\$${zone}_interfaces + + for interface in $interfaces; do + [ -n "`echo $noping_interfaces | grep $interface`" ] && \ + target=DROP || target=ACCEPT + addrule ${zone}2${FW} -i $interface \ + -p icmp --icmp-type echo-request -j $target + done + done + + [ -z "$NAT_BEFORE_RULES" ] && setup_nat + + policy=`find_file policy` + + echo "Processing $policy..." + + strip_file policy $policy + + apply_policy_rules + + masq=`find_file masq` + + [ -f $masq ] && setup_masq $masq + + tos=`find_file tos` + + [ -f $tos ] && [ -n "$MANGLE_ENABLED" ] && process_tos $tos + + [ -n "$TC_ENABLED" ] && setup_tc + + echo "Activating Rules..." + + activate_rules + + run_user_exit start + + createchain shorewall no + + echo "Shorewall ${1}ed" + + logger "Shorewall ${1}ed" + + rm -rf $TMP_DIR +} + +################################################################################ +# Check the configuration # +################################################################################ +check_config() { + echo "Verifying Configuration..." + + verify_os_version + + load_kernel_modules + + echo "Determining Zones..." + + determine_zones + + [ -z "$zones" ] && startup_error "ERROR: No Zones Defined" + + display_list "Zones:" $zones + + echo "Validating interfaces file..." + + validate_interfaces_file + + echo "Validating hosts file..." + + validate_hosts_file + + echo "Determining Hosts in Zones..." + + determine_interfaces + determine_hosts + + echo "Validating rules file..." + + validate_rules + + echo "Validating policy file..." + + validate_policy + + rm -rf $TMP_DIR + + echo "Configuration Validated" +} + +################################################################################ +# Rebuild the common chain # +################################################################################ +refresh_firewall() +{ + echo "Refreshing Shorewall..." + + echo "Determining Zones and Interfaces..." + + determine_zones + + [ -z "$zones" ] && startup_error "ERROR: No Zones Defined" + + determine_interfaces + + run_iptables -F common + + ############################################################################ + # White List + # + refresh_whitelist + + echo "Adding Common Rules" + ############################################################################ + # Common rules in each chain + # + common=`find_file common` + + if [ -f $common ]; then + . $common + else + . `find_file common.def` + fi + ########################################################################### + # BROADCASTS + # + for zone in $zones multi; do + eval interfaces=\"\$${zone}_interfaces\" + + [ -n "$interfaces" ] && drop_broadcasts `find_broadcast $zone` + done + + ########################################################################### + # Blacklist + # + refresh_blacklist + + echo "Shorewall Refreshed" + + logger "Shorewall Refreshed" + + rm -rf $TMP_DIR +} + +################################################################################ +# Determine the value for a parameter that defaults to Yes # +################################################################################ +added_param_value_yes() # $1 = Parameter Name, $2 = Parameter value +{ + local val="$2" + + if [ -z "$val" ]; then + echo "Yes" + else case $val in + [Yy][Ee][Ss]) + echo "Yes" + ;; + [Nn][Oo]) + echo "" + ;; + *) + startup_error "Invalid value ($val) for $1" + ;; + esac + fi +} + +################################################################################ +# Determine the value for a parameter that defaults to No # +################################################################################ +added_param_value_no() # $1 = Parameter Name, $2 = Parameter value +{ + local val="$2" + + if [ -z "$val" ]; then + echo "" + else case $val in + [Yy][Ee][Ss]) + echo "Yes" + ;; + [Nn][Oo]) + echo "" + ;; + *) + startup_error "Invalid value ($val) for $1" + ;; + esac + fi +} + +################################################################################ +# Initialize this program # +################################################################################ +do_initialize() { + # Run all utility programs using the C locale + # + # Thanks to Vincent Planchenault for this tip # + + export LC_ALL=C + + PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin + ############################################################################ + # Clear all configuration variables + # + version= + FW= + SUBSYSLOCK= + STATEDIR= + ALLOWRELATED= + LOGRATE= + LOGBURST= + LOGPARMS= + NAT_ENABLED= + MANGLE_ENABLED= + ADD_IP_ALIASES= + ADD_SNAT_ALIASES= + TC_ENABLED= + LOGUNCLEAN= + BLACKLIST_DISPOSITION= + BLACKLIST_LOGLEVEL= + CLAMPMSS= + ROUTE_FILTER= + NAT_BEFORE_RULES= + stopping= + have_mutex= + masq_seq=1 + + 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=/etc/shorewall/functions + + [ -n "$SHOREWALL_DIR" -a -f $SHOREWALL_DIR/functions ] && \ + functions=$SHOREWALL_DIR/functions + + if [ -f $functions ]; then + . $functions + else + startup_error "/etc/shorewall/functions does not exist!" + fi + + version_file=`find_file version` + + [ -f $version_file ] && version=`cat $version_file` + # + # Strip the files that we use often + # + strip_file interfaces + strip_file hosts + + run_user_exit shorewall.conf + run_user_exit params + + [ -z "${STATEDIR}" ] && STATEDIR=/var/state/shorewall + + [ -d $STATEDIR ] || mkdir -p $STATEDIR + + [ -z "$FW" ] && FW=fw + + ALLOWRELATED="`added_param_value_yes ALLOWRELATED $ALLOWRELATED`" + NAT_ENABLED="`added_param_value_yes NAT_ENABLED $NAT_ENABLED`" + MANGLE_ENABLED="`added_param_value_yes MANGLE_ENABLED $MANGLE_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 + LOGPARMS="--match limit" + [ -n "$LOGRATE" ] && LOGPARMS="$LOGPARMS --limit $LOGRATE" + [ -n "$LOGBURST" ] && LOGPARMS="$LOGPARMS --limit-burst $LOGBURST" + fi + + if [ -n "$IP_FORWARDING" ]; then + case "$IP_FORWARDING" in + [Oo][Nn]|[Oo][Ff][Ff]|[Kk][Ee][Ee][Pp]) + ;; + *) + startup_error "Invalid value ($IP_FORWARDING) for IP_FORWARDING" + ;; + esac + else + IP_FORWARDING=On + fi + + if [ -n "$TC_ENABLED" -a -z "$MANGLE_ENABLED" ]; then + startup_error "Traffic Control requires Mangle" + fi + + [ -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` +} + +################################################################################ +# Give Usage Information # +################################################################################ +usage() { + echo "Usage: $0 [debug] {start|stop|reset|restart|status|refresh|clear]}" + exit 1 +} + +################################################################################ +# E X E C U T I O N B E G I N S H E R E # +################################################################################ +# +# Start trace if first arg is "debug" +# +[ $# -gt 1 ] && [ "$1" = "debug" ] && { set -x ; shift ; } + +nolock= + +[ $# -gt 1 ] && [ "$1" = "nolock" ] && { nolock=Yes; shift ; } + +[ $# -ne 1 ] && usage + +command="$1" + +case "$command" in + stop) + do_initialize + my_mutex_on + echo -n "Stopping Shorewall..." + determine_zones + stop_firewall + [ -n "$SUBSYSLOCK" ] && rm -f $SUBSYSLOCK + echo "done." + my_mutex_off + ;; + start) + do_initialize + my_mutex_on + if qt iptables -L shorewall -n ; then + [ -n "$SUBSYSLOCK" ] && touch $SUBSYSLOCK + echo "Shorewall Already Started" + my_mutex_off + exit 0; + fi + define_firewall "Start" && [ -n "$SUBSYSLOCK" ] && touch $SUBSYSLOCK + my_mutex_off + ;; + restart) + do_initialize + my_mutex_on + if qt iptables -L shorewall -n ; then + define_firewall "Restart" + else + echo "Shorewall Not Currently Running" + define_firewall "Start" + fi + + [ $? -eq 0 ] && [ -n "$SUBSYSLOCK" ] && touch $SUBSYSLOCK + my_mutex_off + ;; + status) + echo -e "Shorewall-$version Status at $HOSTNAME - `date`\\n" + iptables -L -n -v + ;; + reset) + iptables -L -n -Z -v + echo "Shorewall Counters Reset" + logger "Shorewall Counters Reset" + ;; + refresh) + do_initialize + my_mutex_on + if ! qt iptables -L shorewall -n ; then + echo "Shorewall Not Started" + my_mutex_off + exit 2; + fi + refresh_firewall; + my_mutex_off + ;; + clear) + do_initialize + my_mutex_on + echo -n "Clearing Shorewall..." + determine_zones + clear_firewall + [ -n "$SUBSYSLOCK" ] && rm -f $SUBSYSLOCK + echo "done." + my_mutex_off + ;; + check) + do_initialize + check_config + ;; + *) + usage + ;; +esac diff --git a/Shorewall/functions b/Shorewall/functions new file mode 100755 index 000000000..cfd2d00b0 --- /dev/null +++ b/Shorewall/functions @@ -0,0 +1,167 @@ +# +# Shorewall 1.2 -- /etc/shorewall/functions + +# +# Suppress all output for a command +# +qt() +{ + "$@" >/dev/null 2>&1 +} + +# +# Find a File -- 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 +} + +# +# Replace commas with spaces and echo the result +# +separate_list() +{ + echo $1 | sed 's/,/ /g' +} + +# +# Find the zones +# +find_zones() # $1 = name of the zone file +{ + while read zone display comments; do + [ -n "$zone" ] && case "$zone" in + \#*) + ;; + $FW|multi) + echo "Reserved zone name \"$zone\" in zones file ignored" >&2 + ;; + *) + echo $zone + ;; + esac + done < $1 +} + +find_display() # $1 = zone, $2 = name of the zone file +{ + grep ^$1 $2 | while read z display comments; do + [ "x$1" = "x$z" ] && echo $display + done +} + +determine_zones() +{ + local zonefile=`find_file zones` + + multi_display=Multi-zone + + if [ -f $zonefile ]; then + zones=`find_zones $zonefile` + zones=`echo $zones` # Remove extra trash + + for zone in $zones; do + dsply=`find_display $zone $zonefile` + eval ${zone}_display=\$dsply + done + else + zones="net local dmz gw" + net_display=Net + local_display=Local + dmz_display=DMZ + gw_display=Gateway + fi + +} + +############################################################################### +# The following functions may be used by apps that wish to ensure that +# the state of Shorewall isn't changing +#------------------------------------------------------------------------------ +# This function loads the STATEDIR variable (directory where Shorewall is to +# store state files). If your application supports alternate Shorewall +# configurations then the name of the alternate configuration directory should +# be in $SHOREWALL_DIR at the time of the call. +# +# If the shorewall.conf file does not exist, this function does not return +############################################################################### +get_statedir() +{ + local config=`find_file shorewall.conf` + + if [ -f $config ]; then + . $config + else + echo "/etc/shorewall/shorewall.conf does not exist!" >&2 + exit 2 + fi + + [ -z "${STATEDIR}" ] && STATEDIR=/var/state/shorewall +} + +############################################################################### +# Call this function to assert MUTEX with Shorewall. If you invoke the +# /sbin/shorewall program while holding MUTEX, you should pass "nolock" as +# the first argument. Example "shorewall nolock refresh" +# +# This function uses the lockfile utility from procmail if it exists. +# Otherwise, it uses a somewhat race-prone algorithm to attempt to simulate the +# behavior of lockfile. +############################################################################### +mutex_on() +{ + local try=0 + local max=15 + local int=2 + + local lockf=$STATEDIR/lock + + [ -d $STATEDIR ] || mkdir -p $STATEDIR + + if qt which lockfile; then + lockfile -030 -r1 ${lockf} || exit 2 + else + while [ -f ${lockf} -a ${try} -lt ${max} ] ; do + sleep ${int} + try=$((${try} + 1)) + done + + if [ ${try} -lt ${max} ] ; then + # Create the lockfile + echo $$ > ${lockf} + else + echo "Giving up on lock file ${lockf}" >&2 + exit 2 + fi + fi +} + +############################################################################### +# Call this function to release MUTEX +############################################################################### +mutex_off() +{ + rm -f $STATEDIR/lock +} + +############################################################################### +# Strip comments and blank lines from a file and place the result in the # +# temporary directory # +############################################################################### +strip_file() # $1 = Base Name of the file, $2 = Full Name of File (optional) +{ + local fname + + [ $# = 1 ] && fname=`find_file $1` || fname=$2 + + if [ -f $fname ]; then + cut -d'#' -f1 $fname | grep -v '^[[:space:]]*$' > $TMP_DIR/$1 + else + > $TMP_DIR/$1 + fi +} diff --git a/Shorewall/hosts b/Shorewall/hosts new file mode 100644 index 000000000..100b02b72 --- /dev/null +++ b/Shorewall/hosts @@ -0,0 +1,36 @@ +# +# Shorewall 1.2 - /etc/shorewall/hosts +# +# WARNING: 90% of Shorewall users don't need to add entries to this +# file and 80% of those who try to add such entries get it +# wrong. Unless you are ABSOLUTELY SURE that you need entries +# in this file, don't touch it! +# +# 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. +# +# ZONE - The name of a zone defined in /etc/shorewall/zones +# +# HOST(S) - The name of an interface followed by a colon (":") and +# either: +# +# a) The IP address of a host +# b) A subnetwork in the form +# / +# +# Examples: +# +# eth1:192.168.1.3 +# eth2:192.168.2.0/24 +# +# OPTIONS - A comma-separated list of options. Currently-defined +# options are: +# +# routestopped - route messages to and from this +# member when the firewall is in the +# stopped state +# +# +#ZONE HOST(S) OPTIONS +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS LINE -- DO NOT REMOVE diff --git a/Shorewall/icmp.def b/Shorewall/icmp.def new file mode 100644 index 000000000..6e639151c --- /dev/null +++ b/Shorewall/icmp.def @@ -0,0 +1,17 @@ +############################################################################## +# Shorewall 1.2 /etc/shorewall/icmp.def +# +# This file defines the default rules for accepting ICMP packets. +# +# Do not modify this file -- if you want to change these rules, copy this +# file to /etc/shorewall/icmpdef and modify that file. +# +# In particular, if you want to accept 'ping' everywhere then add +# +# run_iptables -A icmpdef -p ICMP --icmp-type echo-request -j ACCEPT +# +run_iptables -A icmpdef -p ICMP --icmp-type echo-reply -j ACCEPT +run_iptables -A icmpdef -p ICMP --icmp-type source-quench -j ACCEPT +run_iptables -A icmpdef -p ICMP --icmp-type destination-unreachable -j ACCEPT +run_iptables -A icmpdef -p ICMP --icmp-type time-exceeded -j ACCEPT +run_iptables -A icmpdef -p ICMP --icmp-type parameter-problem -j ACCEPT diff --git a/Shorewall/install.sh b/Shorewall/install.sh new file mode 100755 index 000000000..258143066 --- /dev/null +++ b/Shorewall/install.sh @@ -0,0 +1,478 @@ +#!/bin/sh +# +# Script to install Shoreline Firewall +# +# This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] +# +# (c) 2000,2001,2002 - Tom Eastep (teastep@shorewall.net) +# +# Seawall documentation is available at http://seawall.sourceforge.net +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of Version 2 of the GNU General Public License +# as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 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.2.13 + +usage() # $1 = exit status +{ + ME=`basename $0` + echo "usage: $ME [ -r \"\" ] [ ]" + echo " $ME [ -v ]" + echo " $ME [ -h ]" + exit $1 +} + +run_install() +{ + if ! install $*; then + echo -e "\nERROR: Failed to install $*" + exit 1 + fi +} + +cant_autostart() +{ + echo -e "\nWARNING: Unable to configure Shorewall to start" +echo " automatically at boot" +} + +backup_file() # $1 = file to backup +{ + if [ -z "$PREFIX" -a -f $1 -a ! -f ${1}-${VERSION}.bkout ]; then + if (cp $1 ${1}-${VERSION}.bkout); then + echo + echo "$1 saved to ${1}-${VERSION}.bkout" + else + exit 1 + fi + 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 + run_install -o $OWNER -g $GROUP -m $3 $1 ${2} +} + +# +# Parse the run line +# +# DEST is the SysVInit script directory +# RUNLEVELS is the chkconfig parmeters for firewall +# ARGS is "yes" if we've already parsed an argument +# +DEST="" +RUNLEVELS="" +ARGS="" + +if [ -z "$OWNER" ] ; then + OWNER=root +fi + +if [ -z "$GROUP" ] ; then + GROUP=root +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 "Seattle Firewall Installer Version $VERSION" + exit 0 + ;; + *) + if [ -n "$DEST" ]; then + usage 1 + fi + + DEST="$1" + ;; + esac + shift + ARGS="yes" +done + +# +# Determine where to install the firewall script +# +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 +fi + +# +# Change to the directory containing this script +# +cd "`dirname $0`" + +echo "Installing Shorewall Version $VERSION" + +# +# Check for /etc/shorewall +# +if [ -d ${PREFIX}/etc/shorewall ]; then + first_install="" +else + first_install="Yes" +fi + +install_file_with_backup shorewall ${PREFIX}/sbin/shorewall 0544 + +echo -e "\nShorewall 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 firewall > firewall.temp + + if [ $? -ne 0 ]; then + echo -e "\nERROR: 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 firewall.temp ${PREFIX}${DEST}/$FIREWALL 0544 + + rm -f firewall.temp awk.tmp +else + install_file_with_backup firewall ${PREFIX}${DEST}/$FIREWALL 0544 +fi + +echo -e "\nShorewall script installed in ${PREFIX}${DEST}/$FIREWALL" + +# +# Create /etc/shorewall if needed +# +if [ ! -d ${PREFIX}/etc/shorewall ]; then + mkdir ${PREFIX}/etc/shorewall +fi +# +# 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 + echo -e "\nConfig file installed as ${PREFIX}/etc/shorewall/shorewall.conf" +fi +# +# Install the zones file +# +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 + echo -e "\nZones file installed as ${PREFIX}/etc/shorewall/policy" +fi + +# +# Install the functions file +# +install_file_with_backup functions ${PREFIX}/etc/shorewall/functions 0444 + +echo -e "\nCommon functions installed in ${PREFIX}/etc/shorewall/functions" +# +# Install the common.def file +# +install_file_with_backup common.def ${PREFIX}/etc/shorewall/common.def 0444 + +echo -e "\nCommon rules installed in ${PREFIX}/etc/shorewall/common.def" +# +# Install the icmp.def file +# +install_file_with_backup icmp.def ${PREFIX}/etc/shorewall/icmp.def 0444 + +echo -e "\nCommon ICMP rules installed in ${PREFIX}/etc/shorewall/icmp.def" + +# +# Install the policy file +# +if [ -f ${PREFIX}/etc/shorewall/policy ]; then + backup_file /etc/shorewall/policy +else + run_install -o $OWNER -g $GROUP -m 0600 policy ${PREFIX}/etc/shorewall/policy + echo -e "\nPolicy file installed as ${PREFIX}/etc/shorewall/policy" +fi +# +# Install the interfaces file +# +if [ -f ${PREFIX}/etc/shorewall/interfaces ]; then + backup_file /etc/shorewall/interfaces +else + run_install -o $OWNER -g $GROUP -m 0600 interfaces ${PREFIX}/etc/shorewall/interfaces + echo -e "\nInterfaces file installed as ${PREFIX}/etc/shorewall/interfaces" +fi +# +# Install the hosts file +# +if [ -f ${PREFIX}/etc/shorewall/hosts ]; then + backup_file /etc/shorewall/hosts +else + run_install -o $OWNER -g $GROUP -m 0600 hosts ${PREFIX}/etc/shorewall/hosts + echo -e "\nHosts file installed as ${PREFIX}/etc/shorewall/hosts" +fi +# +# Install the rules file +# +if [ -f ${PREFIX}/etc/shorewall/rules ]; then + backup_file /etc/shorewall/rules +else + run_install -o $OWNER -g $GROUP -m 0600 rules ${PREFIX}/etc/shorewall/rules + echo -e "\nRules file installed as ${PREFIX}/etc/shorewall/rules" +fi +# +# Install the NAT file +# +if [ -f ${PREFIX}/etc/shorewall/nat ]; then + backup_file /etc/shorewall/nat +else + run_install -o $OWNER -g $GROUP -m 0600 nat ${PREFIX}/etc/shorewall/nat + echo -e "\nNAT file installed as ${PREFIX}/etc/shorewall/nat" +fi +# +# Install the Parameters file +# +if [ -f ${PREFIX}/etc/shorewall/params ]; then + backup_file /etc/shorewall/params +else + run_install -o $OWNER -g $GROUP -m 0600 params ${PREFIX}/etc/shorewall/params + echo -e "\nParameter file installed as ${PREFIX}/etc/shorewall/params" +fi +# +# Install the proxy ARP file +# +if [ -f ${PREFIX}/etc/shorewall/proxyarp ]; then + backup_file /etc/shorewall/proxyarp +else + run_install -o $OWNER -g $GROUP -m 0600 proxyarp ${PREFIX}/etc/shorewall/proxyarp + echo -e "\nProxy ARP file installed as ${PREFIX}/etc/shorewall/proxyarp" +fi +# +# Install the Masq file +# +if [ -f ${PREFIX}/etc/shorewall/masq ]; then + backup_file /etc/shorewall/masq +else + run_install -o $OWNER -g $GROUP -m 0600 masq ${PREFIX}/etc/shorewall/masq + echo -e "\nMasquerade file installed as ${PREFIX}/etc/shorewall/masq" +fi +# +# Install the Modules file +# +if [ -f ${PREFIX}/etc/shorewall/modules ]; then + backup_file /etc/shorewall/modules +else + run_install -o $OWNER -g $GROUP -m 0600 modules ${PREFIX}/etc/shorewall/modules + echo -e "\nModules file installed as ${PREFIX}/etc/shorewall/modules" +fi +# +# Install the TC Rules file +# +if [ -f ${PREFIX}/etc/shorewall/tcrules ]; then + backup_file /etc/shorewall/tcrules +else + run_install -o $OWNER -g $GROUP -m 0600 tcrules ${PREFIX}/etc/shorewall/tcrules + echo -e "\nTC Rules file installed as ${PREFIX}/etc/shorewall/tcrules" +fi + +# +# Install the TOS file +# +if [ -f ${PREFIX}/etc/shorewall/tos ]; then + backup_file /etc/shorewall/tos +else + run_install -o $OWNER -g $GROUP -m 0600 tos ${PREFIX}/etc/shorewall/tos + echo -e "\nTOS file installed as ${PREFIX}/etc/shorewall/tos" +fi +# +# Install the Tunnels file +# +if [ -f ${PREFIX}/etc/shorewall/tunnels ]; then + backup_file /etc/shorewall/tunnels +else + run_install -o $OWNER -g $GROUP -m 0600 tunnels ${PREFIX}/etc/shorewall/tunnels + echo -e "\nTunnels file installed as ${PREFIX}/etc/shorewall/tunnels" +fi +# +# Install the blacklist file +# +if [ -f ${PREFIX}/etc/shorewall/blacklist ]; then + backup_file /etc/shorewall/blacklist +else + run_install -o $OWNER -g $GROUP -m 0600 blacklist ${PREFIX}/etc/shorewall/blacklist + echo -e "\nBlacklist file installed as ${PREFIX}/etc/shorewall/blacklist" +fi +# +# Install the whitelist file +# +if [ -f ${PREFIX}/etc/shorewall/whitelist ]; then + backup_file /etc/shorewall/whitelist +else + run_install -o $OWNER -g $GROUP -m 0600 whitelist ${PREFIX}/etc/shorewall/whitelist + echo -e "\nWhitelist file installed as ${PREFIX}/etc/shorewall/whitelist" +fi +# +# Backup the version file +# +if [ -z "$PREFIX" ]; then + if [ -f /etc/shorewall/version ]; then + backup_file /etc/shorewall/version + elif [ -n "$oldversion" ]; then + echo $oldversion > /etc/shorewall/version-${VERSION}.bkout + else + echo "Unknown" > /etc/shorewall/version-${VERSION}.bkout + fi +fi +# +# Create the version file +# +echo "$VERSION" > ${PREFIX}/etc/shorewall/version +chmod 644 ${PREFIX}/etc/shorewall/version +# +# Remove and create the symbolic link to the firewall script +# + +if [ -z "$PREFIX" ]; then + rm -f /etc/shorewall/firewall + ln -s ${DEST}/${FIREWALL} /etc/shorewall/firewall +else + pushd ${PREFIX}/etc/shorewall/ >> /dev/null && ln -s ../..${DEST}/${FIREWALL} firewall && popd >> /dev/null +fi + +echo -e "\n${PREFIX}/etc/shorewall/firewall linked to ${PREFIX}$DEST/$FIREWALL" + +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 + echo -e "\nFirewall will start automatically at boot" + else + cant_autostart + fi + elif [ -x /sbin/chkconfig -o -x /usr/sbin/chkconfig ]; then + if chkconfig --add $FIREWALL ; then + echo -e "\nFirewall will automatically start in run levels as follows:" + chkconfig --list $FIREWALL + else + cant_autostart + fi + else + modify_rclocal + fi +fi +# +# Report Success +# +echo -e "\nShorewall Version $VERSION Installed" diff --git a/Shorewall/interfaces b/Shorewall/interfaces new file mode 100644 index 000000000..127ef6818 --- /dev/null +++ b/Shorewall/interfaces @@ -0,0 +1,94 @@ +# +# Shorewall 1.2 -- Interfaces File +# +# /etc/shorewall/interfaces +# +# You must add an entry in this file for each network interface on your +# firewall system. +# +# Columns are: +# +# ZONE Zone for this interface. Must match the short name +# of a zone defined in /etc/shorewall/zones. +# +# If the interface serves multiple zones that will be +# defined in the /etc/shorewall/hosts file, you may +# place "-" in this column. +# +# INTERFACE Name of interface +# +# BROADCAST The broadcast address for the subnetwork to which the +# interface belongs. For P-T-P interfaces, this +# column is left black. +# +# If you use the special value "detect", the firewall +# will detect the broadcast address for you. If you +# select this option, the interface must be up before +# the firewall is started and you must have iproute +# 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 +# "-" in this column. +# +# 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. +# noping - icmp echo-request (ping) packets should +# be ignored on this interface +# routestopped - When the firewall is stopped, allow +# and route traffic to and from this +# interface. +# 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. +# multi - This interface has multiple IP +# addresses and you want to be able to +# route between them. +# routefilter - turn on kernel route filtering for this +# interface (anti-spoofing measure). +# dropunclean - Logs and drops mangled/invalid packets +# +# logunclean - Logs mangled/invalid packets but does +# not drop them. +# . . blacklist - Check packets arriving on this interface +# against the /etc/shorewall/blacklist +# file. +# +# Example 1: Suppose you have eth0 connected to a DSL modem and +# eth1 connected to your local network and that your +# local subnet is 192.168.1.0/24. The interface gets +# it's IP address via DHCP from subnet +# 206.191.149.192/27 and you want pings from the internet +# to be ignored. You interface a DMZ with subnet +# 192.168.2.0/24 using eth2. You want to be able to +# access the firewall from the local network when the +# firewall is stopped. +# +# Your entries for this setup would look like: +# +# net eth0 206.191.149.223 noping,dhcp +# local eth1 192.168.1.255 routestopped +# dmz eth2 192.168.2.255 +# +# Example 2: The same configuration without specifying broadcast +# addresses is: +# +# net eth0 detect noping,dhcp +# loc eth1 detect routestopped +# dmz eth2 detect +# +# Example 3: You have a simple dial-in system with no ethernet +# connections and you want to ignore ping requests. +# +# net ppp0 - noping +############################################################################## +#ZONE INTERFACE BROADCAST OPTIONS +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/masq b/Shorewall/masq new file mode 100755 index 000000000..43627e04d --- /dev/null +++ b/Shorewall/masq @@ -0,0 +1,81 @@ +# +# Shorewall 1.2 - Masquerade file +# +# /etc/shorewall/masq +# +# Use this file to define dynamic NAT (Masquerading) and to define Source NAT +# (SNAT). +# +# Columns are: +# +# INTERFACE -- Outgoing interface. This is usually your internet +# interface. This may be qualified by adding the character +# ":" followed by a destination host or subnet. +# +# +# SUBNET -- Subnet that you wish to masquerade. You can specify this as +# a subnet or as an interface. If you give the name of an +# interface, you must have iproute installed and the interface +# must be up before you start the firewall. +# +# In order to exclude a subset of the specified SUBNET, you +# may append "!" and a comma-separated list of IP addresses +# and/or subnets that you wish to exclude. +# +# Example: eth1!192.168.1.4,192.168.32.0/27 +# +# In that example traffic from eth1 would be masqueraded unless +# it came from 192.168.1.4 or 196.168.32.0/27 +# +# ADDRESS -- (Optional). If you specify an address here, SNAT will be +# used and this will be the source address. If +# ADD_SNAT_ALIASES is set to Yes or yes in +# /etc/shorewall/shorewall.conf then Shorewall +# will automatically add this address to the +# INTERFACE named in the first column. +# +# WARNING: Do NOT specify ADD_SNAT_ALIASES=Yes if +# the address given in this column is the primary +# IP address for the interface in the INTERFACE +# column. +# +# Example 1: +# +# You have a simple masquerading setup where eth0 connects to +# a DSL or cable modem and eth1 connects to your local network +# with subnet 192.168.0.0/24. +# +# Your entry in the file can be either: +# +# eth0 eth1 +# +# or +# +# eth0 192.168.0.0/24 +# +# Example 2: +# +# You add a router to your local network to connect subnet +# 192.168.1.0/24 which you also want to masquerade. You then +# add the following entry to this file: +# +# eth0 192.168.1.0/24 +# +# Example 3: +# +# You have an IPSEC tunnel through ipsec0 and you want to +# masquerade packets coming from 192.168.1.0/24 but only if +# these packets are destined for hosts in 10.1.1.0/24: +# +# ipsec0:10.1.1.0/24 196.168.1.0/24 +# +# Example 4: +# +# You want all outgoing traffic from 192.168.1.0/24 through +# eth0 to use source address 206.124.146.176. +# +# eth0 192.168.1.0/24 206.124.146.176 +# +############################################################################## +#INTERFACE SUBNET ADDRESS +#LAST LINE -- ADD YOUR ENTRIES ABOVE THIS LINE -- DO NOT REMOVE diff --git a/Shorewall/modules b/Shorewall/modules new file mode 100644 index 000000000..6a799484b --- /dev/null +++ b/Shorewall/modules @@ -0,0 +1,14 @@ +############################################################################## +# Shorewall 1.2 /etc/shorewall/modules +# +# This file loads the modules needed by the firewall. + + loadmodule ip_tables + loadmodule iptable_filter + loadmodule ip_conntrack + loadmodule ip_conntrack_ftp + loadmodule ip_conntrack_irc + loadmodule iptable_nat + loadmodule ip_nat_ftp + loadmodule ip_nat_irc + diff --git a/Shorewall/nat b/Shorewall/nat new file mode 100755 index 000000000..a13504bb3 --- /dev/null +++ b/Shorewall/nat @@ -0,0 +1,30 @@ +############################################################################## +# +# Shorewall 1.2 -- Network Address Translation Table +# +# /etc/shorewall/nat +# +# This file is used to define static Network Address Translation (NAT). +# +# WARNING: If all you want to do is simple port forwarding, do NOT use this +# file. See http://www.shorewall.net/FAQ.htm#faq1. Also, in most +# cases, Proxy ARP is a better solution that static NAT. +# +# Columns must be separated by white space and are: +# +# EXTERNAL External IP Address - this should NOT be the primary +# IP address of the interface named in the next +# column +# INTERFACE Interface that we want to EXTERNAL address to appear +# on +# INTERNAL Internal Address +# 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 +# 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 +# system +############################################################################## +#EXTERNAL INTERFACE INTERNAL ALL INTERFACES LOCAL +#LAST LINE -- ADD YOUR ENTRIES ABOVE THIS LINE -- DO NOT REMOVE diff --git a/Shorewall/params b/Shorewall/params new file mode 100644 index 000000000..6e9f4e468 --- /dev/null +++ b/Shorewall/params @@ -0,0 +1,43 @@ +# +# Shorewall 1.2 /etc/shorewall/params +# +# Assign any variables that you need here. +# +# It is suggested that variable names begin with an upper case letter +# to distinguish them from variables used internally within the +# Shorewall programs +# +# Example: +# +# NET_IF=eth0 +# NET_BCAST=130.252.100.255 +# NET_OPTIONS=noping,norfc1918 +# +# Example (/etc/shorewall/interfaces record): +# +# net $NET_IF $NET_BCAST $NET_OPTIONS +# +# The result will be the same as if the record had been written +# +# net eth0 130.252.100.255 noping,norfc1918 +# +# Variables can be used in the following places in the other configuration +# files: +# +# /etc/shorewall/interfaces: +# /etc/shorewall/hosts +# +# All except the first column. +# +# /etc/shorewall/rules +# +# First column after ":". +# All remaining columns +# +# /etc/shorewall/tunnels +# /etc/shorewall/proxyarp +# /etc/shorewall/nat +# +# All columns +############################################################################## +#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONE - DO NOT REMOVE diff --git a/Shorewall/policy b/Shorewall/policy new file mode 100644 index 000000000..1a2b8c0a1 --- /dev/null +++ b/Shorewall/policy @@ -0,0 +1,47 @@ +# +# Shorewall 1.2 -- Policy File +# +# /etc/shorewall/policy +# +# 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 client/server pair, the +# file is processed in order until a match is found ("all" will match +# any client or server). +# +# Columns are: +# +# CLIENT Location of client. Must be the name of a zone defined +# in /etc/shorewall/zones, $FW or "all". +# +# SERVER Location of server. Must be the name of a zone defined +# in /etc/shorewall/zones, $FW or "all" +# +# POLICY Policy if no match from the rules file is found. Must +# be "ACCEPT", "DENY", "REJECT" or "CONTINUE" +# +# 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 +# description of log levels. +# +# If you don't want to log but need to specify the +# following column, place "_" here. +# +# LIMIT:BURST If passed, specifies the maximum TCP connection rate +# and the size of an acceptable burst. If not specified, +# TCP connections are not limited. +# +# As shipped, the default policies are: +# +# a) All connections from the local network to the internet are allowed +# b) All connections from the network are ignored but logged at syslog +# level KERNEL.INFO. +# d) All other connection requests are rejected and logged at level +# KERNEL.INFO. +############################################################################### +#CLIENT SERVER POLICY LOG LEVEL LIMIT:BURST +loc net ACCEPT +net all DROP info +all all REJECT info +#LAST LINE -- ADD YOUR ENTRIES ABOVE THIS LINE -- DO NOT REMOVE diff --git a/Shorewall/proxyarp b/Shorewall/proxyarp new file mode 100644 index 000000000..746d087f5 --- /dev/null +++ b/Shorewall/proxyarp @@ -0,0 +1,30 @@ +############################################################################## +# +# Shorewall 1.2 -- Proxy ARP +# +# /etc/shorewall/proxyarp +# +# This file is used to define Proxy ARP. +# +# 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. +# +# 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 HAVEROUTE +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/releasenotes.txt b/Shorewall/releasenotes.txt new file mode 100755 index 000000000..30ce758e5 --- /dev/null +++ b/Shorewall/releasenotes.txt @@ -0,0 +1,16 @@ +This is a minor release of Shorewall. + +In this release: + +1. Whitelist support has been added. +2. Optional SYN Flood protection is now available + + + + + + + + + + diff --git a/Shorewall/rules b/Shorewall/rules new file mode 100755 index 000000000..c71c56dab --- /dev/null +++ b/Shorewall/rules @@ -0,0 +1,151 @@ +# +# Shorewall version 1.2 - Rules File +# +# /etc/shorewall/rules +# +# Rules in this file govern connection establishment. Requests and +# responses are automatically allowed using connection tracking. +# +# 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. +# +# If any of the following columns contain the word "none" then the rule +# is ignored: +# +# PORT(S), CLIENT PORT(S), CLIENT(S) and SERVER. +# +# Columns are: +# +# +# RESULT ACCEPT, DROP or REJECT +# +# ACCEPT -- allow the connection request +# DROP -- ignore the request +# REJECT -- disallow the request and return an +# icmp-unreachable packet. +# +# May optionally be followed by ":" and a syslog log +# level (e.g, REJECT:info). This causes the packet to be +# logged at the specified level. +# +# CLIENT(S) Hosts permitted to be clients. May be a zone defined +# in /etc/shorewall/zones or $FW to indicate the +# firewall itself. +# +# Clients may be further restricted to a list of subnets +# and/or hosts by appending ":" and a comma-separated +# list of subnets and/or hosts. Hosts may be specified +# by IP or MAC address; mac addresses must begin with +# "~" and must use "-" as a separator. +# +# dmz:192.168.2.2 Host 192.168.2.2 in the DMZ +# +# net:155.186.235.0/24 Subnet 155.186.235.0/24 on the +# Internet +# +# loc:192.168.1.1,192.168.1.2 +# Hosts 192.168.1.1 and +# 192.168.1.2 in the local zone. +# loc:~00-A0-C9-15-39-78 Host in the local zone with +# MAC address 00:A0:C9:15:39:78. +# +# Alternatively, clients may be specified by interface +# by appending ":" followed by the interface name. For +# example, loc:eth1 specifies a client that +# communicates with the firewall system through eth1. +# +# SERVER Location of Server. May be a zone defined in +# /etc/shorewall/zones or $FW to indicate the firewall +# itself. +# +# The server may be further restricted to a particular +# subnet, host or interface by appending ":" and the +# subnet, host or interface. See above. +# +# The port that the server is listening on may be +# included and separated from the server's IP address by +# ":". If omitted, the firewall will not modifiy the +# destination port. +# +# Example: loc:192.168.1.3:8080 specifies a local +# server at IP address 192.168.1.3 and listening on port +# 8080. The port number MUST be specified as an integer +# and not as a name from /etc/services. +# +# PROTO Protocol - Must be "tcp", "udp", "icmp", a number, +# "all" or "related". If "related", the remainder of the +# entry must be omitted and connection requests that are +# related to existing requests will be accepted. +# +# PORT(S) Destination Ports. A comma-separated list of Port +# names (from /etc/services), port numbers or port +# ranges; if the protocol is "icmp", this column is +# interpreted as the destination icmp-type(s). +# +# This column is ignored if PROTOCOL = all but must be +# entered if any of the following ields are supplied. +# In that case, it is suggested that this field contain +# "-" +# +# CLIENT PORT(S) (Optional) Port(s) used by the client. If omitted, +# any source port is acceptable. Specified as a comma- +# separated list of port names, port numbers or port +# 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. +# +# ADDRESS (0ptional) If included and different from the IP +# address given in the SERVER column, this is an address +# on some interface on the firewall and connections to +# that address will be forwarded to the IP and port +# specified in the SERVER column. +# +# If the special value "all" is used, then requests from +# the client zone given in the CLIENT(s) column with the +# destination port given in PORT(s) will be forwarded to +# the IP address given in SERVER. The value "all" is +# intended to be used when your internet IP address is +# dynamic and you want to do port forwarding or you want +# to do proxy redirection. IT SHOULD NOT BE USED IN ANY +# OTHER SITUATION. +# +# The address (or "all") may optionally be followed by +# a colon (":") an an IP address. This causes Shorewall +# to use the specified IP address as the source address +# in forwarded packets. See the Shorewall documentation +# for restrictions concerning this feature. If no source +# IP address is given, the original source address is not +# altered. +# +# Example: Forward all ssh and http connection requests from the internet +# to local system 192.168.1.3 +# +# #RESULT CLIENTS SERVER(S) PROTO PORT(S) CLIENT PORT(S) ADDRESS +# ACCEPT net loc:192.168.1.3 tcp ssh,http - all +# +# Example: Redirect all locally-originating www connection requests to +# port 8080 on the firewall (Squid running on the firewall +# system)except when the destination address is 192.168.2.2 +# +# #RESULT CLIENTS SERVER(S) PROTO PORTS(S) CLIENT PORT(S) ADDRESS +# ACCEPT loc $FW::8080 tcp www - !192.168.2.2 +############################################################################## +#RESULT CLIENT(S) SERVER(S) PROTO PORT(S) CLIENT PORT(S) ADDRESS +# +# Allow SSH from the local network +# +ACCEPT loc $FW tcp ssh +# +# Allow SSH and Auth from the internet +# +ACCEPT net $FW tcp ssh,auth +# +# Run an NTP daemon on the firewall that is synced with outside sources +# +ACCEPT $FW net udp ntp +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/shorewall b/Shorewall/shorewall new file mode 100755 index 000000000..946e8072f --- /dev/null +++ b/Shorewall/shorewall @@ -0,0 +1,561 @@ +#!/bin/sh +# +# Shorewall Packet Filtering Firewall Control Program - V1.2 - 12/21/2001 +# +# This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] +# +# (c) 1999,2000,2001,2002 - Tom Eastep (teastep@shorewall.net) +# +# +# This file should be placed in /sbin/shorewall. +# +# Shorewall documentation is available at http://shorewall.sourceforge.net +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of Version 2 of the GNU General Public License +# as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA +# +# If an error occurs while starting or restarting the firewall, the +# firewall is automatically stopped. +# +# The firewall uses configuration files in /etc/shorewall/ - skeleton +# files is included with the firewall. +# +# Commands are: +# +# shorewall start Starts the firewall +# shorewall restart Restarts the firewall +# shorewall stop Stops the firewall +# shorewall monitor [ refresh-interval ] Repeatedly Displays firewall status +# plus the last 20 "interesting" +# packets +# shorewall status Displays firewall status +# shorewall reset Resets iptables packet and +# byte counts +# shorewall clear Open the floodgates by +# removing all iptables rules +# and setting the three permanent +# chain policies to ACCEPT +# shorewall refresh Rebuild the common chain to +# compensate for a change of +# broadcast address on any "detect" +# interface. +# shorewall show Display the rules in a +# shorewall show log Print the last 20 log messages +# shorewall show connections Show the kernel's connection +# tracking table +# shorewall show nat Display the rules in the nat table +# shorewall show {mangle|tos} Display the rules in the mangle table +# shorewall show tc Display traffic control info +# shorewall version Display the installed version id +# shorewall check Verify the more heavily-used +# configuration files. +# shorewall try [ ] Try a new configuration and if +# it doesn't work, revert to the +# standard one. If a timeout is supplied +# the command reverts back to the +# standard configuration after that many +# seconds have elapsed after successfully +# starting the new configuration. +# +# Display a chain if it exists +# +showfirstchain() # $1 = name of chain +{ + awk \ + 'BEGIN {prnt=0;}; \ + /^$/ { next; };\ + /^Chain/ {if ( prnt == 1 ) exit; };\ + /Chain '$1'/ { prnt=1; }; \ + { if (prnt == 1) print; }' /tmp/chains-$$ +} + +showchain() # $1 = name of chain +{ + if [ "$firstchain" = "Yes" ]; then + showfirstchain $1 + firstchain= + else + awk \ + 'BEGIN {prnt=0;};\ + /^$|^ pkts/ { next; };\ + /^Chain/ {if ( prnt == 1 ) exit; };\ + /Chain '$1'/ { prnt=1; };\ + { if (prnt == 1) print; }' /tmp/chains-$$ + fi +} + +################################################################################# +# Set the configuration variables from shorewall.conf # +################################################################################# +get_config() { + get_statedir + + [ -z "$LOGFILE" ] && LOGFILE=/var/log/messages + + if [ ! -f $LOGFILE ]; then + echo "LOGFILE ($LOGFILE) does not exist!" >&2 + exit 2 + fi + # + # See if we have a real version of "tail" -- use separate redirection so + # that ash (aka /bin/sh on LRP) doesn't crap + # + if ( tail -n5 $LOGFILE > /dev/null 2> /dev/null ) ; then + realtail="Yes" + else + realtail="" + fi + + [ -n "$FW" ] || FW=fw +} + +################################################################################# +# Display IPTABLES rules -- we used to store them in a variable but ash # +# dies when trying to display large sets of rules # +################################################################################# +display_chains() +{ + trap "rm -f /tmp/chains-$$; exit 1" 1 2 3 4 5 6 9 + + if [ "$haveawk" = "Yes" ]; then + # + # 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-$$ + + clear + echo -e "$banner `date`\\n" + echo -e "Standard Chains\\n" + firstchain="Yes" + showchain INPUT + showchain OUTPUT + showchain FORWARD + + timed_read + + for zone in $zones multi; do + if [ -n "`grep "^Chain \.*${zone}" /tmp/chains-$$`" ] ; then + clear + echo -e "$banner `date`\\n" + firstchain=Yes + eval display=\$${zone}_display + echo -e "$display Chains\\n" + for zone1 in $FW $zones; do + showchain ${zone}2$zone1 + showchain @${zone}2$zone1 + [ "$zone" != "$zone1" ] && \ + showchain ${zone1}2${zone} && \ + showchain @${zone1}2${zone} + done + + timed_read + fi + done + + clear + echo -e "$banner `date`\\n" + firstchain=Yes + echo -e "Policy Chains\\n" + showchain badpkt + showchain common + showchain icmpdef + showchain rfc1918 + showchain blacklst + showchain reject + for zone in $zones all; do + showchain ${zone}2all + showchain @${zone}2all + [ "$zone" = "all" ] || { showchain all2${zone}; showchain @all2${zone}; } + done + + timed_read + + qt rm -f /tmp/chains-$$ + else + iptables -L -n -v + timed_read + fi + trap - 1 2 3 4 5 6 9 + +} + +################################################################################# +# Delay $timeout seconds -- if we're running on a recent bash2 then allow # +# to terminate the delay # +################################################################################# +timed_read () +{ + read -t $timeout foo 2> /dev/null + + test $? -eq 2 && sleep $timeout +} + +################################################################################# +# Display the last 20 packets logged # +################################################################################# +packet_log() +{ + local options + + [ -n "$realtail" ] && options="-n20" + + grep 'Shorewall:\|ipt_unclean' $LOGFILE | \ + sed s/" $host kernel: Shorewall:"/" "/ | \ + sed s/" $host kernel: ipt_unclean: "/" "/ | \ + sed 's/MAC=.*SRC=/SRC=/' | \ + tail $options +} + +################################################################################# +# Show traffic control information # +################################################################################# +show_tc() { + + show_one_tc() { + local device=${1%@*} + qdisc=`tc qdisc list dev $device` + + if [ -n "$qdisc" ]; then + echo Device $device: + tc -s -d qdisc show dev $device + tc -s -d class show dev $device + echo + fi + } + + ip link list | \ + while read inx interface details; do + case $inx in + [0-9]*) + show_one_tc ${interface%:} + ;; + *) + ;; + esac + done + +} + +################################################################################# +# Monitor the Firewall # +################################################################################# +monitor_firewall() # $1 = timeout -- if negative, prompt each time that + # an 'interesting' packet count changes +{ + + get_config + host=`echo $HOSTNAME | sed 's/\..*$//'` + oldrejects=`iptables -L -v -n | grep 'LOG'` + + if [ $1 -lt 0 ]; then + let "timeout=- $1" + pause="Yes" + else + pause="No" + timeout=$1 + fi + + qt which awk && { haveawk=Yes; determine_zones; } || haveawk= + + while true; do + display_chains + + clear + echo -e "$banner `date`\\n" + + echo -e "Dropped/Rejected Packet Log\\n" + + rejects=`iptables -L -v -n | grep 'LOG'` + + if [ "$rejects" != "$oldrejects" ]; then + oldrejects="$rejects" + echo -e '\a' + packet_log + + if [ "$pause" = "Yes" ]; then + echo -en '\nEnter any character to continue: ' + read foo + else + timed_read + fi + else + if [ "$pause" != "Yes" ]; then + echo + packet_log + fi + + timed_read + fi + + clear + echo -e "$banner `date`\\n" + echo -e "NAT Status\\n" + iptables -t nat -L -n -v + echo -e "\\nTOS/MARK Status\\n" + iptables -t mangle -L -n -v + timed_read + + clear + echo -e "$banner `date`\\n" + echo -e "\\nTracked Connections\\n" + cat /proc/net/ip_conntrack + timed_read + + clear + echo -e "$banner `date`\\n" + echo -e "\\nTraffic Shaping/Control\\n" + show_tc + timed_read + done +} + +################################################################################# +# Give Usage Information # +################################################################################# +usage() # $1 = exit status +{ + echo "Usage: `basename $0` [debug] [nolock] [-c ] " + echo "where is one of:" + echo " show [|connections|log|nat|tc|tos]" + echo " start" + echo " stop" + echo " reset" + echo " restart" + echo " status" + echo " clear" + echo " refresh" + echo " hits" + echo " monitor []" + echo " version" + echo " check" + echo " try [ ]" + exit $1 +} + +################################################################################# +# Execution begins here # +################################################################################# +debugging= + +if [ $# -gt 0 ] && [ "$1" = "debug" ]; then + debugging=debug + shift +fi + +nolock= + +if [ $# -gt 0 ] && [ "$1" = "nolock" ]; then + nolock=nolock + shift +fi + +SHOREWALL_DIR= +done=0 + +while [ $done -eq 0 ]; do + [ $# -eq 0 ] && usage 1 + case $1 in + -c) + [ $# -eq 1 ] && usage 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 + shift + shift + ;; + *) + done=1 + ;; + esac +done + +if [ $# -eq 0 ] || [ $# -gt 3 ]; then + usage 1 +fi + +functions=/etc/shorewall/functions + +if [ -n "$SHOREWALL_DIR" ]; then + export SHOREWALL_DIR + [ -f $SHOREWALL_DIR/functions ] && functions=$SHOREWALL_DIR/functions +fi + +if [ -f $functions ]; then + . $functions +else + echo "/etc/shorewall/functions does not exist!" >&2 + exit 2 +fi + +firewall=`find_file firewall` + +if [ ! -f $firewall ]; then + echo "ERROR: Shorewall is not properly installed" + if [ -L $firewall ]; then + echo " $firewall is a symbolic link to a" + echo " non-existant file" + else + echo " The file /etc/shorewall/firewall does not exist" + fi + + exit 2 +fi + +PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin + +version_file=`find_file version` + +if [ -f $version_file ]; then + version=`cat $version_file` +else + echo "ERROR: Shoreline Firewall is not properly installed" + echo " The file /etc/shorewall/version does not exist" + exit 1 +fi + +banner="Shorewall-$version Status at $HOSTNAME -" + +case "$1" in + start|stop|restart|reset|clear|refresh|check) + [ $# -ne 1 ] && usage 1 + exec $firewall $debugging $nolock $1 + ;; + show) + [ $# -gt 2 ] && usage 1 + case "$2" in + connections) + echo -e "Shorewall-$version Connections at $HOSTNAME - `date`\\n" + cat /proc/net/ip_conntrack + ;; + nat) + echo -e "Shorewall-$version NAT at $HOSTNAME - `date`\\n" + iptables -t nat -L -n -v + ;; + tos|mangle) + echo -e "Shorewall-$version TOS at $HOSTNAME - `date`\\n" + iptables -t mangle -L -n -v + ;; + log) + get_config + echo -e "Shorewall-$version Log at $HOSTNAME - `date`\\n" + host=`echo $HOSTNAME | sed 's/\..*$//'` + packet_log + ;; + tc) + echo -e "Shorewall-$version Traffic Control at $HOSTNAME - `date`\\n" + show_tc + ;; + *) + echo -e "Shorewall-$version Chain $2 at $HOSTNAME - `date`\\n" + iptables -L $2 -n -v + ;; + esac + ;; + monitor) + if [ $# -eq 2 ]; then + monitor_firewall $2 + elif [ $# -eq 1 ]; then + monitor_firewall 30 + else + usage 1 + fi + ;; + status) + [ $# -eq 1 ] || usage 1 + get_config + clear + echo -e "Shorewall-$version Status at $HOSTNAME - `date`\\n" + host=`echo $HOSTNAME | sed 's/\..*$//'` + iptables -L -n -v + echo + packet_log + echo + iptables -t nat -L -n -v + echo + iptables -t mangle -L -n -v + echo + cat /proc/net/ip_conntrack + ;; + hits) + [ $# -eq 1 ] || usage 1 + get_config + clear + echo -e "Shorewall-$version Hits at $HOSTNAME - `date`\\n" + timeout=30 + + if [ `grep -c "Shorewall:" $LOGFILE ` -gt 0 ] ; then + echo " HITS IP DATE" + grep "Shorewall:" $LOGFILE | sed 's/\(.\{6\}\)\(.*SRC=\)\(.*\)\( DST=.*\)/\3 \1/' | sort | uniq -c | sort -rn + echo "" + + echo " HITS IP" + grep "Shorewall:" $LOGFILE | sed 's/\(.*SRC=\)\(.* \)\(DST=.*\)/\2/' | sort | uniq -c | sort -rn + echo "" + + echo " HITS DATE" + grep "Shorewall:" $LOGFILE | sed 's/\(.\{6\}\)\(.*\)/\1/' | sort | uniq -c | sort -rn + echo "" + + echo " HITS PORT SERVICE(S)" + grep 'Shorewall:.*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'` + + if [ -n "$srv" ] ; then + printf '%7d %5d %s\n' $count $port $srv + else + printf '%7d %5d\n' $count $port + fi + done + fi + ;; + version) + echo $version + ;; + try) + [ -n "$SHOREWALL_DIR" ] && startup_error "Error: -c option may not be used with \"try\"" + [ $# -lt 2 -o $# -gt 3 ] && usage 1 + $0 -c $2 restart + if ! iptables -L shorewall > /dev/null 2> /dev/null; then + $0 start + elif [ $# -eq 3 ]; then + sleep $3 + $0 restart + fi + ;; + *) + usage 1 + ;; +esac + + + + + + + + + + + + diff --git a/Shorewall/shorewall.conf b/Shorewall/shorewall.conf new file mode 100755 index 000000000..6e9df879f --- /dev/null +++ b/Shorewall/shorewall.conf @@ -0,0 +1,189 @@ +############################################################################## +# /etc/shorewall/shorewall.conf V1.2 - 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 - Tom Eastep (teastep@shorewall.net) +############################################################################## +# +# Name of the firewall zone -- if not set or if set to an empty string, "fw" +# is assumed. +# +FW=fw + + +# Set this to the name of the lock file expected by your init scripts. For +# RedHat, this should be /var/lock/subsys/shorewall. On Debian, it +# should be /var/state/shorewall. If your init scripts don't use lock files, +# set -this to "". +# + +SUBSYSLOCK=/var/lock/subsys/shorewall + +# This is the directory where the firewall maintains state information while +# it is running +# + +STATEDIR=/var/lib/shorewall + +# +# Set this to "yes" or "Yes" if you want to accept all connection requests +# that are related to already established connections. For example, you want +# to accept FTP data connections. If you say "no" here, then to accept +# these connections between particular zones or hosts, you must include +# explicit "related" rules in /etc/shorewall/rules. +# + +ALLOWRELATED="yes" + +# +# If your netfilter kernel modules are in a directory other than +# /lib/modules/`uname -r`/kernel/net/ipv4/netfilter then specify that +# directory in this variable. Example: MODULESDIR=/etc/modules. + +MODULESDIR="" + +# +# The next two variables can be used to control the amount of log output +# generated. LOGRATE is expressed as a number followed by an optional +# `/second', `/minute', `/hour', or `/day' suffix and specifies the maximum +# rate at which a particular message will occur. LOGBURST determines the +# 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. +# + +LOGRATE="" +LOGBURST="" + + +# +# 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. +# + +LOGUNCLEAN=info + +# This variable tells the /sbin/shorewall program where to look for Shorewall +# log messages. If not set or set to an empty string (e.g., LOGFILE="") then +# /var/log/messages is assumed. +# +# WARNING: The LOGFILE variable simply tells the 'shorewall' program where to +# look for Shorewall messages.It does NOT control the destination for +# these messages. For information about how to do that, see +# +# http://www.shorewall.net/FAQ.htm#faq6 + +LOGFILE="/var/log/messages" + +# +# Enable nat support. +# +# You probally want yes here. Only gateways not doing NAT in any form, like +# SNAT,DNAT masquerading, port forwading etc. should say "no" here. +# +NAT_ENABLED="Yes" + +# +# Enable mangle support. +# +# If you say "no" here, Shorewall will ignore the /etc/shorewall/tos file +# and will not initialize the mangle table when starting or stopping +# your firewall. You must enable mangling if you want Traffic Shaping +# (see TC_ENABLED below). +# +MANGLE_ENABLED="Yes" + +# +# Enable IP Forwarding +# +# If you say "On" or "on" here, IPV4 Packet Forwarding is enabled. If you +# say "Off" or "off", packet forwarding will be disabled. You would only want +# to disable packet forwarding if you are installing Shorewall on a +# standalone system or if you want all traffic through the Shorewall system +# to be handled by proxies. +# +# If you set this variable to "Keep" or "keep", Shorewall will neither +# enable nor disable packet forwarding. +# +IP_FORWARDING="On" +# +# Automatically add IP Aliases +# +# If you say "Yes" or "yes" here, Shorewall will automatically add IP aliases +# for each NAT external address that you give in /etc/shorewall/nat. If you say +# "No" or "no", you must add these aliases youself. +# +ADD_IP_ALIASES="Yes" + +# +# Automatically add SNAT Aliases +# +# If you say "Yes" or "yes" here, Shorewall will automatically add IP aliases +# for each SNAT external address that you give in /etc/shorewall/masq. If you say +# "No" or "no", you must add these aliases youself. +# +ADD_SNAT_ALIASES="No" + +# +# Enable Traffic Shaping +# +# If you say "Yes" or "yes" here, Traffic Shaping is enabled in the firewall. If +# you say "No" or "no" then traffic shaping is not enabled. If you enable traffic +# shaping you must have iproute[2] installed (the "ip" and "tc" utilities) and +# you must enable packet mangling above. +# +TC_ENABLED="No" + +# +# Blacklisting +# +# Set this variable to the action that you want to perform on packets from +# Blacklisted systems. Must be DROP or REJECT. If not set or set to empty, +# DROP is assumed. +# +BLACKLIST_DISPOSITION=DROP + +# +# Blacklist Logging +# +# Set this variable to the syslogd level that you want blacklist packets logged +# (beward of DOS attacks resulting from such logging). If not set, no logging +# of blacklist packets occurs. +# +BLACKLIST_LOGLEVEL= + +# +# MSS Clamping +# +# Set this variable to "Yes" or "yes" if you want the TCP "Clamp MSS to PMTU" +# option. This option is most commonly required when your internet +# interface is some variant of PPP (PPTP or PPPoE). Your kernel must +# +# If left blank, or set to "No" or "no", the option is not enabled. +# +CLAMPMSS="No" + +# +# Route Filtering +# +# Set this variable to "Yes" or "yes" if you want kernel route filtering on all +# interfaces (anti-spoofing measure). +# +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". + +NAT_BEFORE_RULES="Yes" + +#LAST LINE -- DO NOT REMOVE diff --git a/Shorewall/shorewall.spec b/Shorewall/shorewall.spec new file mode 100644 index 000000000..607fdad64 --- /dev/null +++ b/Shorewall/shorewall.spec @@ -0,0 +1,215 @@ +%define name shorewall +%define version 1.2 +%define release 13 +%define prefix /usr + +Summary: Shoreline Firewall is an iptables-based firewall for Linux systems. +Name: %{name} +Version: %{version} +Release: %{release} +Prefix: %{prefix} +License: GPL +Packager: Tom Eastep +Group: Networking/Utilities +Source: %{name}-%{version}.%{release}.tgz +URL: http://www.shorewall.net/ +BuildArch: noarch +BuildRoot: /%{_tmppath}/%{name}-%{version}-%{release}-root +Requires: iptables +Conflicts: kernel <= 2.2 +Provides: shorewall + +%description + +Shoreline Firewall is an iptables-based firewall for Linux systems. The firewall +is designed to be used on: + +a) Single systems attached to the internet via dial-in POP or ISDN. +b) Single systems attached full-time to the internet (ASDL, Cable, etc.) +c) Linux system used as a Masquerading gateway for one or more client and/or +server systems. + +%prep + +%setup -n %name-%version.%release + +%build + +%install +export PREFIX=$RPM_BUILD_ROOT ; \ +export OWNER=`id -n -u` ; \ +export GROUP=`id -n -g` ;\ +./install.sh /etc/init.d + +%clean +rm -rf $RPM_BUILD_ROOT + +%post +if [ -x /sbin/insserv ]; then /sbin/insserv /etc/rc.d/shorewall; elif [ -x /sbin/chkconfig ]; then /sbin/chkconfig --add shorewall; fi + +%preun +if [ $1 = 0 ]; then if [ -x /sbin/insserv ]; then /sbin/insserv -r /etc/init.d/shorewall ; elif [ -x /sbin/chkconfig ]; then /sbin/chkconfig --del shorewall; fi ; fi + +%files +/etc/init.d/shorewall +%attr(0700,root,root) %dir /etc/shorewall +%attr(0600,root,root) /etc/shorewall/version +%attr(0600,root,root) /etc/shorewall/common.def +%attr(0600,root,root) /etc/shorewall/icmp.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/params +%attr(0600,root,root) %config(noreplace) /etc/shorewall/proxyarp +%attr(0600,root,root) %config(noreplace) /etc/shorewall/masq +%attr(0600,root,root) %config(noreplace) /etc/shorewall/modules +%attr(0600,root,root) %config(noreplace) /etc/shorewall/tcrules +%attr(0600,root,root) %config(noreplace) /etc/shorewall/tos +%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/whitelist +%attr(0544,root,root) /sbin/shorewall +%attr(0444,root,root) /etc/shorewall/functions +/etc/shorewall/firewall +%doc documentation +%doc COPYING INSTALL changelog.txt releasenotes.txt tunnel + +%changelog +* Tue Apr 23 2002 Tom Eastep +- changed version to 13 +- Added whitelist file. +* Thu Apr 18 2002 Tom Eastep +- changed version to 12 +* Tue Apr 16 2002 Tom Eastep +- Merged Stefan's changes to create single RPM +* Mon Apr 15 2002 Stefan Mohr +- changed to SuSE Linux 7.3 +* Wed Apr 10 2002 Tom Eastep +- changed Version to 11 +* Tue Mar 19 2002 Tom Eastep +- changed Version to 10 +* Sat Mar 09 2002 Tom Eastep +- changed Version to 9 +* Sat Feb 23 2002 Tom Eastep +- changed Version to 8 +* Thu Feb 21 2002 Tom Eastep +- changed Version to 7 +* Tue Feb 05 2002 Tom Eastep +- changed Version to 6 +* Wed Jan 30 2002 Tom Eastep +- changed Version to 5 +* Sat Jan 26 2002 Tom Eastep +- changed Version to 4 +- Merged Ajay's change to allow build by non-root +* Sun Jan 12 2002 Tom Eastep +- changed Version to 3 +* Tue Jan 01 2002 Tom Eastep +- changed Version to 2 +- Updated URL +- Added blacklist file +* Mon Dec 31 2001 Tom Eastep +- changed Version to 1 +* Wed Dec 19 2001 Tom Eastep +- changed Version to 0 +* Tue Dec 18 2001 Tom Eastep +- changed Version to Rc1 +* Sat Dec 15 2001 Tom Eastep +- changed Version to Beta2 +* Thu Nov 08 2001 Tom Eastep +- changed Version to 1.2 +- added tcrules file +* Sun Oct 21 2001 Tom Eastep +- changed release to 17 +* Sun Oct 21 2001 Tom Eastep +- changed release to 16 +* Sun Oct 14 2001 Tom Eastep +- changed release to 15 +* Thu Oct 11 2001 Tom Eastep +- changed release to 14 +* Tue Sep 11 2001 Tom Eastep +- changed release to 13 +- added params file +* Tue Aug 28 2001 Tom Eastep +- Changed release to 12 +* Fri Jul 27 2001 Tom Eastep +- Changed release to 11 +* Sun Jul 08 2001 Ajay Ramaswamy +- reorganized spec file +- s/Copyright/License/ +- now will build fron rpm -tb +* Fri Jul 06 2001 Tom Eastep +- Changed release to 10 +* Tue Jun 19 2001 Tom Eastep +- Changed release to 9 +- Added tunnel file +- Readded tunnels file +* Mon Jun 18 2001 Tom Eastep +- Changed release to 8 +* Sat Jun 02 2001 Tom Eastep +- Changed release to 7 +- Changed iptables dependency. +* Tue May 22 2001 Tom Eastep +- Changed release to 6 +- Added tunnels file +* Sat May 19 2001 Tom Eastep +- Changed release to 5 +- Added modules and tos files +* Sat May 12 2001 Tom Eastep +- Changed release to 4 +- Added changelog.txt and releasenotes.txt +* Sat Apr 28 2001 Tom Eastep +- Changed release to 3 +* Mon Apr 9 2001 Tom Eastep +- Added files common.def and icmpdef.def +- Changed release to 2 +* Wed Apr 4 2001 Tom Eastep +- Changed the release to 1. +* Mon Mar 26 2001 Tom Eastep +- Changed the version to 1.1 +- Added hosts file +* Sun Mar 18 2001 Tom Eastep +- Changed the release to 4 +- Added Zones and Functions files +* Mon Mar 12 2001 Tom Eastep +- Change ipchains dependency to an iptables dependency and + changed the release to 3 +* Fri Mar 9 2001 Tom Eastep +- Add additional files. +* Thu Mar 8 2001 Tom EAstep +- Change version to 1.0.2 +* Tue Mar 6 2001 Tom Eastep +- Change version to 1.0.1 +* Sun Mar 4 2001 Tom Eastep +- Changes for Shorewall +* Thu Feb 22 2001 Tom Eastep +- Change version to 4.1.0 +* Fri Feb 2 2001 Tom Eastep +- Change version to 4.0.4 +* Mon Jan 22 2001 Tom Eastep +- Change version to 4.0.2 +* Sat Jan 20 2001 Tom Eastep +- Changed version to 4.0 +* Fri Jan 5 2001 Tom Eastep +- Added dmzclients file +* Sun Dec 24 2000 Tom Eastep +- Added ftpserver file +* Sat Aug 12 2000 Tom Eastep +- Added "nat" and "proxyarp" files for 4.0 +* Mon May 20 2000 Tom Eastep +- added updown file +* Sat May 20 2000 Simon Piette +- Corrected the group - Networking/Utilities +- Added "noreplace" attributes to config files, so current confis is not + changed. +- Added the version file. +* Sat May 20 2000 Tom Eastep +- Converted Simon's patch to version 3.1 +* Sat May 20 2000 Simon Piette +- 3.0.2 Initial RPM + Patched the install script so it can take a PREFIX variable + + diff --git a/Shorewall/tcrules b/Shorewall/tcrules new file mode 100755 index 000000000..082165d10 --- /dev/null +++ b/Shorewall/tcrules @@ -0,0 +1,47 @@ +# +# Shorewall version 1.2 - Traffic Control Rules File +# +# /etc/shorewall/tcrules +# +# Entries in this file cause packets to be marked as a means of +# classifying them for traffic control. +# +# Columns are: +# +# +# MARK The mark value which is an +# integer in the range 1-255 +# +# SOURCE Source of the packet. A comma-separated list of +# interface names, IP addresses, MAC addresses +# and/or subnets. Use $FW if the packet originates on +# the firewall. +# +# MAC addresses must be prefixed with "~" and use +# "-" as a separator. +# +# Example: ~00-A0-C9-15-39-78 +# +# DEST Destination of the packet. Comma separated list of +# IP addresses and/or subnets. +# +# PROTO Protocol - Must be "tcp", "udp", "icmp", a number, +# or "all". +# +# PORT(S) Destination Ports. A comma-separated list of Port +# names (from /etc/services), port numbers or port +# ranges; if the protocol is "icmp", this column is +# interpreted as the destination icmp-type(s). +# +# This column is ignored if PROTOCOL = all but must be +# entered if any of the following field is supplied. +# In that case, it is suggested that this field contain +# "-" +# +# CLIENT PORT(S) (Optional) Port(s) used by the client. If omitted, +# any source port is acceptable. Specified as a comma- +# separated list of port names, port numbers or port +# ranges. +############################################################################## +#MARK SOURCE DEST PROTO PORT(S) CLIENT PORT(S) +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/tos b/Shorewall/tos new file mode 100755 index 000000000..80b7ad3d8 --- /dev/null +++ b/Shorewall/tos @@ -0,0 +1,52 @@ +# +# Shorewall 1.2 -- /etc/shorewall/tos +# +# This file defines rules for setting Type Of Service (TOS) +# +# Columns are: +# +# SOURCE Name of a zone declared in /etc/shorewall/zones, "all" +# or $FW. +# +# If not "all" or $FW, may optionally be followed by +# ":" and an IP address, a MAC address, a subnet +# specification or the name of an interface. +# +# Example: loc:192.168.2.3 +# +# MAC addresses must be prefixed with "~" and use +# "-" as a separator. +# +# Example: ~00-A0-C9-15-39-78 +# +# DEST Name of a zone declared in /etc/shorewall/zones, "all" +# or $FW. +# +# If not "all" or $FW, may optionally be followed by +# ":" and an IP address or a subnet specification +# +# Example: loc:192.168.2.3 +# +# PROTOCOL Protocol. +# +# SOURCE PORTS Source port or port range. If all ports, use "-". +# +# DEST PORTS Destination port or port range. If all ports, use "-" +# +# TOS Type of service. Must be one of the following: +# +# Minimize-Delay (16) +# Maximize-Throughput (8) +# Maximize-Reliability (4) +# Minimize-Cost (2) +# Normal-Service (0) +# +############################################################################## +#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 +#LAST LINE -- Add your entries above -- DO NOT REMOVE diff --git a/Shorewall/tunnel b/Shorewall/tunnel new file mode 100755 index 000000000..42d234f09 --- /dev/null +++ b/Shorewall/tunnel @@ -0,0 +1,159 @@ +#!/bin/sh + +RCDLINKS="2,S45 3,S45 6,K45" +################################################################################ +# Script to create a gre or ipip tunnel -- Shorewall 1.2 +# +# 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 - Tom Eastep (teastep@shorewall.net) +# +# Modify the following variables to match your configuration +# +# chkconfig: 2345 26 89 +# description: GRE/IP Tunnel +# +################################################################################ + +# +# Type of tunnel (gre or ipip) +# + +tunnel_type=gre + +# Name of the tunnel +# + +tunnel="dfwbos" +# +# Address of your External Interface (only required for gre tunnels) +# +myrealip="x.x.x.x" + +# Address of the local system -- this is the address of one of your +# local interfaces (or for a mobile host, the address that this system has +# when attached to the local network). +# + +myip="192.168.1.254" + +# Address of the Remote system -- this is the address of one of the +# remote system's local interfaces (or if the remote system is a mobile host, +# the address that it uses when attached to the local network). + +hisip="192.168.9.1" + +# Internet address of the Remote system +# + +gateway="x.x.x.x" + +# Remote sub-network -- if the remote system is a gateway for a +# private subnetwork that you wish to +# access, enter it here. If the remote +# system is a stand-alone/mobile host, leave this +# empty + +subnet="192.168.9.0/24" + +PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin + +load_modules () { + case $tunnel_type in + ipip) + echo "Loading IP-ENCAP Module" + modprobe ipip + ;; + gre) + echo "Loading GRE Module" + modprobe ip_gre + ;; + esac +} + +do_stop() { + + if [ -n "`ip link show $tunnel 2>/dev/null`" ]; then + echo "Stopping $tunnel" + ip link set dev $tunnel down + fi + + if [ -n "`ip addr show $tunnel 2>/dev/null`" ]; then + echo "Deleting $tunnel" + ip tunnel del $tunnel + fi +} + +do_start() { + + #NOTE: Comment out the next line if you have built gre/ipip into your kernel + + load_modules + + if [ -n "`ip link show $tunnel 2>/dev/null`" ]; then + do_stop + fi + + echo "Adding $tunnel" + + case $tunnel_type in + gre) + ip tunnel add $tunnel mode gre remote $gateway local $myrealip ttl 255 + ;; + *) + ip tunnel add $tunnel mode ipip remote $gateway + ;; + esac + + echo "Starting $tunnel" + + + ip link set dev $tunnel up + + case $tunnel_type in + gre) + ip addr add $myip dev $tunnel + ;; + *) + ip addr add $myip peer $hisip dev $tunnel + ;; + esac + + # + # As with all interfaces, the 2.4 kernels will add the obvious host + # route for this point-to-point interface + # + + if [ -n "$subnet" ]; then + echo "Adding Routes" + case $tunnel_type in + gre) + ip route add $subnet dev $tunnel + ;; + ipip) + ip route add $subnet via $gateway dev $tunnel onlink + ;; + esac + fi +} + +case "$1" in + start) + do_start + ;; + stop) + do_stop + ;; + restart) + do_stop + sleep 1 + do_start + ;; + *) + echo "Usage: $0 {start|stop|restart}" + exit 1 +esac +exit 0 diff --git a/Shorewall/tunnels b/Shorewall/tunnels new file mode 100644 index 000000000..e5ef9bc1b --- /dev/null +++ b/Shorewall/tunnels @@ -0,0 +1,51 @@ +# +# Shorewall 1.2 - /etc/shorewall/tunnels +# +# This file defines IPSEC, GRE and IPIP tunnels. +# +# IPIP and GRE tunnels must be configured on the firewall/gateway itself. +# IPSEC endpoints may be defined on the firewall/gateway or on an +# internal system. +# +# The columns are: +# +# TYPE -- must start in column 1 and be "ipsec", "ip" or "gre" +# +# ZONE -- The zone of the physical interface through which +# tunnel traffic passes. This is normally your internet +# zone. +# +# GATEWAY -- The IP address of the remote tunnel gateway. If the +# remote getway has no fixed address (Road Warrior) +# then specify the gateway as 0.0.0.0/0. +# +# GATEWAY ZONE-- Optional. If the gateway system specified in the third +# column is a standalone host then this column should +# contain the name of the zone that the host is in. This +# column only applies to IPSEC tunnels. +# +# Example 1: +# +# IPSec tunnel. The remote gateway is 4.33.99.124 and +# the remote subnet is 192.168.9.0/24 +# +# ipsec net 4.33.99.124 +# +# Example 2: +# +# Road Warrior (LapTop that may connect from anywhere) +# where the "gw" zone is used to represent the remote +# LapTop. +# +# ipsec net 0.0.0.0/0 gw +# +# Example 3: +# +# Host 4.33.99.124 is a standalone system connected +# via an ipsec tunnel to the firewall system. The host +# is in zone gw. +# +# ipsec net 4.33.99.124 gw +# +# TYPE ZONE GATEWAY GATEWAY ZONE +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/uninstall.sh b/Shorewall/uninstall.sh new file mode 100755 index 000000000..46f8367b5 --- /dev/null +++ b/Shorewall/uninstall.sh @@ -0,0 +1,155 @@ +#!/bin/sh +# +# Script to back uninstall Shoreline Firewall +# +# This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] +# +# (c) 2000,2001,2002 - Tom Eastep (teastep@shorewall.net) +# +# Shorewall documentation is available at http://shorewall.sourceforge.net +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of Version 2 of the GNU General Public License +# as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA +# +# Usage: +# +# You may only use this script to uninstall the version +# shown below. Simply run this script to remove Seattle Firewall + +VERSION=1.2.13 + +usage() # $1 = exit status +{ + ME=`basename $0` + echo "usage: $ME" + exit $1 +} + +restore_file() # $1 = file to restore +{ + if [ -f ${1}-shorewall.bkout ]; then + if (mv -f ${1}-shorewall.bkout $1); then + echo + echo "$1 restored" + else + exit 1 + fi + fi +} + +remove_file() # $1 = file to restore +{ + if [ -f $1 -o -L $1 ] ; then + rm -f $1 + echo "$1 Removed" + fi +} + +if [ -f /etc/shorewall/version ]; then + INSTALLED_VERSION="`cat /etc/shorewall/version`" + if [ "$INSTALLED_VERSION" != "$VERSION" ]; then + echo "WARNING: Shoreline Firewall Version $INSTALLED_VERSION is installed" + echo " and this is the $VERSION uninstaller." + VERSION="$INSTALLED_VERSION" + fi +else + echo "WARNING: Shoreline Firewall Version $VERSION is not installed" + VERSION="" +fi + +echo "Uninstalling Shoreline Firewall $VERSION" + +if [ -L /etc/shorewall/firewall ]; then + FIREWALL=`ls -l /etc/shorewall/firewall | sed 's/^.*> //'` + + 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` + fi + + remove_file $FIREWALL +fi + +remove_file /sbin/shorewall + +if [ -n "$VERSION" ]; then + restore_file /etc/rc.d/rc.local + remove_file /etc/shorewall/shorewall.conf-${VERSION}.bkout + remove_file /etc/shorewall/zones-${VERSION}.bkout + remove_file /etc/shorewall/policy-${VERSION}.bkout + remove_file /etc/shorewall/interfaces-${VERSION}.bkout + remove_file /etc/shorewall/rules-${VERSION}.bkout + remove_file /etc/shorewall/nat-${VERSION}.bkout + remove_file /etc/shorewall/params-${VERSION}.bkout + remove_file /etc/shorewall/proxyarp-${VERSION}.bkout + remove_file /etc/shorewall/masq-${VERSION}.bkout + remove_file /etc/shorewall/version-${VERSION}.bkout + remove_file /etc/shorewall/functions-${VERSION}.bkout + remove_file /etc/shorewall/common.def-${VERSION}.bkout + remove_file /etc/shorewall/icmp.def-${VERSION}.bkout + remove_file /etc/shorewall/tunnels-${VERSION}.bkout + remove_file /etc/shorewall/tcrules-${VERSION}.bkout + remove_file /etc/shorewall/tos-${VERSION}.bkout + remove_file /etc/shorewall/modules-${VERSION}.bkout + remove_file /etc/shorewall/blacklist-${VERSION}.bkout + remove_file /etc/shorewall/whitelist-${VERSION}.bkout +fi + +remove_file /etc/shorewall/firewall + +remove_file /etc/shorewall/functions + +remove_file /etc/shorewall/common.def + +remove_file /etc/shorewall/icmp.def + +remove_file /etc/shorewall/zones + +remove_file /etc/shorewall/policy + +remove_file /etc/shorewall/interfaces + +remove_file /etc/shorewall/hosts + +remove_file /etc/shorewall/rules + +remove_file /etc/shorewall/nat + +remove_file /etc/shorewall/params + +remove_file /etc/shorewall/proxyarp + +remove_file /etc/shorewall/masq + +remove_file /etc/shorewall/modules + +remove_file /etc/shorewall/tcrules + +remove_file /etc/shorewall/tos + +remove_file /etc/shorewall/tunnels + +remove_file /etc/shorewall/blacklist + +remove_file /etc/shorewall/whitelist + +remove_file /etc/shorewall/shorewall.conf + +remove_file /etc/shorewall/version + +rmdir /etc/shorewall + +echo "Shoreline Firewall Uninstalled" + + diff --git a/Shorewall/whitelist b/Shorewall/whitelist new file mode 100644 index 000000000..cce680b17 --- /dev/null +++ b/Shorewall/whitelist @@ -0,0 +1,18 @@ +# +# Shorewall 1.2 -- Whitelist File +# +# /etc/shorewall/whitelist +# +# This file contains a list of IP addresses, MAC addresses and/or subnetworks. +# If a connection request fails to match any of the rules defined in +# /etc/shorewall/rules then the connection source is compared against this +# list; if a match is found, the connection request is accepted. +# +# MAC addresses must be prefixed with "~" and use "-" as a separator. +# +# Example: ~00-A0-C9-15-39-78 +############################################################################### +#ADDRESS/SUBNET +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE + + diff --git a/Shorewall/zones b/Shorewall/zones new file mode 100644 index 000000000..5e3dca11b --- /dev/null +++ b/Shorewall/zones @@ -0,0 +1,14 @@ +# +# Shorewall 1.2 /etc/shorewall/zones +# +# This file determines your network zones. Columns are: +# +# ZONE Short name of the zone +# DISPLAY Display name of the zone +# COMMENTS Comments about the zone +# +#ZONE DISPLAY COMMENTS +net Net Internet +loc Local Local networks +dmz DMZ Demilitarized zone +#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONE - DO NOT REMOVE