pax_global_header00006660000000000000000000000064122573133370014520gustar00rootroot0000000000000052 comment=9253c667bbefda1f7fcb93bfffac8979b29cde5f firehol-1.297/000077500000000000000000000000001225731333700131725ustar00rootroot00000000000000firehol-1.297/.cvs000077500000000000000000000001471225731333700137730ustar00rootroot00000000000000#!/bin/sh export CVS_RSH=ssh cvs -z3 -d:ext:ktsaou@firehol.cvs.sourceforge.net:/cvsroot/firehol "$@" firehol-1.297/.spec000066400000000000000000000074261225731333700141360ustar00rootroot00000000000000Summary: An easy to use but powerfull iptables stateful firewall Name: firehol Version: MYVERSION Release: MYRELEASE Copyright: GPL Group: Applications/Internet Source: %{name}-%{version}.tar.bz2 URL: http://firehol.sourceforge.net Vendor: Costa Tsaousis Packager: Costa Tsaousis BuildArchitectures: noarch BuildRoot: %{_tmppath}/%{name}-buildroot requires: bash >= 2.04 requires: fileutils >= 4.0.36 requires: gawk >= 3.0 requires: grep >= 2.4.2 requires: iproute >= 2.2.4 requires: iptables >= 1.2.4 requires: kernel >= 2.4 requires: less requires: modutils >= 2.4.13 requires: net-tools >= 1.57 requires: sed >= 3.02 requires: sh-utils >= 2.0 requires: textutils >= 2.0.11 requires: util-linux >= 2.11 %description FireHOL uses an extremely simple but powerfull way to define firewall rules which it turns into complete stateful iptables firewalls. FireHOL is a generic firewall generator, meaning that you can design any kind of local or routing stateful packet filtering firewalls with ease. Install FireHOL if you want an easy way to configure stateful packet filtering firewalls on Linux hosts and routers. You can run FireHOL with the 'helpme' argument, to get a configuration file for the system run, which you can modify according to your needs. The default configuration file will allow only client traffic on all interfaces. %prep %{__rm} -rf %{buildroot} %setup %build %install mkdir -p %{buildroot}/etc/firehol/examples mkdir -p %{buildroot}/etc/firehol/services test -f /etc/firehol.conf -a ! -f /etc/firehol/firehol.conf && mv -f /etc/firehol.conf /etc/firehol/firehol.conf mkdir -p %{buildroot}/etc/init.d install -m 750 firehol.sh %{buildroot}/etc/init.d/firehol install -m 640 examples/client-all.conf %{buildroot}/etc/firehol/firehol.conf mkdir -p %{buildroot}/%{_mandir}/man1 mkdir -p %{buildroot}/%{_mandir}/man5 gzip -9 man/firehol.1 gzip -9 man/firehol.conf.5 install -m 644 man/firehol.1.gz %{buildroot}/%{_mandir}/man1/firehol.1.gz install -m 644 man/firehol.conf.5.gz %{buildroot}/%{_mandir}/man5/firehol.conf.5.gz install -m 644 examples/home-adsl.conf %{buildroot}/etc/firehol/examples/home-adsl.conf install -m 644 examples/home-dialup.conf %{buildroot}/etc/firehol/examples/home-dialup.conf install -m 644 examples/office.conf %{buildroot}/etc/firehol/examples/office.conf install -m 644 examples/server-dmz.conf %{buildroot}/etc/firehol/examples/server-dmz.conf install -m 644 examples/client-all.conf %{buildroot}/etc/firehol/examples/client-all.conf install -m 644 examples/lan-gateway.conf %{buildroot}/etc/firehol/examples/lan-gateway.conf %pre %post if [ -f /etc/firehol.conf -a ! -f /etc/firehol/firehol.conf ] then mv -f /etc/firehol.conf /etc/firehol/firehol.conf echo echo echo "FireHOL has now its configuration in /etc/firehol/firehol.conf" echo "Your existing configuration has been moved to its new place." echo fi /sbin/chkconfig --del firehol %preun /sbin/chkconfig --del firehol %postun %clean rm -rf ${RPM_BUILD_DIR}/%{name}-%{version} %files %defattr(-,root,root) %doc README TODO COPYING ChangeLog WhatIsNew %dir /etc/firehol %dir /etc/firehol/examples %dir /etc/firehol/services /etc/init.d/firehol %{_mandir}/man1/firehol.1.gz %{_mandir}/man5/firehol.conf.5.gz %config(noreplace) /etc/firehol/firehol.conf /etc/firehol/examples/home-adsl.conf /etc/firehol/examples/home-dialup.conf /etc/firehol/examples/office.conf /etc/firehol/examples/server-dmz.conf /etc/firehol/examples/client-all.conf /etc/firehol/examples/lan-gateway.conf %doc adblock.sh get-iana.sh check-iana.sh %doc doc/adding.html %doc doc/css.css %doc doc/fwtest.html %doc doc/index.html %doc doc/language.html %doc doc/services.html %doc doc/search.html %doc doc/tutorial.html %doc doc/commands.html %doc doc/header.html %doc doc/invoking.html %doc doc/overview.html %doc doc/trouble.html %doc doc/faq.html %changelog firehol-1.297/COPYING000066400000000000000000000431101225731333700142240ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, 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. firehol-1.297/ChangeLog000066400000000000000000002465021225731333700147550ustar00rootroot00000000000000revision 1.297 Remove adsense from offline manual pages Fix persmissions on a couple of examples ---------------------------- RCS file: /cvsroot/firehol/firehol/firehol.sh,v Working file: firehol.sh head: 1.296 branch: locks: strict access list: symbolic names: start: 1.1.1.1 vendor: 1.1.1 keyword substitution: kv total revisions: 297; selected revisions: 297 description: ---------------------------- revision 1.296 date: 2013/01/06 23:49:08; author: ktsaou; state: Exp; lines: +9 -8 Removed depedency to get-iana.sh It is not usefull any more. ---------------------------- revision 1.295 date: 2013/01/06 23:26:04; author: ktsaou; state: Exp; lines: +11 -8 Updated blackist command so that it does not lead to timeouts when an internal host is trying to reach a blacklisted host. ---------------------------- revision 1.294 date: 2010/10/05 21:10:08; author: ktsaou; state: Exp; lines: +7 -7 Updated RESERVED_IPS ---------------------------- revision 1.293 date: 2010/04/08 22:27:18; author: ktsaou; state: Exp; lines: +16 -16 Removed unnecessary quotes from logs. ---------------------------- revision 1.292 date: 2010/04/08 22:16:03; author: ktsaou; state: Exp; lines: +10 -6 Added service: sane ---------------------------- revision 1.291 date: 2010/04/08 22:12:35; author: ktsaou; state: Exp; lines: +13 -6 Added services: ipsecnatt l2tp ---------------------------- revision 1.290 date: 2010/04/08 21:55:07; author: ktsaou; state: Exp; lines: +7 -7 Fixed bug: 2873689 Mispelled server_yppasswdd. ---------------------------- revision 1.289 date: 2010/04/08 21:51:26; author: ktsaou; state: Exp; lines: +12 -6 Added support for NFLOG as requested per patch 2954470. ---------------------------- revision 1.288 date: 2010/04/06 22:23:16; author: ktsaou; state: Exp; lines: +47 -6 Added support to block concurrent running of FireHOL by multiple admins. FireHOL uses the lockfile command, if it finds it, allowing to detect stale locks if 600 seconds have been passed since the last lock. The lock file is /var/run/firehol.lck ---------------------------- revision 1.287 date: 2009/10/01 10:25:23; author: ktsaou; state: Exp; lines: +8 -7 Fixed issue with TRY and START. ---------------------------- revision 1.286 date: 2009/02/26 02:13:54; author: ktsaou; state: Exp; lines: +128 -61 Added syslog support. FireHOL now logs to syslog all important events. Variable for the user: FIREHOL_SYSLOG_FACILITY="daemon" Default is shown. User can set it in config file. ---------------------------- revision 1.285 date: 2009/02/25 23:30:14; author: ktsaou; state: Exp; lines: +19 -7 Made it detect when the simple services have either server or client ports defined, but not both. ---------------------------- revision 1.284 date: 2009/02/22 00:35:16; author: ktsaou; state: Exp; lines: +12 -10 Fixed an issue where the wizard/helpme generated too long names. ---------------------------- revision 1.283 date: 2009/02/21 21:42:07; author: ktsaou; state: Exp; lines: +28 -19 Updated the kernel module handling for certain helpers. ---------------------------- revision 1.282 date: 2009/02/19 05:27:49; author: ktsaou; state: Exp; lines: +259 -182 Added helper_="helper" functionality. This allows to consider as simple all the services which rely on a kernel netfilter module. Converted the following services to simple: amanda, ftp, pptp, tftp Updated the following simple services to use kernel modules: h323, GRE, sip ---------------------------- revision 1.281 date: 2009/02/19 02:47:36; author: ktsaou; state: Exp; lines: +8 -8 Fixed ftp helper match to allow only ESTABLISHED or RELATED connections. Otherwise it would allow NEW connections in the reverse direction too. ---------------------------- revision 1.280 date: 2009/02/19 02:33:08; author: ktsaou; state: Exp; lines: +37 -91 Updated service ftp to match everything with the kernel ftp helper. Removed incomplete p2p service. ---------------------------- revision 1.279 date: 2009/02/06 04:18:31; author: ktsaou; state: Exp; lines: +8 -6 Service SIP now uses the kernel modules. ---------------------------- revision 1.278 date: 2009/02/05 02:45:00; author: ktsaou; state: Exp; lines: +9 -9 Fixed a copy and paste error in connmark helper. ---------------------------- revision 1.277 date: 2009/02/05 02:03:07; author: ktsaou; state: Exp; lines: +63 -7 Updated RESERVED_IPS for the latest IANA reservations. Added classify helper for traffic shapping without marks. Added connmark helper for statefull connection marking to assist the routing decision (i.e. multiple upstream providers). ---------------------------- revision 1.276 date: 2008/12/02 20:28:02; author: ktsaou; state: Exp; lines: +16 -16 Renamed fixtos to tosfix, optimize it a bit, and added documentation about it. ---------------------------- revision 1.275 date: 2008/12/02 20:01:11; author: ktsaou; state: Exp; lines: +35 -6 Added fixtos helper to mangle packets that may have invalid TOS ---------------------------- revision 1.274 date: 2008/08/09 21:48:02; author: ktsaou; state: Exp; lines: +44 -12 fixed tcpmss issue described in bug 2043915. It seems that LARTC is very old for this. ---------------------------- revision 1.273 date: 2008/07/31 00:46:41; author: ktsaou; state: Exp; lines: +7 -7 update RESERVED_IPS according to latest IANA reservations. ---------------------------- revision 1.272 date: 2008/04/09 21:03:13; author: ktsaou; state: Exp; lines: +7 -7 Updated IANA reservations. ---------------------------- revision 1.271 date: 2008/03/17 22:08:43; author: ktsaou; state: Exp; lines: +7 -7 Updated for latest IANA reservations format. ---------------------------- revision 1.270 date: 2007/12/11 22:05:24; author: ktsaou; state: Exp; lines: +47 -6 Added service xbox. This is not final, as it opens all unprivileged UDP ports to anyone from source port UDP 3074. ---------------------------- revision 1.269 date: 2007/12/08 10:39:06; author: ktsaou; state: Exp; lines: +23 -23 Fixed the operation of FIREHOL_DROP_ORPHAN_TCP_ACK_FIN. It did not work because it was also checking for a NEW state (which is not the case). ---------------------------- revision 1.268 date: 2007/11/30 19:22:36; author: ktsaou; state: Exp; lines: +7 -7 Updated RESERVED_IPS ---------------------------- revision 1.267 date: 2007/10/25 12:34:06; author: ktsaou; state: Exp; lines: +13 -13 Changed all service definitions which can use client ports bellow 1024 to allow client connections from any possible port, because when natted, these services will me remapped to client ports bellow 1024 without any restriction on the port range. ---------------------------- revision 1.266 date: 2007/10/15 00:43:17; author: ktsaou; state: Exp; lines: +95 -37 'less' is no more required. Now FireHOL can use 'less', 'more' or 'cat' in that order, for a pager. FireHOL will now correctly use 'zcat', 'gzcat' or 'gzip' for uncompressing /proc/config.gz, and it will ignore /proc/config.gz if it cannot find any of these commands (with a warning). There was a case, where an attacker could use firehol to execute a custom script, if it was saved at a location where the kernel config file is expected by firehol, and /proc/config, /proc/config.gz did not exist. FireHOL now greps the kernel config file for the information it needs, so this threat has been eliminated. Updated the line number management of the configuration file, using the latest user commands offered by firehol. ---------------------------- revision 1.265 date: 2007/10/14 23:02:39; author: ktsaou; state: Exp; lines: +11 -11 Replace gzcat with zcat. ---------------------------- revision 1.264 date: 2007/10/14 23:00:41; author: ktsaou; state: Exp; lines: +7 -7 Updated RESERVED_IPS to latest IANA reservations. ---------------------------- revision 1.263 date: 2007/08/20 02:03:28; author: ktsaou; state: Exp; lines: +8 -8 Made the helpme wizard correctly recognize services listening on the IPv6 equivalent of 0.0.0.0 (::). ---------------------------- revision 1.262 date: 2007/08/20 00:53:22; author: ktsaou; state: Exp; lines: +8 -8 Changed the protections to activate the 'invalid' match last, after all other protections. ---------------------------- revision 1.261 date: 2007/07/30 22:52:48; author: ktsaou; state: Exp; lines: +39 -39 Various updates in 'helpme' mode. There is still one issue unsolved: When there are routes to specific nets befind a gateway, FireHOL checks if the IP of the host or the gateway are inside the networks routed through the gateway. This is wrong. In several cases, the network behind a gateway will not include the IP of the gateway or the IP of the interface the firehol host routes this traffic via. However, there seems to be no easy solution to this. For PPP interfaces the IP of the PPP concentrator is included in the IPs that are reported by 'ip route show dev ppp0' as the networks behind this device. May be the 'scope' paramater of the routing table should be used to exclude 'scope link' routes. If 'scope link' routes are ommitted, the resulting set could be used to identify the routes behind a router. ---------------------------- revision 1.260 date: 2007/07/26 21:39:50; author: ktsaou; state: Exp; lines: +7 -7 Updated RESERVED_IPS. ---------------------------- revision 1.259 date: 2007/07/20 21:28:13; author: ktsaou; state: Exp; lines: +11 -8 Service multicast has been changed to match dst 224.0.0.0/4 proto IGMP and UDP. ---------------------------- revision 1.258 date: 2007/07/20 21:16:59; author: ktsaou; state: Exp; lines: +49 -18 Various minor fixed. firehol 'save' now saves also the required kernel modules to restore the firewall at /var/spool/firehol/last_save_modules.sh. This is executable already and can be called from boot scripts to load the kernel modules required when restoring the firewall with: iptables-restore ---------------------------- revision 1.257 date: 2007/07/20 19:58:38; author: ktsaou; state: Exp; lines: +55 -7 Added helper action: action [chain ] The action helper creates an iptables chain which can be used to control the action of other firewall rules during runtime. For example, you can setup the custom action ACT1, which by default is ACCEPT, but under certain cases it can be changed to DROP, REJECT or RETURN without restarting the firewall. The first argument must always be the word 'chain', for the moment. name can be any chain name accepted by iptables. It is suggested to keep it between 5 to 10 letters. action can be any action supported by FireHOL, although ony ACCEPT, REJECT, DROP, RETURN may have any meaning under this use. Example 1: At the top of firehol.conf, create the action ACT1: action chain ACT1 accept later, in interfaces and routers, create rules that use the ACT1 action: server smtp ACT1 client imap ACT1 Please note that actions created this way are case sensitive. At some point, and while the firewall is running, the action ACT1 can be changed to DROP, with this linux command (this is not FireHOL specific): iptables -t filter -I ACT1 -j DROP The above command inserts (-I) the new action DROP above the default action ACCEPT, and therefore all the traffic matching the FireHOL rules that have the action ACT1 will now be dropped. To return to the default action (ACCEPT), run the following linux command: iptables -t filter -D ACT1 -j DROP This command deletes (-D) the DROP action that was inserted above the default action. If you delete all actions in the chain ACT1, the default action will be RETURN, in which case all rules with action ACT1 will be nutralized (it will be the same as they were not specified at all in firehol.conf). Example 2: action chain "ACT1 ACT2 ACT3" accept chain "ACT4 ACT5 ACT6" drop will create 6 actions, ACT1, ACT2, ACT3 with ACCEPT, and ACT4, ACT5, ACT6 with DROP. ---------------------------- revision 1.256 date: 2007/05/22 22:52:53; author: ktsaou; state: Exp; lines: +7 -7 Updated IANA RESERVED_IPS. ---------------------------- revision 1.255 date: 2007/05/06 14:42:43; author: ktsaou; state: Exp; lines: +23 -11 Made firehol correctly identify newer kernel options regarding iptables modules (applies to kernels 2.6.20+). ---------------------------- revision 1.254 date: 2007/05/05 23:38:31; author: ktsaou; state: Exp; lines: +92 -8 Added support for external definitions of: RESERVED_IPS PRIVATE_IPS MULTICAST_IPS UNROUTABLE_IPS in files under the same name in /etc/firehol/. Only RESERVED_IPS is mandatory (firehol will complain if it is not there, but it will still work without it), and is also the only file that firehol checks how old is it. If it is 90+ days old, firehol will complain again. Changed the supplied get-iana.sh script to generate the RESERVED_IPS file. FireHOL also instructs the user to use this script if the file is missing or is too old. ---------------------------- revision 1.253 date: 2007/04/29 18:38:41; author: ktsaou; state: Exp; lines: +7 -7 Updated RESERVED_IPS ---------------------------- revision 1.252 date: 2007/04/29 18:34:55; author: ktsaou; state: Exp; lines: +9 -9 BASH 3.2 support. The problem is in array variables. For some reason, an empty array member in BASH 3.1 produces no iptables arguments, but in BASH 3.2 an empty array member produces an empty iptables argument which breaks iptables. ---------------------------- revision 1.251 date: 2007/02/04 23:28:41; author: ktsaou; state: Exp; lines: +7 -7 Updated RESERVED_IPS. ---------------------------- revision 1.250 date: 2006/11/21 23:41:23; author: ktsaou; state: Exp; lines: +7 -7 Updated latest IANA RESERVED_IPS. ---------------------------- revision 1.249 date: 2006/06/05 17:47:48; author: ktsaou; state: Exp; lines: +11 -6 Applied patch of bug: 1498292, "nfs" service missing ports for "rpc.statd" ---------------------------- revision 1.248 date: 2006/06/05 17:25:33; author: ktsaou; state: Exp; lines: +53 -15 Added support for TARPIT. Made 'policy' work for routers too. ---------------------------- revision 1.247 date: 2006/04/22 17:26:18; author: ktsaou; state: Exp; lines: +11 -6 Added protection 'bad-packets'. ---------------------------- revision 1.246 date: 2006/03/23 18:50:16; author: ktsaou; state: Exp; lines: +8 -8 Fixed bug 1455569: When FireHOL has created the $FIREHOL_SPOOL_DIR, it then runs chown and chmod on the $FIREHOL_CONFIG_DIR. This looks like a cut-n-paste error, since it at that point makes more sense to chown/chmod $FIREHOL_SPOOL_DIR. ---------------------------- revision 1.245 date: 2006/03/12 12:54:55; author: ktsaou; state: Exp; lines: +7 -7 Updated RESERVED_IPS for latest IANA assignements. ---------------------------- revision 1.244 date: 2006/03/11 12:24:34; author: ktsaou; state: Exp; lines: +15 -7 Added service OSPF. Make the wizard to ommit /32 from IPs since iptables now seems to complain about it. Check bug: 1435098 ---------------------------- revision 1.243 date: 2006/01/18 21:24:22; author: ktsaou; state: Exp; lines: +7 -7 Updated RESERVED_IPS. ---------------------------- revision 1.242 date: 2006/01/18 21:20:28; author: ktsaou; state: Exp; lines: +7 -7 Fixed the SIP service to allow port 5060 for the client (had only 'default'). ---------------------------- revision 1.241 date: 2005/11/19 09:38:25; author: ktsaou; state: Exp; lines: +7 -7 Added tcp/8333 to vmwareweb ---------------------------- revision 1.240 date: 2005/11/11 21:49:03; author: ktsaou; state: Exp; lines: +70 -9 Added option 'recent' to action 'ACCEPT': Example: server smtp accept with recent NAME SECONDS HITS where NAME is a name for this RECENT match SECONDS is a number, or empty ("") HITS is a number, or empty ("") Check: iptables -m recent --help for more information. ---------------------------- revision 1.239 date: 2005/10/27 23:46:01; author: ktsaou; state: Exp; lines: +9 -6 created a copy of "microsoft_ds" service as "ms_ds" to overcome the issue of long chain names. ---------------------------- revision 1.238 date: 2005/10/16 08:55:53; author: ktsaou; state: Exp; lines: +24 -6 Added variable FIREHOL_DROP_ORPHAN_TCP_ACK_FIN which once set to 1 in the config file, it makes FireHOL drop all packets that appear as NEW connections to the connection tracker but they are TCP and have ACK and FIN set. This should eliminate the logs that appear in a few busy environments where the iptables connection tracker removes entries from its table when it sees the FIN and therefore the ACK,FIN is considered a NEW connection. See also https://sourceforge.net/tracker/?func=detail&atid=487693&aid=1326811&group_id=58425 ---------------------------- revision 1.237 date: 2005/09/21 21:32:58; author: ktsaou; state: Exp; lines: +16 -13 Made it dynamically detect /var/lock/subsys and switch back to /var/lock if the first does not exist. ---------------------------- revision 1.236 date: 2005/06/02 16:20:35; author: ktsaou; state: Exp; lines: +7 -7 fixed a bug in negative 'mac' expressions where a faulty rule was generated for matching mac-source 'any'. ---------------------------- revision 1.235 date: 2005/06/02 15:48:52; author: ktsaou; state: Exp; lines: +7 -7 Allowed 127.0.0.1 to be in RESERVED_IPS ---------------------------- revision 1.234 date: 2005/05/08 23:27:22; author: ktsaou; state: Exp; lines: +7 -7 Updated RESERVED_IPS to current IANA reservations. ---------------------------- revision 1.233 date: 2005/04/18 22:38:23; author: ktsaou; state: Exp; lines: +83 -8 Added 'addrtype' matches, in the form of 'srctype' and 'dsttype' optional rule parameters. ---------------------------- revision 1.232 date: 2005/04/18 21:00:22; author: ktsaou; state: Exp; lines: +11 -10 Added FIREHOL_LOG_PREFIX. ---------------------------- revision 1.231 date: 2005/04/03 21:48:04; author: ktsaou; state: Exp; lines: +16 -6 Added experimental protection all-floods. ---------------------------- revision 1.230 date: 2005/03/01 19:52:56; author: ktsaou; state: Exp; lines: +7 -6 Made FireHOL trap SIGHUP and cleanup properly on it. ---------------------------- revision 1.229 date: 2005/02/17 23:45:02; author: ktsaou; state: Exp; lines: +64 -19 Made a set of external commands optional in wizard mode, so that FireHOL will work if these are absent, but will refuse to enter wizard mode. ---------------------------- revision 1.228 date: 2005/02/09 22:36:24; author: ktsaou; state: Exp; lines: +17 -8 Added support for /proc/config.gz for kernel configuration. This is silently ignored if the command 'gzcat' cannot be found in the system path. ---------------------------- revision 1.227 date: 2005/02/07 20:56:09; author: ktsaou; state: Exp; lines: +31 -7 Made wget and curl optional. Now they are required only when they are really needed. Also, small fixes in ecn_shame helper. ---------------------------- revision 1.226 date: 2005/01/25 21:28:19; author: ktsaou; state: Exp; lines: +10 -10 Remove -p from mkdir commands, in order for them to fail if the directory to be created already exists. ---------------------------- revision 1.225 date: 2005/01/25 21:07:01; author: ktsaou; state: Exp; lines: +12 -12 Made sure that no files are created anywhere except the firehol temp dir. Made the firehol temp dir use the $RANDOM variable to randomize its name. ---------------------------- revision 1.224 date: 2005/01/24 22:24:48; author: ktsaou; state: Exp; lines: +8 -8 Fixed service pptp to control GRE traffic in a stateless way. ---------------------------- revision 1.223 date: 2005/01/24 21:23:38; author: ktsaou; state: Exp; lines: +145 -103 Added security checks to directory creation mechanism. ---------------------------- revision 1.222 date: 2005/01/21 19:58:09; author: ktsaou; state: Exp; lines: +9 -6 Added service DICT (kdict, gnome-dictionary). ---------------------------- revision 1.221 date: 2004/12/29 22:34:45; author: ktsaou; state: Exp; lines: +21 -14 Minor fixes for calculating minor firehol version number, added transparent proxy to line number calculation and fix a typo in the docs. ---------------------------- revision 1.220 date: 2004/12/23 18:43:03; author: ktsaou; state: Exp; lines: +8 -6 The knock was not allowing established connections, and knockd was inserting a rule with a -s which matched requests but did not match the replies. Now, the default is to allow established connections for knock and only control NEW connections via knockd. ---------------------------- revision 1.219 date: 2004/12/22 23:05:57; author: ktsaou; state: Exp; lines: +38 -8 Small internal changes. Added support for integration with knockd (http://www.zeroflux.org/knock/) This integration comes as part of the ACCEPT action: accept [with knock ] The optional parameter 'with knock' allows easy integration with knockd, a server that allows you to control access to services, by sending certain packets to "knock" the door, before the door is open for service. This parameter accepts just a name. This name is used to build a special chain knock_ which will contain no rules, so that the traffic entering this chain will just return back and continue to match against the other rules until the end of the firewall. As an example, lets say that you want to allow https traffic based on a knock. In FireHOL you write: server https accept with knock hidden and you configure knockd so that it runs: iptables -A knock_hidden -s %IP% -j ACCEPT to enable the https service (notice that there is no need to match anything else than the IP. FireHOL already matches everything needed for its rules to work), and: iptables -D knock_hidden -s %IP% -j ACCEPT to disable this service for the given IP. ---------------------------- revision 1.218 date: 2004/12/21 21:49:11; author: ktsaou; state: Exp; lines: +24 -18 Added helper 'transparent_proxy' and modified 'transparent_squid' to call the new helper for setting up transparent web proxies. ---------------------------- revision 1.217 date: 2004/12/03 21:29:41; author: ktsaou; state: Exp; lines: +36 -5 Added service TIMESTAMP. ---------------------------- revision 1.216 date: 2004/11/04 19:47:05; author: ktsaou; state: Exp; lines: +7 -7 Fixed a bug in FIREHOL_OUTPUT_ACTIVATION_POLICY which was incorrectly setting the INPUT policy. ---------------------------- revision 1.215 date: 2004/11/02 00:37:15; author: ktsaou; state: Exp; lines: +38 -5 Added service ANYSTATELESS ---------------------------- revision 1.214 date: 2004/11/01 00:13:00; author: ktsaou; state: Exp; lines: +30 -10 Implemented minor version check on services in /etc/firehol/services ---------------------------- revision 1.213 date: 2004/10/31 03:17:00; author: ktsaou; state: Exp; lines: +9 -6 Fixed a type in DSCP optional rule parameter. Added line numbering to newly added helpers. ---------------------------- revision 1.212 date: 2004/10/31 02:21:02; author: ktsaou; state: Exp; lines: +497 -256 Added helpers: tos - to set the TOS of packets dscp - to set the DSCP field of packets (both raw and class) Added optional rule parameters: tos - to match the TOS of packets mark - to match the MARK ID of packets dscp - to match the DSCP field of packets (both raw and class) Added the following actions to the rule() function: dscp The rule() function already had support for TOS and MARK. ---------------------------- revision 1.211 date: 2004/10/30 23:03:57; author: ktsaou; state: Exp; lines: +35 -8 Created the complex service DHCP and removed the simple one. The complex DHCP is now stateless to overcome all the problems that arise due to the initial DHCP broadcast. ---------------------------- revision 1.210 date: 2004/10/30 22:41:21; author: ktsaou; state: Exp; lines: +16 -12 Service SAMBA now includes MICROSOFT_DS (tcp/445). Also, updated samba related documentation. ---------------------------- revision 1.209 date: 2004/10/30 21:27:00; author: ktsaou; state: Exp; lines: +18 -8 Some error detection for /etc/firehol/services directory creation. ---------------------------- revision 1.208 date: 2004/10/30 21:13:26; author: ktsaou; state: Exp; lines: +109 -5 Added service NIS. Created by Carlos Rodrigues Feature Requests item #1050951 These rules work for client access only! Pushing changes to slave servers won't work if these rules are active somewhere between the master and its slaves, because it is impossible to predict the ports where "yppush" will be listening on each push. Pulling changes directly on the slaves will work, and could be improved performance-wise if these rules are modified to open "fypxfrd". This wasn't done because it doesn't make that much sense since pushing changes on the master server is the most common, and recommended, way to replicate maps. ---------------------------- revision 1.207 date: 2004/10/28 23:03:06; author: ktsaou; state: Exp; lines: +67 -13 Added support for externally defined services in files under directory: /etc/firehol/services This directory may contain files ending with .conf. Example: imap.conf Each file should *start* with a line like this: #FHVER: 1 This must be the FIRST line of the file. The number 1 is the FIREHOL_SERVICES_API version number. If the API within FireHOL changes, FireHOL will refuse to load all those services files that their API version number does not match. ---------------------------- revision 1.206 date: 2004/10/28 22:02:43; author: ktsaou; state: Exp; lines: +9 -5 Added service nut. ---------------------------- revision 1.205 date: 2004/10/08 22:30:52; author: ktsaou; state: Exp; lines: +90 -46 Added helper 'tcpmss'. Added service 'nntps'. Converted all simple services' port definitions to numeric. Updated documentation accordingly. ---------------------------- revision 1.204 date: 2004/09/26 00:52:55; author: ktsaou; state: Exp; lines: +55 -6 Added services: asterisk, darkstat, distcc, eserver, gift, giftui, h323, iax, iax2, icp, rtp, sip, stun, upnp. ---------------------------- revision 1.203 date: 2004/09/14 21:15:44; author: ktsaou; state: Exp; lines: +119 -7 Added support for options to the ACCEPT action in order to allow a certain frequency of NEW connections per service. Now the template for the ACCEPT action is this: ACCEPT [with limit frequency burst [overflow action]] for example: server smtp accept with limit 10/s 100 overflow drop which means there is now control for the frequency at which NEW incoming connections are accepted and control is also provided for the overflow NEW ones. The default overflow action is REJECT which rejects TCP connections with TCP-RESET and all others with ICMP-PORT-UNREACHABLE. To add other optional rule parameters to the server/client/route command just add them after the ACCEPT expression. For example: server smtp accept with limit 10/s 1000 src 1.2.3.4 If there are overflow NEW connections, the firewall will log "OVERFLOW" with the packets and the frequency of loglimit (controled via global variables). The overflow action cannot accept parameters. ---------------------------- revision 1.202 date: 2004/09/12 07:24:58; author: ktsaou; state: Exp; lines: +8 -5 Added RDP service. ---------------------------- revision 1.201 date: 2004/09/12 06:57:47; author: ktsaou; state: Exp; lines: +9 -5 Added service NXSERVER. ---------------------------- revision 1.200 date: 2004/09/10 22:07:18; author: ktsaou; state: Exp; lines: +16 -5 Added a warning if wrong arguments are detected. ---------------------------- revision 1.199 date: 2004/09/10 21:36:26; author: ktsaou; state: Exp; lines: +12 -5 Added rquotad to the NFS service. ---------------------------- revision 1.198 date: 2004/08/21 21:07:09; author: ktsaou; state: Exp; lines: +6 -6 Updated RESERVED_IPS according to current IANA reserved IP range. ---------------------------- revision 1.197 date: 2004/07/31 22:31:08; author: ktsaou; state: Exp; lines: +31 -33 Due to a bug in BASH 3.0, the unset bash function corrupts array variables. Changed FireHOL to set all variables to empty instead of unseting them. ---------------------------- revision 1.196 date: 2004/07/29 22:31:14; author: ktsaou; state: Exp; lines: +12 -6 Added documentation for DHCP and dropped packets. Changed radius definition to use port numbers instead of port names (gentoo has different names). Added RADIUSPROXY and RADIUSOLDPROXY services. ---------------------------- revision 1.195 date: 2004/07/07 22:09:31; author: ktsaou; state: Exp; lines: +14 -7 Added variable FIREHOL_TRUST_LOOPBACK=1 which if set to 0, FireHOL will not trust the lo interface allowing the admin to setup a firewall on it. ---------------------------- revision 1.194 date: 2004/05/15 10:19:01; author: ktsaou; state: Exp; lines: +9 -5 Added an iptables -nxvL command at the top of firehol.sh to initialize iptables. Without it a few users have reported problems using firehol during boot. ---------------------------- revision 1.193 date: 2004/05/05 23:41:19; author: ktsaou; state: Exp; lines: +88 -11 Added helper 'ecn_shame' that once called, it looks if ECN is enabled in the kernel, and if it is, it fetches: http://urchin.earth.li/cgi-bin/ecn.pl?output=ip and disables ECN for all communication with these hosts. ---------------------------- revision 1.192 date: 2004/05/04 21:39:33; author: ktsaou; state: Exp; lines: +76 -5 Added grouping functionality. This is not yet finished. It has been added to allow other developers test the functionality before optimizing all the rules to use groups. To use grouping, within an interface or router write: group with [optional rule parameters] server x accept server y accept group end This will generate a much more optimized version of: server "x y" accept [optional rule parameters] by applying all the optional rule parameters once (instead of once per service). ---------------------------- revision 1.191 date: 2004/04/23 22:15:18; author: ktsaou; state: Exp; lines: +26 -15 Made the nat helpers print their real statements instead of always appearing as 'nat'. ---------------------------- revision 1.190 date: 2004/04/23 07:36:12; author: ktsaou; state: Exp; lines: +7 -7 Changed two: tr [a-z] [A-Z] to: tr a-z A-Z because a few versions of tr complain with the first format. ---------------------------- revision 1.189 date: 2004/04/23 07:32:01; author: ktsaou; state: Exp; lines: +6 -6 Fixed a printf that was giving errors because an argument was not numeric. ---------------------------- revision 1.188 date: 2004/04/21 22:57:11; author: ktsaou; state: Exp; lines: +5 -7 Removed the "press return to continue" from the 'debug' mode. ---------------------------- revision 1.187 date: 2004/04/21 22:39:40; author: ktsaou; state: Exp; lines: +12 -7 FireHOL now checks that /var/lock/subsys (the dir RH uses for startup services lock files) exists before using it. ---------------------------- revision 1.186 date: 2004/04/21 22:23:10; author: ktsaou; state: Exp; lines: +8 -5 Added service WHOIS. ---------------------------- revision 1.185 date: 2004/04/21 21:48:32; author: ktsaou; state: Exp; lines: +10 -5 Kernel configuration is now searched in this order: 1. /proc/config 2. /lib/modules/`uname -r`/build/.config 3. /boot/config-`uname -r` 4. /usr/src/linux/.config Check No 3 was added now. ---------------------------- revision 1.184 date: 2004/04/21 21:35:29; author: ktsaou; state: Exp; lines: +108 -49 IMPORTANT: My second kid was born a week ago! Added a lot of information to the generated iptables command line to debug both the commands generated and what FireHOL did. Fixed a bug in kernel module management: check_kernel_module() was supposed to be a runtime function, but accidentaly I had it generating commands to be run later - which of course were not run. ---------------------------- revision 1.183 date: 2004/04/01 23:30:28; author: ktsaou; state: Exp; lines: +19 -9 Added finer control to control INVALID packets. The default is now not to drop invalid packets globaly, but to drop them as part of the protection statement (i.e. protection invalid). The default full/strong/all protections include the invalid match. To enable invalid packets dropping globaly (the previous behaviour) one can give: FIREHOL_DROP_INVALID=1 at the top of the configuration file. ---------------------------- revision 1.182 date: 2004/03/04 22:05:53; author: ktsaou; state: Exp; lines: +5 -6 Removed a tcp-flags match from protection because it was a subset of another one already defined. ---------------------------- revision 1.181 date: 2004/03/03 23:18:43; author: ktsaou; state: Exp; lines: +40 -36 Fixed the required commands finder to stop properly when some system command is not found in the system path. ---------------------------- revision 1.180 date: 2004/03/03 22:19:15; author: ktsaou; state: Exp; lines: +6 -5 Added: --tcp-flags SYN,RST,PSH,ACK,URG SYN,RST,PSH,URG to the list of malformed packets. ---------------------------- revision 1.179 date: 2004/03/03 21:24:41; author: ktsaou; state: Exp; lines: +12 -15 Minor mac optional rule parameter fix. ---------------------------- revision 1.178 date: 2004/03/03 20:32:35; author: ktsaou; state: Exp; lines: +11 -6 Completed the mac optional rule parameter. This was implemented since v1.134 but it was producing rules for both input and output packets. Now, it produces mac rules only for packets comming in the firewall (interfaces and routers). ---------------------------- revision 1.177 date: 2004/02/07 00:43:11; author: ktsaou; state: Exp; lines: +6 -6 BUG 891471: Multicast CIDR block is actually 224.0.0.0/4. It extends from 224-239. Fixed. ---------------------------- revision 1.176 date: 2004/01/10 18:44:39; author: ktsaou; state: Exp; lines: +8 -6 Further optimized and reduced PRIVATE_IPS using: http://www.vergenet.net/linux/aggregate/ The supplied get-iana.sh uses 'aggregate-flim' if it finds it in the path. (aggregate-flim is the name of this program when installed on Gentoo) ---------------------------- revision 1.175 date: 2004/01/02 22:32:28; author: ktsaou; state: Exp; lines: +6 -6 Fixed a warning generated incorrectly by the mark helper. ---------------------------- revision 1.174 date: 2003/12/29 22:46:00; author: ktsaou; state: Exp; lines: +7 -7 Aesthetic changes. ---------------------------- revision 1.173 date: 2003/12/29 22:40:11; author: ktsaou; state: Exp; lines: +70 -11 Added count of iptables commands generated. ---------------------------- revision 1.172 date: 2003/12/01 05:03:11; author: ktsaou; state: Exp; lines: +17 -8 Added FIREHOL_LOG_MODE which can either be LOG or ULOG to select the logging mode for iptables. All FireHOL optional rule parameters use this. Updated documentation to reflect the change. ---------------------------- revision 1.171 date: 2003/11/23 19:27:58; author: ktsaou; state: Exp; lines: +6 -6 Changed a "head -1" to "head -n 1" because head does not support the first syntax anymore. Thanks to Maik Schreiber for reporting this. ---------------------------- revision 1.170 date: 2003/11/23 13:43:19; author: ktsaou; state: Exp; lines: +11 -5 Added support for kernel config in /lib/modules/`uname -r`/build/.config Updated documentation. ---------------------------- revision 1.169 date: 2003/11/18 23:00:48; author: ktsaou; state: Exp; lines: +6 -6 There was an extra - (minus) in the iptables command generation for negative protocol expressions. Fixed. ---------------------------- revision 1.168 date: 2003/11/04 21:43:02; author: ktsaou; state: Exp; lines: +21 -6 NETBIOS initiates based on the broadcast address of an interface (request goes to broadcast address) but the server responds from its own IP address. This makes the server samba accept statement drop the server reply. Bellow is a hack, that allows a linux samba server to respond correctly, as it allows new outgoing connections from the well known netbios-ns port to the clients high ports. For clients and routers this hack is not applied because it would be a huge security hole. ---------------------------- revision 1.167 date: 2003/11/03 20:43:09; author: ktsaou; state: Exp; lines: +6 -6 Added again 172.16.0.0/12 to PRIVATE_IPS. ---------------------------- revision 1.166 date: 2003/10/26 21:40:30; author: ktsaou; state: Exp; lines: +67 -56 Fixed PRIVATE_IPS (there was an duplicate entry and a wrong entry). ---------------------------- revision 1.165 date: 2003/10/26 21:27:31; author: ktsaou; state: Exp; lines: +102 -8 Changed kernel module management to read kernel configuration and detect if a module is compiled in the kernel or needs to be loaded separately. (note: this is not finished yet) ---------------------------- revision 1.164 date: 2003/10/22 06:58:27; author: ktsaou; state: Exp; lines: +6 -6 Changed TIME service ports to numeric since a few versions of bash get confused by the use of the reserved keywork "time". ---------------------------- revision 1.163 date: 2003/10/20 17:49:56; author: ktsaou; state: Exp; lines: +7 -7 Fixed service CUPS according to the following: > The firehol system defines the 'cups' protocol as: > > server_cups_ports="tcp/631" > client_cups_ports="default" > > This isn't a complete definition - CUPS also has an internal printer > browsing protocol that operates over UDP, on port 631. > > The following definition is more correct: > > server_cups_ports="tcp/631 udp/631" > client_cups_ports="default 631" ---------------------------- revision 1.162 date: 2003/10/18 09:40:45; author: ktsaou; state: Exp; lines: +8 -5 Added Distributed Checksum Clearinghouses (DCC) service. ---------------------------- revision 1.161 date: 2003/10/16 22:05:22; author: ktsaou; state: Exp; lines: +194 -84 Added the PHYSIN and PHYSOUT optional rule parameters to match the physical network interface in cases where iptables defines as inface and outface a virtual interface such as a bridge. ---------------------------- revision 1.160 date: 2003/10/13 18:50:30; author: ktsaou; state: Exp; lines: +13 -5 Added services ORACLE and GKRELLMD. ---------------------------- revision 1.159 date: 2003/10/09 10:01:26; author: ktsaou; state: Exp; lines: +9 -5 Added service Veritas NetBackup. ---------------------------- revision 1.158 date: 2003/10/07 22:31:06; author: ktsaou; state: Exp; lines: +12 -7 Added lockd support in service NFS, as suggested by "Daniel Pittman" ---------------------------- revision 1.157 date: 2003/10/06 00:17:23; author: ktsaou; state: Exp; lines: +18 -6 Fixed TFTP service according to Goetz Bock suggestions. ---------------------------- revision 1.156 date: 2003/10/05 22:58:57; author: ktsaou; state: Exp; lines: +110 -68 Cleaned up all complex services. Added complex service TFTP. ---------------------------- revision 1.155 date: 2003/09/18 20:54:25; author: ktsaou; state: Exp; lines: +8 -5 When I first started FireHOL (about a year before) I started with the header part of /etc/init.d/iptables (of redhat 7.2). This header just checked the kernel version and made a check on whether ipchains was running. If any of the above was faulty (kernel version less than 2.3 or ipchains loaded into the kernel) it was exiting silently. Although I still keep this logic, now FireHOL will print a warning instead of just exiting silently. ---------------------------- revision 1.154 date: 2003/09/13 01:03:46; author: ktsaou; state: Exp; lines: +26 -5 Added helper 'mark' Abstract from the documentation: mark [optional rule parameters] The mark helper marks the traffic with a specific mark NUMBER that can be matched by traffic shapping tools for controlling the traffic. Parameters * NUMBER is a number to mark the packets with. * WHERE tells FireHOL where to search for the specific traffic to be marked. Currently, WHERE can be one of the build-in iptables chains attached to table mangle. (for example: INPUT, FORWARD, OUTPUT, PREROUTING, POSTROUTING - case does matter here). * optional rule parameters is a set of rules that allow further restriction of the traffic that gets matched by this rule. See Optional Rules Parameters for more information. Example 1: mark 1 OUTPUT will mark with 1 all packets send by the local machine. Example 2: mark 2 FORWARD will mark with 2 all packets passing through the local machine. Example 3: mark 3 FORWARD proto tcp dport 25 dst 1.1.1.1 src 2.2.2.2 will match with 3 all packets sent by 2.2.2.2, passing through the local machine and targeting port TCP/25 of host 1.1.1.1. ---------------------------- revision 1.153 date: 2003/08/31 22:21:49; author: ktsaou; state: Exp; lines: +8 -5 Added service XDMCP. ---------------------------- revision 1.152 date: 2003/08/23 23:26:50; author: ktsaou; state: Exp; lines: +6 -6 Bug #793889: Change #!/bin/sh to #!/bin/bash to allow FireHOL run on systems that bash is not linked to /bin/sh. ---------------------------- revision 1.151 date: 2003/08/23 22:50:14; author: ktsaou; state: Exp; lines: +7 -7 Bug #893887: Added -q to modprobe in order not to complain about modules already loaded in kernel 2.6.x with module-init-tools ---------------------------- revision 1.150 date: 2003/08/23 22:27:34; author: ktsaou; state: Exp; lines: +35 -11 Made the blacklist helper produce only one set of chains for all its runs. This will keep the produced rules clearer and the firewall smaller. ---------------------------- revision 1.149 date: 2003/08/23 21:42:35; author: ktsaou; state: Exp; lines: +54 -5 Added "blacklist" helper to create blacklists. Abstract from the documentation: blacklist [option] The blacklist helper creates a blacklist for the IP addresses given. It supports two modes of operation based on the option given (or the absence of it). The option can be: * one of the words them, him, her, it, this, these, input in which case it will generate a unidirectional statefull blacklist, meaning that you will be able to ask (initiate connections) anything from them, but they will not be able to ask (initiate connections) anything from you or the remote hosts you protect (routing). * one of the words all, full or ommitted (no option given), in which case FireHOL will create bidirectional stateless rules that will DROP all traffic comming in from these IPs and will REJECT all traffic going to them. The blacklist helper affects both interfaces and routers. Example 1: blacklist this 195.97.5.202 Example 2: blacklist full 195.97.5.202 Suggested by: Mikkel Schubert ---------------------------- revision 1.148 date: 2003/08/19 22:21:32; author: ktsaou; state: Exp; lines: +6 -6 Fixed a minor bug in kernel module handling that made it not detect that ip_tables is already compiled (or loaded) in the kernel. ---------------------------- revision 1.147 date: 2003/07/31 20:44:45; author: ktsaou; state: Exp; lines: +7 -7 More Gentoo compatibility (mainly change of port names to port numbers in services). ---------------------------- revision 1.146 date: 2003/07/27 22:58:59; author: ktsaou; state: Exp; lines: +21 -8 Minor changes for gentoo compatibility (SAVE feature) . ---------------------------- revision 1.145 date: 2003/07/20 22:45:50; author: ktsaou; state: Exp; lines: +43 -7 Added service HYLAFAX, although experimental. ---------------------------- revision 1.144 date: 2003/07/20 22:14:28; author: ktsaou; state: Exp; lines: +37 -37 As suggested by "Francisco Javier Félix Belmonte" fixed all EOF statements in order to produce cleaner iptables run script. ---------------------------- revision 1.143 date: 2003/07/20 21:52:41; author: ktsaou; state: Exp; lines: +8 -5 Added service POSTGRES. ---------------------------- revision 1.142 date: 2003/07/20 21:50:29; author: ktsaou; state: Exp; lines: +8 -5 Added TIME service. ---------------------------- revision 1.141 date: 2003/07/20 21:48:01; author: ktsaou; state: Exp; lines: +6 -6 Changed service CUPS ports to numeric. Gentoo does not have this defined. ---------------------------- revision 1.140 date: 2003/07/20 21:46:41; author: ktsaou; state: Exp; lines: +131 -86 Added --cmd-owner support. ---------------------------- revision 1.139 date: 2003/06/30 22:18:46; author: ktsaou; state: Exp; lines: +8 -5 Added service webmin. ---------------------------- revision 1.138 date: 2003/06/30 22:07:01; author: ktsaou; state: Exp; lines: +11 -5 Added jabber and jabberd services. ---------------------------- revision 1.137 date: 2003/06/28 23:22:49; author: ktsaou; state: Exp; lines: +9 -7 Aesthetic changes in mac helper. ---------------------------- revision 1.136 date: 2003/06/28 21:26:20; author: ktsaou; state: Exp; lines: +6 -6 Updated service LPD according to RFCs, and now it accepts only ports 721 to 731 inclusive, plus the default client ports. ---------------------------- revision 1.135 date: 2003/06/28 20:52:09; author: ktsaou; state: Exp; lines: +7 -7 Reverted DEFAULT_CLIENT_PORTS to 1024+ (was 1000+) Made LPD client ports "any". ---------------------------- revision 1.134 date: 2003/06/18 22:56:24; author: ktsaou; state: Exp; lines: +120 -52 Added the "mac" optional rule parameter, that matches the source mac address of packets. Added the "mac" helper that verifies that packets comming in from a specific source IP address, always come from a specific MAC address. This applies to the whole firewall (INPUT and FORWARD). ---------------------------- revision 1.133 date: 2003/06/18 21:44:52; author: ktsaou; state: Exp; lines: +19 -5 Added FIREHOL_INPUT_ACTIVATION_POLICY, FIREHOL_OUTPUT_ACTIVATION_POLICY, and FIREHOL_FORWARD_ACTIVATION_POLICY to control the firewall default policy during firewall activation. ---------------------------- revision 1.132 date: 2003/06/11 07:00:24; author: ktsaou; state: Exp; lines: +7 -7 Optimized RESERVED_IPS as suggested by Marc 'HE' Brockschmidt . ---------------------------- revision 1.131 date: 2003/06/10 21:27:46; author: ktsaou; state: Exp; lines: +11 -5 Added MSN and DCPP services. ---------------------------- revision 1.130 date: 2003/06/10 20:44:27; author: ktsaou; state: Exp; lines: +7 -8 Added man page for firehol.conf, contributed by "Marc 'HE' Brockschmidt" Thanks Marc. ---------------------------- revision 1.129 date: 2003/05/22 19:39:53; author: ktsaou; state: Exp; lines: +56 -29 Made FireHOL mv /etc/firehol.conf to /etc/firehol/firehol.conf, if /etc/firehol (directory) does not exist. Also, made _CMD variables better detect wrong situations, such as multiple instanses of the same command, command not found, etc. ---------------------------- revision 1.128 date: 2003/05/01 01:30:24; author: ktsaou; state: Exp; lines: +9 -9 Made default config in /etc/firehol/firehol.conf to comform with various distributions that prefer it this way (Gentoo). This will also allow to have services.d within this directory. ---------------------------- revision 1.127 date: 2003/04/30 23:29:47; author: ktsaou; state: Exp; lines: +9 -9 "Marc 'HE' Brockschmidt" wrote: Today, I've tried to debianize firehol, but noticed a few problems (eg. the need for a force-reload-option for every init-script [you could realize it as an alias for restart]). I've corrected a few " !!!" (As a reader of Terry Pratchett, I had to kill them ;-) I'm attaching a patch for these issues. I've also created a manpage for FireHOL, and I'm working on the manpage for firehole.conf. --- Thank you Marc. ---------------------------- revision 1.126 date: 2003/04/24 08:15:08; author: ktsaou; state: Exp; lines: +6 -6 Fixed a 'touch' cmd to use the external command system. ---------------------------- revision 1.125 date: 2003/04/24 08:12:51; author: ktsaou; state: Exp; lines: +12 -5 Made HELPME detect duplicate routers and prevent multiple definitions of them. ---------------------------- revision 1.124 date: 2003/04/23 20:42:26; author: ktsaou; state: Exp; lines: +18 -7 Eliminated duplicate router definitions in HELPME, when an interface has multiple IPs on the same subnet. ---------------------------- revision 1.123 date: 2003/04/20 10:18:10; author: ktsaou; state: Exp; lines: +27 -7 FireHOL now stops the firewall with its own logic (without calling /etc/init.d/iptables) since some distribution do not have this. ---------------------------- revision 1.122 date: 2003/04/18 20:52:44; author: ktsaou; state: Exp; lines: +48 -13 Module management can now be controlled with FIREHOL_LOAD_KERNEL_MODULES. Default value is 1, it can be set to 0 to disable module management. Also, now FireHOL automatically detects if ip_tables and ip_conntrack are build into the kernel, by looking for relative files in /proc/net. ---------------------------- revision 1.121 date: 2003/04/08 00:12:02; author: ktsaou; state: Exp; lines: +184 -150 Removed all hard-coded references to external commands and made a dynamic list at the top of FireHOL. Now FireHOL will refuse to run if some command is missing. ---------------------------- revision 1.120 date: 2003/03/19 21:51:56; author: ktsaou; state: Exp; lines: +16 -6 Fixed MIRROR statements to produce REJECT on the OUTPUT of the host. ---------------------------- revision 1.119 date: 2003/03/18 21:27:35; author: ktsaou; state: Exp; lines: +9 -9 Copyright notices now print year 2003. ---------------------------- revision 1.118 date: 2003/03/17 23:03:00; author: ktsaou; state: Exp; lines: +13 -6 Cosmetic changes in 'helpme' ---------------------------- revision 1.117 date: 2003/03/17 22:57:26; author: ktsaou; state: Exp; lines: +7 -6 Fixed broken 'helpme' detection of networks behind gateways. Now it works. ---------------------------- revision 1.116 date: 2003/03/17 22:42:18; author: ktsaou; state: Exp; lines: +46 -9 'helpme' now detects multiple overlapping networks defined for the same interface. In such cases it only defines the wider network. ---------------------------- revision 1.115 date: 2003/03/16 22:13:30; author: ktsaou; state: Exp; lines: +138 -50 Made 'helpme' detect point-to-point routes better. ---------------------------- revision 1.114 date: 2003/03/15 01:24:19; author: ktsaou; state: Exp; lines: +8 -5 Added service 'socks'. ---------------------------- revision 1.113 date: 2003/03/15 00:59:27; author: ktsaou; state: Exp; lines: +25 -5 'panic' now prevent you from loosing the SSH you are issuing this command by allowing the established connection specified in the environment variable SSH_CLIENT (only if it exists: it is lost if you su -, you should su without the minus). Also, the panic argument takes one optional argument. This can be an IP address in which case all established connections between the host and this IP will be allowed. ---------------------------- revision 1.112 date: 2003/03/14 21:22:37; author: ktsaou; state: Exp; lines: +6 -6 The squid service has been defined with numeric port numbers because Debian systems have not this service defined. ---------------------------- revision 1.111 date: 2003/03/14 20:59:07; author: ktsaou; state: Exp; lines: +26 -7 Command line argument 'panic' does not call the system's iptables script but blocks all traffic by itself, since many systems do not have the 'panic' argument. ---------------------------- revision 1.110 date: 2003/03/14 20:36:52; author: ktsaou; state: Exp; lines: +30 -10 Added FIREHOL_AUTOSAVE variable that controls the file that is saved with the 'save' argument of FireHOL. By default this variable is empty in which case FireHOL detects RedHat and Debian systems and saves it to the right place. ---------------------------- revision 1.109 date: 2003/03/07 23:34:29; author: ktsaou; state: Exp; lines: +7 -5 'helpme' now allows ICMP traffic by default. ---------------------------- revision 1.108 date: 2003/03/07 23:17:38; author: ktsaou; state: Exp; lines: +15 -15 Fixed double quoting in router statements produced by 'helpme'. ---------------------------- revision 1.107 date: 2003/03/07 23:12:15; author: ktsaou; state: Exp; lines: +15 -7 'helpme' handles multiple networks in router statements. ---------------------------- revision 1.106 date: 2003/03/07 23:01:31; author: ktsaou; state: Exp; lines: +6 -6 'helpme' mode does not require a configuration file present. ---------------------------- revision 1.105 date: 2003/03/07 09:19:19; author: ktsaou; state: Exp; lines: +6 -6 Made it not ignore the default route in 'helpme' routers. ---------------------------- revision 1.104 date: 2003/03/06 08:18:49; author: ktsaou; state: Exp; lines: +17 -14 Minor changes in 'helpme' generation. ---------------------------- revision 1.103 date: 2003/03/05 22:06:51; author: ktsaou; state: Exp; lines: +23 -14 Made it ignore a default gateway when there was a P-t-P default gateways found. ---------------------------- revision 1.102 date: 2003/03/05 18:23:57; author: ktsaou; state: Exp; lines: +106 -72 Made the 'helpme' feature append another interface for the default gateway. ---------------------------- revision 1.101 date: 2003/03/05 00:33:56; author: ktsaou; state: Exp; lines: +23 -10 Minor changes in the default help page presented by FireHOL. ---------------------------- revision 1.100 date: 2003/03/05 00:11:56; author: ktsaou; state: Exp; lines: +232 -154 Re-wrote 'helpme' to detect multiple IPs and networks per interfaces, and to produce multiple interfaces for each IP. This means that FireHOL is somewhat smart to match IPs with networks and interfaces, to detect networks behind gateways, default gateways on point-to-point interfaces, and to produce router statements matching the interfaces detected above. ---------------------------- revision 1.99 date: 2003/03/03 21:51:04; author: ktsaou; state: Exp; lines: +22 -10 Made 'helpme' ignore interfaces that do not have an IP or no traffic is routed to them (no route). ---------------------------- revision 1.98 date: 2003/02/26 22:26:16; author: ktsaou; state: Exp; lines: +6 -6 Minor changes in 'helpme' and changes in documentation to reflect the 'helpme' feature addition. ---------------------------- revision 1.97 date: 2003/02/25 21:35:06; author: ktsaou; state: Exp; lines: +151 -61 'helpme' now produces router statements for each network each interface is attached to. This produces templates to be used in cases where one interface is used for routing traffic between multiple networks. Additionally, 'helpme' produces example SNAT statements to be used instead of masquerade when the IPs of the interfaces are statically assigned. ---------------------------- revision 1.96 date: 2003/02/24 23:30:21; author: ktsaou; state: Exp; lines: +48 -58 The helpme wizard now detects interfaces using: ip link show detects interface IPs using: ip addr show and detects interface networks using: ip route show This makes the 'helpme' wizard support any kind of interfaces, configurations and interfaces aliases. ---------------------------- revision 1.95 date: 2003/02/22 03:50:55; author: ktsaou; state: Exp; lines: +15 -7 Minor changes to helpme output. ---------------------------- revision 1.94 date: 2003/02/22 03:41:16; author: ktsaou; state: Exp; lines: +203 -33 The helpme command line argument is now somewhat useful. It produces a FireHOL configuration file in standard output. ---------------------------- revision 1.93 date: 2003/02/21 23:47:22; author: ktsaou; state: Exp; lines: +6 -5 Added a modprobe ip_tables before iptables-save to make sure that the later will not fail during boot. ---------------------------- revision 1.92 date: 2003/02/20 22:32:56; author: ktsaou; state: Exp; lines: +126 -5 Fixed snmptrap and syslog. Added the still 'under construction' wizard mode. ---------------------------- revision 1.91 date: 2003/02/18 20:42:20; author: ktsaou; state: Exp; lines: +4 -4 Updated RESERVED_IPS according to the latest IANA Reserved IPv4 address space. ---------------------------- revision 1.90 date: 2003/02/11 22:20:07; author: ktsaou; state: Exp; lines: +25 -9 Added /sbin in front of two sysctl statements that were producing errors in a few systems. Added control option FIREHOL_LOG_LEVEL and the optional argument 'level' to the 'log' parameter in order to accept custom log levels per rule. Now, to have different log levels, one could write: server dhcp accept log "my-dhcp" src 1.1.1.1 to get the default controlled by FIREHOL_LOG_LEVEL, or server dhcp accept log "my-dhcp" level critical src 1.1.1.1 Note that the 'level' is NOT a FireHOL optional rule parameter. It is an optional argument to the 'log' parameter. This for example is invalid: server dhcp accept level critical log "my-dhcp" src 1.1.1.1 The new definition of the 'log' optional rule parameter is: log "some text" [level a_level] ---------------------------- revision 1.89 date: 2003/02/03 23:11:49; author: ktsaou; state: Exp; lines: +52 -3 Added service emule. ---------------------------- revision 1.88 date: 2003/01/30 21:39:36; author: ktsaou; state: Exp; lines: +6 -6 Fixed a typo. ---------------------------- revision 1.87 date: 2003/01/30 21:36:07; author: ktsaou; state: Exp; lines: +65 -15 Added TOS and MARK actions in FireHOL's core to support Type-Of-Service and MARKing (for traffic shapping) in the future. Also, added an error handler that detects use of SNAT, DNAT, REDIRECT outside the 'nat' table and TOS, MARK outside the 'mangle' table. ---------------------------- revision 1.86 date: 2003/01/29 23:19:20; author: ktsaou; state: Exp; lines: +26 -12 The nat helper was wrongly producing duplicate logs when log/loglimit was present in the optional rule parameters. Fixed. ---------------------------- revision 1.85 date: 2003/01/28 19:47:31; author: ktsaou; state: Exp; lines: +4 -4 Made masquerade handle correctly interfaces given directly to it. ---------------------------- revision 1.84 date: 2003/01/28 19:42:09; author: ktsaou; state: Exp; lines: +4 -4 Made it handle the 'reverse' keyword of masquerade correctly. ---------------------------- revision 1.83 date: 2003/01/25 02:33:59; author: ktsaou; state: Exp; lines: +77 -36 FireHOL now supports runtime ERRORs and WARNINGs. ERRORs are assumed to be situations where FireHOL cannot continue, and it will exit just after restoring the previous firewall. WARNINGs are situations where FireHOL cannot determine if the firewall will or won't work, and it will just present the warning and continue. ---------------------------- revision 1.82 date: 2003/01/25 01:46:11; author: ktsaou; state: Exp; lines: +15 -9 Made FireHOL not stop processing if some required kernel module is not present. This behaviour is required when the required module is compiled in the kernel, instead of being a module. However, FireHOL still calls /sbin/modprobe which will print some error to the console (this will not make FireHOL stop functioning). ---------------------------- revision 1.81 date: 2003/01/25 00:37:37; author: ktsaou; state: Exp; lines: +25 -9 Added redirect helper to implement port redirections. ---------------------------- revision 1.80 date: 2003/01/22 21:14:21; author: ktsaou; state: Exp; lines: +4 -4 Fixed a small typo. ---------------------------- revision 1.79 date: 2003/01/22 21:02:43; author: ktsaou; state: Exp; lines: +11 -5 Added some comments to the just added code. ---------------------------- revision 1.78 date: 2003/01/22 20:54:05; author: ktsaou; state: Exp; lines: +56 -93 Fixed a bug in 'REJECT with auto' that made FireHOL produce wrong iptables statements in some versions of BASH. Fixed a problem of some early 2.4 kernels where not all mangle default chains are defined. Now, FireHOL detects which chains are present. ---------------------------- revision 1.77 date: 2003/01/22 19:13:27; author: ktsaou; state: Exp; lines: +5 -5 Some text changes. ---------------------------- revision 1.76 date: 2003/01/20 22:10:56; author: ktsaou; state: Exp; lines: +15 -5 Allowed multiple 'to' arguments to DNAT and SNAT. ---------------------------- revision 1.75 date: 2003/01/20 21:50:36; author: ktsaou; state: Exp; lines: +6 -3 Added service cvspserver as suggested by Florian Thiel ---------------------------- revision 1.74 date: 2003/01/16 00:55:36; author: ktsaou; state: Exp; lines: +38 -27 Made snat and dnat use one core function named 'nat'. ---------------------------- revision 1.73 date: 2003/01/16 00:33:26; author: ktsaou; state: Exp; lines: +166 -70 Added experimental "snat" and "dnat" helpers. ---------------------------- revision 1.72 date: 2003/01/14 21:49:23; author: ktsaou; state: Exp; lines: +5 -5 *** empty log message *** ---------------------------- revision 1.71 date: 2003/01/13 23:31:03; author: ktsaou; state: Exp; lines: +406 -281 Added user (uid), group (gid), process (pid), session (sid) to optional rule parameters. Modified FireHOL to apply such parameters only to traffic send by the localhost and silently ignore them on incoming and passing through traffic. ---------------------------- revision 1.70 date: 2003/01/08 23:33:25; author: ktsaou; state: Exp; lines: +68 -6 Added detection of overwritten optional rule parameters. ---------------------------- revision 1.69 date: 2003/01/08 22:42:46; author: ktsaou; state: Exp; lines: +9 -6 changed helpers to overwrite illegal optional parameters in order to avoid building rules that match nothing. transparent_squid now passes some rule parameters to the rules matching the user ids. This makes it possible to use succesfully negative rules, such as: dst not "A B C" to make the transparent cache exclude these. ---------------------------- revision 1.68 date: 2003/01/07 20:21:57; author: ktsaou; state: Exp; lines: +39 -30 Made transparent_squid accept multiple users ---------------------------- revision 1.67 date: 2003/01/07 01:51:47; author: ktsaou; state: Exp; lines: +4 -22 Made internal parameters of masquerade to overwrite its optional ones. Made the version command optional. ---------------------------- revision 1.66 date: 2003/01/06 16:13:34; author: ktsaou; state: Exp; lines: +186 -93 The previous implementation of the "with" parameter was conflicting with negative expressions. Fixed. Now each action (ACCEPT, REJECT, etc) can have each own optional rule parameters. Currently only REJECT (with) and REDIRECT (to-port) have such parameters. Implemented the REDIRECT action (usefull in NAT). Introduced a new concept in FireHOL: helpers Helpers are functions that do some job for you, like a shortcut. Implemented the transparent_squid helper. ---------------------------- revision 1.65 date: 2003/01/06 01:16:41; author: ktsaou; state: Exp; lines: +19 -3 I have added a not-to-be-documented command line argument: gimme-the-services-defs An application can choose to run FireHOL with this argument to have all the service definitions FireHOL knows in the environment variables. ---------------------------- revision 1.64 date: 2003/01/06 00:41:10; author: ktsaou; state: Exp; lines: +736 -671 Changed the method with which the current command line was saved for the error handler. The new way saved a fork() and gave some speed improvements. Re-arranged the code so that the global variables and the services definitions will be at the top of the file firehol.sh Developed a work-around for a bug in iptables-save where: ! --uid-owner A was saved as --uid-owner !A which was giving errors during restoration. Unfortunatelly this made firehol saving the running firewall without the use of /etc/init.d/iptables save. The "save" argument to firehol saves the firewall to: /etc/sysconfig/iptables ---------------------------- revision 1.63 date: 2003/01/05 20:03:07; author: ktsaou; state: Exp; lines: +29 -3 Added service ping ---------------------------- revision 1.62 date: 2003/01/03 23:34:37; author: ktsaou; state: Exp; lines: +16 -4 Added protocols as services: ICMP, AH, GRE, ESP ---------------------------- revision 1.61 date: 2003/01/01 04:32:48; author: ktsaou; state: Exp; lines: +6 -3 Added service: microsoft_ds ---------------------------- revision 1.60 date: 2003/01/01 03:12:17; author: ktsaou; state: Exp; lines: +51 -38 FireHOL has been changed to be "smart" when REJECTing packets. If the packet to be rejected is a TCP packet, it will send back a tcp-reset message, while for any other protocol it will send icmp-port-unreachable. This is now the default behavior, without specifing a 'with' parameter. Also, the multicast service has been changed to additionally match protocol No 2. ---------------------------- revision 1.59 date: 2002/12/31 09:10:15; author: ktsaou; state: Exp; lines: +20 -12 Extended REJECT control ('with' parameter) to work on 'policy' and on the default firewall policies. ---------------------------- revision 1.58 date: 2002/12/31 08:55:42; author: ktsaou; state: Exp; lines: +19 -4 Added optional rule parameter "with" which is only valid just after the action "REJECT" on all rules. "with" allows finer control over the method of packet rejection. ---------------------------- revision 1.57 date: 2002/12/23 14:39:19; author: ktsaou; state: Exp; lines: +609 -501 Code cleanup and code comments ---------------------------- revision 1.56 date: 2002/12/23 13:49:09; author: ktsaou; state: Exp; lines: +27 -4 Error handles now shows the command line that generated the error as-is in the configuration file. ---------------------------- revision 1.55 date: 2002/12/22 14:02:54; author: ktsaou; state: Exp; lines: +6 -3 Added service APCUPSDNIS. ---------------------------- revision 1.54 date: 2002/12/20 20:31:11; author: ktsaou; state: Exp; lines: +10 -6 Added variable FIREHOL_AMANDA_PORTS to control which ports amanda has been compiled with. Added service CUPS. ---------------------------- revision 1.53 date: 2002/12/19 22:52:15; author: ktsaou; state: Exp; lines: +43 -3 Added service AMANDA. ---------------------------- revision 1.52 date: 2002/12/18 23:36:07; author: ktsaou; state: Exp; lines: +98 -42 Fixed a bug in command line parsing when there was a configuration file specified in the command line together with a command. Now, when a filename is specified only three commands are valid: debug, try, start Fixed error handling to detect errors in a few functions that were ignored. Updated documentation to reflect the above changes. Updated interactive mode help and added directive 'in' as a shortcut to interface eth0 internet ---------------------------- revision 1.51 date: 2002/12/18 22:05:37; author: ktsaou; state: Exp; lines: +20 -5 Enhanced the error handler to detect errors separately for each protection. ---------------------------- revision 1.50 date: 2002/12/18 20:44:08; author: ktsaou; state: Exp; lines: +78 -71 Fixed a potential security hole where UDP traffic could come in uncoditionally from source port 53 when there was a: client dns accept This means that DNS is back to statefull mode. Also, removed from ICMP the RELATED state, since it will be matched at the end of the end of the interface or firewall. ---------------------------- revision 1.49 date: 2002/12/18 20:18:53; author: ktsaou; state: Exp; lines: +13 -5 Fixed active FTP bug. It was not working. ---------------------------- revision 1.48 date: 2002/12/18 00:35:42; author: ktsaou; state: Exp; lines: +7 -3 Added help entry for explain. ---------------------------- revision 1.47 date: 2002/12/18 00:30:28; author: ktsaou; state: Exp; lines: +67 -13 More changes regarding explain. Added interactive commands 'help', 'show' and 'quit'. Now the interactive mode automatically generates a configuration file from all the successfull commands. Made interactive mode accept variable definitions and loops. ---------------------------- revision 1.46 date: 2002/12/17 20:47:34; author: ktsaou; state: Exp; lines: +100 -24 Added command line argument "explain" to run in interactive debugging mode. This resulted in discovering bugs in NFS (fixed) and masquerade (fixed). Also, enriched the error handler to be more descriptive about what FireHOL is doing. ---------------------------- revision 1.45 date: 2002/12/16 20:41:39; author: ktsaou; state: Exp; lines: +56 -86 Added service DHCP Relay. Made kernel modules loaded during run time. Saving of old firewall takes now place before processing the configuration file, in order to make sure it will not be altered by accident due to some illegal commands in the configuration file. FireHOL enables kernel routing automatically when there is at least a router defined in the configuration. Now the configuration accepts command line arguments given to FireHOL. To send a set of arguments to the script, either just append them to FireHOL command line or (in case it is not clear if the argument is going to be used by FireHOL or the configuration) precede the configuration arguments by -- (two dashes). ---------------------------- revision 1.44 date: 2002/12/16 18:57:30; author: ktsaou; state: Exp; lines: +12 -12 Restored gawk stuff to previous methodology, using <<"EOF" since escaping produced warnings in debian systems. ---------------------------- revision 1.43 date: 2002/12/13 21:52:19; author: ktsaou; state: Exp; lines: +13 -17 Further optimizations in the error handler. ---------------------------- revision 1.42 date: 2002/12/13 19:56:11; author: ktsaou; state: Exp; lines: +93 -113 Made tons of optimizations for better FireHOL speed. ---------------------------- revision 1.41 date: 2002/12/12 20:07:47; author: ktsaou; state: Exp; lines: +22 -4 Added services: APTPROXY, APCUPSD, ISAKMP Removed Service: TFTP ---------------------------- revision 1.40 date: 2002/12/11 20:51:38; author: ktsaou; state: Exp; lines: +4 -4 Changed service submission to be presented by number instead of name because debian does not have this service in /etc/services. ---------------------------- revision 1.39 date: 2002/12/10 23:31:32; author: ktsaou; state: Exp; lines: +3 -3 Made default protections burst 50. ---------------------------- revision 1.38 date: 2002/12/10 23:08:07; author: ktsaou; state: Exp; lines: +5 -3 Added FIREHOL_LOG_FREQUENCY and FIREHOL_LOG_BURST to allow control on the frequency of the loglimit rule parameter. ---------------------------- revision 1.37 date: 2002/12/10 18:10:38; author: ktsaou; state: Exp; lines: +4 -4 Fixed a bug in netbios_ns ---------------------------- revision 1.36 date: 2002/12/09 21:13:35; author: ktsaou; state: Exp; lines: +9 -9 Fixed a typo in protections, that made them unusable in the previous version. ---------------------------- revision 1.35 date: 2002/12/08 22:05:40; author: ktsaou; state: Exp; lines: +8 -2 The command line argument stop was not working. Fixed. ---------------------------- revision 1.34 date: 2002/12/07 18:12:43; author: ktsaou; state: Exp; lines: +26 -13 Now protections can be applied on both directions of a router. When running firehol with a configuration file as the first argument, now you can specify an action (start, debug, try, etc) as the second argument. ---------------------------- revision 1.33 date: 2002/12/07 00:47:30; author: ktsaou; state: Exp; lines: +27 -174 Re-organized parameters parsing to prevent processing a possible file in the current directory with filename the name of the FireHOL command. Now FireHOL locks the subsys firehol, in addition to iptables. ---------------------------- revision 1.32 date: 2002/12/05 09:23:36; author: ktsaou; state: Exp; lines: +31 -2 Added many new services. ---------------------------- revision 1.31 date: 2002/12/05 09:03:37; author: ktsaou; state: Exp; lines: +13 -3 The problem with line numbers on debian systems found to be an awk alternative those systems use. Now FireHOL uses gawk instead of awk. Added service SUBMISSION (SMTP or SSL/TLS). ---------------------------- revision 1.30 date: 2002/12/04 23:12:10; author: ktsaou; state: Exp; lines: +35 -2 Fixed a problem where empty parameters to src, dst, etc where not giving an error and where not producing any iptables statements. This was happening because FireHOL relies on nested BASH loops, and bash does not loop with empty iterations... ---------------------------- revision 1.29 date: 2002/12/04 22:41:13; author: ktsaou; state: Exp; lines: +155 -114 Re-wrote the negative expressions handling to archieve near hand-made (i.e. optimum) quality of iptables firewall. Now, instead of the linked-list that was created for negative expressions, we match all positive expressions before the negatives and all the negatives are together in one chain. This also fixed possible performance problems due to the large number of chains and rules that the packets had to traverse in order to get matched (or not matched). The fact that now positive rules are matched before negatives has also the benefit that not all traffic has to be matched against the negatives. Now, first we select what might be good for a rule, and then we check if this breaks the negative expressions. Last, this made the iptables firewall much more clear and human readable. ---------------------------- revision 1.28 date: 2002/12/04 21:32:26; author: ktsaou; state: Exp; lines: +17 -14 Fixed a bug that FireHOL was incorrectly choosing LOCAL_CLIENT_PORTS on router configurations. This bug appeared when the router configurations were made to accept normal server/client statements. ---------------------------- revision 1.27 date: 2002/12/04 07:20:19; author: ktsaou; state: Exp; lines: +13 -2 Error handler now works on protections too. ---------------------------- revision 1.26 date: 2002/12/03 22:49:16; author: ktsaou; state: Exp; lines: +75 -20 Changed the banner to be much more descriptive. It now also shows the services FireHOL supports (removed the services parameter). ---------------------------- revision 1.25 date: 2002/12/03 22:07:09; author: ktsaou; state: Exp; lines: +12 -3 Fixed the usage banner to show the "services" parameter. ---------------------------- revision 1.24 date: 2002/12/03 22:03:00; author: ktsaou; state: Exp; lines: +87 -7 Another work around to fix the problem of LINENO not working in debian systems. Added command line argument "services" which shows all the service definitions firehol knows about. ---------------------------- revision 1.23 date: 2002/12/02 17:48:41; author: ktsaou; state: Exp; lines: +13 -8 Fixed a bug where some versions of BASH do not handle correctly cat >>"EOF". They treat it as cat >>EOF and thus they do variable substitution on the text. Now, FireHOL uses cat >>EOF but the text has been escaped in order to avoid variable substitution. The problem has been reported by Florian Thiel . ---------------------------- revision 1.22 date: 2002/12/02 00:01:24; author: ktsaou; state: Exp; lines: +14 -7 Fixed parameter 'custom' processing. It is not an array now, but it is treated specially to support BASH special characters such as ! Quoting things in parameters 'custom' needs tweaking still. ---------------------------- revision 1.21 date: 2002/12/01 04:34:00; author: ktsaou; state: Exp; lines: +48 -61 More quoting issues fixed. Changed the core to work with BASH arrays in order to handle quoted arguments accurately. Fixed a bug in postprocessing error handler that did not present the command line that produced the error. ---------------------------- revision 1.20 date: 2002/11/30 22:53:55; author: ktsaou; state: Exp; lines: +235 -186 Fixed various problems related to quoted arguments. Fixed iptables generation to support quoted arguments. Made chain names shorter. Every single element in the firehol config now gets its own chain. Previously, the same services (e.g. smtp servers) were implemented using only one pair of chains. Enhanced the error handler of logical and syntactical error. Now it says were and why an error has occured. ---------------------------- revision 1.19 date: 2002/11/30 14:33:33; author: ktsaou; state: Exp; lines: +77 -57 As suggested by Florian Thiel : a. Fixed service IRC to work on TCP instead of UDP. b. Added services: UUCP, VNC, WEBCACHE, IMAPS, IKE. Also fixed the home-router.conf example (it was outdated). ---------------------------- revision 1.18 date: 2002/11/03 13:17:39; author: ktsaou; state: Exp; lines: +30 -10 Minor aesthetic changes. ---------------------------- revision 1.17 date: 2002/11/01 19:37:20; author: ktsaou; state: Exp; lines: +82 -1 Added service: any Any allows the administrator to define any stateful rule to match services that cannot have source and destination ports, such as unusual protocols, etc. Syntax: type any name action [optional rule parameters] type: server/client/route name: the name for the service (used for the chain) action: accept, reject, etc. Added service: multicast Multicast allows the administrator to match packets with destination 224.0.0.0/8 in both directions (input/output). ---------------------------- revision 1.16 date: 2002/10/31 15:31:52; author: ktsaou; state: Exp; lines: +61 -13 Added command line parameter 'try' (in addition to 'start', 'stop', etc) that when used it activates the firewall and waits 30 seconds for the administrator to type 'commit' in order to keep the firewall active. If the administrator does not write 'commit' or the timeout passes, FireHOL restores the previous firewall. Also, if you break (Ctrl-C) FireHOL while activating the new firewall, FireHOL will restore the old firewall. ---------------------------- revision 1.15 date: 2002/10/30 23:25:07; author: ktsaou; state: Exp; lines: +80 -61 Rearranged default RELATED rules to match after normal processing and protections. Made the core of FireHOL operate on multiple tables (not assuming the rules refer to the 'filter' table). This will allow FireHOL to support all kinds of NAT chains in the future. ---------------------------- revision 1.14 date: 2002/10/29 22:20:41; author: ktsaou; state: Exp; lines: +79 -27 Client and server keywords now work on routers too. (The old 'route' subcommand is an alias for the 'server' subcommand - within a router). Protection can be reversed on routers to match outface instead of inface. Masquerade can be used in interfaces, routers (matches outface - but can be reverse(ed) to match inface) or as a primary command with all the interfaces to be masqueraded in an argument. ---------------------------- revision 1.13 date: 2002/10/28 19:47:02; author: ktsaou; state: Exp; lines: +31 -27 Protection has been extented to work on routers too. Made a few minor aesthetic changes on the generated code. Now in/out chains on routers match the inface/outface correctly. ---------------------------- revision 1.12 date: 2002/10/28 18:45:54; author: ktsaou; state: Exp; lines: +35 -14 Added support for ICMP floods protection and from BAD TCP flags protection. This was suggested by: Fco.Felix Belmonte (ffelix@gescosoft.com). ---------------------------- revision 1.11 date: 2002/10/27 12:47:48; author: ktsaou; state: Exp; lines: +5 -0 Added CVS versioning to all files. ---------------------------- revision 1.10 date: 2002/10/27 02:49:34; author: ktsaou; state: Exp; lines: +66 -5 Added service IRC. Extended kernel modules handling to simple services too. Simple services can now have: require_myservice_modules="module" require_myservice_nat_modules="module" in order to have these modules installed if and when "myservice" is used. Added the "masquerade" interfaces subcommand, that gives a shortcut to masquerade on the output of an interface. FireHOL, now have a separate rule to match all RELATED sockets on all chains. This is always added at the top of the firewall. FireHOL, now DROPs all INVALID packets, as suggested by the iptables HOW-TO. Various other minor enhancements. ---------------------------- revision 1.9 date: 2002/10/26 15:14:52; author: ktsaou; state: Exp; lines: +40 -26 Added logging options support as suggested by: Fco.Felix Belmonte ---------------------------- revision 1.8 date: 2002/10/24 21:10:01; author: ktsaou; state: Exp; lines: +86 -9 Removed service TFTP since this requires a kernel module for stateful operation. After suggestions by Fco.Felix Belmonte (ffelix@gescosoft.com), I have added: a) RESERVED_IPS, PRIVATE_IPS, MULTICAST_IPS and UNROUTABLE_IPS You can use the above in SRC (not) parameters to match them. The use of UNROUTABLE_IPS is suggested for cases where an interface is exclusivelly public. b) kernel module requirements per complex service and for the configuration file as a whole. Now you can use: # one line for each module, somewhere in your config file require_kernel_module to have FireHOL require some kernel module to succesfully complete the firewall configuration. As an option for those running NAT, you can use: FIREHOL_NAT=1 # put this at the top of your config file to make the complex services require also the NAT modules for the services they implement. Finally, I have added a get-iana.sh script that produces one BASH statement for RESERVED_IPS. ---------------------------- revision 1.7 date: 2002/10/20 19:09:18; author: ktsaou; state: Exp; lines: +1 -1 Changed TFTP from TCP to UDP. ---------------------------- revision 1.6 date: 2002/10/11 21:09:11; author: ktsaou; state: Exp; lines: +18 -0 Added services RNDC, FINGER, ECHO, DAYTIME, NNTP ---------------------------- revision 1.5 date: 2002/10/04 17:35:49; author: ktsaou; state: Exp; lines: +137 -7 Fixed negative expressions in FireHOL statements. By default, when multiple instances of interfaces/ports/addresses exist FireHOL produces one rule for each instance. However when negative expressions were defined the previous approach was producing ORed iptables statements instead of ANDed statements. The new code, now produces linked lists of iptables chains for all negative expressions so that only if ALL the negative are matched, one rule for each positive expression will be produced. Example: interface eth0 myname src "1.1.1.1 2.2.2.2" This will correctly produce two indepedent rules, one for each IP address. But: interface eth0 myname src NOT "1.1.1.1 2.2.2.2" was incorrectly producing two indepedent rules. Now the later statement produces a linked list that first matches that the source of the packets is not 1.1.1.1, in which case it forwards the packets to the second chain in the lists that confirms that the packets are not comming from 2.2.2.2, which finally sends the packets to their destination to be checked if they are comming from eth0. Note: I don't know the overhead of this linked list thing. I hope iptables is fast enough... ---------------------------- revision 1.4 date: 2002/10/03 23:53:09; author: ktsaou; state: Exp; lines: +68 -58 Added control for unmatched packets using: UNMATCHED_INPUT_POLICY= UNMATCHED_OUTPUT_POLICY= UNMATCHED_ROUTER_POLICY= and removed DEFAULT_ROUTER_POLICY since iptables accepts only DROP and ACCEPT. To control what will happen to unmatched packets just set the above variables in /etc/firehol.conf Note that in any case (e.g. UMATCHED_ROUTER_POLICY=ACCEPT) the packets will still be logged to syslog. Made also various aesthetic changes in the code. Rules programmers can now include their service names in the ALL_SHOULD_ALSO_RUN variable and the "all" service will run them automatically. ---------------------------- revision 1.3 date: 2002/10/03 16:28:16; author: ktsaou; state: Exp; lines: +60 -7 Service ntp is now both TCP and UDP and accepts clients from default ports. DNS over TCP is stateful but over UDP is now not stateful. This will not bother your syslog if your DNS server fails to reply within the stateful UDP timeout of iptables. Added service rsync. Added service vmwareauth. Added service vmwareweb. Added DEFAULT_ROUTER_POLICY to control how firehol handles its routing. Fixed a bug where firehol script arguments were not passed to /etc/init.d/iptables. Increased version number to 5. ---------------------------- revision 1.2 date: 2002/09/08 12:05:10; author: ktsaou; state: Exp; lines: +28 -18 Release 4. Made it work on non RedHat systems. client/server/route now accept many services on the same line. Other minor fixes and enhancements. Verified NFS operation. ---------------------------- revision 1.1 date: 2002/09/05 20:57:59; author: ktsaou; state: Exp; branches: 1.1.1; Initial revision ---------------------------- revision 1.1.1.1 date: 2002/09/05 20:57:59; author: ktsaou; state: Exp; lines: +0 -0 First Public Release ============================================================================= firehol-1.297/README000066400000000000000000000043521225731333700140560ustar00rootroot00000000000000$Id: README,v 1.8 2013/01/06 23:49:08 ktsaou Exp $ FireHOL, an iptables stateful packet filtering firewall for humans! Copyright (C) 2003 - 2013 Costa Tsaousis LICENSE ------- 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 DOCUMENTATION ------------- If you received this program in as a RPM, documentation should be installed at /usr/share/doc/firehol-X.XX. Otherwise, documentation should be available in the doc/ directory of the .tar.bz2 archive you received. In any case, you can also find the documentation online, at: http://firehol.sf.net INSTALLATION ------------ To make FireHOL start at boot time you have to add it to the startup procedure of your operating system. Three things are needed to start FireHOL properly: 1. Move firehol.sh to the directory where your startup scripts exist and rename it to firehol (i.e. remove the .sh). 2. Make sure FireHOL is called with something like: /path/to/startup/scripts/firehol start 3. Make sure there is a valid configuration file in /etc/firehol/firehol.conf This is it. IMPORTANT NOTES --------------- If you decide to use FireHOL regularly (or permanently) you have to understand that it will control your firewall and therefore be a key point of your security. You should do something to be notified of bugs or other kind of problems as soon as they appear. I suggest to subscribe to the notification engine of freshmeat.net under this project or to monitor FireHOL's file releases at sourceforge.net. Both of these services will keep you anonymous (to me) but will update you if and when new releases become available. firehol-1.297/TODO000066400000000000000000000222551225731333700136700ustar00rootroot00000000000000$Id: TODO,v 1.19 2005/04/03 21:48:04 ktsaou Exp $ The following is a list of features I plan to add to FireHOL, assuming that my time permits and there is demand for them. The list appears in no particular order. 1.The ability to have multiple versions of the firewall in memory and "activate" them on demand. This can be done if each "start" of FireHOL produces all the iptables rules in one "numbered" iptables chain (in each build-in table and chain) and then switching by "firehol activate 1" and "firehol activate 2". This will also solve the issue that FireHOL allows all traffic during firewall activation. This will also provide a method for dynamic configuration of firehol, so that changes would be applied without stopping and restarting the whole firewall. 2.Protections on interfaces should operate only when the firewall is going to allow the traffic. Now, protections operate on a per network interface basis, before the firewall rules, which means that an attacker could just produce a denial of service attack on http by SYN-FLOODing port 32000. Of course, the attacker can always SYN-FLOOD the http service to make the firewall drop temporarily all connections anyway. So, this ToDo item is more like a "should be the optimum way", without meaning that it is not right now. 3.Extend HELPME to guess network broadcast network addresses too. 4.Bandwidth accounting support per firehol element. 5.Show the currently active connections from the connection tracker (like a network top). There are a few other tools for this, but ideally, our solution should show the active connections categorized according to firehol rules, not iptables rules. 6.Protections should be able to applied to each firehol element individualy. 7.Support groups of services. Today, an interface or a router is much like a group. Ideally, we should also support subgroups that will allow the sharing of common protections and src/dst restriction and in the future common NAT and bandwidth shapping values. ==> DONE <== 8. A Web interface for configuring FireHOL. 9. A secure mechanism for centralized control of a large number of Linux hosts and routers. 10. There should be a simple way to produce service variations. For example, "I need an http server running on port 81". Possibly with: server http/80=81 accept 11. FireHOL services should be left to an external directory when installation programs could just drop in files for adding services to FireHOL. ==> DONE <== Ideally, this should also allow a "service documentation navigrator", something like a dynamic services.html (from the web site) based on the services installed on the machine. 12. FireHOL's speed on processing configuration directives could be significantly improved if the rule() function is written in C. This will improve processing of FireHOL directives and will allow the rest of FireHOL to be compatible with faster sh versions (like ash). However, the absolute speed improvement will be accomplished only if the rule() is written in C and instead of producing iptables statements, it talks to the kernel to activate them at once (thus eliminating iptables user-land programs altogether...) 13. Split FireHOL into multiple programs each providing some of the functions already supported. The idea is that there should be a "library" of shell functions and then a few drivers that provide the functions of the current command line arguments to FireHOL. 14. Isolation of parts of the firewall and separate management for each. For example, the master configuration should state about interfaces and routers that all come from different files, and each of those could be started stopped and altered indepedently of the other. This will be very usefull for providing delegated administration to dedicated server hosting environments where each customer can control his own part of the firewall through a simple web interface. 15. Add support for psad by replacing the default log strings of the DROPs at the end of interfaces and the firewall to "DROP". 16. Change the way "debug" mode is handled so that the generated debug file can be run without FireHOL installed. This requires a change in the way FireHOL configuration settings are processed and the way it is inlined/sourced, since a few configuration settings affect the standard header ruleset generated. 17. Support for TCPMSS action. ==> DONE <== 18. Support for ULOG as rule parameter. 19. Support pre-defined rules to be loaded when the firewall is stopped. 20. Support for logging only NEW connections so that only connection attempts will be logged. Not every packet. 21. Support for POLICY-ACCEPT - DROP EXPLICITLY type of firewalls when the interface policy is 'accept'. This can be done only for interfaces, when the interface policy is 'accept' and should be implemented by ignoring the source ports of the request. 22. Support for ratelimiting NEW connections on ACCEPT. This can be done with something: server smtp accept with limit 10/s 50 ==> DONE <== 23. Allow limit as a second parameter to policy: Instead of this: interface ... policy drop ... server any myreject reject limit 5/s 5 Allow something like this: interface ... policy reject limit 10/s 10 then drop 24. Add the ability to log only specific states, for example to log only new requests. 25. Remove the need to have all the helpers at the top, and then the interface/router blocks. 26. Allow a firewall to be build in multiple runs of FireHOL, so that we can split the configuration in multiple files and process them individually. 27. Support newer netfilter modules: NETMAP The CONFIG_IP_NF_TARGET_NETMAP provides a target for the nat table. It creates a static 1:1 mapping of the network address, while keeping host addresses intact. It can be applied to the PREROUTING chain to alter the destination of incoming connections, to the POSTROUTING chain to alter the source of outgoing connections, or both (with separate rules). Examples: iptables -t nat -A PREROUTING -d 1.2.3.0/24 -j NETMAP --to 5.6.7.0/24 iptables -t nat -A POSTROUTING -s 5.6.7.0/24 -j NETMAP --to 1.2.3.0/24 IPRANGE This patch makes possible to match source/destination IP addresses against inclusive IP address ranges. Examples: iptables -A FORWARD -m iprange --src-range 192.168.1.5-192.168.1.124 -j ACCEPT iptables -A FORWARD -m iprange --dst-range 10.0.0.0-10.255.255.255 -j ACCEPT SAME CONFIG_IP_NF_TARGET_SAME is similar to SNAT/DNAT depending on chain: it takes a range of addresses (`--to 1.2.3.4-1.2.3.7') and gives a client the same source-/destination-address for each connection. It has a --nodst option to make it not use the destination-ip in the calculations when selecting the new source-ip It has support for multiple ranges, including 1-address ranges. NOTRACK This option adds a new 'raw' table to iptables. The raw table is the very first in netfilter (it even precedes the conntrack subsystem) and uses the PREROUTING and OUTPUT built-in chains. The NOTRACK target can be used to select which packets *not* to enter the conntrack/NAT subsystems. Please keep in mind: if you mark a packet with NOTRACK, then - all the conntrack functionalities are lost for the packet (ICMP error tracking, protocol helpers, etc) - all the NAT functionalities are also lost. Packets marked with NOTRACK can be matched by the 'UNTRACKED' state using the state or conntrack matches. Example # Very busy webserver iptables -t raw -A PREROUTING -d 1.2.3.4 -p tcp --dport 80 -j NOTRACK iptables -t raw -A PREROUTING -s 1.2.3.4 -p tcp --sport 80 -j NOTRACK ... # filter rules iptables -A FORWARD -m state --state UNTRACKED -j ACCEPT SCTP This module helps to match SCTP packets based on the following criteria Destination Port: --dest-port Source Port: --source-port Chunk Types: --chunk-types (all|any|only) The flag letter in upper case indicates that the flag is to match if set, in the lower case indicates to match if unset. iptables -A INPUT -p sctp --dest-port 80 -j DROP iptables -A INPUT -p sctp --chunk-types any DATA,INIT -j DROP iptables -A INPUT -p sctp --chunk-types any DATA:Be -j ACCEPT REALM realm match: uses realm key from routing as match criteria similiar to one in packet classifier /** snip from packet classifier documentation */ Routing tables based classifier CONFIG_NET_CLS_ROUTE4 If you say Y here, you will be able to classify outgoing packets according to the route table entry they matched. If unsure, say Y. /** end snip **/ # Example # add route /sbin/ip route add 194.29.194.0/24 via 194.29.192.1 realm 10 # source realm is in realm with mask 0xFFFF0000, # destination is in realm with mask 0x0000FFFF # match destination realm /usr/local/sbin/iptables -A OUTPUT -m realm --realm 10 -j LOG # match realm of source, this is also determinated by routing, /usr/local/sbin/iptables -A INPUT -m realm --realm 655360 -j LOG THIS PATCH REQUIRES CONFIG_NET_CLS_ROUTE TO BE SET Note: With 2.6 CONFIG_NET_CLS_ROUTE is automatically selected. firehol-1.297/WhatIsNew000066400000000000000000000156361225731333700150010ustar00rootroot00000000000000$Id: WhatIsNew,v 1.12 2010/10/05 21:10:08 ktsaou Exp $ What Is New in public releases. ------------------------------- R5 v1.294, October 6, 2010 Added support for traffic shapping without marks (using marks already exists) using classify. Added support for stateful connection marking to assist the routing decision (e.g. when there are multiple upstream providers). Added more services: sane, ipsecnatt, l2tp. The services: amanda, ftp, pptp, tftp, h323, GRE, sip have been modified to use their respective netfilter kernel modules for matching the related traffic. Added support for NFLOG support for logging packet drops and syslog support for logging important administration events. Added tosfix, a helper that detects invalid TOS values and fixes them. Finally, updated get-iana to use the updated IANA page for IP reservations, fixed several minor bugs and issues reported. R5 v1.273, July 31, 2008 Updated to parse the latest format of the IANA reservations page. Added support for custom actions for services. This opens a way for allowing actions that can be controlled externally without restarting the firewall. Fixed several minor issues (better NAT support for all services, handling for external pager command, kernel config parsing, config wizard, etc). R5 v1.255, May 20, 2007 Fixed kernel 2.6.20+ compatibility issues. Fixed BASH 3.2 compatibility issues. Fixed iptables compatibility issues. FireHOL supports external definitions of RESERVED_IPS, PRIVATE_IPS, MULTICAST_IPS, UNROUTABLE_IPS in /etc/firehol. Also, complains if RESERVED_IPS is older that 90 days. Policy, now works on routers too. Updated services: nfs, OSPF, sip, vmwareweb, Added protections: bad-packets, all-floods Added actions: TARPIT Added support for the RECENT iptables module. Added addrtype support in optional rule parameters. Added FIREHOL_DROP_ORPHAN_TCP_ACK_FIN for busy servers. Added FIREHOL_LOG_PREFIX to improve logging. Fixed various minor bugs. R5 v1.226, Jan 30, 2005 Still there were issues with the temporary files. Fixed all of them for good. R5 v1.224, Jan 25, 2005 Added services ANYSTATELESS, TIMESTAMP, DICT. Added support for knockd (http://www.zeroflux.org/knock/). Fixed various minor bugs and eliminated all vulnerabilities where malicious local system users could use FireHOL's temporary files to overwrite arbitrary files on the system (http://secunia.com/advisories/13970/). R5 v1.214, Nov 1, 2004 This is a major release which includes several updates and fixes. All users are advised to update to this version. This release includes new service definitions: NIS, NUT, NNTPS, ASTERISK, DARKSTAT, DISTCC, ESERVER, GIFT, GIFTUI, H323, IAX, IAX2, ICP, RTP, SIP, STUN, UPNP, RDP, NXSERVER, RADIUSPROXY, RADIUSOLDPROXY. The following service definitions have been updated: DHCP, SAMBA, NFS. The following helpers have been added: TOS, DSCP, TCPMSS, ECN_SHAME. The following optional rule parameters have been added: TOS, MARK, DSCP. Added support for automatic installation of service definitions with third party packages, in /etc/firehol/services/. Also, FireHOL now has improved interoperability with various Linux distributions, including BASH 3.x, updated RESERVED_IPS for current IANA IPv4 reservations, finer control on ACCEPTed services to allow controllable requests per second, the ability to control loopback traffic and support for service groups. R5 v1.191, May 2, 2004 This release features more services, including ORACLE, GKRELLMD, DCC, WHOIS, fixed CUPS, enhanced SAMBA services, new optional rule parameters, including PHYSIN, PHYSOUT, updated MAC helper, better compatibility, better kernel module management, support for ULOG logging, better iptables statements generation, updated PRIVATE_IPS for IANA reservations, and various bug fixes. All users are advised to update to this version. R5 v1.159, Oct 10, 2003 This release features more services including MSN, DCPP, JABBER, JABBERD, WEBMIN, TIME, POSTGRES, HYLAFAX, XDMCP, TFTP, Veritas NetBackup, many updates and fixes to other services, three new helpers, the MAC helper (global pairing of MAC and IP addresses), the BLACKLIST helper (blacklist certain IPs - unidirectional or bidirectional), the MARK helper (mark packets for use by QoS), two new optional rule parameters, MAC (match source MAC address) and OWNER (match the user sending traffic), and it also provides better interoperability with various distributions (mainly Gentoo - also firehol now detects if all needed commands are present), more control on kernel module management (and better detection of iptables modules compiled in the kernel), more control on firewall status during a firewall restart, cleaner iptables commands generation, better support for kernel 2.6.x, and more. R5 v1.120, Apr 6, 2003 The main new feature of this release is the HELPME function that detects and produces the FireHOL configuration for the host run. Additionally, this release introduces a new PANIC mode which is now handled entirely by FireHOL, has better handling of the MIRROR target, has wider support for SNMPTRAP and SYSLOG, a definition for the SOCKS service, and better interoperability with various Linux distributions (i.e. Debian). R5, v1.91, Feb 18, 2003 This release adds support for controlling log levels on a per rule basis, updated RESERVED_IPS variable according to the latest releases of IANA, and a few minor fixes to increase compatibility on various Linux distributions. R5, v1.89, Feb 3, 2003 This release adds the service eMule (for clients, servers, and routers), supporting the bi-directional socket environment required by the popular eDonkey network client. R5, v1.88, Jan 30, 2003 This release fixes all reported problems related to NAT. FireHOL now fully supports DNAT, SNAT, REDIRECT, and MASQUERADE implemented as helper commands, and also the TRANSPARENT_SQUID helper for setting up transparent HTTP caches running on the firewall host (supporting transparent caching for traffic targeting, passing through, and originated from the firewall host). R5, v1.85, Jan 28, 2003 The masquerade helper has been fixed to handle the 'reverse' keyword correctly and accept the network interface as expected. R5, v1.83, Jan 27, 2003 This release adds support for NAT (SNAT, DNAT, and REDIRECT), support for the OWNER iptables module (user, group, session, and process), various error handler enhancements, support for runtime warnings (for missing kernel modules; it now runs on kernels compiled without modules), and a few workarounds for bugs in iptables-save (regarding the owner module). R5, v1.70, Jan 8, 2003 In this release the services ping, AH (IPSEC), ESP (IPSEC), GRE, and microsoft_ds have been added, the action REJECT has been changed to be "smart" and send TCP RST on TCP and ICMP port unreachable on all other protocols, various speed optimizations have been applied, and a "transparent_squid" helper has been added to take care of port forwarding for setting up a transparent cache. For files released before 2003, please check the ChangeLog file. firehol-1.297/adblock.sh000066400000000000000000000012461225731333700151300ustar00rootroot00000000000000#!/bin/sh # # $Id: adblock.sh,v 1.1 2003/10/07 23:42:17 ktsaou Exp $ # A script that will fetch the IPs of popular add servers. # # To use this, just put in your cron jobs, like this: # # 0 * * * * /path/to/adblock.sh >/etc/firehol/adblock-ips # # and then in your firehol.conf: # # source /etc/firehol/adblock-ips # # later in the config file you can use (for example) # # client http accept dst not "${ADSERVERS_IPS}" # # or even: # # blacklist full "${ADSERVERS_IPS}" # # printf "ADSERVERS_IPS=\"" printf "%q " `wget -q -O - "http://pgl.yoyo.org/adservers/iplist.php?ipformat=plain&showintro=0" | egrep -e "^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\$"` printf "\"\n" firehol-1.297/buildrpm.sh000066400000000000000000000044021225731333700153440ustar00rootroot00000000000000#!/bin/bash # $Id: buildrpm.sh,v 1.9 2004/11/01 00:23:08 ktsaou Exp $ # # This script will build a FireHOL RPM. # here=`pwd` if [ -z "$1" -o -z "$2" ] then printf "\n\nUSAGE: $0 version release\n\n" exit 1 fi files="firehol.sh .spec examples/client-all.conf" for x in $files do if [ ! -f $x ] then printf "\n\nPlease step into firehol directory before doing this.\n\n" exit 1 fi done myname="firehol-$1" rpmname="$myname-$2" printf "\nFireHOL RPM builder.\n" printf "====================\n\n" printf "This procedure will build the FireHOL RPM.\n\n" printf "During this, your installed FireHOL files might\n" printf "be overwritten.\n\n" printf "Are you sure you want to build '${rpmname}' ? (yes/no) > " read if [ ! "$REPLY" = "yes" ] then printf "ok. bye...\n\n" exit 1 fi backup="/etc/init.d/firehol.$$" backupconf="/etc/firehol/firehol.conf.$$" # backup the current files. test -f /etc/init.d/firehol && mv -f /etc/init.d/firehol "${backup}" test -f /etc/firehol/firehol.conf && mv -f /etc/firehol/firehol.conf "${backupconf}" # make the tmp dir test -d "/tmp/$myname" && rm -rf "/tmp/${myname}" mkdir -p "/tmp/${myname}" files=" README TODO COPYING ChangeLog WhatIsNew firehol.sh adblock.sh buildrpm.sh get-iana.sh man/firehol.1 man/firehol.conf.5 examples/client-all.conf examples/home-adsl.conf examples/home-dialup.conf examples/office.conf examples/server-dmz.conf examples/lan-gateway.conf doc/adding.html doc/commands.html doc/css.css doc/faq.html doc/fwtest.html doc/header.html doc/index.html doc/invoking.html doc/language.html doc/overview.html doc/services.html doc/search.html doc/support.html doc/trouble.html doc/tutorial.html " for x in $files do if [ ! -f "$x" ] then echo "Cannot find file: $x" exit 1 fi install -D -m 644 $x "/tmp/$myname/$x" done chmod 755 /tmp/$myname/*.sh # fix the rpm spec file cat .spec |\ sed "s/^Version: MYVERSION/Version: $1/" |\ sed "s/^Release: MYRELEASE/Release: $2/" >"/tmp/$myname/.spec" # make the tar cd /tmp tar jcpf "$myname.tar.bz2" "$myname" # make the rpm rpmbuild -tb "$myname.tar.bz2" # cd to the old directory cd "$here" # restore the original files. test -f "${backup}" && mv -f "${backup}" /etc/init.d/firehol test -f "${backupconf}" && mv -f "${backupconf}" /etc/firehol/firehol.conf firehol-1.297/check-iana.sh000077500000000000000000000031031225731333700155110ustar00rootroot00000000000000#!/bin/sh # $Id: check-iana.sh,v 1.2 2008/03/17 22:08:43 ktsaou Exp $ MYMAIL="$1" if [ -z "${MYMAIL}" ] then echo >&2 "Please set your e-mail." exit 1 fi IPV4_ADDRESS_SPACE_URL="http://www.iana.org/assignments/ipv4-address-space" ianafile=iana-reserved.txt spooldir=/var/spool/firehol mkdir -p "${spooldir}" || exit 1 cd "${spooldir}" || exit 1 wget -O - --proxy=off "${IPV4_ADDRESS_SPACE_URL}?" >"${spooldir}/${ianafile}.tmp" 2>/dev/null if [ ! -s "${spooldir}/${ianafile}.tmp" ] then logger -p alert -t FireHOL "Cannot fetch '${IPV4_ADDRESS_SPACE_URL}'." exit 1 fi if [ ! -s "${spooldir}/${ianafile}" ] then logger -p alert -t FireHOL "First fetch of '${IPV4_ADDRESS_SPACE_URL}'." mv -f "${spooldir}/${ianafile}.tmp" "${spooldir}/${ianafile}" exit 0 fi diff "${spooldir}/${ianafile}" "${spooldir}/${ianafile}.tmp" >/dev/null 2>&1 if [ $? -eq 0 ] then logger -p alert -t FireHOL "Page '${IPV4_ADDRESS_SPACE_URL}' not changed." exit 0 else cat < To: FireHOL Admins <${MYMAIL}> Errors-To: FireHOL Admins <${MYMAIL}> Subject: New IANA Reservations Detected! Dear admin, The following changes have been made at IANA Reservations page. `diff "${spooldir}/${ianafile}" "${spooldir}/${ianafile}.tmp"` You may have to update your firewall by running the get-iana.sh script. Regards, Your IANA Reservations Monitor EOF logger -p alert -t FireHOL "Changes detected in '${IPV4_ADDRESS_SPACE_URL}'. Mail sent to '${MYMAIL}'." mv -f "${spooldir}/${ianafile}.tmp" "${spooldir}/${ianafile}" exit 0 fi exit 1 firehol-1.297/doc/000077500000000000000000000000001225731333700137375ustar00rootroot00000000000000firehol-1.297/doc/adding.html000066400000000000000000000302251225731333700160550ustar00rootroot00000000000000 FireHOL, Adding new services to FireHOL.

It is very simple to extend FireHOL for simple single socket services. There are two different ways to do it.

The service definition syntax

The first needs a small service definition somewhere at the beginning of the FireHOL configuration file.

For example the following:

	server_myservice_ports="proto/sports"
	client_myservice_ports="cports"
Where:
  • myservice is the name of the service,
     
  • proto is either tcp, udp, icmp - or whatever else iptables accepts as protocol, including numeric representations of protocols
     
  • sports is the port number (or port name or port range) the server is listening at. To specify port ranges use the iptables syntax: i.e. 1000:1010 will match all ports from 1000 to 1010 inclusive.
    The special keyword any will match any server port.
     
  • cports is the port (or port name or port range or space separated list of ports) clients might use to connect to the server. There are two keywords that can be used for cports:
     
    • any is a keyword that matches any client port.
       
    • default is a keyword that matches the default client ports and it resolves to:
       
      • if it is used for a localhost client (i.e. client within an interface), it resolves to a list of ports as set by the Linux kernel and controlled by the sysctl variable net.ipv4.ip_local_port_range (or /proc/sys/net/ipv4/ip_local_port_range),
         
      • if it is used for a client running at remote host (i.e. server within an interface or any kind within a router), it resolves to the contents of the FireHOL variable DEFAULT_CLIENT_PORTS.
         
Just the above two lines will allow you to use (for example):
	interface eth0 internet
		server myservice accept
		client myservice reject
	
	router myrouter
		route myservice drop
later in the configuration file.

As an example, assuming that the IMAP4 service was not defined in FireHOL you would have to write:

	version 5
	
	server_imap_ports="tcp/143"
	client_imap_ports="default"
	
	interface eth0 lan0
		server imap accept
	
	interface eth1 lan1
		client imap reject
	
	router lan2lan inface eth0 outface eth1
		route imap accept

The inline service definition syntax

The second way is to use the inline service definition syntax:

		server custom myservice proto/sports cports accept
All the parameters are the same with the one presented above, in the previous section.

The IMAP4 service example above, now becomes:

	version 5
	
	interface eth0 lan0
		server custom imap tcp/143 default accept
	
	interface eth1 lan1
		client custom imap tcp/143 default reject
	
	router lan2lan inface eth0 outface eth1
		route custom imap tcp/143 default accept
So, if you are only going to need a service just once in your firewall, it might be convenient to use the inline syntax, while if you are going to need it many times, it would be easier to use the service definition syntax.
Personally, I always prefer to use the service definition syntax and to avoid the inline one (I always forget that the inline one requires a service name too...).

Multi-socket, but simple servers

Both of the expressions, given above for defining more services, accept multiple arguments.

Fox example, assume there is a service named serveme that listens at two ports, port 1234 TCP and 1234 UDP. The expected client ports are the default random ports a system may choose, plus the same port numbers the server is listening at.

To define this service you will have to write:

	version 5
	
	server_serveme_ports="tcp/1234 udp/1234"
	client_serveme_ports="default 1234"
		
	interface eth0 lan0
		server serveme accept
	
	interface eth1 lan1
		client serveme reject
	
	router lan2lan inface eth0 outface eth1
		route serveme accept
In this situation, FireHOL simply produces all the combinations between client and server ports and generates multiple iptables statements to accomplish them.

This is also the reason why the protocol cannot be defined in client ports.

Requiring kernel modules

Each service can be configured to require two sets of kernel modules depending whether NAT is enabled or not. This is done on a per service basis, so that if a service is not used in a configuration, FireHOL will not load the module.

The general format is:

	require_service_modules="some_module"
	require_service_nat_modules="some_module_for_nat"
As an example you can see the complete IRC definition within FireHOL:
	server_irc_ports="tcp/ircd"
	client_irc_ports="default"
	
	require_irc_modules="ip_conntrack_irc"
	require_irc_nat_modules="ip_nat_irc"
	
	ALL_SHOULD_ALSO_RUN="${ALL_SHOULD_ALSO_RUN} irc"
The last statement in the above example says to FireHOL, that if the configuration is using the all service, FireHOL should indirectly also setup the irc service with all the optional rule parameters of the all service.

Complex services

Complex services are those that use multiple sockets initiated on both directions (where the client becomes a server and vice versa) of the communication, and possibly involving protocols beyond TCP and UDP.

Currently you will have also to consider as complex all the services that you would prefer not to implement using the connection tracker of iptables (i.e. stateless). In the future, and if there is enough demand, I might expand simple services to handle stateless services too.

To write a complex service you will have to write a BASH function. It is not hard, but it is not two lines of code too, and most probably I am going to change the interface to those functions in the future, as FireHOL evolves. So, if you write one, please sumbit a patch so that I will be able to change your function if and when I change the interface to those functions.

Note however that there are a few types of currently complex services that I'll try to avoid. These are all those services that in order to be implemented in a stateful way there must exist a kernel module for them. If I support these services now, FireHOL will loose its beauty since it will have to have ranges of ports completely open to everyone just in case your service wants them. There are plenty of such kernel modules in an experimental state, which you can use if you decide to patch and recompile your kernel. If you do this, I'll be glad to support your stateful rules about them. If you try to allow such services in a stateless maner by, for example, allowing uncodintionally all traffic at high numbered ports... you are on your own.

If you decide to write a complex service, open FireHOL in your favorite editor and find all the functions that start with rules_. All these functions define rules for the complex services currently supported. If you know the basics of BASH programming, the existing functions will give you a clear idea of what you have to do to write your own.

Distribution of services with third party packages

FireHOL v1.213 and above includes a feature that allows third parties to install new service definitions in the directory /etc/firehol/services. The purpose of this feature is to allow the distributors of third party packages (like proxy servers, dns servers, etc) automatically install their service definitions in your system when their applications are installed.

To install a service definition, just create a file with any name, but with extension .conf in the directory /etc/firehol/services. The file itself must be a BASH script with any logic in it. The only requirements are:

  • The script sets up one or more service definitions, either in simple or complex form.
  • The first line of the script looks like this:

    #FHVER: 1:213

    The two numbers are the major and minor versions of the FireHOL service definition API. In fact, the major number (1) is increased if the API logic is changed, and the minor (213) is the minimum version of FireHOL the service is expected to work with.

    FireHOL will deny to run the service if the major number is different or if the installed version of FireHOL is older than the one expected by the service.


" echo >&2 "Closing ${last_letter}" last_letter= fi if [ ! -z "${1}" ] then lc=$[lc + 1] if [ $lc -eq 5 ] then echo "" echo >&2 "--- break ---" lc=1 fi printf >&2 "Openning ${1}... " last_letter=${1} echo "
$Id: adding.html,v 1.10 2004/10/31 23:43:25 ktsaou Exp $

FireHOL, a firewall for humans...
© Copyright 2004 Costa Tsaousis <costa@tsaousis.gr> firehol-1.297/doc/commands.html000066400000000000000000003142171225731333700164360ustar00rootroot00000000000000 FireHOL, Configuration commands

Table of Contents

  • Primary Commands
    • interface, control what the firewall host can do
    • router, control what traffic can pass through the firewall host
     
  • Sub-Commands  
  • Helper commands
    • action, setup custom filtering actions
    • blacklist, setup a unidirectional or bidirectional blacklist
    • classify, classify traffic for traffic shapping tools
    • connmark, set a statefull mark on a connection
    • dnat, setup a Destination NAT rule for routed traffic
    • dscp, set the DSCP field in the packet header, to a raw value or a DiffServ class
    • ecn_shame, disable ECN for all hosts in the ECN Shame list
    • iptables, add some custom iptables commands to the firewall
    • mac, setup a source mac address with IP match
    • mark, mark traffic for traffic shapping tools
    • masquerade, setup masquerading (NAT) to the output of a network interface
    • nat, setup a NAT rule for routed traffic
    • redirect, setup a port redirection rule
    • snat, setup a Source NAT rule for routed traffic
    • tcpmss, set the MSS of TCP SYN packets for routers
    • tos, set the Type of Service (TOS) field in the packet header
    • tosfix, fix the TOS value of packets
    • transparent_proxy, setup a transparent TCP proxy running on the firewall host
    • transparent_squid, setup a transparent web proxy running on the firewall host
    • version, require a specific version of FireHOL
     
  • Actions
    • accept, allow the traffic to reach its destination
    • reject, don't allow the traffic to pass, but send a rejection message to the sender
    • drop, discard the traffic without sending anything back to the sender
    • deny, an alias for drop
    • tarpit, tarpit TCP traffic making the remote client to timeout after several minutes
    • return, return to processing the parent flow of rules
    • mirror, send the traffic back to the sender at the port of the destination
    • redirect, redirect the traffic to another port on the local host
     
  • Optional Rule Parameters
    • src, match the source of traffic
    • dst, match the destination of traffic
    • srctype, match the source address type of traffic
    • dsttype, match the destination address type of traffic
    • inface, match the network interface traffic is received via
    • outface, match the network interface traffic is send via
    • physin, match the physical network interface (for bridges) traffic is received via
    • physout, match the physical network interface (for bridges) traffic is send via
    • custom, pass a few custom parameters to the generated iptables statements
    • log, write something to the syslog when traffic is matched
    • loglimit, write (limited) something to the syslog when traffic is matched
    • proto, match a specific protocol
    • limit, limit the frequency traffic is matched
    • sport, match the source ports
    • dport, match the destination ports
    • uid, user, match the users sending this traffic
    • gid, group, match the user groups sending this traffic
    • pid, process, match the process IDs sending this traffic
    • sid, session, match the process session IDs sending this traffic
    • cmd, command, match the command name sending this traffic
    • mac, match the source MAC address of packets.
    • mark, match the MARK ID of packets.
    • tos, match the Type of Service (TOS) of packets.
    • dscp, match the DSCP raw value or DiffServ class value of packets.
     
  • Variables that control FireHOL
     
  • Variables FireHOL offers
     
Primary Commands
Primary commands form groups of rules within a FireHOL firewall. The optional rule parameters given to the primary commands are indirectly applied to all sub-commands given within this primary command.

interface <real interface> <name> [optional rule parameters]

Description

The interface command creates a firewall for protecting the host the firewall is running, from the given interface.
The default interface policy is drop, so that if no subcommands are given, the firewall will just drop all incoming and outgoing traffic using this interface.

INPORTANT
Note that unlike ipchains, in iptables traffic passing through the firewall host (FORWARDed traffic) does not pass through the INPUT/OUTPUT chains of the firewall and therefore the interface rules in FireHOL never match it. To match the traffic passing through (even if DNATed) you have to place the filtering rules in router statements. Interface statements filter traffic only from/to the firewall host. Nothing else.

Parameters

  • real interface is the interface name as shown by ip link show. Generally anything iptables accepts, including the pattern character + (the plus sign), is valid.
    The plus sign after some text will match all interfaces that start with this text.
    It is allowed to use more than one interfaces separated by spaces, but all of them should be given within one quoted argument:
    Example: interface "eth0 eth1 ppp0" myname
     
  • name is a name for this interface.
    Generally you should use short names (10 characters max) without spaces or other symbols.
    You should not use the same name more than once in FireHOL primary commands.
     
  • optional rule parameters is a set of rules that allow further restriction of the traffic that gets matched for this interface. See Optional Rules Parameters for more information.
    Example 1: interface eth0 intranet src 10.0.0.0/16
    Example 2: interface eth0 internet src not "$UNROUTABLE_IPS" (note: UNROUTABLE_IPS is a variable defined by FireHOL that includes all IPs that should not be routable by the Internet).
     


router <name> [optional rule parameters]

Description

The router command creates a firewall for the traffic passing through the host running the firewall. The default policy on router commands is return. This means that by default no packets are dropped in a router. Packets not matched by any router command will be dropped at the end of the firewall. Change the default policy of a router only if you understand clearly what gets matched by the router statement. It is very common to have overlapping definitions of routers and changing this policy to anything other than the default may have strange results for your configuration. (Changing the policy on routers appeared in v1.248).

INPORTANT
Note that unlike ipchains, in iptables traffic passing through the firewall host (FORWARDed traffic) does not pass through the INPUT/OUTPUT chains of the firewall and therefore the interface rules in FireHOL never match it. To match the traffic passing through (even if DNATed) you have to place the filtering rules in router statements. Interface statements filter traffic only from/to the firewall host. Router statements filter traffic that passes through the firewall host.

Parameters

  • name is a name for this router.
    The same restrictions of interface names apply here too.
     
  • optional rule parameters is a set of rules that allow further restriction of the traffic that gets matched for this router. See Optional Rules Parameters for more information.
     
Router statements produce similar iptables commands the interface statements produce. For each router statement an in_<name> and an out_<name> chain are produced to match the traffic in both directions of the router.
To match some client or server traffic the administrator has to specify the input/output interface or the source/destination of the request. All inface/outface, src/dst optional rule parameters can be given either on the router statement in which case will be applied to all subcommands for this router, or on each subcommand within a router. Both are valid.
For example:
		router mylan inface ppp+ outface eth0
			server http accept
			client smtp accept
	
The above says: Define a router that matches all requests that originate from some PPP interface and go out to eth0.
There is an HTTP server in eth0 that client from the PPP interfaces are allowed to reach.
Clients on eth0 are allowed to get SMTP traffic from the PPP interfaces.

While:
		router mylan
			server http accept inface ppp+ outface eth0
			server smtp accept inface eth0 outface ppp+
	
The above says: Define a router that matches any kind of forwarded traffic.
For HTTP traffic the clients are on a PPP interface and the servers on eth0.
For SMTP traffic the clients are on a eth0 interface and the servers o a PPP interface.

Please note that in the second example the SMTP traffic is matched again with a server subcommand, not a client (as in the first example).

The client subcommand reverses all the optional rules that are applied indirectly to it. Indirect rule parameters are those that are inherited from the parent command (router in this case).
To make it simple, for FireHOL a client is: "a server with all the implicit optional rule parameters reversed".

So, in the first example, the client simply flipped the inface and outface rules defined at the router and became an SMTP server.
In the second example there is nothing to be flipped, so server and client are exactly the same.

I suggest to use client subcommands in routers only if you have inface/outface or src/dst in the router statements. If you are building routers like the second example, don't use client, it is confusing.

Older versions of FireHOL did not allow server and client subcommands in routers. Only the route subcommand was allowed. Today, route is just an alias for server and can be used only in routers, not interfaces.

Any number of router statements can exist. Since the policy is RETURN on all of them, any traffic not matched by a router will continue to be checked against the second.

Sub-Commands
Subcommands must be given within Primary commands.

policy <action>

Description

The policy subcommand defines the default policy for an interface.

This directive accepts all the actions specified in Actions.

Please note that FireHOL is only useful for "DROP/REJECT EVERYTHING, ALLOW EXPLICITLY" type of firewalls. By changing the policy to accept, you CANNOT create valid "ACCEPT EVERYTHING, DROP EXPLICITLY" firewalls.
The policy should be set to accept only if you really trust the hosts that can reach the machine via this interface. For information about this, see: Bug 927532.


protection [reverse] <type> [requests/sec [burst]]

Description

The protection subcommand sets a number of protection rules on an interface.

In router configurations, protections are setup on inface. The reverse keyword will make the protections setup on outface. Please note that the reverse keyword must be the first given. Otherwise it will not work.

type can be:

    strong, or full, or all
    turns on all the possible protections.
    Currently it includes: invalid fragments new-tcp-w/o-syn icmp-floods syn-floods malformed-xmas malformed-null malformed-bad.
    bad-packets
    turns on all the possible protections that detect bad packets based one the packet contents themselves, not the packets transfer rate.
    Currently it includes: invalid fragments new-tcp-w/o-syn malformed-xmas malformed-null malformed-bad.
    invalid
    Drops all incoming INVALID packets. Invalid packets are those that are matched by "-m state --state INVALID", so they are all those packets that the iptables connection tracker believes are INVALID.
    There is also the FIREHOL_DROP_INVALID variable which controls the same function globally, for the whole firewall.
    fragments
    Drops all packet fragments. Please note that most probably this rule will never match anything since iptables reconstructs all packets automatically, before the iptables firewall rules are processed, when its connection tracker is running.
    I left this here for psychological reasons and in case some one finds some use for it.
    new-tcp-w/o-syn
    Drops all TCP packets that initiate a socket but have no the SYN bit set.
    syn-floods
    Allows only a certain amount of new TCP connections per second. The optional two arguments [requests/sec] and [burst] are used by this rule in order to provide control on the number of connections to be allowed. The default is 100 connections per second that can match 50 (it was 4 in v1.38 and before) packets initially (this is implemented using the limit module of iptables: see man iptables for more).
    Note that this rule applies to all connections attempted regardless of their final result (rejected, dropped, established, etc). Therefore it might not be a good idea to set it too low.
    icmp-floods
    Allows only a certain amount of ICMP echo requests per second. The optional two arguments [requests/sec] and [burst] are used by this rule in order to provide control on the number of connections to be allowed. The default is 100 connections per second that can match 50 (it was 4 in v1.38 and before) packets initially (this is implemented using the limit module of iptables: see man iptables for more).
    all-floods
    Allows only a certain amount of new connections per second. The optional two arguments [requests/sec] and [burst] are used by this rule in order to provide control on the number of connections to be allowed. The default is 100 connections per second that can match 50 (it was 4 in v1.38 and before) packets initially (this is implemented using the limit module of iptables: see man iptables for more).
    Note that this rule applies to all connections attempted regardless of their final result (rejected, dropped, established, etc). Therefore it might not be a good idea to set it too low.
    malformed-xmas
    Drops all TCP packets that have all the TCP flags set.
    malformed-null
    Drops all TCP packets that have all the TCP flags unset.
    malformed-bad
    Drops all TCP packets that have illegal combinations of TCP flags set.


server <service> <action> [optional rule parameters]

Description

The server subcommand defines a server of a service. For FireHOL a server is the destination of a request, and even if this is more complex for multi-socket services, for FireHOL a server always accepts requests.

The optional rule parameters given to the parent primary command (interface or router) are inherited by the server as they have been given.


This subcommand can be used on both interfaces and routers.

Parameters

  • service is one of the supported service names.
    The command accepts more than one services in the same argument if they are separated by space and quoted as a single argument.
    Example 1: server smtp accept
    Example 2: server "smtp pop3 imap" accept
     
  • action tells FireHOL what to do with the traffic matching this rule.

    FireHOL supports the actions defined in the section Actions.
     

  • optional rule parameters is a set of rules that allow further restriction of the traffic that gets matched by this rule. See Optional Rules Parameters for more information.
    Example 1: server smtp accept src 1.2.3.4
    Example 2: server smtp accept log "its mail" src 1.2.3.4
     


client <service> <action> [optional rule parameters]

The client subcommand defines a client of a service. For FireHOL a client is the source of a request. FireHOL follows this simple rule even on multi-socket complex protocols, so that for FireHOL a client always sends requests.
The parameters are exactly the same with the server subcommand.

The optional rule parameters given to the parent primary command (interface or router) are inherited by the client, but they are reversed. For an explanation of this please refer to the documentation of the router primary command.


This subcommand can be used on both interfaces and routers.


route <service> <action> [optional rule parameters]

The route subcommand is an alias for the server command that can be used only on routers, not interfaces.


group with [optional rule parameters]

group end

The group subcommand allows grouping for server and client subcommands that share common optional rule parameters.

There is only one reason for using groups: Optimization of the generated firewall rules. With groups, all the optional rule parameters are checked only once, while entering the group, and then each service is applied without extra processing.

For example:


	interface any world
		server http accept
		
		# trusted services
		group with src "1.2.3.4 5.6.7.8"
			server ssh	accept
			server telnet	accept
		group end
		
		client all accept
The above will be optimal compared with server "ssh telnet" accept src "1.2.3.4 5.6.7.8".

FireHOL supports nested groups.

Helper Commands
Helper commands provide shortcuts for common functions not handled by the core of FireHOL's logic.

action [chain <name> <action>

The action helper creates an iptables chain which can be used to control the action of other firewall rules during runtime. For example, you can setup the custom action ACT1, which by default is ACCEPT, but under certain cases it can be changed to DROP, REJECT or RETURN without restarting the firewall.

The first argument must always be the word chain, for the moment.

  • name can be any chain name accepted by iptables. It is suggested to keep it between 5 to 10 letters.
     
  • action can be any action supported by FireHOL, although only ACCEPT, REJECT, DROP, RETURN may have any meaning under this use.
Example 1:

At the top of firehol.conf, create the action ACT1:

action chain ACT1 accept

later, in interfaces and routers, create rules that use the ACT1 action:

server smtp ACT1 client imap ACT1

Please note that actions created this way are case sensitive.
At some point, and while the firewall is running, the action ACT1 can be changed to DROP, with this linux command (this is not FireHOL specific):

iptables -t filter -I ACT1 -j DROP

The above command inserts (-I) the new action DROP above the default action ACCEPT, and therefore all the traffic matching the FireHOL rules that have the action ACT1 will now be dropped.
To return to the default action (ACCEPT), run the following linux command:

iptables -t filter -D ACT1 -j DROP

This command deletes (-D) the DROP action that was inserted above the default action. If you delete all actions in the chain ACT1, the default action will be RETURN, in which case all rules with action ACT1 will be neutralized (it will be the same as they were not specified at all in firehol.conf).

Example 2: action chain "ACT1 ACT2 ACT3" accept chain "ACT4 ACT5 ACT6" drop # will create 6 actions, ACT1, ACT2, ACT3 with ACCEPT and ACT4, ACT5, ACT6 with DROP


blacklist [option] <IPs>

The blacklist helper creates a blacklist for the IP addresses given. It supports two modes of operation based on the option given (or the absence of it).

The option can be:

  • one of the words them, him, her, it, this, these, input in which case it will generate a unidirectional statefull blacklist, meaning that you will be able to ask (initiate connections) anything from them, but they will not be able to ask (initiate connections) anything from you or the remote hosts you protect (routing).
     
  • one of the words all, full or ommitted (no option given), in which case FireHOL will create bidirectional stateless rules that will DROP all traffic comming in from these IPs and will REJECT all traffic going to them.
The blacklist helper affects both interfaces and routers and can be used as many times as needed, but before the first interface statement. The blacklist helper accepts multiple IPs both as one quoted and space separated list and as separate arguments.

Example 1: blacklist this "195.97.5.202 10.1.1.1" # please note the quotes
Example 2: blacklist full 195.97.5.202 10.1.1.1 # please note the absence of quotes


classify <CLASS> [optional rule parameters]

The classify helper classifies the traffic into a specific traffic shapping class.

Parameters

  • CLASS is a class, as accepted by iptables (i.e. MAJOR:MINOR).
     
  • optional rule parameters is a set of rules that allow further restriction of the traffic that gets matched by this rule. See Optional Rules Parameters for more information.
     

Example 1: classify 1:1 outface eth1 proto tcp dport 25, will send all smtp traffic going out via eth1 to class 1:1.


connmark <VALUE> <WHERE> [optional rule parameters]

The connmark helper is used to set a mark on a whole connection in both directions of the traffic automatically. The difference with mark is that the later just marks the packets matched by the optional rule parameters, while connmark marks the whole statefull connection.

Parameters

  • VALUE can be a mark value to set, or the words save to convert the existing mark of the packets to connmark, or restore to convert the existing connmark of the connection to a mark on the packets.
     
  • WHERE tells FireHOL where to search for the specific traffic to be marked.
    Currently, WHERE can be one of the build-in iptables chains attached to table mangle. (for example: INPUT, FORWARD, OUTPUT, PREROUTING, POSTROUTING - case does matter here).
     
  • optional rule parameters is a set of rules that allow further restriction of the traffic that gets matched by this rule. See Optional Rules Parameters for more information.
     

Example 1: Let's say that you have 3 ethernet interfaces: eth0, eth1 and eth2. eth0 connects you to the LAN, while eth1 and eth2 connect you to the internet via 2 different service providers. You want to guarrantee that when a connection is coming from provider 1 (eth1) will go back through this provider and the same for provider 2 (eth2).

Step 1: You mark the connections when they enter the firewall host from the provider interfaces:
connmark 1 PREROUTING inface eth1
connmark 2 PREROUTING inface eth2

Step 2: You restore the mark (from the connmark) when the packets come in from the LAN:
connmark restore OUTPUT
connmark restore PREROUTING inface eth0

Now you can use iproute2 to pick the right routing table (eth1 or eth2 and the default gateway) based on the MARK of the packets.

Example 2: connmark 1 PREROUTING inface eth1, Set the CONNMARK 1 to all packets coming in from eth1.
Example 3: connmark save PREROUTING inface eth1, Save the MARK value to the CONNMARK value on all packets coming in from eth1.


dnat [to] <target> [optional rule parameters]

The dnat helper sets up a Destination NAT rule for routed traffic, by calling
nat to-destination <target> [optional rule parameters]

See the nat helper.

Example: dnat to 1.1.1.1 inface eth0 src 2.2.2.2 dst 3.3.3.3


dscp <NUMBER> <WHERE> [optional rule parameters]


dscp class <CLASSID> <WHERE> [optional rule parameters]

The dscp helper sets the DSCP field in the header of the packets matching the optional rule parameters.

Parameters

  • NUMBER is a decimal or hex (0xNN) number to set the DSCP field to.
     
  • CLASSID is any of the iptables supported DiffServ class values (EF, BE, CSxx, AFxx - check iptables -j DSCP --help for more information).
     
  • WHERE tells FireHOL where to search for the specific traffic to be marked.
    Currently, WHERE can be one of the build-in iptables chains attached to table mangle. (for example: INPUT, FORWARD, OUTPUT, PREROUTING, POSTROUTING - case does matter here).
     
  • optional rule parameters is a set of rules that allow further restriction of the traffic that gets matched by this rule. See Optional Rules Parameters for more information.
     

Example 1: dscp 32 OUTPUT, will set the DSCP field to 32 of all packets sent by the local machine.
Example 2: dscp 0x20 FORWARD, will set DCSP to 0x20 (32) of all packets passing through the local machine.
Example 3: dscp class EF FORWARD proto tcp dport 25 dst 1.1.1.1 src 2.2.2.2, will set DSCP to DeffServ class EF for all packets sent by 2.2.2.2, passing through the local machine and targeting port TCP/25 of host 1.1.1.1.


ecn_shame

The ecn_shame helper checks if Explicit Congestion Notification (ECN) is enabled in the kernel, and if it is, it fetches the ECN Hall of Shame list and disables ECN for all hosts present in the list.


iptables <arguments>

Description

The iptables command passes all its arguments to the real iptables command, during run-time.

You should not use in FireHOL configurations /sbin/iptables or other means to alter a FireHOL firewall. If you do, your commands will be run before FireHOL activates its firewall and while the previous firewall is still running. Also, since FireHOL will delete all previous firewall rules in order to activate the new firewall, any changes you will make, will be deleted too.

Always use the iptables directive to hook iptables commands in a FireHOL firewall. Nothing else.


mac <IP> <MAC>

The mac helper verifies that all traffic comming in with source the IP address, comes from the MAC address. The helper applies its rules to filter/INPUT and filter/FORWARD and checks the source IP address in combination with the source MAC address.

The same MAC address is allowed to use other IPs; only the specific IP is required to be used with the specified MAC address.

Packets with the given IP address but with wrong MAC address will be DROPped and a log (as in loglimit) with label "MAC MISSMATCH" will appear in the system logs.

This helper has to be used before all interface or router statements. Of course, you can use as many mac statements as you wish.

Example: mac 195.97.5.202 00:02:8a:21:a9:d8


mark <NUMBER> <WHERE> [optional rule parameters]

The mark helper marks the traffic with a specific mark NUMBER that can be matched by traffic shapping tools for controlling the traffic.

Parameters

  • NUMBER is a number to mark the packets with.
     
  • WHERE tells FireHOL where to search for the specific traffic to be marked.
    Currently, WHERE can be one of the build-in iptables chains attached to table mangle. (for example: INPUT, FORWARD, OUTPUT, PREROUTING, POSTROUTING - case does matter here).
     
  • optional rule parameters is a set of rules that allow further restriction of the traffic that gets matched by this rule. See Optional Rules Parameters for more information.
     
Keep in mind that if you need to do policy based routing based on iptables marks, you should disable the Root Path Filtering on the interfaces involved (rp_filter in sysctl).
Example 1: mark 1 OUTPUT, will mark with 1 all packets send by the local machine.
Example 2: mark 2 FORWARD, will mark with 2 all packets passing through the local machine.
Example 3: mark 3 FORWARD proto tcp dport 25 dst 1.1.1.1 src 2.2.2.2, will match with 3 all packets sent by 2.2.2.2, passing through the local machine and targeting port TCP/25 of host 1.1.1.1.


masquerade [reverse | interface] [optional rule parameters]

Masquerading is a special from of SNAT (Source NAT) that changes the source of requests when they go out and replaces their original source when replies come in. This way a Linux box can become an internet router for a LAN of clients having unroutable IP addresses. Masquerading takes care to re-map IP addresses and ports as required.

Masquerading is "expensive" compared to SNAT because it checks the IP address of the ougoing interface every time for every packet, and therefore it is suggested that if you connect to the internet with a static IP address, to prefer SNAT.

The masquerade helper sets up masquerading on the output of a network interface (not the interface command, but a real network interface).

If the masquerade command is placed within an interface command, its network interface(s) will be used.
If the masquerade command is placed within a router command that has an outface defined, then the outface network interface(s) will be used.
If placed within a router command but the keyword reverse is specified and the router command has an inface defined, then the inface network interface(s) will be used.
If placed outside and before all primary commands, an interface (or list of space separated interfaces, within double quotes) can be specified on the masquerade command.

In all cases, masquerade will setup itself on the output of the given interface(s).

Please note that if masquerade is used within some interface or router, it does not respect the optional rule parameters given to this interface or router command. Masquerade uses only its own optional rule parameters.

inface and outface should not be given as parameters to masquerade (inface because iptables does not support this in the POSTROUTING chain, and outface because it will be overwritten by the interface(s) mentioned above).

Finally, the masquerade helper will turn on FIREHOL_NAT and instruct the kernel to do packet forwarding (like the router commands do).

Example 1: before the first interface or router: masquerade eth0 src 10.0.0.0/8 dst not 10.0.0.0/8
Example 2: within an interface: masquerade, to masquerade on the output of this interface
Example 3: within a router: masquerade reverse, to masquerade on the output of the router's inface.


nat <type> <target> [optional rule parameters]

The nat helper sets up a NAT rule for routed traffic.

The type parameter can be:

  • to-source, to define a Source NAT (created in NAT/POSTROUTING).
    The target in this case is the source address to be set in packets matching the optional rule parameters (if no optional rule parameters, all forwarded traffic will be matched). target accepts all --to-source values iptables accepts (see iptables -j SNAT --help). Multiple --to-source values can be given, if separated by space and quoted as a single argument.

    inface should not be used in SNAT, because iptables does not provide this information at this point.

    YOU HAVE TO MAKE SURE THAT THE SOURCE ADDRESS YOU SPECIFY IS SUCH THAT THE REPLIES WILL BE SEND BACK TO THE HOST DOING THE NAT. If the traffic does not get back to this host, then SNAT will simply not work.

    THE PACKET FILTERING MECHANISM WILL NOT KNOW THE CHANGE OF THE SOURCE ADDRESS. For packet filtering (client, server, route statements in interfaces and routers), the traffic will flow in both directions with its real source address (i.e. real = as it is, before SNATed). For the host doing the NAT, real is "where do I have to really send it?"
     

  • to-destination, to define a Destination NAT (created in NAT/PREROUTING).
    The target in this case is the destination address to be set in packets matching the optional rule parameters (if no optional rule parameters, all forwarded traffic will be matched). target accepts all --to-destination values iptables accepts (see iptables -j DNAT --help). Multiple --to-destination values can be given, if separated by space and quoted as a single argument (in which case DNAT becomes a load-balancer).

    outface should not be used in DNAT, because iptables does not provide this information at this point.

    THE PACKET FILTERING MECHANISM WILL KNOW THE CHANGE OF THE DESTINATION ADDRESS. For packet filtering (client, server, route statements in interfaces and routers), the traffic will flow in both directions with its real destination address (i.e. real = as it is, after DNATed). For the host doing the NAT, real is "where do I have to really send it?"
     

  • redirect-to, to catch traffic comming in and send it to the local machine (created in NAT/PREROUTING).
    The target in this case is a port or a range of ports (XXX-YYY) that packets matching the rule will be redirected to (if no optional rule parameters are given, all incomming traffic will be matched). target accepts all --to-ports values iptables accepts (see iptables -j REDIRECT --help).

    outface should not be used in REDIRECT, because iptables does not provide this information at this point.

    THE PACKET FILTERING MECHANISM WILL KNOW THE CHANGE OF THE DESTINATION PORT. For packet filtering (client, server statements in interfaces), the traffic will flow in both directions with its real destination port (i.e. real = as it is, after REDIRECTed). For the host doing the NAT, real is "where do I have to really send it?"
     

Please understand that the optional rule parameters are used only to limit the traffic to be matched. Consider these examples:

CommandDescription
nat to-destination 1.1.1.1 Sends to 1.1.1.1 all traffic comming in or passing trhough the firewall host.
nat to-destination 1.1.1.1 dst 2.2.2.2 Redirects to 1.1.1.1 all traffic comming in or passing through, and going to 2.2.2.2.
nat to-destination 1.1.1.1 proto tcp dst 2.2.2.2 Redirects to 1.1.1.1 all TCP traffic comming in or passing through and going to 2.2.2.2.
nat to-destination 1.1.1.1 proto tcp dport 25 dst 2.2.2.2 Redirects to 1.1.1.1 all traffic comming in or passing through and going to 2.2.2.2 to port tcp/25.
nat to-destination 1.1.1.1 proto tcp dport 25 dst 2.2.2.2 src 3.3.3.3 Redirects to 1.1.1.1 all traffic comming in or passing through from 3.3.3.3 and going to 2.2.2.2 to port tcp/25.

Example 1: nat to-source 1.1.1.1 outface eth0 src 2.2.2.2 dst 3.3.3.3
Example 2: nat to-destination 4.4.4.4 inface eth0 src 5.5.5.5 dst 6.6.6.6
Example 3: nat redirect-to 8080 inface eth0 src 2.2.2.0/24 proto tcp dport 80


redirect [to] <target> [optional rule parameters]

The redirect helper catches all incomming traffic matching the optional rule parameters given and redirects it to ports on the local host, by calling
nat redirect-to <target> [optional rule parameters]

See the nat helper.

Example: redirect to 8080 inface eth0 src 2.2.2.0/24 proto tcp dport 80


snat [to] <target> [optional rule parameters]

The snat helper sets up a Source NAT rule for routed traffic, by calling
nat to-source <target> [optional rule parameters]

See the nat helper.

Example: snat to 1.1.1.1 outface eth0 src 2.2.2.2 dst 3.3.3.3


tcpmss <what>

The tcpmss helper sets the MSS (Maximum Segment Size) of TCP SYN packets routed through the firewall. Its purpose is to overcome situations where Path MTU Discovery is not working and packet fragmentation is not possible.

Within FireHOL, it can be defined either before any primary command, in which case it is applied to all traffic passing through the firewall, or to any router, in which case it is applied to traffic going out on the outfaces of the router.

The argument can either be the word auto or a number:

  • The word auto will make the TCP connections have MSS equal to the MTU of the outgoing intefrace minus 40 (clamp-mss-to-pmtu).
  • A numeric argument will make the TCP connections have MSS equal to the number given.

See also TCPMSS target in iptables tutorial.

Example 1: tcpmss auto
Example 2: tcpmss 500


tos <NUMBER> <WHERE> [optional rule parameters]

The tos helper sets the Type of Service (TOS) in packets.

Parameters

  • NUMBER is a number to set TOS to. FireHOL supports decimal numbers, hex numbers and the descriptive values iptables supports. For more information see iptables -j TOS --help.
     
  • WHERE tells FireHOL where to search for the specific traffic to be marked.
    Currently, WHERE can be one of the build-in iptables chains attached to table mangle. (for example: INPUT, FORWARD, OUTPUT, PREROUTING, POSTROUTING - case does matter here).
     
  • optional rule parameters is a set of rules that allow further restriction of the traffic that gets matched by this rule. See Optional Rules Parameters for more information.
     

Example 1: tos 16 OUTPUT, will set TOS to 16 for all packets sent by the local machine.
Example 2: tos 0x10 FORWARD, will set TOS to 0x10 (16) for all packets passing through the local machine.
Example 3: tos Maximize-Throughput FORWARD proto tcp dport 25 dst 1.1.1.1 src 2.2.2.2, will set TOS to Maximize-Throughput (8) for all packets sent by 2.2.2.2, passing through the local machine and targeting port TCP/25 of host 1.1.1.1.


tosfix

The tosfix helper is based on the suggestions given by Erik Hensema for iptables and tc shapping tricks (check the source here). It does:
  • All TCP ACK packets with length less than 128 bytes are assigned the Minimize-Delay TOS, while bigger ones are assigned the Maximize-Throughput.
     
  • All packets with TOS Minimize-Delay, that are bigger than 512 bytes are set to Maximize-Throughput, except for short bursts of 2 packets per second.
     


transparent_proxy <service> <port> <user> [optional rule parameters]

The transparent_proxy helper sets up trasparent proxy server for TCP traffic. The proxy is assumed to be running on the firewall host at port port, with the credentials of the local user user serving TCP port's service requests.

The transparent_proxy helper can be used for two kinds of traffic:

  • Incomming TCP traffic, either targeted to the firewall host or passing through the firewall host.
    The optional rule parameters can be used to specify which kind of incomming traffic to be catched (by using inface, src, dst, etc -- outface should not be used here, because the rules generated are placed before the routing decision and therefore the outgoing interface is not yet known).

    If no optional rule parameters are given, then the transparent proxy will be setup on all network interfaces for all TCP traffic (use this with care since you are risking to serve requests from the internet using your proxy).
     

  • Locally generated outgoing TCP traffic, except TCP traffic generated by processes running as the user argument. The optional rule parameters inface, outface and src are ignored for this type of traffic.

    This kind of matching makes it possible to support transparent proxying for clients running on the firewall host, as far as they do not run as the user excluded. More than one users can be specified by space-separating and enclosing them in double quotes.

    This rule can be disabled by specifing as user the empty string: ""
     

Of course, make sure that your firewall allows requests to reach your proxy server.

In kernel versions prior to 2.6 you need to enable CONFIG_IP_NF_NAT_LOCAL for locally generated outgoing traffic to be redirected correctly.

Example 1: transparent_proxy 80 3128 squid inface eth0 src 10.0.0.0/8 to redirect all tcp/80 requests coming in from eth0 (10.0.0.0/8) to your local web caching proxy server listening at port 3128 and running as user squid.
Example 2: transparent_proxy "80 3128 8080" 8080 "squid privoxy root bin" inface not "ppp+ ipsec+" dst not "a.not.proxied.server" to redirect all web and proxy requests (tcp: 80, 3128, 8080) coming in from all interfaces except ppp+ and ipsec+ to your local squid server listening at tcp/8080 except those requests generated by the local users squid, privoxy, root and bin, and all matching traffic that is targeting host 'a.not.proxied.server'.


transparent_squid <port> <user> [optional rule parameters]

The transparent_squid helper sets up trasparent caching for HTTP traffic. It is equivalent to:

transparent_proxy 80 <port> <user> [optional rule parameters]

Example 1: transparent_squid 3128 squid inface eth0 src 10.0.0.0/8
Example 2: transparent_squid 8080 "squid privoxy root bin" inface not "ppp+ ipsec+" dst not "a.not.proxied.server"


version <number>

Description

The version command states the FireHOL release the configuration file was created for. In case the configuration file is newer than FireHOL, FireHOL will deny to run it.

This command is here to allow you or anyone else design and distribute FireHOL configuration files, while ensuring that the correct FireHOL version is going to run them.

Since FireHOL configurations are BASH script, it is relatively easy to use FireHOL configurations as small scripts that dynamically process rules stored in a database, in a file system as separate files, or elsewhere. This directive will help the developers of FireHOL configurations to control the required version of FireHOL.

The FireHOL release is increased every time the format of the configuration file and the internals of FireHOL are changed.

Since FireHOL v1.67 version is not required to be present in every configuration file.

Actions
Actions are the actions to be taken on services and traffic described by other commands and functions. Please note that normally, FireHOL will pass-through to the generated iptables statements all the possible actions iptables accepts, but only the ones defined here can be used with lower case letters and currently it will be impossible to pass arguments to some unknown action. Also, keep in mind that the iptables action LOG is a FireHOL optional rule parameter (see log and loglimit) that can be defined together with one of the following actions and FireHOL will actually produce multiple iptables statements to achieve both the logging and the action.

accept [with limit <frequency> <burst> [overflow <action>]]

accept [with knock <name>]

accept [with recent <name> <seconds> <hits>]

accept allows the traffic matching the rules to reach its destination.

with limit
The optional parameter with limit offers control over the allowed frequency of NEW connections. frequency and burst have the same syntax of the limit optional rule parameter.

The overflow action offers control over the overflowed NEW connections. The default is to REJECT overflowed connections (not DROP them, since DROP produces timeouts on the otherwise valid service clients). Also, the REJECT overflow action, will reject TCP connections with tcp-reset and all others with icmp-host-unreachable.
The overflowed NEW connection attempts will be logged with a OVERFLOW message, with the options the loglimit parameter works.

with knock
The optional parameter with knock allows easy integration with knockd, a server that allows you to control access to services, by sending certain packets to "knock" the door, before the door is open for service.
This parameter accepts just a name. This name is used to build a special chain knock_<name> which will contain just the rules to allow established connections to work, but it prevent any new connections from taking place. In case, knockd has not allowed new connections, this traffic entering this chain will just return back and continue to match against the other rules until the end of the firewall.

How to use it: lets say that you want to allow https traffic based on a knock. In FireHOL you write:

server https accept with knock hidden

and you configure knockd so that it runs:

iptables -A knock_hidden -s %IP% -j ACCEPT

to enable the https service (notice that there is no need to match anything else than the IP. FireHOL already matches everything needed for its rules to work), and:

iptables -D knock_hidden -s %IP% -j ACCEPT

to disable this service for the given IP.

You can use the same knock name in more than one FireHOL services to enable/disable all the services together, without any extra effort in knockd configuration (just one ACCEPT row like above - i.e. the same knock as far as knockd is concerned - will allow all the FireHOL services with the same knock name to serve requests for the given IP). Check also this forum post.

with recent
The optional parameter with recent allows new connections to be limited per remote IP for a number of seconds and/or hits. The name parameter allows multiple statements to share the same recent list of IPs. If the time or the hits are not required, set them to empty. Keep in mind that when a new connection is not allowed, the traffic will continue to be matched by the rest of the firewall. In other words, if the traffic is not allowed due to the limitations set here, it is not dropped. It is just not matched by this rule.

Example 1: server smtp accept, to allow SMTP requests and their replies to flow.
Example 2: server smtp accept with limit 10/s 100, to allow SMTP requests to come at 10/second max, with a burst of 100, and their replies to flow back.
Example 3: server smtp accept with limit 10/s 100 overflow drop, to allow SMTP requests to come at 10/second max, with a burst of 100, and their replies to flow back. The overflow requests will be dropped.
Example 4: server smtp accept with limit 10/s 100 src "1.2.3.4 5.6.7.8", same as example 2, but the only valid clients are given as argument to src Example 4: server smtp accept with recent mail 60 2, to allow only 2 connections every 60 seconds per remote IP, to the smtp server.


reject [with <message>]

reject discards the matching traffic but sends a rejecting message back to the sender.

with is used to offer control on the message to be returned to the sender. with accepts all the arguments the --reject-with iptables expression accepts. For an updated list of these messages type iptables -j REJECT --help. Bellow you can find the list my system accepts.

By default (no with argument given), reject will send an icmp-port-unreachable on all protocols except TCP, for which it will send a tcp-reset.

MessageAliasDescriptionReference
icmp-net-unreachable net-unreach ICMP network unreachable

From RFC 1812 section 5.2.7.1
Generated by a router if a forwarding path (route) to the destination network is not available.

Notes
Use this with care. The sender and the routers between you and the sender may conclude that the whole network your host resides in, is unreachable and prevent other traffic from reaching you.

RFC 1812 RFC 792
icmp-host-unreachable host-unreach ICMP host unreachable

From RFC 1812 section 5.2.7.1
Generated by a router if a forwarding path (route) to the destination host on a directly connected network is not available (does not respond to ARP).

Notes
Use this with care. The sender and the routers between you and the sender may conclude that your server is unreachable and prevent the transmission of other traffic to you.

RFC 1812 RFC 792
icmp-proto-unreachable proto-unreach ICMP protocol unreachable

From RFC 1812 section 5.2.7.1
Generated if the transport protocol designated in a datagram is not supported in the transport layer of the final destination.

RFC 1812 RFC 792
icmp-port-unreachable port-unreach ICMP port unreachable (default)

From RFC 1812 section 5.2.7.1
Generated if the designated transport protocol (e.g. TCP, UDP, etc) is unable to demultiplex the datagram in the transport layer of the final destination but has no protocol mechanism to inform the sender.

In other words
Generated by hosts to indicate that the required port is not active.

RFC 1812 RFC 792
icmp-net-prohibited net-prohib ICMP communication with destination network administratively prohibited

From RFC 1812 section 5.2.7.1
This code was intended for use by end-to-end encryption devices used by U.S military agencies. Routers SHOULD use the newly defined Code 13 (Communication Administratively Prohibited) if they administratively filter packets.

In other words
Use it, but don't expect that this will be widely understood.

RFC 1812 RFC 1122
icmp-host-prohibited host-prohib ICMP communication with destination host administratively prohibited

From RFC 1812 section 5.2.7.1
This code was intended for use by end-to-end encryption devices used by U.S military agencies. Routers SHOULD use the newly defined Code 13 (Communication Administratively Prohibited) if they administratively filter packets.

In other words
Use it, but don't expect that this will be widely understood.

RFC 1812 RFC 1122
tcp-reset tcp-reset TCP RST

This is the port unreachable message of the TCP stack. It is useful when you want to prevent timeouts on rejected TCP services when the client is badly written to ignore ICMP port unreachable messages.

I suggest to use this for rejecting idents:
server ident reject with tcp-reset.

RFC 1122


Example 1: policy reject with host-unreach
Example 2: server ident reject with tcp-reset
Example 3: UNMATCHED_INPUT_POLICY="reject with host-prohib"


drop

drop silently discards the matching traffic. The fact that the traffic is silently discarded makes the sender timeout in order to conclude that it is not possible to use the wanted service.

Example: server smtp drop, to silently discard SMTP requests and their replies.


deny

deny is just an alias for drop, made for those who are used to ipchains terminology.

Example: server smtp deny, to silently discard SMTP requests and their replies.


tarpit

Captures and holds incoming TCP connections using no local per-connection resources. Connections are accepted, but immediately switched to the persist state (0 byte window), in which the remote side stops sending data and asks to continue every 60-240 seconds. Attempts to close the connection are ignored, forcing the remote side to time out the connection in 12-24 minutes.

Example: server smtp tarpit, to force remote clients to timeout.


return

return will return the flow of processing to the parent of the current command. Currently, it has meaning to specify the action return only as a policy to some interface.

Example: policy return, to have traffic not matched by any rule within an interface to continue traveling through the firewall and possibly matched by other interfaces bellow.


mirror

mirror will return the traffic to the wanted port, back to the sending host. Use this with care, and only if you understand what you doing. Keep also in mind that FireHOL will apply this action to both requests and replies comming in or passing through, and will replace it with REJECT for traffic generated by the local host.


redirect [to-port port]

redirect is used internally by FireHOL Helper Commands to redirect traffic to ports on the local host. Unless you are a developer, you will never need to use this directly.

Optional Rule Parameters
Optional rule parameters are accepted by many commands to narrow the match they do by default. The parameters described bellow are all that FireHOL supports. You should check the documentation of each command to find which parameters should not be used with it. Normally, all FireHOL commands are designed so that if you specify a parameters that is also used internally, the internal one will overwrite the one given in the configuration file. In such a case, FireHOL will present you a warning with the old and the new value.

Not all parameters should be used in all cases. For example sport and dport should not be used in normal server and client commands since such ports are internally defined by the services themselves. In any case, FireHOL will complain about optional rule parameters that should not be used in certain commands.

src [not] <host>

Description

src defines the source IP address of the REQUEST. If src is defined on a server statement it matches the source of the request which is the remote host, while if it is defined on a client statement it matches again the source of the request, but this time it is the local host. Focus on the REQUEST!!! Forget the reply.

Parameters

  • not is an optional argument that reverses the match. When defined, the rule will match all hosts except the ones defined.
    Example: server smtp accept src not 1.2.3.4
     
  • host can be an IP address, a hostname, or a subnet.
    Multiple hosts/networks can be defined if separated by space and quoted as a single argument.
    Example 1: server smtp accept src 1.2.3.4
    Example 2: server smtp accept src not "1.2.3.0/24 5.6.7.8 badhost.example.com"
     


dst [not] <host>

Description

dst defines the destination of the REQUEST. If dst is defined on a server statement it matches the destination of the request which is the local host, while if it is defined on a client statement it matches again the destination of the request, but this time it is the remote host. Focus on the REQUEST!!! Forget the reply.

dst accepts the same parameters as src


srctype [not] <type>

Description

srctype defines the source IP address type. The following types are supported:
  • UNSPEC an unspecified address (i.e. 0.0.0.0)
  • UNICAST an unicast address
  • LOCAL a local address
  • BROADCAST a broadcast address
  • ANYCAST an anycast packet
  • MULTICAST a multicast address
  • BLACKHOLE a blackhole address
  • UNREACHABLE an unreachable address
  • PROHIBIT a prohibited address
  • THROW
  • NAT
  • XRESOLVE

More that one types can be specified if given as a space separated list enclosed in quotes.
FireHOL will convert to upper case any strings given as types.

For more information check: iptables -m addrtype --help (or man iptables).


dsttype [not] <type>

Description

dsttype defines the destination IP address type. This parameter has the same rules with srctype.


inface [not] <interface>

Description

inface defines the interface the REQUEST is received via. inface cannot be used in interface commands.

Parameters

  • not is an optional argument that reverses the match. When defined, the rule will match all interfaces except the ones defined.
    Example: server smtp accept inface not eth0
     
  • interface if an interface name in the same format the interface command accepts.
    Multiple interfaces can be defined if separated by space and quoted as a single argument.
    Example 1: server smtp accept inface not eth0
    Example 2: server smtp accept inface not "eth0 eth1"
     


outface [not] <interface>

Description

outface defines the interface the REQUEST is send via. outface cannot be used in interface commands.

outface accepts the same parameters as inface.


physin [not] <interface>

Description

physin defines the physical interface the REQUEST is received via and is used in cases where inface is defined as a virtual interface (such as a bridge interface). In such cases, the physdev iptables module (which is used by physin) can be used to match the physical network interface the REQUEST is recieved via.

physin accepts the same parameters as inface.


physout [not] <interface>

Description

physout defines the physical interface the REQUEST is send via and is used in cases where outface is defined as a virtual interface (such as a bridge interface). In such cases, the physdev iptables module (which is used by physout) can be used to match the physical network interface the REQUEST is send via.

physout accepts the same parameters as outface.


custom "parameters"

Description

custom passes its arguments to the generated iptables commands.

It is required to quote all the parameters given to custom. If the parameters include a space character between some text that is required to be given to iptables as one argument, it is required to escape another set of quotes in order. Another way is to use double quotes externally and single quotes internally.

Example 1: server smtp accept custom "--some-iptables-option and_its_value"
Example 2: server smtp accept custom "--some-iptables-option 'one_value another_value'"


log "<some text>" [level a_level]

Description

log will log the matching packets to syslog. Note that this is not an action (in iptables it is). FireHOL will actually produce multiple iptables commands to accomplish both the action for the rule and the logging. You can control how logging works, by altering the variables FIREHOL_LOG_MODE, FIREHOL_LOG_OPTIONS and FIREHOL_LOG_LEVEL. You can also change the level of just one rule by using the level argument of the log parameter (only when FIREHOL_LOG_MODE=LOG).

FireHOL logs traffic, exactly the same way iptables does. Many users have complained about packet logs appearing at their console. To avoid this you will have to:

  • setup klogd to log only more important traffic
  • change FIREHOL_LOG_LEVEL to log at a not so important log-level
Actually klogd's -c option and iptables' --log-level option are the same thing (iptables accepts also the numeric values klogd accepts). If iptables logs at a higher priority than klogd is configured to use, then your packets will appear in the console too.

In most kernels klogd is by default configured to log everything, so if you don't also change klogd's -c option, the --log-level setting of iptables has no effect. Use the table bellow to match klogd options with --log-level options:

PriorityklogdiptablesDescription
0 0 emerg system is unusable
1 1 alert action must be taken immediately
2 2 crit critical conditions
3 3 error error conditions
4 4 warning (default) warning conditions
5 5 notice normal but significant condition
6 6 info informational
7 7 (default) debug debug-level messages

To prevent packet logs appearing to the console, klogd option must be LOWER than the one iptables uses.

On RedHat systems, you can configure klogd by changing /etc/sysconfig/syslog and adding to KLOGD_OPTIONS the required -c level.


loglimit "<some text>"

Description

loglimit is the same with log but limits the frequency of logging according to the setting of FIREHOL_LOG_FREQUENCY and FIREHOL_LOG_BURST.


proto [not] <protocol>

Description

proto sets the required protocol for the traffic. This command accepts anything iptables accepts as protocols.


limit <frequency> <burst>

Description

limit will limit the match in both directions of the traffic (request and reply). This is used internally by FireHOL and its effects has not been tested in the high level configuration file directives.


sport <port>

Description

sport defines the source port of a request. It accepts port names, port numbers, port ranges (FROM:TO) and multiple ports (or ranges) seperated by spaces and quoted as a single argument. This parameter should not be used in normal services definitions (client and server commands) or interface and router definitions, unless you really understand what you are doing.


dport <port>

Description

dport defines the destination port of a request. It accepts port names, port numbers, port ranges (FROM:TO) and multiple ports (or ranges) seperated by spaces and quoted as a single argument. This parameter should not be used in normal services definitions (client and server commands) or interface and router definitions, unless you really understand what you are doing.


uid [not] <user>

user [not] <user>

Description

uid or user define the operating system user sending this traffic. The parameter can be a username, a user number or a list of these two, seperated by spaces and quoted as a single argument.

This parameter can be used only in services (client and server commands) defined within interfaces, not routers. FireHOL is "smart" enough to apply this parameter only to traffic send by the localhost, i.e. the replies of servers and requests of clients. It is not possible, and FireHOL will simply ignore this parameter, on traffic coming in or passign through the firewall host.


Example 1: client "pop3 imap" accept user not "user1 user2 user3" dst mymailer.example.com
The above will allow local users except user1, user2 and user3 to use POP3 and IMAP services on mymailer.example.com. You can use this, for example, to allow only a few of the local users use the fetchmail program to fetch their mail from the mail server.


Example 2: server http accept user apache
The above will allow all HTTP to reach the local http server, but only if the web server is running as user apache the replies will be send back to the HTTP client.


gid <group>

group <group>

Description

gid or group define the operating system user group sending this traffic. The parameter can be a group name, a group number or a list of these two, seperated by spaces and quoted as a single argument.

This parameter can be used only in services (client and server commands) defined within interfaces, not routers. FireHOL is "smart" enough to apply this parameter only to traffic send by the localhost, i.e. the replies of servers and requests of clients. It is not possible, and FireHOL will simply ignore this parameter, on traffic coming in or passign through the firewall host.


pid <process>

process <process>

Description

pid or process define the operating system process ID (or PID) sending this traffic. The parameter can be a PID or a list of PIDs, seperated by spaces and quoted as a single argument.

This parameter can be used only in services (client and server commands) defined within interfaces, not routers. FireHOL is "smart" enough to apply this parameter only to traffic send by the localhost, i.e. the replies of servers and requests of clients. It is not possible, and FireHOL will simply ignore this parameter, on traffic coming in or passign through the firewall host.


sid <session>

session <session>

Description

sid or session define the operating system session ID of the process sending this traffic (The session ID of a process is the process group ID of the session leader). The parameter can be a list of such IDs, seperated by spaces and quoted as a single argument.

This parameter can be used only in services (client and server commands) defined within interfaces, not routers. FireHOL is "smart" enough to apply this parameter only to traffic send by the localhost, i.e. the replies of servers and requests of clients. It is not possible, and FireHOL will simply ignore this parameter, on traffic coming in or passign through the firewall host.


cmd <name>

command <name>

Description

cmd or command define the operating system command name of the process sending this traffic. The parameter can be a list of such command names, seperated by spaces and quoted as a single argument.

This parameter can be used only in services (client and server commands) defined within interfaces, not routers. FireHOL is "smart" enough to apply this parameter only to traffic send by the localhost, i.e. the replies of servers and requests of clients. It is not possible, and FireHOL will simply ignore this parameter, on traffic coming in or passign through the firewall host.


mac [not] <address>

Description

mac matches the source MAC address of packets comming into the firewall. The mac parameter does nothing for outgoing traffic.
For interfaces, the mac parameter matches against all traffic that comes into the firewall, whether it is server or client traffic.
For routers, the mac parameter matches also against all traffic comming into the firewall, but firehol considers the router input differently based on the command given. For server or route statements, the mac parameter matches the MAC address of the client (the host sending the request), while for client statements it matches the source MAC address of the server (the host accepting requests).

In principle, the mac parameter behaves the same for both interfaces and routers and this is why: The mac parameter matches the source MAC address of what FireHOL considers the "remote" host, not the one that FireHOL considers the "protected" one. For interfaces, this is simple, because always the "remote" host is a remote host and the "protected" host is the one running the firewall. For routers though, the command chosen (client or server) defines what the firewall protects. Therefore, a client statement protects the client making the "remote" host the server, while a server statement protects the server and therefore the "remote" host is the client.

More than one MAC addresses can be given if separated by spaces and enclosed in quotes as a single argument to the mac parameter.

The not argument will reverse the match. In case there are many MAC addresses defined, positive expressions are ORed (either address should be matched), while negative expressions are ANDed (none of the addresses should be matched).


mark [not] <ID>

Description

mark matches the traffic against the given IDs. This command accepts anything iptables accepts as MARKs (see iptables -m mark --help).

More than one MARK IDs can be given if separated by spaces and enclosed in quotes as a single argument to the mark parameter.


tos [not] <ID>

Description

tos matches the traffic against the given IDs. This command accepts anything iptables accepts as TOS (see iptables -m tos --help).

More than one IDs can be given if separated by spaces and enclosed in quotes as a single argument to the tos parameter.


dscp [not] <ID>


dscp [not] class <ID>

Description

dscp matches the traffic against the given DSCP IDs. This command accepts anything iptables accepts as DSCP (see iptables -m dscp --help).

More than one IDs can be given if separated by spaces and enclosed in quotes as a single argument.

Variables that control FireHOL

DEFAULT_INTERFACE_POLICY

Description

DEFAULT_INTERFACE_POLICY controls the default action to be taken on traffic not matched by any rule within an interface. Actually, this is a global setting for what policy does for an interface.

All packets that reach the end of an interface are logged only if the action is not return or accept. You can control the frequency of this logging by altering the frequency loglimit uses.

Default: DEFAULT_INTERFACE_POLICY="DROP"

Example: DEFAULT_INTERFACE_POLICY="REJECT"


DEFAULT_ROUTER_POLICY

Description

DEFAULT_ROUTER_POLICY controls the default action to be taken on traffic not matched by any rule within a router. Actually, this is a global setting for what policy does for a router.

All packets that reach the end of a router are logged only if the action is not return or accept. You can control the frequency of this logging by altering the frequency loglimit uses.

Default: DEFAULT_ROUTER_POLICY="RETURN"

Example: DEFAULT_ROUTER_POLICY="REJECT"


UNMATCHED_INPUT_POLICY

UNMATCHED_OUTPUT_POLICY

UNMATCHED_ROUTER_POLICY

Description

UNMATCHED_INPUT_POLICY controls the default action to be taken for incoming traffic not matched by any interface command.
UNMATCHED_OUTPUT_POLICY controls the default action to be taken for outgoing traffic not matched by any interface command.
UNMATCHED_ROUTER_POLICY controls the default action to be taken for forwarded traffic not matched by any router command.

All variables accept all the Actions FireHOL supports.

All packets that reach the end of firewall in all three chains are logged (always, regardless of these settings). You can control the frequency of this logging by altering the frequency loglimit uses.

Default: UNMATCHED_INPUT_POLICY="DROP"
Default: UNMATCHED_OUTPUT_POLICY="DROP"
Default: UNMATCHED_ROUTER_POLICY="DROP"

Example: UNMATCHED_INPUT_POLICY="REJECT"
Example: UNMATCHED_OUTPUT_POLICY="REJECT"
Example: UNMATCHED_ROUTER_POLICY="REJECT"


FIREHOL_INPUT_ACTIVATION_POLICY

FIREHOL_OUTPUT_ACTIVATION_POLICY

FIREHOL_FORWARD_ACTIVATION_POLICY

Description

All these variables have been added in v1.133

FIREHOL_INPUT_ACTIVATION_POLICY controls the default action to be taken for incoming traffic during firewall activation.
FIREHOL_OUTPUT_ACTIVATION_POLICY controls the default action to be taken for outgoing traffic during firewall activation.
FIREHOL_FORWARD_ACTIVATION_POLICY controls the default action to be taken for forwarded traffic during firewall activation.

All variables accept either ACCEPT, DROP or REJECT.

The default is ACCEPT in order to prevent a denial of service during a firewall restart. This is by design correct, since FireHOL will block all invalid connections after the firewall is fully activated (remember that FireHOL allows specific traffic to pass in both directions of the firewall).

Default: FIREHOL_INPUT_ACTIVATION_POLICY="ACCEPT"
Default: FIREHOL_OUTPUT_ACTIVATION_POLICY="ACCEPT"
Default: FIREHOL_FORWARD_ACTIVATION_POLICY="ACCEPT"

Example: FIREHOL_INPUT_ACTIVATION_POLICY="REJECT"
Example: FIREHOL_OUTPUT_ACTIVATION_POLICY="REJECT"
Example: FIREHOL_FORWARD_ACTIVATION_POLICY="REJECT"


FIREHOL_LOG_MODE

FIREHOL_LOG_LEVEL

FIREHOL_LOG_OPTIONS

FIREHOL_LOG_FREQUENCY

FIREHOL_LOG_BURST

FIREHOL_LOG_PREFIX

Description

FIREHOL_LOG_MODE controls the method of logging used by FireHOL. Currently, two modes are supported: LOG and ULOG. FIREHOL_LOG_LEVEL controls the level at which iptables will log things to the syslog. For a description of the possible values supported and for per-rule control of log level, see the log optional rule parameter. FIREHOL_LOG_LEVEL is ignored when FIREHOL_LOG_MODE=ULOG.

FIREHOL_LOG_OPTIONS controls the way iptables will log things to the syslog. The value of this variable is passed as is to iptables, so use exact iptables parameters. This variable can have special arguments for the LOG or ULOG actions of iptables.

FIREHOL_LOG_FREQUENCY and FIREHOL_LOG_BURST (added in v1.39 of FireHOL) control the frequency at each each logging rule will write packets to the syslog. FIREHOL_LOG_FREQUENCY is set to the maximum average frequency and FIREHOL_LOG_BURST specifies the maximum initial number of packets to match.

FIREHOL_LOG_PREFIX adds its contents to every log line, so that FireHOL logs can easily be detected in the system log. By default it is empty.

Default: FIREHOL_LOG_MODE="LOG"
Default: FIREHOL_LOG_OPTIONS="--log-level warning"
Default: FIREHOL_LOG_FREQUENCY="1/second"
Default: FIREHOL_LOG_BURST="5"
Default: FIREHOL_LOG_PREFIX=""

Example: FIREHOL_LOG_OPTIONS="--log-level info --log-tcp-options --log-ip-options"
Example: FIREHOL_LOG_FREQUENCY="30/minute"
Example: FIREHOL_LOG_BURST="2"
Example: FIREHOL_LOG_PREFIX="FIREHOL: "

To see the available iptables log options, run /sbin/iptables -j LOG --help or /sbin/iptables -j ULOG --help (depending on FIREHOL_LOG_MODE)
To see what iptables accepts as frequencies and bursts run, /sbin/iptables -m limit --help
You can also check man iptables.


FIREHOL_DROP_INVALID

Description

If FIREHOL_DROP_INVALID is set to 1, FireHOL will drop all packets that are matched by the INVALID state of the iptables connection tracker. The default in versions prior to v1.183 was to drop all those packers. The new default is not to drop those packets globally, but only as part of the protection statement.

See also Bug 927509 that discusses the effects of globally dropping invalid packets.

Default: FIREHOL_DROP_INVALID="0"
Example: FIREHOL_DROP_INVALID="1"


DEFAULT_CLIENT_PORTS

Description

DEFAULT_CLIENT_PORTS controls the port range to be used when a remote client is specified. For localhost clients, FireHOL finds the exact client ports by querying the kernel options.

Default: DEFAULT_CLIENT_PORTS="1024:65535"
Example: DEFAULT_CLIENT_PORTS="0:65535"


FIREHOL_NAT

Description

If FIREHOL_NAT is set to 1, FireHOL will load NAT kernel modules for those services that they are require such. FireHOL sets this to 1 automatically if you use the Helper Commands that do NAT.

Default: FIREHOL_NAT="0"
Example: FIREHOL_NAT="1"


FIREHOL_AUTOSAVE

Description

FIREHOL_AUTOSAVE controls the file that will be created when FireHOL is called with the save command line argument. If this variable is empty (the default), FireHOL will try to detect where to save the file. Currently, the RedHat way (/etc/sysconfig/iptables) and the Debian way (/var/lib/iptables/autosave) are automatically detected (in the order given here) based on the existance of the directory this file should be created in.

Default: FIREHOL_AUTOSAVE=""
Example: FIREHOL_AUTOSAVE="/tmp/firehol-saved.txt"


FIREHOL_LOAD_KERNEL_MODULES

Description

FIREHOL_LOAD_KERNEL_MODULES controls the way FireHOL handles required kernel modules. If set to 0 (zero), FireHOL will not attempt to load kernel modules at all. Set this to 0 (zero) if you have compiled a kernel that has all the modules build into it.

Since v1.165 of the FireHOL this feature is almost useless. FireHOL now tries to find the .config file of your kernel (in /proc/config or /lib/modules/`uname -r`/build/.config or /usr/src/linux/.config, in this order) and figures out which kernel modules are compiled build-in and which are modules.
So, this variable is only used in cases where FireHOL has no access at all to kernel configuration.

Keep in mind, that FireHOL is able to detect the ip_tables and ip_conntrack modules by examining the relative entries in /proc, so it can detect whether these are loaded without the need for the kernel configuration.

Default: FIREHOL_LOAD_KERNEL_MODULES=1
Example: FIREHOL_LOAD_KERNEL_MODULES=0


FIREHOL_TRUST_LOOPBACK

Description

FIREHOL_TRUST_LOOPBACK allows you to choose if FireHOL will trust the lo interface and accept all traffic to or from it (although not FORWARD, it matches only INPUT and OUTPUT).

The default is to accept all traffic from/to lo. If however you need to control what the local system users can use on the local machine, you can set this to anything other than 1 allowing you to setup the firewall as you will.

IMPORTANT: If you choose not to trust interface lo and you don't specifically setup the lo interface in firehol.conf, no local process will be able to communicate to any other local process, which most likely will break several things. Be sure you know what you are doing.

This option appeared in FireHOL version 1.195.

Default: FIREHOL_TRUST_LOOPBACK=1
Example: FIREHOL_TRUST_LOOPBACK=0


FIREHOL_DROP_ORPHAN_TCP_ACK_FIN

Description

FIREHOL_DROP_ORPHAN_TCP_ACK_FIN allows you to choose if FireHOL will drop all TCP connections with ACK FIN set without logging them. In busy environments the iptables connection tracker removes from the connection tracking list entries when it receives a FIN. This makes the ACK FIN appear as an invalid packet (it does not match anything on the connection tracking list, and it is not a new connection). Normally FireHOL logs this traffic. If FIREHOL_DROP_ORPHAN_TCP_ACK_FIN is set to 1, FireHOL will silentrly drop such packets.

Default: FIREHOL_DROP_ORPHAN_TCP_ACK_FIN=0
Example: FIREHOL_DROP_ORPHAN_TCP_ACK_FIN=1

Variables that FireHOL offers

RESERVED_IPS

Description

This variable includes all the IP addresses defined as IANA - Reserved by IANA. You can overwrite the internal default definion of this variable by creating a file with same name in /etc/firehol. This file accepts an IP definition per line. The supplied get-iana.sh script creates this file by directly fetching this document.

Example: interface eth0 internet src not "${RESERVED_IPS}"


PRIVATE_IPS

Description

This variable includes all the IP addresses defined as Private or Test by RFC 3330. You can overwrite the internal default definion of this variable by creating a file with same name in /etc/firehol. This file accepts an IP definition per line.

Example: interface eth0 internet src not "${PRIVATE_IPS}"


UNROUTABLE_IPS

Description

This variable is both RESERVED_IPS and PRIVATE_IPS together. I suggest to use this variable on interfaces and routers accepting Internet traffic. You can overwrite the internal default definion of this variable by creating a file with same name in /etc/firehol. This file accepts an IP definition per line.

Example: interface eth0 internet src not "${UNROUTABLE_IPS}"


MULTICAST_IPS

Description

You can overwrite the internal default definion of this variable by creating a file with same name in /etc/firehol. This file accepts an IP definition per line.

Example: interface eth0 internet src not "${MULTICAST_IPS}"


EOF } smart_print_service() { local server="${1}" local server_varname="server_${server}_ports" local server_ports="`eval echo \\\$${server_varname}`" local client_varname="client_${server}_ports" local client_ports="`eval echo \\\$${client_varname}`" local mods_varname="helper_${server}" local require_modules="`eval echo \\\$${mods_varname}`" local notes_varname="service_${server}_notes" local notes="`eval echo \\\$${notes_varname}`" local type_varname="service_${server}_type" local type="`eval echo \\\$${type_varname}`" local title_varname="title_${server}" local title="`eval echo \\\$${title_varname}`" local wiki_varname="wikipedia_${server}" local wiki="`eval echo \\\$${wiki_varname}`" local home_varname="home_${server}" local home="`eval echo \\\$${home_varname}`" if [ -z "${title}" ] then title="${server}" fi if [ -z "${type}" ] then local type="simple" fi local example_varname="service_${server}_example" local example="`eval echo \\\$${example_varname}`" if [ -z "${example}" ] then local example="server ${server} accept" fi print_service "${server}" "${type}" "${server_ports}" "${client_ports}" "${require_modules}" "${title}" "${home}" "${wiki}" "${example}" "${notes}" } tmp="/tmp/services.$$" # The simple services cat "../firehol.sh" |\ grep -e "^server_.*_ports=" >"${tmp}" cat "../firehol.sh" |\ grep -e "^client_.*_ports=" >>"${tmp}" cat "../firehol.sh" |\ grep -e "^service_.*_notes=" >>"${tmp}" cat "../firehol.sh" |\ grep -e "^helper_.*=" >>"${tmp}" . "${tmp}" rm -f "${tmp}" all_services() { ( cat "../firehol.sh" |\ grep -e "^server_.*_ports=" |\ cut -d '=' -f 1 |\ sed "s/^server_//" |\ sed "s/_ports\$//" cat "../firehol.sh" |\ grep -e "^rules_.*()" |\ cut -d '(' -f 1 |\ sed "s/^rules_//" ) | sort -f | uniq } # header cat <<"EOF" FireHOL, Pre-defined service definitions.

Bellow is the list of FireHOL supported services. You can overwrite all the services (including those marked as complex) with the procedures defined in Adding Services.

In case you have problems with some service because it is defined by its port names instead of its port numbers, you can find the required port numbers at http://www.graffiti.com/services.

Please report problems related to port names usage. I will replace the faulty names with the relative numbers to eliminate this problem. All the services defined by name in FireHOL are known to resolve in RedHat systems 7.x and 8.


$Id: commands.html,v 1.75 2010/06/07 15:44:09 ktsaou Exp $

FireHOL, a firewall for humans...
© Copyright 2004 Costa Tsaousis <costa@tsaousis.gr> firehol-1.297/doc/create_services.sh000066400000000000000000001172361225731333700174530ustar00rootroot00000000000000#!/bin/bash if [ ! -f ../firehol.sh -o ! -f services.html ] then echo "Please step into the 'doc' directory of firehol" exit 1 fi title_AH="IPSec Authentication Header (AH)" wikipedia_AH="http://en.wikipedia.org/wiki/IPsec#Authentication_Header" service_AH_notes=" For more information see the FreeS/WAN documentation and RFC 2402. " home_amanda="http://www.amanda.org/" title_amanda="Advanced Maryland Automatic Network Disk Archiver" wikipedia_amanda="http://en.wikipedia.org/wiki/Advanced_Maryland_Automatic_Network_Disk_Archiver" title_aptproxy="Advanced Packaging Tool" wikipedia_aptproxy="http://en.wikipedia.org/wiki/Apt-proxy" title_apcupsd="APC UPS Daemon" home_apcupsd="http://www.apcupsd.com" wikipedia_apcupsd="http://en.wikipedia.org/wiki/Apcupsd" service_apcupsd_notes="This service must be defined as server apcupsd accept on all machines not directly connected to the UPS (i.e. slaves).

Note that the port defined here is not the default port (6666) used if you download and compile APCUPSD, since the default is conflicting with IRC and many distributions (like Debian) have changed this to 6544.

You can define port 6544 in APCUPSD, by changing the value of NETPORT in its configuration file, or overwrite this FireHOL service definition using the procedures described in Adding Services. " title_apcupsdnis="APC UPS Daemon" home_apcupsdnis="http://www.apcupsd.com" wikipedia_apcupsdnis="http://en.wikipedia.org/wiki/Apcupsd" service_apcupsdnis_notes="APC UPS Network Information Server. This service allows the remote WEB interfaces APCUPSD has, to connect and get information from the server directly connected to the UPS device. " server_all_ports="all" client_all_ports="all" service_all_type="complex" service_all_notes=" Matches all traffic (all protocols, ports, etc) while ensuring that required kernel modules are loaded.
This service may indirectly setup a set of other services, if they are required by the kernel modules to be loaded. Currently it activates also ftp, irc and icmp. " server_any_ports="all" client_any_ports="all" service_any_type="complex" service_any_notes=" Matches all traffic (all protocols, ports, etc), but does not care about kernel modules and does not activate any other service indirectly. In combination with the Optional Rule Parameters this service can match unusual traffic (e.g. GRE - protocol 47). " service_any_example="server any myname accept proto 47" server_anystateless_ports="all" client_anystateless_ports="all" service_anystateless_type="complex" service_anystateless_notes=" Matches all traffic (all protocols, ports, etc), but does not care about kernel modules and does not activate any other service indirectly. In combination with the Optional Rule Parameters this service can match unusual traffic (e.g. GRE - protocol 47).

Also, this service is exactly the same with service any, but does not care about the state of traffic. " service_anystateless_example="server anystateless myname accept proto 47" wikipedia_asterisk="http://en.wikipedia.org/wiki/Asterisk_PBX" home_asterisk="http://www.asterisk.org" service_asterisk_notes=" This service refers only to the manager interface of asterisk. You should normally need to enable sip, h323, rtp, etc at the firewall level, if you enable the relative channel drivers of asterisk." title_cups="Common UNIX Printing System" home_cups="http://www.cups.org" wikipedia_cups="http://en.wikipedia.org/wiki/Common_Unix_Printing_System" title_cvspserver="Concurrent Versions System" home_cvspserver="http://www.nongnu.org/cvs/" wikipedia_cvspserver="http://en.wikipedia.org/wiki/Concurrent_Versions_System" server_custom_ports="defined in the command" client_custom_ports="defined in the command" service_custom_type="complex" service_custom_notes=" This service is used by FireHOL to allow you define services it currently does not support.
To find more about this service please check the Adding Services section. " service_custom_example="server custom myimap tcp/143 default accept" home_darkstat="http://dmr.ath.cx/net/darkstat/" service_darkstat_notes=" Darkstat is a network traffic analyzer. It's basically a packet sniffer which runs as a background process on a cable/DSL router and gathers all sorts of useless but interesting statistics. " title_daytime="Daytime Protocol" wikipedia_daytime="http://en.wikipedia.org/wiki/Daytime_Protocol" home_distcc="http://distcc.samba.org/" wikipedia_distcc="http://en.wikipedia.org/wiki/Distcc" service_distcc_notes=" For distcc security, please check the distcc security design. " title_dcc="Distributed Checksum Clearinghouses" wikipedia_dcc="http://en.wikipedia.org/wiki/Distributed_Checksum_Clearinghouse" service_dcc_notes=" See http://www.rhyolite.com/anti-spam/dcc/FAQ.html#firewall-ports. " title_dcpp="Direct Connect++" home_dcpp="http://dcplusplus.sourceforge.net" title_dhcp="Dynamic Host Configuration Protocol" wikipedia_dhcp="http://en.wikipedia.org/wiki/Dhcp" server_dhcp_ports="udp/67" client_dhcp_ports="68" service_dhcp_notes=" The DHCP service has been changed in v1.211 of FireHOL and now it is implemented as stateless. This has been done because DHCP clients broadcast the network (src 0.0.0.0 dst 255.255.255.255) to find a DHCP server. If the DHCP service was stateful the iptables connection tracker would not match the packets and deny to send the reply. Note that this change does not affect the security of either DHCP servers or clients, since only the specific ports are allowed (there is no random port at either the server or the client side).

Also, keep in mind that the server dhcp accept or client dhcp accept commands should placed within interfaces that either do not have src and / or dst defined (because of the initial broadcast).

You can overcome this problem by placing the DHCP service on a separate interface, without an src or dst but with a policy return. Place this interface before the one that defines the rest of the services.

For example:

    interface eth0 dhcp
        policy return
        server dhcp accept

    interface eth0 lan src \"\$mylan\" dst \"\$myip\"
        ...
        client all accept
" service_dhcprelay_notes="DHCP Relay.

From RFC 1812 section 9.1.2
In many cases, BOOTP clients and their associated BOOTP server(s) do not reside on the same IP (sub)network. In such cases, a third-party agent is required to transfer BOOTP messages between clients and servers. Such an agent was originally referred to as a BOOTP forwarding agent. However, to avoid confusion with the IP forwarding function of a router, the name BOOTP relay agent has been adopted instead.

For more information about DHCP Relay see section 9.1.2 of RFC 1812 and section 4 of RFC 1542 " title_dict="Dictionary Server Protocol" wikipedia_dict="http://en.wikipedia.org/wiki/DICT" service_dict_notes=" See RFC2229. " title_dns="Domain Name System" wikipedia_dns="http://en.wikipedia.org/wiki/Domain_Name_System" service_dns_notes=" On very busy DNS servers you may see a few dropped DNS packets in your logs. This is normal. The iptables connection tracker will timeout the session and leave unmatched DNS packets that arrive too late to be any usefull. " title_echo="Echo Protocol" wikipedia_echo="http://en.wikipedia.org/wiki/Echo_Protocol" service_ESP_notes="IPSec Encapsulated Security Payload (ESP).

For more information see the FreeS/WAN documentation and RFC RFC 2406. " title_emule="eMule (Donkey network client)" home_emule="http://www.emule-project.com" server_emule_ports="many" client_emule_ports="many" service_emule_example="client emule accept src 1.1.1.1" service_emule_type="complex" service_emule_notes=" FireHOL defines:

  • Connection from any client port to the server at tcp/4661
     
  • Connection from any client port to the server at tcp/4662
     
  • Connection from any client port to the server at udp/4665
     
  • Connection from any client port to the server at udp/4672
     
  • Connection from any server port to the client at tcp/4662
     
  • Connection from any server port to the client at udp/4672
     
Use the FireHOL client command to match the eMule client.

Please note that the eMule client is an HTTP client also. " title_eserver="eDonkey network server" wikipedia_eserver="http://en.wikipedia.org/wiki/Eserver" title_finger="Finger Protocol" wikipedia_finger="http://en.wikipedia.org/wiki/Finger_protocol" title_ftp="File Transfer Protocol" wikipedia_ftp="http://en.wikipedia.org/wiki/Ftp" service_ftp_notes="FireHOL uses the netfilter module to match both active and passive ftp connections." title_gift="giFT Internet File Transfer" home_gift="http://gift.sourceforge.net" wikipedia_gift="http://en.wikipedia.org/wiki/GiFT" service_gift_notes=" The gift FireHOL service supports:

  • Gnutella listening at tcp/4302
  • FastTrack listening at tcp/1214
  • OpenFT listening at tcp/2182 and tcp/2472
The above ports are the defaults given for the coresponding GiFT modules.

To allow access to the user interface ports of GiFT, use the giftui FireHOL service. " title_giftui="giFT Internet File Transfer" home_giftui="http://gift.sourceforge.net" wikipedia_giftui="http://en.wikipedia.org/wiki/GiFT" service_giftui_notes=" This service refers only to the user interface ports offered by GiFT. To allow gift accept P2P requests, use the gift FireHOL service. " home_gkrellmd="http://members.dslextreme.com/users/billw/gkrellm/gkrellm.html" wikipedia_gkrellmd="http://en.wikipedia.org/wiki/Gkrellm" title_GRE="Generic Routing Encapsulation" wikipedia_GRE="http://en.wikipedia.org/wiki/Generic_Routing_Encapsulation" service_GRE_notes=" This service matches just the protocol. For full VPN functionality additional services may be needed (such as pptp)" home_heartbeat="http://www.linux-ha.org/" service_heartbeat_notes=" This FireHOL service has been designed such a way that it will allow multiple heartbeat clusters on the same LAN. " wikipedia_h323="http://en.wikipedia.org/wiki/H323" title_http="Hypertext Transfer Protocol" wikipedia_http="http://en.wikipedia.org/wiki/Http" title_https="Secure Hypertext Transfer Protocol" wikipedia_https="http://en.wikipedia.org/wiki/Https" home_hylafax="http://www.hylafax.org" wikipedia_hylafax="http://en.wikipedia.org/wiki/Hylafax" server_hylafax_ports="many" client_hylafax_ports="many" service_hylafax_type="complex" service_hylafax_notes=" This complex service allows incomming requests to server port tcp/4559 and outgoing from server port tcp/4558.

The correct operation of this service has not been verified.

USE THIS WITH CARE. A HYLAFAX CLIENT MAY OPEN ALL TCP UNPRIVILEGED PORTS TO ANYONE (from port tcp/4558). " title_iax="Inter-Asterisk eXchange" wikipedia_iax="http://en.wikipedia.org/wiki/Iax" home_iax="http://www.asterisk.org" service_iax_notes=" This service refers to IAX version 1. There is also the iax2 service.

" title_iax2="Inter-Asterisk eXchange" wikipedia_iax2="http://en.wikipedia.org/wiki/Iax" home_iax2="http://www.asterisk.org" service_iax2_notes=" This service refers to IAX version 2. There is also the iax service.

" title_ICMP="Internet Control Message Protocol" wikipedia_ICMP="http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol" title_icmp="${title_ICMP}" wikipedia_icmp="${wikipedia_ICMP}" title_icp="Internet Cache Protocol" wikipedia_icp="http://en.wikipedia.org/wiki/Internet_Cache_Protocol" wikipedia_ident="http://en.wikipedia.org/wiki/Ident" service_ident_example="server ident reject with tcp-reset" title_imap="Internet Message Access Protocol" wikipedia_imap="http://en.wikipedia.org/wiki/Imap" title_imaps="Secure Internet Message Access Protocol" wikipedia_imaps="http://en.wikipedia.org/wiki/Imap" title_ipsecnatt="NAT traversal and IPsec" wikipedia_ipsecnatt="http://en.wikipedia.org/wiki/NAT_traversal#NAT_traversal_and_IPsec" title_irc="Internet Relay Chat" wikipedia_irc="http://en.wikipedia.org/wiki/Internet_Relay_Chat" title_isakmp="Internet Security Association and Key Management Protocol" wikipedia_isakmp="http://en.wikipedia.org/wiki/ISAKMP" service_isakmp_notes="IPSec key negotiation (IKE on UDP port 500).

For more information see the FreeS/WAN documentation. " title_jabber="Extensible Messaging and Presence Protocol" wikipedia_jabber="http://en.wikipedia.org/wiki/Jabber" service_jabber_notes=" Clear and SSL client-to-server connections. " title_jabberd="Extensible Messaging and Presence Protocol" wikipedia_jabberd="http://en.wikipedia.org/wiki/Jabber" service_jabberd_notes=" Clear and SSL jabber client-to-server and server-to-server connections.

Use this service for a jabberd server. In all other cases, use the jabber service. " title_l2tp="Layer 2 Tunneling Protocol" wikipedia_l2tp="http://en.wikipedia.org/wiki/L2tp" title_ldap="Lightweight Directory Access Protocol" wikipedia_ldap="http://en.wikipedia.org/wiki/Ldap" title_ldaps="Lightweight Directory Access Protocol" wikipedia_ldaps="http://en.wikipedia.org/wiki/Ldap" title_lpd="Line Printer Daemon protocol" wikipedia_lpd="http://en.wikipedia.org/wiki/Line_Printer_Daemon_protocol" service_lpd_notes=" LPD is documented in RFC 1179.

Since many operating systems are incorrectly using non-default client ports for LPD access, this definition allows any client port to access the service (additionally to the RFC defined 721 to 731 inclusive)." service_microsoft_ds_notes=" Direct Hosted (i.e. NETBIOS-less SMB)

This is another NETBIOS Session Service with minor differences with netbios_ssn. It is supported only by Windows 2000 and Windows XP and it offers the advantage of being indepedent of WINS for name resolution.

It seems that samba supports transparently this protocol on the netbios_ssn ports, so that either direct hosted or traditional SMB can be served simultaneously.

Please refer to the netbios_ssn service for more information. " title_mms="Microsoft Media Server" wikipedia_mms="http://en.wikipedia.org/wiki/Microsoft_Media_Server" service_mms_notes=" Microsoft's proprietary network streaming protocol used to transfer unicast data in Windows Media Services (previously called NetShow Services). MMS can be transported via UDP or TCP. The MMS default port is UDP/TCP 1755. " service_ms_ds_notes=" Direct Hosted (i.e. NETBIOS-less SMB)

This is another NETBIOS Session Service with minor differences with netbios_ssn. It is supported only by Windows 2000 and Windows XP and it offers the advantage of being indepedent of WINS for name resolution.

It seems that samba supports transparently this protocol on the netbios_ssn ports, so that either direct hosted or traditional SMB can be served simultaneously.

Please refer to the netbios_ssn service for more information. " service_msn_notes=" Microsoft MSN Messenger Service

For a discussion about what works and what is not, please take a look at this technet note. " wikipedia_multicast="http://en.wikipedia.org/wiki/Multicast" server_multicast_ports="N/A" client_multicast_ports="N/A" service_multicast_type="complex" service_multicast_notes=" The multicast service matches all packets send to 224.0.0.0/4 using IGMP or UDP. " service_multicast_example="server multicast reject with proto-unreach" home_mysql="http://www.mysql.com/" wikipedia_mysql="http://en.wikipedia.org/wiki/Mysql" wikipedia_netbackup="http://en.wikipedia.org/wiki/Netbackup" service_netbackup_notes=" This is the Veritas NetBackup service. To use this service you must define it as both client and server in NetBackup clients and NetBackup servers." service_netbackup_example="server netbackup accept
client netbackup accept" title_netbios_ns="NETBIOS Name Service" wikipedia_netbios_ns="http://en.wikipedia.org/wiki/Netbios#Name_service" service_netbios_ns_notes=" See also the samba service. " title_netbios_dgm="NETBIOS Datagram Distribution Service" wikipedia_netbios_dgm="http://en.wikipedia.org/wiki/Netbios#Datagram_distribution_service" service_netbios_dgm_notes=" See also the samba service.

Keep in mind that this service broadcasts (to the broadcast address of your LAN) UDP packets. If you place this service within an interface that has a dst parameter, remember to include (in the dst parameter) the broadcast address of your LAN too. " title_netbios_ssn="NETBIOS Session Service" wikipedia_netbios_ssn="http://en.wikipedia.org/wiki/Netbios#Session_service" service_netbios_ssn_notes=" See also the samba service.

Please keep in mind that newer NETBIOS clients prefer to use port 445 (microsoft_ds) for the NETBIOS session service, and when this is not available they fall back to port 139 (netbios_ssn). Versions of samba above 3.x bind automatically to ports 139 and 445.

If you have an older samba version and your policy on an interface or router is DROP, clients trying to access port 445 will have to timeout before falling back to port 139. This timeout can be up to several minutes.

To overcome this problem either explicitly REJECT the microsoft_ds service with a tcp-reset message (server microsoft_ds reject with tcp-reset), or redirect port 445 to port 139 using the following rule (put it all-in-one-line at the top of your FireHOL config):

iptables -t nat -A PREROUTING -i eth0 -p tcp -s 1.1.1.1/24 --dport 445 -d 2.2.2.2 -j REDIRECT --to-port 139

or

redirect to 139 inface eth0 src 1.1.1.1/24 proto tcp dst 2.2.2.2 dport 445

where:

  • eth0 is the network interface your NETBIOS server uses
     
  • 1.1.1.1/24 is the subnet matching all the clients IP addresses
     
  • 2.2.2.2 is the IP of your linux server on eth0 (or whatever you set the first one above)
" title_nfs="Network File System" wikipedia_nfs="http://en.wikipedia.org/wiki/Network_File_System_%28protocol%29" server_nfs_ports="many" client_nfs_ports="500:65535" service_nfs_type="complex" service_nfs_notes=" The NFS service queries the RPC service on the NFS server host to find out the ports nfsd, mountd, lockd and rquotad are listening. Then, according to these ports it sets up rules on all the supported protocols (as reported by RPC) in order the clients to be able to reach the server.

For this reason, the NFS service requires that:

  • the firewall is restarted if the NFS server is restarted
  • the NFS server must be specified on all nfs statements (only if it is not the localhost)
Since NFS queries the remote RPC server, it is required to also be allowed to do so, by allowing the portmap service too. Take care, that this is allowed by the running firewall when FireHOL tries to query the RPC server. So you might have to setup NFS in two steps: First add the portmap service and activate the firewall, then add the NFS service and restart the firewall.

To avoid this you can setup your NFS server to listen on pre-defined ports, as it is well documented in http://nfs.sourceforge.net/nfs-howto/ar01s06.html#srv_security_nfsd_mountd. If you do this then you will have to define the the ports using the procedure described in Adding Services. " service_nfs_example="client nfs accept dst 1.2.3.4" title_nis="Network Information Service" wikipedia_nis="http://en.wikipedia.org/wiki/Network_Information_Service" server_nis_ports="many" client_nis_ports="500:65535" service_nis_type="complex" service_nis_notes=" The nis service queries the RPC service on the nis server host to find out the ports ypserv and yppasswdd are listening. Then, according to these ports it sets up rules on all the supported protocols (as reported by RPC) in order the clients to be able to reach the server.

For this reason, the nis service requires that:

  • the firewall is restarted if the nis server is restarted
  • the nis server must be specified on all nis statements (only if it is not the localhost)
Since nis queries the remote RPC server, it is required to also be allowed to do so, by allowing the portmap service too. Take care, that this is allowed by the running firewall when FireHOL tries to query the RPC server. So you might have to setup nis in two steps: First add the portmap service and activate the firewall, then add the nis service and restart the firewall.

This service has been created by Carlos Rodrigues. His comments regarding this implementation, are:

These rules work for client access only!

Pushing changes to slave servers won't work if these rules are active somewhere between the master and its slaves, because it is impossible to predict the ports where yppush will be listening on each push.

Pulling changes directly on the slaves will work, and could be improved performance-wise if these rules are modified to open fypxfrd. This wasn't done because it doesn't make that much sense since pushing changes on the master server is the most common, and recommended, way to replicate maps. " service_nis_example="client nis accept dst 1.2.3.4" title_nntp="Network News Transfer Protocol" wikipedia_nntp="http://en.wikipedia.org/wiki/Nntp" title_nntps="Secure Network News Transfer Protocol" wikipedia_nntps="http://en.wikipedia.org/wiki/Nntp" title_ntp="Network Time Protocol" wikipedia_ntp="http://en.wikipedia.org/wiki/Network_Time_Protocol" title_nut="Network UPS Tools" home_nut="http://networkupstools.org/" wikipedia_nxserver="http://en.wikipedia.org/wiki/NX_Server" service_nxserver_notes=" Default ports used by NX server for connections without encryption.
Note that nxserver also needs the ssh service to be enabled.

The TCP ports used by nxserver is 4000 + DISPLAY_BASE to 4000 + DISPLAY_BASE + DISPLAY_LIMIT. DISPLAY_BASE and DISPLAY_LIMIT are set in /usr/NX/etc/node.conf and the defaults are DISPLAY_BASE=1000 and DISPLAY_LIMIT=200.

For encrypted nxserver sessions, only ssh is needed. " title_oracle="Oracle Database" wikipedia_oracle="http://en.wikipedia.org/wiki/Oracle_db" title_ospf="Open Shortest Path First" wikipedia_ospf="http://en.wikipedia.org/wiki/Ospf" wikipedia_ping="http://en.wikipedia.org/wiki/Ping" server_ping_ports="N/A" client_ping_ports="N/A" service_ping_type="complex" service_ping_notes=" This services matches requests of protocol ICMP and type echo-request (TYPE=8) and their replies of type echo-reply (TYPE=0).

The ping service is stateful. " title_pop3="Post Office Protocol" wikipedia_pop3="http://en.wikipedia.org/wiki/Pop3" title_pop3s="Secure Post Office Protocol" wikipedia_pop3s="http://en.wikipedia.org/wiki/Pop3" title_portmap="Open Network Computing Remote Procedure Call - Port Mapper" wikipedia_portmap="http://en.wikipedia.org/wiki/Portmap" title_postgres="PostgreSQL" wikipedia_postgres="http://en.wikipedia.org/wiki/Postgres" title_pptp="Point-to-Point Tunneling Protocol" wikipedia_pptp="http://en.wikipedia.org/wiki/Pptp" home_privoxy="http://www.privoxy.org/" title_radius="Remote Authentication Dial In User Service (RADIUS)" wikipedia_radius="http://en.wikipedia.org/wiki/RADIUS" title_radiusold="Remote Authentication Dial In User Service (RADIUS)" wikipedia_radiusold="http://en.wikipedia.org/wiki/RADIUS" title_radiusoldproxy="Remote Authentication Dial In User Service (RADIUS)" wikipedia_radiusoldproxy="http://en.wikipedia.org/wiki/RADIUS" title_radiusproxy="Remote Authentication Dial In User Service (RADIUS)" wikipedia_radiusproxy="http://en.wikipedia.org/wiki/RADIUS" title_rdp="Remote Desktop Protocol (also known as Terminal Services)" wikipedia_rdp="http://en.wikipedia.org/wiki/Remote_Desktop_Protocol" title_rndc="Remote Name Daemon Control" wikipedia_rndc="http://en.wikipedia.org/wiki/Rndc" home_rsync="http://rsync.samba.org/" wikipedia_rsync="http://en.wikipedia.org/wiki/Rsync" title_rtp="Real-time Transport Protocol" wikipedia_rtp="http://en.wikipedia.org/wiki/Real-time_Transport_Protocol" service_rtp_notes=" RTP ports are generally all the UDP ports. This definition narrows down RTP ports to UDP 10000 to 20000. " server_samba_ports="many" client_samba_ports="default" service_samba_type="complex" service_samba_notes=" The samba service automatically sets all the rules for netbios_ns, netbios_dgm, netbios_ssn and microsoft_ds.

Please refer to the notes of the above services for more information.

NETBIOS initiates based on the broadcast address of an interface (request goes to broadcast address) but the server responds from its own IP address. This makes the server samba accept statement drop the server reply, because of the way the iptables connection tracker works.

This service definition includes a hack, that allows a linux samba server to respond correctly in such situations, by allowing new outgoing connections from the well known netbios_ns port to the clients high ports.

However, for clients and routers this hack is not applied because it would open all unpriviliged ports to the samba server. The only solution to overcome the problem in such cases (routers or clients) is to build a trust relationship between the samba servers and clients. " service_sip_notes=" SIP is the Session Initiation Protocol, an IETF standard protocol (RFC 2543) for initiating interactive user sessions involving multimedia elements such as video, voice, chat, gaming, etc. SIP works in the application layer of the OSI communications model. " service_stun_notes=" STUN is a protocol for assisting devices behind a NAT firewall or router with their packet routing. " server_timestamp_ports="N/A" client_timestamp_ports="N/A" service_timestamp_type="complex" service_timestamp_notes=" This services matches requests of protocol ICMP and type timestamp-request (TYPE=13) and their replies of type timestamp-reply (TYPE=14).

The timestamp service is stateful. " service_upnp_notes=" UPNP is Univeral Plug and Play.

For a linux implementation check: Linux IGD. " service_whois_notes="See: O'Reilly's Building Internet Firewalls book about whois and firewalls." service_webmin_notes="Webmin is a web-based interface for system administration for Unix." service_xdmcp_notes=" X Display Manager Control Protocol
See http://www.jirka.org/gdm-documentation/x70.html for a discussion about XDMCP and firewalls (this is about Gnome Display Manager, a replacement of XDM). " # --------------------------------------------------------------------------------------------------------------- scount=0 print_service() { scount=$[scount + 1] if [ $scount -gt 1 ] then color=' bgcolor="#F0F0F0"' scount=0 else color="" fi local service="${1}"; shift local type="${1}"; shift local sports="${1}"; shift local dports="${1}"; shift local mods="${1}"; shift local title="${1}"; shift local home="${1}"; shift local wiki="${1}"; shift local example="${1}"; shift local notes="${*}" cat <

${service} ${type} EOF echo "" fi if [ ! -z "${home}" ] then echo "" fi if [ ! -z "${wiki}" ] then echo "" fi # echo "" cat <
Server Ports" c=0 for x in ${sports} do if [ $c -ne 0 ] then echo ", " fi echo "${x}" c=$[c + 1] done echo "
Client Ports" c=0 for x in ${dports} do if [ $c -ne 0 ] then echo ", " fi echo "${x}" c=$[c + 1] done if [ ! -z "${mods}" ] then echo "
Netfilter Modules" c=0 for x in ${mods} do if [ $c -ne 0 ] then echo ",
" fi local kv="NF_CONNTRACK_`echo ${x} | tr [a-z] [A-Z]`" test "${kv}" = "NF_CONNTRACK_PROTO_GRE" && local kv="NF_CT_PROTO_GRE" echo "${x} (CONFIG_${kv})" c=$[c + 1] done echo "
Netfilter NAT Modules" c=0 for x in ${mods} do case "${x}" in netbios_ns|netlink|sane) # these do not exist in nat continue ;; esac if [ $c -ne 0 ] then echo ",
" fi local kv="NF_NAT_`echo ${x} | tr [a-z] [A-Z]`" echo "${x} (CONFIG_${kv})" c=$[c + 1] done echo "
Official Site${title} Home
Wikipedia${title} in Wikipedia
Google Search${title} in Google
Notes${notes}
 
Example${example}
EOF lc=0 last_letter= do_letter() { if [ ! -z "${last_letter}" ] then echo "
${last_letter}
" fi } all_services |\ ( last= t=0 while read do first=`echo ${REPLY:0:1} | tr "[a-z]" "[A-Z]"` while [ ! "$first" = "$last" ] do # echo >&2 "F:$first L:$last" t=0 case "$last" in A) last=B test "$first" = "$last" && do_letter $last ;; B) last=C test "$first" = "$last" && do_letter $last ;; C) last=D test "$first" = "$last" && do_letter $last ;; D) last=E test "$first" = "$last" && do_letter $last ;; E) last=F test "$first" = "$last" && do_letter $last ;; F) last=G test "$first" = "$last" && do_letter $last ;; G) last=H test "$first" = "$last" && do_letter $last ;; H) last=I test "$first" = "$last" && do_letter $last ;; I) last=J test "$first" = "$last" && do_letter $last ;; J) last=K test "$first" = "$last" && do_letter $last ;; K) last=L test "$first" = "$last" && do_letter $last ;; L) last=M test "$first" = "$last" && do_letter $last ;; M) last=N test "$first" = "$last" && do_letter $last ;; N) last=O test "$first" = "$last" && do_letter $last ;; O) last=P test "$first" = "$last" && do_letter $last ;; P) last=Q test "$first" = "$last" && do_letter $last ;; Q) last=R test "$first" = "$last" && do_letter $last ;; R) last=S test "$first" = "$last" && do_letter $last ;; S) last=T test "$first" = "$last" && do_letter $last ;; T) last=U test "$first" = "$last" && do_letter $last ;; U) last=V test "$first" = "$last" && do_letter $last ;; V) last=W test "$first" = "$last" && do_letter $last ;; W) last=X test "$first" = "$last" && do_letter $last ;; X) last=Y test "$first" = "$last" && do_letter $last ;; Y) last=Z test "$first" = "$last" && do_letter $last ;; Z) echo >&2 "internal error" exit 1 ;; *) last=A test "$first" = "$last" && do_letter $last ;; esac done t=$[t + 1] test $t -gt 1 && printf ", " printf "$REPLY" done do_letter "" ) cat <<"EOF"

EOF all_services |\ ( while read do smart_print_service $REPLY done ) cat <<"EOF"
ServiceTypeDescription


SourceForge Logo $Id: create_services.sh,v 1.58 2013/01/06 23:49:08 ktsaou Exp $

FireHOL, a firewall for humans...
© Copyright 2004 Costa Tsaousis <costa@tsaousis.gr> EOF firehol-1.297/doc/css.css000066400000000000000000000011031225731333700152340ustar00rootroot00000000000000A:link { text-decoration:none; color:navy; font-weight: bold;} A:visited { text-decoration:none; color:navy; font-weight: bold;} A:active { text-decoration:none; color:navy; font-weight: bold;} A:hover { text-decoration:underline; color:navy; font-weight: bold;} BODY, P, DIV, TD, TH, TR, FORM, OL, UL, LI, INPUT, TEXTAREA, SELECT { font-family: Trebuchet ms, Tahoma, Verdana, Arial, Helvetica; } B { font-family: Trebuchet ms, Tahoma, Verdana, Arial, Helvetica; font-weight: bold; } PRE, TT { font-family: lucidatypewriter, lucida console, courier; font-weight: bold; } firehol-1.297/doc/faq.html000066400000000000000000000372351225731333700154060ustar00rootroot00000000000000 FireHOL, Frequently Asked Questions

Table of Contents

How did you come with this idea?

When you have to manage several dozens of Linux systems and you have a team of engineers to do the job, then for the firewalling of all those you have to find solutions so that:

  • Each member of your team can setup firewalling in a consistent way. In the past, I have seen all kinds of misconfigurations in iptables, even when I was building the rules. Iptables is not easy, it provides many alternatives for doing the job and each engineer knows or likes just a few of them.
     
  • Each member of your team knows exactly how each service operates, which ports it needs, how to prevent various attacks, etc. Again this is not easy stuff. Some techies are more experienced than others and many have very limited knowledge of the underlying stuff. To see the complication, if I tell you to setup a firewall for an FTP server supporting active and passive mode, how much time do you need to find the exact iptables rules and successfully configure the firewall?
     
  • Each member of your team can examine and modify the firewalling rules that another member build some time ago. This is really nightmare. If I give you 200 iptables rules, how much time do you need to figure out what is happening and make a few changes?
     
  • For Quality Assurance, ensure that there is an easy way for auditing the firewall quickly. This is very important. Firewalling is the place that tells you exactly what is allowed and what is not.
I believe that FireHOL solves all these problems in an ideal way. Of course there are many wonderful iptables generators out there, many of them with many more features than FireHOL, with GUIs, centralized configuration of many systems, etc. But consider the following:

  • FireHOL abstracts the service definitions from the firewall rules. In FireHOL you say "I run a FTP server here" and you don't care what FTP means for iptables. FireHOL takes care of this detail, so the engineers can focus on what they already know: The machine runs a FTP server.
     
  • FireHOL minimizes the configuration directives. Do you know how many iptables statements is this:

    route "smtp http ftp" accept src not "a.client b.client c.client" dst "a.server b.server c.server"

    It is 92 iptables statements and it would be more than 1000 if in the clients list there was the UNROUTABLE_IPS variable!!!

  • The FireHOL's configuration file is the best place to look for what a server does. This is actually the first thing I use to audit the configuration of my servers. I just take a look at the firewall configuration. Even if something more is running, I am sure that it cannot be accessed from the outside world.

    Also, this is why I like the client statement so much. Personally, I expect all production systems to be configured with client statements that specifically allow only client requests that are really needed. Although it is pretty helpfull for workstations, I consider client all accept as a security thread for production servers.

For all the above, I consider FireHOL as the most functional way for working with iptables firewalls.

Who are you and why should I trust you for handling my firewall?

Well, don't trust me. I don't want you to do so and you are not supposed to do so. I have made the most to make it possible for you to audit the generated firewall. You have the explain feature where FireHOL interactivelly produces iptables statements for the configuration directives you enter, the debug feature where FireHOL produces all the iptables statements for the entire configuration for you to examine, and extensive automatically generated documentation for all the services supported.

Don't trust me. You are supposed to audit FireHOL services at least once, and if you agree, trust it, not me.

Is the produced iptables firewall optimized?

You have to understand that FireHOL is a generic tool. As such, you gain something and you loose something. Except the fact that all FireHOL configuration rules take one iptables chain (that is one "jump") the produced rules are fully optimized. In many cases, this "jump" optimizes the firewall even further (for example in interface and router statements), while in other cases the "jumps" could be moved to a place where they are really necessary (it is not possible to avoid them). The good thing is that these "jumps" are not so expensive. So, although there is some room for improvement, I have reports from users saying that a huge FireHOL firewall did not introduced a noticable increase in CPU utilization compared to a hand made firewall, for the same traffic.

For the moment, I prefer to keep all the "jumps" there, since it makes the iptables rules a lot more clear and easy to understand. If you believe that I should work on this and you can prove that the "jumps" that could be moved deeper are really expensive at the place they are now, send me a note and I'll do my best.

If you are so interested about performance, you should know that FireHOL places all rules in the iptables firewall, in the same order they appear in the configuration file. So placing your most heavy interface at the top, and within this interface the most heavy service first will really save a lot of processing for iptables.

FireHOL is toooooooooo slow!

This is partially true and partially false. FireHOL runs in two phases: Configuration Processing and Firewall Activation.

Processing of FireHOL configuration files is somewhat slow since all processing is done by BASH (I have not programmed a parser, BASH runs the configuration as if it was a BASH script). This processing however, even if it takes several seconds, it does not affect your security, since the running firewall is not touched during this phase.

Firewall activation is again slow in a few situations, especially if you have lists of hosts that should be allowed or rejected (like UNROUTABLE_IPS). During the processing phase, FireHOL produces a list of the iptables commands to be executed at the activation phase. This list of iptables commands, first clears the running firewall and then it runs iptables commands, one-by-one, until all have executed. As an example, my personal machine configuration file is about 50 lines. These 50 lines produce about 900 iptables statements. For BASH these 900 iptables statements are also followed by another statement to check if the command succeded or failed, which totals to about 1800 BASH statements to be executed. In my machine these 1800 commands take about 8 seconds to be executed. During these 8 seconds the firewall is from totally empty (all traffic allowed) to simply incomplete (some traffic is allowed or dropped explicitly, all other is allowed to pass).

I have written FireHOL in such a way that you can restart the firewall any time you like without disrupting the running traffic. Try it. Start downloading a file, and in the middle of it, restart FireHOL. No change. The download proceeds without any disruption. The only chance for traffic disruption is when you have NAT rules. For just a fraction of the total activation time (normally less than a second, since NAT rules are the first to be executed - i.e. the first few of the huge iptables list) your system will run without them, meaning that no new NATed traffic will be accepted (established connections will work). Again, this will be just for a fraction of a second.

I see you now thinking: OK, but what happens if someone connects to my systems to unwanted services during the activation time? Well, FireHOL's beauty is that it explicitly allows the connections in both ways of the firewall. Most of the other iptables generators allow all established connections to pass unchecked. FireHOL doesn't. It allows the established connections that match the services you have allowed. Nothing more. This means that even if someone is lucky enough to connect to a non-allowed service during the activation time, he will simply be blocked as soon as the firewall activation completes. This gives a window of just a few seconds at which someone could be able to connect to and use private services. Even if he manages to get access within these few seconds, his socket will simply timeout after FireHOL completes.

I installed FireHOL but where is it located? I cannot run it!

FireHOL has been designed to be a startup service. Its exact location depends on the distribution you are using. Most probably you will find FireHOL in /etc/init.d and in RedHat systems you can also access it with the service command.

On Ubuntu, become root and modify /etc/default/firehol to have START_FIREHOL=YES, then, as root, start it with "/etc/init.d/firehol start". To make it start automatically run "update-rc.d firehol defaults".

Is there a list of the system commands FireHOL needs?

As of v1.121 and later, you can find a list of such commands at the top of the FireHOL program file. Currently, FireHOL uses the system path to find these commands and will exit with an error if some command is missing or exists multiple times.

I really need help designing the configuration. Could you help?

You can use the helpme feature of FireHOL to get a configuration file quickly. The helpme feature reads various system parameters of your system and generates a configuration file especially for the host it runs. Helpme is safe to use: it does not alter your running firewall, it does not modify anything on your system. Just try it (give the keyword helpme as a command line argument to FireHOL).

In general, I will try to avoid helping you on manual configuring your specific firewall; I commit however on making helpme detect correctly every single case. I believe, this will benefit all the community, not just you.

In any case, I guess I have done a good job in designing FireHOL the way you expect it to work, and that the documentation is helpful enough, since all the support tools are pretty silent. Of course you are welcome to ask anything you might need regarding FireHOL.

How can I mangle the packets (set TOS, MARK, etc)?

For MARKing packets, you can use the mark helper. For all the other iptables features that FireHOL does not support directly, you can put normal iptables statements anywhere in the configuration file, using the iptables helper. If you really like the FireHOL optional rule parameters for doing this job, just send me an e-mail and I'll write a few helper statements especially for TOS, or whatever.

Why I cannot use the service definitions in helpers?

As you have noted, the service definitions cannot be used in helper statements (mainly NAT). The reason is that currently FireHOL's core logic is limited to one iptables table (filter). To extend this to all iptables tables a new core logic is needed that should be based on something that can be shared across all iptables tables. The only such thing today is MARKs. MARKs are also used for QoS unifying all major traffic management applications.

I have made a few experiments with MARKs but I stuck because there are bugs in the iptables logic when using MARKs. These bugs exist in most kernels distributed today with the main Linux distributions.


$Id: faq.html,v 1.7 2007/05/20 18:36:49 ktsaou Exp $

FireHOL, a firewall for humans...
© Copyright 2004 Costa Tsaousis <costa@tsaousis.gr> firehol-1.297/doc/fwtest.html000066400000000000000000000077231225731333700161520ustar00rootroot00000000000000 FireHOL, Tools to audit your security and test your firewall.

To test your firewall there are a few software tools and a few online services to help you.

I suggest the following tools (of course you need two computers to run the test):

  • Nessus is probably the best open source security scanner available.
    Nessus not only checks the firewall of a host, but also scans for known application vulnerabilities.
    I highly recommend Nessus for periodic (weekly, monthly, etc) scans.
     
  • Nmap ("Network Mapper") is an open source utility for network exploration or security auditing.
     

There are a number of sites that offer firewall testing services to everyone:

  • AuditMyPC
     
  • BroadBand Reports port scanner.
     
  • Security Space, a commercial service with a free scan.
    These people are using something like Nessus (if not Nessus itself).
     
  • Shields UP!! NanoProbe Technology Internet Security Testing for... Windows Users. (note: well, it says for Windows, but it is a port scanner with a limited range of ports to be scanned...)
     
  • SyGate Online Services (S.O.S.) Very nice site to quickly check the security of your system. They have a stealth scanner that tries to break the firewall with a few nice ways (this can show you the difference between FireHOL and a hand made stateless firewall).
     

Other testers on the net:

  • Smurf Amplifier Registry (SAR) The SAR is a tool for Internet administrators being attacked by or implicated in smurf attacks, or those who wish to take precautions.
     

Other useful links:


$Id: fwtest.html,v 1.11 2013/01/07 00:10:31 ktsaou Exp $

FireHOL, a firewall for humans...
© Copyright 2004 Costa Tsaousis <costa@tsaousis.gr> firehol-1.297/doc/header.html000066400000000000000000000105441225731333700160610ustar00rootroot00000000000000 FireHOL, a Linux iptables packet filtering firewall builder for humans...
 FireHOL 
FireHOL, the iptables stateful packet filtering firewall builder.

FireHOL is distributed under GPL.

FireHOL at  Sourceforge   Freshmeat   Ohloh     Downloads   WebCVS   Live Change Log   Support   
Documentation Overview Invoking Language Commands Services Adding Services Tutorial Troubleshooting Firewall Test FAQ  
firehol-1.297/doc/index.html000066400000000000000000000032051225731333700157340ustar00rootroot00000000000000 FireHOL, a Linux iptables packet filtering firewall builder for humans... <P>This frameset document contains: <UL> <LI><A href="header.html">Main Menu</A> <LI><A href="overview.html">Overview of FireHOL</A> </UL> firehol-1.297/doc/invoking.html000066400000000000000000000251661225731333700164630ustar00rootroot00000000000000 FireHOL, How to start FireHOL.

FireHOL has been designed to be a startup service. As such, FireHOL accepts all the command line arguments /etc/init.d/iptables plus a few more. Bellow is a list of the currently supported command line arguments:

ParameterDescription
start Activates the firewall configuration.
The configuration is expected to be found in /etc/firehol/firehol.conf
try Activates the firewall, but waits until the user types the word commit. If this word is not typed within 30 seconds, the previous firewall is restored.
stop Stops a running iptables firewall. This will allow all traffic to pass unchecked.
restart this is an alias for start and is given for compatibility with /etc/init.d/iptables.
condrestart Starts the FireHOL firewall only if it is not already active. It does not detect a modified configuration file, only verifies that FireHOL has been started in the past and not stopped yet.
status Shows the running firewall, as in /sbin/iptables -nxvL | less
panic It removes all rules from the running firewall and then it DROPs all traffic on all iptables tables (mangle, nat, filter) and pre-defined chains (PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING), thus blocking all IP communication. DROPing is not done by changing the default policy to DROP, but by adding just one rule per table/chain to drop all traffic, because the default iptables scripts supplied by many systems (including RedHat 8) do not reset all the chains to ACCEPT when starting (FireHOL resets them correctly).

When activating panic mode, FireHOL checks for the existance of the SSH_CLIENT shell environment variable (set by SSH). If it find this, then panic mode will allow the established SSH connection specified in this variable to operate. Notice that in order for this to work, you should have su without the minus (-) sign, since su - overwrites the shell variables and therefore the SSH_CLIENT variable is lost.

Alternativelly, after the panic argument you can specify an IP address in which case all established connections between this IP address and the host in panic will be allowed.

save Start the firewall and then save it using /sbin/iptables-save to /etc/sysconfig/iptables.

Since v1.64, this is not implemented using /etc/init.d/iptables save because there is a bug in some versions of iptables-save that save invalid commands (! --uid-owner A is saved as --uid-owner !A) which cannot be restored. FireHOL fixes this problem (by saving it, and then replacing --uid-owner ! with ! --uid-owner ).

Note that not all FireHOL firewalls will work if restored with: /etc/init.d/iptables start because FireHOL handles kernel modules and might have queried RPC servers (used by the NFS service) before starting the firewall. Also, FireHOL automatically checks current kernel configuration for client ports range. If you restore a firewall using the iptables service your firewall may not work as expected.

Since v1.258 FireHOL also saves the required kernel modules in an executable shell script in /var/spool/firehol/last_save_modules.sh. This script can be called during boot to restore the required kernel modules for the firewall saved using this command.

debug Parses the configuration file but instead of activating it, it shows the generated iptables statements.
explain Enters an interactive mode where it accepts normal configuration commands and presents the generated iptables commands for each of them, together with some reasoning for its purpose. Additionally, it automatically generates a configuration script based on the successfull commands given.

When in directive mode, FireHOL has the following special commands:

  • help to present some help
  • show to present the generated FireHOL configuration
  • quit to exit interactive mode and quit FireHOL
helpme Tries to guess the FireHOL configuration needed for the current machine.
FireHOL will not stop or alter the running firewall. The configuration file is given in the standard output of FireHOL, thus

/etc/init.d/firehol helpme >/tmp/firehol.conf

will produce the output in /tmp/firehol.conf.

The generated FireHOL configuration should and must be edited before used on your systems. You are required to take many decisions and the comments of the generated file will instruct you for many of them.

<a filename> a different configuration file. If no other argument is given, the configuration file will be "tried" (default = try). Otherwise the argument next to the filename can be one of start, debug, try.
<nothing> Presents help about FireHOL usage.

Since version 1.45 of FireHOL, configuration files can accept command line arguments. These commands line arguments are given to FireHOL which passes them to the configuration file. All the above FireHOL parameters support this feature. To activate it, add a double dash (--) as the command line argument to FireHOL and then just give parameters to be passed to the configuration file.

What happens when FireHOL runs?

FireHOL is a BASH script. To run its configuration file, FireHOL first defines a set of functions and variables and then it "sources" (runs inline) its configuration file to be executed by BASH.

The keywords interface, client, server, router, etc. are all BASH functions that are executed by BASH when and if they appear in the configuration file. Using shared variables these functions share some state information that allows them to know, for example, that a client command appears within an interface and not within a router and that the name given to an interface has not been used before.

Instead of running iptables commands directly, each of these functions (i.e. FireHOL) just writes the generated iptables commands to a temporary file. This is done to prevent altering a running firewall before ensuring that the syntax of the configuration file is correct. So, a complete run of the configuration file actually produces all the iptables commands for the firewall, written to a temporary file (script).  Even the iptables commands given within the configuration file use the same concept (they just generate iptables commands in this script).

Finally, this script (the generated iptables commands) has to be run, but before doing so, FireHOL saves the running firewall to another temporary file. The saved firewall will be automatically restored if some of the generated iptables commands produces an error. Such an error is possible when for example, you specify an invalid IP address or hostname, or an invalid argument to some  parameter that gets passed to iptables as-is.

It is important to understand that during the run of the generated iptables script (including the possible restoration of the old firewall), FireHOL allows all traffic to reach its destination. This has been done to prevent a possible lock-out situation where you are SSHing to the server to alter its firewall, and suddenly you loose the connection (although this can still happen if your new firewall doesn't allow the connection).

If no error has been seen, FireHOL deletes all temporary files generated and exits.

In case there was an error, FireHOL will make the most to restore your previous firewall and will present you details about the error and its line number in the original configuration file.


$Id: invoking.html,v 1.20 2007/07/20 21:16:59 ktsaou Exp $

FireHOL, a firewall for humans...
© Copyright 2004 Costa Tsaousis <costa@tsaousis.gr> firehol-1.297/doc/language.html000066400000000000000000000110001225731333700164000ustar00rootroot00000000000000 FireHOL, The configuration language.

FireHOL configuration files are normal BASH scripts. As such, you can use all BASH features within FireHOL configuration files, including functions, loops, variables, I/O, etc, etc.

I have chosen BASH as the configuration language for FireHOL since it is the common denominator for a language that all UNIX system administrators and developers (or at least those that respect themselves) know and understand better.

The fact that FireHOL uses BASH for its configuration, allows third parties to develop add-ons, to enable FireHOL use SQL databases, directory structures, DBM or other files, WEB front ends or other means for the rules of the firewall.

Exactly the same reason allows the build of remote managers for centralized administration of a large number of Linux hosts and routers.

The only BASH features a FireHOL configuration script should never use, is traps and the exit command. Traps are used by FireHOL for cleaning up all temporary files, and possibly restoring the previously running firewall in case FireHOL execution breaks, and the exit command will not just exit the configuration file, it will exit FireHOL. FireHOL has disabled these features by default, so that you will not be able to use them, unless you specifically enable them.

Also, since a FireHOL configuration script runs inline with FireHOL, all variables and function names defined within the configuration file overwrite the ones defined by FireHOL. For this reason you should avoid using variables that start with FIREHOL_, work_, server_, and client_ as many such variables are used by FireHOL internally. There are also a number of functions names you should avoid, but there is no generic pattern at the moment. I suggest you should avoid defining functions with the names of FireHOL commands (interface, router, client, server, etc) and functions starting with rules_.

Note however that it is allowed to overwrite a few variables and functions if you want to modify FireHOL services (See the Adding Services section for more on this).

To learn BASH scripting I suggest the following documents:


$Id: language.html,v 1.9 2004/10/31 23:43:25 ktsaou Exp $

FireHOL, a firewall for humans...
© Copyright 2004 Costa Tsaousis <costa@tsaousis.gr> firehol-1.297/doc/overview.html000066400000000000000000000670501225731333700165030ustar00rootroot00000000000000 FireHOL, a Linux iptables packet filtering firewall builder for humans...

Latest News

Jan 07, 2013 FireHOL R5 v1.296 released.
Added support for NFLOG. Firehol now syslogs all important actions. Updated services amanda, ftp, pptp, tftp, h323, GRE, sip. Added support for CONNMARK and CLASSIFY. Fixed several issues.


July 31, 2008 FireHOL R5 v1.273 released.
Updated to parse the latest format of the IANA reservations page.

Added support for custom actions for services. This opens a way for allowing actions that can be controlled externally without restarting the firewall.
Fixed several minor issues (better NAT support for all services, handling for external pager command, kernel config parsing, config wizard, etc).

May 20, 2007 FireHOL R5 v1.255 released.
Fixed kernel 2.6.20+ compatibility issues, fixed BASH 3.2 compatibility issues, fixed various iptables compatibility issues.

FireHOL now supports external definitions of RESERVED_IPS, PRIVATE_IPS, MULTICAST_IPS, UNROUTABLE_IPS in /etc/firehol. Also, complains if RESERVED_IPS is older that 90 days.

Policy, now works on routers too.

Updated services: nfs, OSPF, sip, vmwareweb. Added protections: bad-packets, all-floods. Added actions: tarpit. Added support for the recent iptables module. Added addrtype (srctype, dsttype) support in optional rule parameters.

Added FIREHOL_DROP_ORPHAN_TCP_ACK_FIN for busy servers.
Added FIREHOL_LOG_PREFIX to improve logging.

Jan 30, 2005, FireHOL R5 v1.226 released.
This release fixes vulnerabilities where malicious local system users could use FireHOL's temporary files to overwrite arbitrary files on the system (See Secunia Advisory SA13970).

All users are advised to update to this version.

This release includes new service definitions: ANYSTATELESS, TIMESTAMP and DICT. The following helpers have been added: TRANSPARENT_PROXY. Also, added support for knockd as an argument to the accept action.


2003-2004 FireHOL remains as one of the BEST RATED open source applications.
FireHOL is ranked in TOP 20 BEST RATED of FreshMeat II. See the current rating rank at FireHOL's FreshMeat page (note that this page changes dynamically, so the rating might have changed).
I really thank you all for this...

Are you using FireHOL too? Tell us your opinion: rate it here.


May 3, 2004, Latest CVS tarballs available.
You can download a nightly-build CVS version of FireHOL at http://firehol.sf.net/firehol.tar.gz
Although I try to keep CVS versions fully operational, please keep in mind that this CVS version might have bugs.

You can always see what has changed using FireHOL's WebCVS Change Log viewer.

Testimonials
Date: Thu, Mar 30, 2006 19:21

FireHOL is an amazing tool. It leverages the incredible power of netfilter/iptables to turn Linux into a viable firewall solution, even for complex scenarios where people would think "Cisco PIX" or "Check Point FW-1".
Right now I'm using it on a box that filters the traffic passing between the public Internet, 4 VLANs, 1 DMZ and 2 VPN endpoints, with address forwardings (DNAT) thrown in for good measure. This amounts to over 3000 iptables rules (according to "iptables-save") and I still haven't lost my sanity!
Needless to say, I'm using it on all the other Linux servers too. :)

Carlos Rodrigues


Date: Wed, July 7, 2004 03:55

I want to thank you for making such a brilliant firewall configuration tool. I have just finished configuring a firewall with 5 ethernets (two office LANs, two DMZs and one ISP upstream with aliased IPs) for two companies with a shared broadband internet connection, and it works perfectly.
I still marvel at the shortness and simplicity of your configuration language contrasted against the completeness and tightness of the fully stateful iptables rules!

Brian Hoy


Date: Fri, October 31, 2003 21:39

After six hours of nothing but trouble, frustration and desperation with fwbuilder, I installed FireHOL and within minutes I got everything to work as desired. Once more: why making things complicate, when you can make it easy. Thanks a lot.

cassielix


Date: Sat, September 27, 2003 19:23

Hello, I just wanted to thank you for making FireHOL. Explaining firewalls to my girlfriend is, well, a tough thing to do. After getting your script configured and our new DSL connection working, she said "Wow that was fast", then the inevitable "What did you do?". I showed her the short script and she read it like it was english. I can't stop smiling.

Erik Peterson


Date: Thu, July 31, 2003 23:52

Just wanted to drop you a quick note to let you know that I just installed FireHOL 1.120 on my Linux router/firewall, and it worked like a champ!
Super-easy (your example on the FireHOL web page is a perfect starting point for setups like mine, which is a single PC doing NAT/MASQ and firewalling over DSL for an internal LAN) and much more effective than my old stateless firewall that it replaced (which wouldn't even let me ftp without shutting it down).
Just wanted to say thanks for a job well done, and for making your work available to the rest of us!

Scott Taylor
ALVE Technology Corporation

What is FireHOL?

FireHOL is... firewalling made easy:

	transparent_squid 8080 "squid root" inface eth0

interface eth0 mylan
policy accept

interface ppp+ internet
server smtp accept
server http accept
server ftp accept
server ssh accept src trusted.example.com

client all accept

router mylan2internet inface eth0 outface ppp+
masquerade route all accept
FireHOL is an iptables firewall generator producing stateful iptables packet filtering firewalls, on Linux hosts and routers with any number of network interfaces, any number of routes, any number of services served, any number of complexity between variations of the services (including positive and negative expressions).

FireHOL is a language to express firewalling rules, not just a script that produces some kind of a firewall.

The goals of FireHOL are:

  • Make firewalling an easy, straight forward task for everyone, independently of the security skills he/she has.
    FireHOL configuration files are very easy to type and read. To understand a complex firewall you will need just a few seconds.
    Take a look bellow for an example configuration.  
  • Be as secure as possible by allowing explicitly only the wanted traffic to flow.
    FireHOL produces stateful rules for any service or protocol, in both directions of the firewall.  
  • Be a resource of knowledge around services and their peculiarities, as far as firewalling is concerned.
    Check the services list.  
  • Be open enough for any firewalling need. Although FireHOL is pre-configured for a large number of services, you can configure any service you like and FireHOL will turn it into a client, a server, or a router.  
  • Be flexible enough to be used by end users and guru administrators requiring extremely complex firewalls.
    FireHOL configuration files are BASH scripts; you can write in them anything BASH accepts, including variables, pipes, loops, conditions, calls to external programs, run other BASH scripts with FireHOL directives in them, etc.  
  • Be simple to install on any modern Linux system; only one file is required, no compilations involved.  
Is it secure?

FireHOL is secure because it has been designed with the right firewalling concept: deny everything, then allow only what is needed.

Also, FireHOL produces stateful iptables packet filtering firewalls (and possibly, the only generic tool today that does that for all services in both directions of the firewall).

Stateful means that traffic allowed to pass is part of a valid connection that has been initiated the right way. Stateful also means that you can have control based on who initiated the traffic. For example: you can choose to be able to ping anyone on the internet, but no one to be able to ping you. If for example you don't need to run a server on your Linux host, you can easily achieve a situation where you are able to do anything to anyone, but as far as the rest of world is concerned, you do not exist!

Learn another language?

FireHOL has been designed to allow you configure your firewall the same way you think of it. Its language is extremely simple. Basically you have to learn four commands:

  • interface, to setup a firewall on a network interface  
  • router, to setup a firewall on traffic routed from one network interface to another  
  • server, to setup a listening service within an interface or router. The same command can be used as route within routers.  
  • client, to setup a service client within an interface or router  
Client and server commands have exactly the same syntax. Interface has two mandatory arguments and router has only one (and this is the same with one of the two interface requires). All the optional parameters are the same to all of them. This sounds like just one command is to be learned...

Of course there are a few more commands defined, but all of them exist just to give you finer control on these four.

If you don't believe it is simple, consider this example:

Thoughts... In FireHOL
I have a Linux host with two network interfaces.
  • The first is eth0 that connects to my LAN  
  • The other is a PPP device that connects to the internet  

interface eth0 lan
		
interface ppp+ internet
		
To the internet my Linux provides:
  • a MAIL server  
  • a WEB server  
  • a FTP server  
  • a SSH server, but only for my office computer  
office="my-office-pc.example.com"

interface eth0 lan

interface ppp+ internet
	server smtp accept
	server http accept
	server ftp  accept
	server ssh  accept src $office
		
My Linux is also a workstation, I want to run any client I wish.
office="my-office-pc.example.com"

interface eth0 lan

interface ppp+ internet
server smtp accept
server http accept
server ftp accept
server ssh accept src "$office"
client all accept
My LAN is trusted.

If a server is running on my Linux I want my LAN PCs to use it.

office="my-office-pc.example.com"

interface eth0 lan policy accept interface ppp+ internet server smtp accept server http accept server ftp accept server ssh accept src "$office" client all accept
I would like my LAN PCs to use this Linux as a gateway for connecting, as clients, to the internet for all the services they wish.
office="my-office-pc.example.com"

interface eth0 lan
policy accept

interface ppp+ internet
server smtp accept
server http accept
server ftp accept
server ssh accept src "$office"

client all accept
router lan2internet inface eth0 outface ppp+ route all accept
My LAN PCs have private IPs, unroutable to the Internet.

I need to masquerade somehow their IP addresses for internet access.

office="my-office-pc.example.com"

interface eth0 lan
policy accept

interface ppp+ internet
server smtp accept
server http accept
server ftp accept
server ssh accept src "$office"

client all accept

router lan2internet inface eth0 outface ppp+
masquerade route all accept

This is it! The firewall is ready. I hope you have noticed that all the rules given match just one direction of the traffic: the request. They don't say anything about replies (see for example the src, inface or outface parameters). This is because FireHOL handles the replies automatically. You don't have to do anything about them: If a request is allowed, then the corresponding reply is also allowed. This also means that FireHOL produces the iptables statements to exactly match what is allowed in both directions and nothing more. If for example we remove the client all accept from the internet interface, our Linux will not be able to do anything with its PPP device except to send replies matching the server statements within this interface; no pings, no DNS, no web browsing, no nothing!

The complete configuration file (a little bit enriched) of the above example could be (all FireHOL directives are clickable):

	# Require release 5 of FireHOL configuration directives
	version 5

# A space separated list of all the IPs on the internet, I trust office="my-office-pc.example.com" # The IP address of this Linux and LAN for the rest of the world public_ip="1.2.3.4" # My LAN. Everything is allowed here. interface eth0 lan
policy accept # The default is 'drop'. # Make sure the traffic coming in, comes from valid Internet IPs,
# and that is targeting my public IP
interface ppp+ internet src not "$UNROUTABLE_IPS" dst "$public_ip"
# Protect me from various kinds of attacks. protection strong

# Public servers. server smtp accept
server http accept
server ftp accept
server ssh accept src "$office"

# Make sure idents do not timeout. server ident reject with tcp-reset

# This is also a workstation. client all accept


# Route the LAN requests to the internet. router lan2internet inface eth0 outface ppp+

# Masquerading on outface. masquerade # Route all requests from inface to outface
# and their replies back.
route all accept
FireHOL is completely dynamic, since with its language you can describe any firewall configuration you wish using simple commands.

Why?

As an IT executive, responsible for many dozens of Linux systems, I needed a firewalling solution that would allow me and my team to have a clear and simple view of what is happening on each server, as far as firewalling is concerned. I also needed a solution that will allow my team members to produce high quality and homogeneous firewalls independently of their security skills and knowledge. After searching for such a tool, I quickly concluded that no tool is flexible, open, easy, and simple enough for what I needed.

I decided to write FireHOL in a way that will allow me, or anyone else, to view, verify and audit the firewall of any linux server or linux router in seconds. FireHOL's configuration is extremely simple... you don't have to be an expert to design a complicated but secure firewall.

What features does it have?

FireHOL handles firewalls protecting one host on all its interfaces and any combination of stateful firewalls routing traffic from one interface to another. There are no limitations on the number of interfaces or on the number of routing routes (except the ones iptables has, if any).

FireHOL, still lacks a few features: QoS for example is not supported directly. You are welcome to extend FireHOL and send me your patches to integrate within FireHOL. In any case however, you can embed normal iptables commands in a FireHOL configuration to do whatever iptables supports.

Since FireHOL produces stateful commands, for every supported service it needs to know the flow of requests and replies. Today FireHOL supports the following services:

  • Many single socket protocols, such as HTTP, NNTP, SMTP, POP3, IMAP4, RADIUS, SSH, LDAP, MySQL, Telnet, NTP, DNS, etc. There are a few dozens of such services defined in FireHOL. Check this list. Even if something is missing, you can define it.
  • Many complex protocols, such as FTP, NFS, SAMBA, PPTP, etc. If you need some complex protocol that is not present, you will have to program it (in simple BASH scripting - there are many commented examples on how this is done). Again, you will just create one BASH function with the rules of the protocol, and FireHOL will turn it to a client, a server or a router.

$Id: overview.html,v 1.38 2013/01/07 00:10:31 ktsaou Exp $

FireHOL, a firewall for humans...
© Copyright 2004 Costa Tsaousis <costa@tsaousis.gr>

firehol-1.297/doc/search.html000066400000000000000000000060551225731333700161000ustar00rootroot00000000000000 FireHOL, a Linux iptables packet filtering firewall builder for humans...
 
Web firehol.sourceforge.net

$Id: search.html,v 1.1 2004/10/31 23:40:50 ktsaou Exp $

FireHOL, a firewall for humans...
© Copyright 2004 Costa Tsaousis <costa@tsaousis.gr> firehol-1.297/doc/services.html000066400000000000000000003732411225731333700164620ustar00rootroot00000000000000 FireHOL, Pre-defined service definitions.

Bellow is the list of FireHOL supported services. You can overwrite all the services (including those marked as complex) with the procedures defined in Adding Services.

In case you have problems with some service because it is defined by its port names instead of its port numbers, you can find the required port numbers at http://www.graffiti.com/services.

Please report problems related to port names usage. I will replace the faulty names with the relative numbers to eliminate this problem. All the services defined by name in FireHOL are known to resolve in RedHat systems 7.x and 8.


A
AH, all, amanda, any, anystateless, apcupsd, apcupsdnis, aptproxy, asterisk
C
cups, custom, cvspserver
D
darkstat, daytime, dcc, dcpp, dhcp, dhcprelay, dict, distcc, dns
E
echo, emule, eserver, ESP
F
finger, ftp
G
gift, giftui, gkrellmd, GRE
H
h323, heartbeat, http, https, hylafax
I
iax, iax2, icmp, ICMP, icp, ident, imap, imaps, ipsecnatt, irc, isakmp
J
jabber, jabberd
L
l2tp, ldap, ldaps, lpd
M
microsoft_ds, mms, ms_ds, msn, multicast, mysql
N
netbackup, netbios_dgm, netbios_ns, netbios_ssn, nfs, nis, nntp, nntps, ntp, nut, nxserver
O
oracle, OSPF
P
ping, pop3, pop3s, portmap, postgres, pptp, privoxy
R
radius, radiusold, radiusoldproxy, radiusproxy, rdp, rndc, rsync, rtp
S
samba, sane, sip, smtp, smtps, snmp, snmptrap, socks, squid, ssh, stun, submission, sunrpc, swat, syslog
T
telnet, tftp, time, timestamp
U
upnp, uucp
V
vmware, vmwareauth, vmwareweb, vnc
W
webcache, webmin, whois
X
xbox, xdmcp

ServiceTypeDescription
AH simple
Server Ports 51/any
Client Ports any
WikipediaIPSec Authentication Header (AH) in Wikipedia
NotesFor more information see the FreeS/WAN documentation and RFC 2402.
 
Exampleserver AH accept
all complex
Server Ports all
Client Ports all
NotesMatches all traffic (all protocols, ports, etc) while ensuring that required kernel modules are loaded.
This service may indirectly setup a set of other services, if they are required by the kernel modules to be loaded. Currently it activates also ftp, irc and icmp.
 
Exampleserver all accept
amanda simple
Server Ports udp/10080
Client Ports default
Netfilter Modules amanda (CONFIG_NF_CONNTRACK_AMANDA)
Netfilter NAT Modules amanda (CONFIG_NF_NAT_AMANDA)
Official SiteAdvanced Maryland Automatic Network Disk Archiver Home
WikipediaAdvanced Maryland Automatic Network Disk Archiver in Wikipedia
Notes
 
Exampleserver amanda accept
any complex
Server Ports all
Client Ports all
NotesMatches all traffic (all protocols, ports, etc), but does not care about kernel modules and does not activate any other service indirectly. In combination with the Optional Rule Parameters this service can match unusual traffic (e.g. GRE - protocol 47).
 
Exampleserver any myname accept proto 47
anystateless complex
Server Ports all
Client Ports all
NotesMatches all traffic (all protocols, ports, etc), but does not care about kernel modules and does not activate any other service indirectly. In combination with the Optional Rule Parameters this service can match unusual traffic (e.g. GRE - protocol 47).

Also, this service is exactly the same with service any, but does not care about the state of traffic.
 

Exampleserver anystateless myname accept proto 47
apcupsd simple
Server Ports tcp/6544
Client Ports default
Official SiteAPC UPS Daemon Home
WikipediaAPC UPS Daemon in Wikipedia
NotesThis service must be defined as server apcupsd accept on all machines not directly connected to the UPS (i.e. slaves).

Note that the port defined here is not the default port (6666) used if you download and compile APCUPSD, since the default is conflicting with IRC and many distributions (like Debian) have changed this to 6544.

You can define port 6544 in APCUPSD, by changing the value of NETPORT in its configuration file, or overwrite this FireHOL service definition using the procedures described in Adding Services.
 

Exampleserver apcupsd accept
apcupsdnis simple
Server Ports tcp/3551
Client Ports default
Official SiteAPC UPS Daemon Home
WikipediaAPC UPS Daemon in Wikipedia
NotesAPC UPS Network Information Server. This service allows the remote WEB interfaces APCUPSD has, to connect and get information from the server directly connected to the UPS device.
 
Exampleserver apcupsdnis accept
aptproxy simple
Server Ports tcp/9999
Client Ports default
WikipediaAdvanced Packaging Tool in Wikipedia
Notes
 
Exampleserver aptproxy accept
asterisk simple
Server Ports tcp/5038
Client Ports default
Official Siteasterisk Home
Wikipediaasterisk in Wikipedia
NotesThis service refers only to the manager interface of asterisk. You should normally need to enable sip, h323, rtp, etc at the firewall level, if you enable the relative channel drivers of asterisk.
 
Exampleserver asterisk accept
cups simple
Server Ports tcp/631 , udp/631
Client Ports any
Official SiteCommon UNIX Printing System Home
WikipediaCommon UNIX Printing System in Wikipedia
Notes
 
Exampleserver cups accept
custom complex
Server Ports defined in the command
Client Ports defined in the command
NotesThis service is used by FireHOL to allow you define services it currently does not support.
To find more about this service please check the Adding Services section.
 
Exampleserver custom myimap tcp/143 default accept
cvspserver simple
Server Ports tcp/2401
Client Ports default
Official SiteConcurrent Versions System Home
WikipediaConcurrent Versions System in Wikipedia
Notes
 
Exampleserver cvspserver accept
darkstat simple
Server Ports tcp/666
Client Ports default
Official Sitedarkstat Home
NotesDarkstat is a network traffic analyzer. It's basically a packet sniffer which runs as a background process on a cable/DSL router and gathers all sorts of useless but interesting statistics.
 
Exampleserver darkstat accept
daytime simple
Server Ports tcp/13
Client Ports default
WikipediaDaytime Protocol in Wikipedia
Notes
 
Exampleserver daytime accept
dcc simple
Server Ports udp/6277
Client Ports default
WikipediaDistributed Checksum Clearinghouses in Wikipedia
NotesSee http://www.rhyolite.com/anti-spam/dcc/FAQ.html#firewall-ports.
 
Exampleserver dcc accept
dcpp simple
Server Ports tcp/1412 , udp/1412
Client Ports default
Official SiteDirect Connect++ Home
Notes
 
Exampleserver dcpp accept
dhcp simple
Server Ports udp/67
Client Ports 68
WikipediaDynamic Host Configuration Protocol in Wikipedia
NotesThe DHCP service has been changed in v1.211 of FireHOL and now it is implemented as stateless. This has been done because DHCP clients broadcast the network (src 0.0.0.0 dst 255.255.255.255) to find a DHCP server. If the DHCP service was stateful the iptables connection tracker would not match the packets and deny to send the reply. Note that this change does not affect the security of either DHCP servers or clients, since only the specific ports are allowed (there is no random port at either the server or the client side).

Also, keep in mind that the server dhcp accept or client dhcp accept commands should placed within interfaces that either do not have src and / or dst defined (because of the initial broadcast).

You can overcome this problem by placing the DHCP service on a separate interface, without an src or dst but with a policy return. Place this interface before the one that defines the rest of the services.

For example:
 
    interface eth0 dhcp
        policy return
        server dhcp accept

    interface eth0 lan src "$mylan" dst "$myip"
        ...
        client all accept

 

Exampleserver dhcp accept
dhcprelay simple
Server Ports udp/67
Client Ports 67
NotesDHCP Relay.

From RFC 1812 section 9.1.2
In many cases, BOOTP clients and their associated BOOTP server(s) do not reside on the same IP (sub)network. In such cases, a third-party agent is required to transfer BOOTP messages between clients and servers. Such an agent was originally referred to as a BOOTP forwarding agent. However, to avoid confusion with the IP forwarding function of a router, the name BOOTP relay agent has been adopted instead.

For more information about DHCP Relay see section 9.1.2 of RFC 1812 and section 4 of RFC 1542
 

Exampleserver dhcprelay accept
dict simple
Server Ports tcp/2628
Client Ports default
WikipediaDictionary Server Protocol in Wikipedia
NotesSee RFC2229.
 
Exampleserver dict accept
distcc simple
Server Ports tcp/3632
Client Ports default
Official Sitedistcc Home
Wikipediadistcc in Wikipedia
NotesFor distcc security, please check the distcc security design.
 
Exampleserver distcc accept
dns simple
Server Ports udp/53 , tcp/53
Client Ports any
WikipediaDomain Name System in Wikipedia
NotesOn very busy DNS servers you may see a few dropped DNS packets in your logs. This is normal. The iptables connection tracker will timeout the session and leave unmatched DNS packets that arrive too late to be any usefull.
 
Exampleserver dns accept
echo simple
Server Ports tcp/7
Client Ports default
WikipediaEcho Protocol in Wikipedia
Notes
 
Exampleserver echo accept
emule complex
Server Ports many
Client Ports many
Official SiteeMule (Donkey network client) Home
NotesFireHOL defines:
  • Connection from any client port to the server at tcp/4661
     
  • Connection from any client port to the server at tcp/4662
     
  • Connection from any client port to the server at udp/4665
     
  • Connection from any client port to the server at udp/4672
     
  • Connection from any server port to the client at tcp/4662
     
  • Connection from any server port to the client at udp/4672
     
Use the FireHOL client command to match the eMule client.

Please note that the eMule client is an HTTP client also.
 

Exampleclient emule accept src 1.1.1.1
eserver simple
Server Ports tcp/4661 , udp/4661 , udp/4665
Client Ports any
WikipediaeDonkey network server in Wikipedia
Notes
 
Exampleserver eserver accept
ESP simple
Server Ports 50/any
Client Ports any
NotesIPSec Encapsulated Security Payload (ESP).

For more information see the FreeS/WAN documentation and RFC RFC 2406.
 

Exampleserver ESP accept
finger simple
Server Ports tcp/79
Client Ports default
WikipediaFinger Protocol in Wikipedia
Notes
 
Exampleserver finger accept
ftp simple
Server Ports tcp/21
Client Ports default
Netfilter Modules ftp (CONFIG_NF_CONNTRACK_FTP)
Netfilter NAT Modules ftp (CONFIG_NF_NAT_FTP)
WikipediaFile Transfer Protocol in Wikipedia
NotesFireHOL uses the netfilter module to match both active and passive ftp connections.
 
Exampleserver ftp accept
gift simple
Server Ports tcp/4302 , tcp/1214 , tcp/2182 , tcp/2472
Client Ports any
Official SitegiFT Internet File Transfer Home
WikipediagiFT Internet File Transfer in Wikipedia
NotesThe gift FireHOL service supports:
  • Gnutella listening at tcp/4302
  • FastTrack listening at tcp/1214
  • OpenFT listening at tcp/2182 and tcp/2472
The above ports are the defaults given for the coresponding GiFT modules.

To allow access to the user interface ports of GiFT, use the giftui FireHOL service.
 

Exampleserver gift accept
giftui simple
Server Ports tcp/1213
Client Ports default
Official SitegiFT Internet File Transfer Home
WikipediagiFT Internet File Transfer in Wikipedia
NotesThis service refers only to the user interface ports offered by GiFT. To allow gift accept P2P requests, use the gift FireHOL service.
 
Exampleserver giftui accept
gkrellmd simple
Server Ports tcp/19150
Client Ports default
Official Sitegkrellmd Home
Wikipediagkrellmd in Wikipedia
Notes
 
Exampleserver gkrellmd accept
GRE simple
Server Ports 47/any
Client Ports any
Netfilter Modules proto_gre (CONFIG_NF_CT_PROTO_GRE)
Netfilter NAT Modules proto_gre (CONFIG_NF_NAT_PROTO_GRE)
WikipediaGeneric Routing Encapsulation in Wikipedia
NotesThis service matches just the protocol. For full VPN functionality additional services may be needed (such as pptp)
 
Exampleserver GRE accept
h323 simple
Server Ports tcp/1720
Client Ports default
Netfilter Modules h323 (CONFIG_NF_CONNTRACK_H323)
Netfilter NAT Modules h323 (CONFIG_NF_NAT_H323)
Wikipediah323 in Wikipedia
Notes
 
Exampleserver h323 accept
heartbeat simple
Server Ports udp/690:699
Client Ports default
Official Siteheartbeat Home
NotesThis FireHOL service has been designed such a way that it will allow multiple heartbeat clusters on the same LAN.
 
Exampleserver heartbeat accept
http simple
Server Ports tcp/80
Client Ports default
WikipediaHypertext Transfer Protocol in Wikipedia
Notes
 
Exampleserver http accept
https simple
Server Ports tcp/443
Client Ports default
WikipediaSecure Hypertext Transfer Protocol in Wikipedia
Notes
 
Exampleserver https accept
hylafax complex
Server Ports many
Client Ports many
Official Sitehylafax Home
Wikipediahylafax in Wikipedia
NotesThis complex service allows incomming requests to server port tcp/4559 and outgoing from server port tcp/4558.

The correct operation of this service has not been verified.

USE THIS WITH CARE. A HYLAFAX CLIENT MAY OPEN ALL TCP UNPRIVILEGED PORTS TO ANYONE (from port tcp/4558).
 

Exampleserver hylafax accept
iax simple
Server Ports udp/5036
Client Ports default
Official SiteInter-Asterisk eXchange Home
WikipediaInter-Asterisk eXchange in Wikipedia
NotesThis service refers to IAX version 1. There is also the iax2 service.


 

Exampleserver iax accept
iax2 simple
Server Ports udp/5469 , udp/4569
Client Ports default
Official SiteInter-Asterisk eXchange Home
WikipediaInter-Asterisk eXchange in Wikipedia
NotesThis service refers to IAX version 2. There is also the iax service.


 

Exampleserver iax2 accept
icmp simple
Server Ports icmp/any
Client Ports any
WikipediaInternet Control Message Protocol in Wikipedia
Notes
 
Exampleserver icmp accept
ICMP simple
Server Ports icmp/any
Client Ports any
WikipediaInternet Control Message Protocol in Wikipedia
Notes
 
Exampleserver ICMP accept
icp simple
Server Ports udp/3130
Client Ports 3130
WikipediaInternet Cache Protocol in Wikipedia
Notes
 
Exampleserver icp accept
ident simple
Server Ports tcp/113
Client Ports default
Wikipediaident in Wikipedia
Notes
 
Exampleserver ident reject with tcp-reset
imap simple
Server Ports tcp/143
Client Ports default
WikipediaInternet Message Access Protocol in Wikipedia
Notes
 
Exampleserver imap accept
imaps simple
Server Ports tcp/993
Client Ports default
WikipediaSecure Internet Message Access Protocol in Wikipedia
Notes
 
Exampleserver imaps accept
ipsecnatt simple
Server Ports udp/4500
Client Ports any
WikipediaNAT traversal and IPsec in Wikipedia
Notes
 
Exampleserver ipsecnatt accept
irc simple
Server Ports tcp/6667
Client Ports default
Netfilter Modules irc (CONFIG_NF_CONNTRACK_IRC)
Netfilter NAT Modules irc (CONFIG_NF_NAT_IRC)
WikipediaInternet Relay Chat in Wikipedia
Notes
 
Exampleserver irc accept
isakmp simple
Server Ports udp/500
Client Ports any
WikipediaInternet Security Association and Key Management Protocol in Wikipedia
NotesIPSec key negotiation (IKE on UDP port 500).

For more information see the FreeS/WAN documentation.
 

Exampleserver isakmp accept
jabber simple
Server Ports tcp/5222 , tcp/5223
Client Ports default
WikipediaExtensible Messaging and Presence Protocol in Wikipedia
NotesClear and SSL client-to-server connections.
 
Exampleserver jabber accept
jabberd simple
Server Ports tcp/5222 , tcp/5223 , tcp/5269
Client Ports default
WikipediaExtensible Messaging and Presence Protocol in Wikipedia
NotesClear and SSL jabber client-to-server and server-to-server connections.

Use this service for a jabberd server. In all other cases, use the jabber service.
 

Exampleserver jabberd accept
l2tp simple
Server Ports udp/1701
Client Ports any
WikipediaLayer 2 Tunneling Protocol in Wikipedia
Notes
 
Exampleserver l2tp accept
ldap simple
Server Ports tcp/389
Client Ports default
WikipediaLightweight Directory Access Protocol in Wikipedia
Notes
 
Exampleserver ldap accept
ldaps simple
Server Ports tcp/636
Client Ports default
WikipediaLightweight Directory Access Protocol in Wikipedia
Notes
 
Exampleserver ldaps accept
lpd simple
Server Ports tcp/515
Client Ports any
WikipediaLine Printer Daemon protocol in Wikipedia
NotesLPD is documented in RFC 1179.

Since many operating systems are incorrectly using non-default client ports for LPD access, this definition allows any client port to access the service (additionally to the RFC defined 721 to 731 inclusive).
 

Exampleserver lpd accept
microsoft_ds simple
Server Ports tcp/445
Client Ports default
NotesDirect Hosted (i.e. NETBIOS-less SMB)

This is another NETBIOS Session Service with minor differences with netbios_ssn. It is supported only by Windows 2000 and Windows XP and it offers the advantage of being indepedent of WINS for name resolution.

It seems that samba supports transparently this protocol on the netbios_ssn ports, so that either direct hosted or traditional SMB can be served simultaneously.

Please refer to the netbios_ssn service for more information.
 

Exampleserver microsoft_ds accept
mms simple
Server Ports tcp/1755 , udp/1755
Client Ports default
Netfilter Modules mms (CONFIG_NF_CONNTRACK_MMS)
Netfilter NAT Modules mms (CONFIG_NF_NAT_MMS)
WikipediaMicrosoft Media Server in Wikipedia
NotesMicrosoft's proprietary network streaming protocol used to transfer unicast data in Windows Media Services (previously called NetShow Services). MMS can be transported via UDP or TCP. The MMS default port is UDP/TCP 1755.
 
Exampleserver mms accept
ms_ds simple
Server Ports tcp/445
Client Ports default
NotesDirect Hosted (i.e. NETBIOS-less SMB)

This is another NETBIOS Session Service with minor differences with netbios_ssn. It is supported only by Windows 2000 and Windows XP and it offers the advantage of being indepedent of WINS for name resolution.

It seems that samba supports transparently this protocol on the netbios_ssn ports, so that either direct hosted or traditional SMB can be served simultaneously.

Please refer to the netbios_ssn service for more information.
 

Exampleserver ms_ds accept
msn simple
Server Ports tcp/6891
Client Ports default
NotesMicrosoft MSN Messenger Service

For a discussion about what works and what is not, please take a look at this technet note.
 

Exampleserver msn accept
multicast complex
Server Ports N/A
Client Ports N/A
Wikipediamulticast in Wikipedia
NotesThe multicast service matches all packets send to 224.0.0.0/4 using IGMP or UDP.
 
Exampleserver multicast reject with proto-unreach
mysql simple
Server Ports tcp/3306
Client Ports default
Official Sitemysql Home
Wikipediamysql in Wikipedia
Notes
 
Exampleserver mysql accept
netbackup simple
Server Ports tcp/13701 , tcp/13711 , tcp/13720 , tcp/13721 , tcp/13724 , tcp/13782 , tcp/13783
Client Ports any
Wikipedianetbackup in Wikipedia
NotesThis is the Veritas NetBackup service. To use this service you must define it as both client and server in NetBackup clients and NetBackup servers.
 
Exampleserver netbackup accept
client netbackup accept
netbios_dgm simple
Server Ports udp/138
Client Ports any
WikipediaNETBIOS Datagram Distribution Service in Wikipedia
NotesSee also the samba service.

Keep in mind that this service broadcasts (to the broadcast address of your LAN) UDP packets. If you place this service within an interface that has a dst parameter, remember to include (in the dst parameter) the broadcast address of your LAN too.
 

Exampleserver netbios_dgm accept
netbios_ns simple
Server Ports udp/137
Client Ports any
WikipediaNETBIOS Name Service in Wikipedia
NotesSee also the samba service.
 
Exampleserver netbios_ns accept
netbios_ssn simple
Server Ports tcp/139
Client Ports default
WikipediaNETBIOS Session Service in Wikipedia
NotesSee also the samba service.

Please keep in mind that newer NETBIOS clients prefer to use port 445 (microsoft_ds) for the NETBIOS session service, and when this is not available they fall back to port 139 (netbios_ssn). Versions of samba above 3.x bind automatically to ports 139 and 445.

If you have an older samba version and your policy on an interface or router is DROP, clients trying to access port 445 will have to timeout before falling back to port 139. This timeout can be up to several minutes.

To overcome this problem either explicitly REJECT the microsoft_ds service with a tcp-reset message (server microsoft_ds reject with tcp-reset), or redirect port 445 to port 139 using the following rule (put it all-in-one-line at the top of your FireHOL config):

iptables -t nat -A PREROUTING -i eth0 -p tcp -s 1.1.1.1/24 --dport 445 -d 2.2.2.2 -j REDIRECT --to-port 139

or

redirect to 139 inface eth0 src 1.1.1.1/24 proto tcp dst 2.2.2.2 dport 445

where:

  • eth0 is the network interface your NETBIOS server uses
     
  • 1.1.1.1/24 is the subnet matching all the clients IP addresses
     
  • 2.2.2.2 is the IP of your linux server on eth0 (or whatever you set the first one above)

 
Exampleserver netbios_ssn accept
nfs complex
Server Ports many
Client Ports 500:65535
WikipediaNetwork File System in Wikipedia
NotesThe NFS service queries the RPC service on the NFS server host to find out the ports nfsd, mountd, lockd and rquotad are listening. Then, according to these ports it sets up rules on all the supported protocols (as reported by RPC) in order the clients to be able to reach the server.

For this reason, the NFS service requires that:

  • the firewall is restarted if the NFS server is restarted
  • the NFS server must be specified on all nfs statements (only if it is not the localhost)
Since NFS queries the remote RPC server, it is required to also be allowed to do so, by allowing the portmap service too. Take care, that this is allowed by the running firewall when FireHOL tries to query the RPC server. So you might have to setup NFS in two steps: First add the portmap service and activate the firewall, then add the NFS service and restart the firewall.

To avoid this you can setup your NFS server to listen on pre-defined ports, as it is well documented in http://nfs.sourceforge.net/nfs-howto/ar01s06.html#srv_security_nfsd_mountd. If you do this then you will have to define the the ports using the procedure described in Adding Services.
 

Exampleclient nfs accept dst 1.2.3.4
nis complex
Server Ports many
Client Ports 500:65535
WikipediaNetwork Information Service in Wikipedia
NotesThe nis service queries the RPC service on the nis server host to find out the ports ypserv and yppasswdd are listening. Then, according to these ports it sets up rules on all the supported protocols (as reported by RPC) in order the clients to be able to reach the server.

For this reason, the nis service requires that:

  • the firewall is restarted if the nis server is restarted
  • the nis server must be specified on all nis statements (only if it is not the localhost)
Since nis queries the remote RPC server, it is required to also be allowed to do so, by allowing the portmap service too. Take care, that this is allowed by the running firewall when FireHOL tries to query the RPC server. So you might have to setup nis in two steps: First add the portmap service and activate the firewall, then add the nis service and restart the firewall.

This service has been created by Carlos Rodrigues. His comments regarding this implementation, are:

These rules work for client access only!

Pushing changes to slave servers won't work if these rules are active somewhere between the master and its slaves, because it is impossible to predict the ports where yppush will be listening on each push.

Pulling changes directly on the slaves will work, and could be improved performance-wise if these rules are modified to open fypxfrd. This wasn't done because it doesn't make that much sense since pushing changes on the master server is the most common, and recommended, way to replicate maps.
 

Exampleclient nis accept dst 1.2.3.4
nntp simple
Server Ports tcp/119
Client Ports default
WikipediaNetwork News Transfer Protocol in Wikipedia
Notes
 
Exampleserver nntp accept
nntps simple
Server Ports tcp/563
Client Ports default
WikipediaSecure Network News Transfer Protocol in Wikipedia
Notes
 
Exampleserver nntps accept
ntp simple
Server Ports udp/123 , tcp/123
Client Ports any
WikipediaNetwork Time Protocol in Wikipedia
Notes
 
Exampleserver ntp accept
nut simple
Server Ports tcp/3493 , udp/3493
Client Ports default
Official SiteNetwork UPS Tools Home
Notes
 
Exampleserver nut accept
nxserver simple
Server Ports tcp/5000:5200
Client Ports default
Wikipedianxserver in Wikipedia
NotesDefault ports used by NX server for connections without encryption.
Note that nxserver also needs the ssh service to be enabled.

The TCP ports used by nxserver is 4000 + DISPLAY_BASE to 4000 + DISPLAY_BASE + DISPLAY_LIMIT. DISPLAY_BASE and DISPLAY_LIMIT are set in /usr/NX/etc/node.conf and the defaults are DISPLAY_BASE=1000 and DISPLAY_LIMIT=200.

For encrypted nxserver sessions, only ssh is needed.
 

Exampleserver nxserver accept
oracle simple
Server Ports tcp/1521
Client Ports default
WikipediaOracle Database in Wikipedia
Notes
 
Exampleserver oracle accept
OSPF simple
Server Ports 89/any
Client Ports any
Notes
 
Exampleserver OSPF accept
ping complex
Server Ports N/A
Client Ports N/A
Wikipediaping in Wikipedia
NotesThis services matches requests of protocol ICMP and type echo-request (TYPE=8) and their replies of type echo-reply (TYPE=0).

The ping service is stateful.
 

Exampleserver ping accept
pop3 simple
Server Ports tcp/110
Client Ports default
WikipediaPost Office Protocol in Wikipedia
Notes
 
Exampleserver pop3 accept
pop3s simple
Server Ports tcp/995
Client Ports default
WikipediaSecure Post Office Protocol in Wikipedia
Notes
 
Exampleserver pop3s accept
portmap simple
Server Ports udp/111 , tcp/111
Client Ports any
WikipediaOpen Network Computing Remote Procedure Call - Port Mapper in Wikipedia
Notes
 
Exampleserver portmap accept
postgres simple
Server Ports tcp/5432
Client Ports default
WikipediaPostgreSQL in Wikipedia
Notes
 
Exampleserver postgres accept
pptp simple
Server Ports tcp/1723
Client Ports default
Netfilter Modules pptp (CONFIG_NF_CONNTRACK_PPTP) ,
proto_gre (CONFIG_NF_CT_PROTO_GRE)
Netfilter NAT Modules pptp (CONFIG_NF_NAT_PPTP) ,
proto_gre (CONFIG_NF_NAT_PROTO_GRE)
WikipediaPoint-to-Point Tunneling Protocol in Wikipedia
Notes
 
Exampleserver pptp accept
privoxy simple
Server Ports tcp/8118
Client Ports default
Official Siteprivoxy Home
Notes
 
Exampleserver privoxy accept
radius simple
Server Ports udp/1812 , udp/1813
Client Ports default
WikipediaRemote Authentication Dial In User Service (RADIUS) in Wikipedia
Notes
 
Exampleserver radius accept
radiusold simple
Server Ports udp/1645 , udp/1646
Client Ports default
WikipediaRemote Authentication Dial In User Service (RADIUS) in Wikipedia
Notes
 
Exampleserver radiusold accept
radiusoldproxy simple
Server Ports udp/1647
Client Ports default
WikipediaRemote Authentication Dial In User Service (RADIUS) in Wikipedia
Notes
 
Exampleserver radiusoldproxy accept
radiusproxy simple
Server Ports udp/1814
Client Ports default
WikipediaRemote Authentication Dial In User Service (RADIUS) in Wikipedia
Notes
 
Exampleserver radiusproxy accept
rdp simple
Server Ports tcp/3389
Client Ports default
WikipediaRemote Desktop Protocol (also known as Terminal Services) in Wikipedia
Notes
 
Exampleserver rdp accept
rndc simple
Server Ports tcp/953
Client Ports default
WikipediaRemote Name Daemon Control in Wikipedia
Notes
 
Exampleserver rndc accept
rsync simple
Server Ports tcp/873 , udp/873
Client Ports default
Official Sitersync Home
Wikipediarsync in Wikipedia
Notes
 
Exampleserver rsync accept
rtp simple
Server Ports udp/10000:20000
Client Ports any
WikipediaReal-time Transport Protocol in Wikipedia
NotesRTP ports are generally all the UDP ports. This definition narrows down RTP ports to UDP 10000 to 20000.
 
Exampleserver rtp accept
samba complex
Server Ports many
Client Ports default
NotesThe samba service automatically sets all the rules for netbios_ns, netbios_dgm, netbios_ssn and microsoft_ds.

Please refer to the notes of the above services for more information.

NETBIOS initiates based on the broadcast address of an interface (request goes to broadcast address) but the server responds from its own IP address. This makes the server samba accept statement drop the server reply, because of the way the iptables connection tracker works.

This service definition includes a hack, that allows a linux samba server to respond correctly in such situations, by allowing new outgoing connections from the well known netbios_ns port to the clients high ports.

However, for clients and routers this hack is not applied because it would open all unpriviliged ports to the samba server. The only solution to overcome the problem in such cases (routers or clients) is to build a trust relationship between the samba servers and clients.
 

Exampleserver samba accept
sane simple
Server Ports tcp/6566
Client Ports default
Netfilter Modules sane (CONFIG_NF_CONNTRACK_SANE)
Netfilter NAT Modules
Notes
 
Exampleserver sane accept
sip simple
Server Ports udp/5060
Client Ports 5060 , default
Netfilter Modules sip (CONFIG_NF_CONNTRACK_SIP)
Netfilter NAT Modules sip (CONFIG_NF_NAT_SIP)
NotesSIP is the Session Initiation Protocol, an IETF standard protocol (RFC 2543) for initiating interactive user sessions involving multimedia elements such as video, voice, chat, gaming, etc. SIP works in the application layer of the OSI communications model.
 
Exampleserver sip accept
smtp simple
Server Ports tcp/25
Client Ports default
Notes
 
Exampleserver smtp accept
smtps simple
Server Ports tcp/465
Client Ports default
Notes
 
Exampleserver smtps accept
snmp simple
Server Ports udp/161
Client Ports default
Notes
 
Exampleserver snmp accept
snmptrap simple
Server Ports udp/162
Client Ports any
Notes
 
Exampleserver snmptrap accept
socks simple
Server Ports tcp/1080 , udp/1080
Client Ports default
Notes
 
Exampleserver socks accept
squid simple
Server Ports tcp/3128
Client Ports default
Notes
 
Exampleserver squid accept
ssh simple
Server Ports tcp/22
Client Ports default
Notes
 
Exampleserver ssh accept
stun simple
Server Ports udp/3478 , udp/3479
Client Ports any
NotesSTUN is a protocol for assisting devices behind a NAT firewall or router with their packet routing.
 
Exampleserver stun accept
submission simple
Server Ports tcp/587
Client Ports default
Notes
 
Exampleserver submission accept
sunrpc simple
Server Ports udp/111 , tcp/111
Client Ports any
Notes
 
Exampleserver sunrpc accept
swat simple
Server Ports tcp/901
Client Ports default
Notes
 
Exampleserver swat accept
syslog simple
Server Ports udp/514
Client Ports syslog , default
Notes
 
Exampleserver syslog accept
telnet simple
Server Ports tcp/23
Client Ports default
Notes
 
Exampleserver telnet accept
tftp simple
Server Ports udp/69
Client Ports default
Netfilter Modules tftp (CONFIG_NF_CONNTRACK_TFTP)
Netfilter NAT Modules tftp (CONFIG_NF_NAT_TFTP)
Notes
 
Exampleserver tftp accept
time simple
Server Ports tcp/37 , udp/37
Client Ports default
Notes
 
Exampleserver time accept
timestamp complex
Server Ports N/A
Client Ports N/A
NotesThis services matches requests of protocol ICMP and type timestamp-request (TYPE=13) and their replies of type timestamp-reply (TYPE=14).

The timestamp service is stateful.
 

Exampleserver timestamp accept
upnp simple
Server Ports udp/1900 , tcp/2869
Client Ports default
NotesUPNP is Univeral Plug and Play.

For a linux implementation check: Linux IGD.
 

Exampleserver upnp accept
uucp simple
Server Ports tcp/540
Client Ports default
Notes
 
Exampleserver uucp accept
vmware simple
Server Ports tcp/902
Client Ports default
Notes
 
Exampleserver vmware accept
vmwareauth simple
Server Ports tcp/903
Client Ports default
Notes
 
Exampleserver vmwareauth accept
vmwareweb simple
Server Ports tcp/8222 , tcp/8333
Client Ports default
Notes
 
Exampleserver vmwareweb accept
vnc simple
Server Ports tcp/5900:5903
Client Ports default
Notes
 
Exampleserver vnc accept
webcache simple
Server Ports tcp/8080
Client Ports default
Notes
 
Exampleserver webcache accept
webmin simple
Server Ports tcp/10000
Client Ports default
NotesWebmin is a web-based interface for system administration for Unix.
 
Exampleserver webmin accept
whois simple
Server Ports tcp/43
Client Ports default
NotesSee: O'Reilly's Building Internet Firewalls book about whois and firewalls.
 
Exampleserver whois accept
xbox simple
Server Ports
Client Ports
Notes
 
Exampleserver xbox accept
xdmcp simple
Server Ports udp/177
Client Ports default
NotesX Display Manager Control Protocol
See http://www.jirka.org/gdm-documentation/x70.html for a discussion about XDMCP and firewalls (this is about Gnome Display Manager, a replacement of XDM).
 
Exampleserver xdmcp accept


$Id: services.html,v 1.68 2013/01/06 23:49:08 ktsaou Exp $

FireHOL, a firewall for humans...
© Copyright 2004 Costa Tsaousis <costa@tsaousis.gr> firehol-1.297/doc/support.html000066400000000000000000000071001225731333700163370ustar00rootroot00000000000000 FireHOL, Getting help about FireHOL.

You can get support about FireHOL using the following services:

  • Web Forums
     
    • Help,
      help about FireHOL configuration directives and the services supported.
       
    • Open Discussion,
      opinions regarding FireHOL, its past and its future, but also regarding iptables firewalling.
       
    • Requests for Enhancements,
      ideas or needs that you believe they will make FireHOL better, they will promote it , enhance it, or simplify it.

       

  • Web Tracking systems
     
  • Mailing Lists
     
    • FireHOL Support,
      help about FireHOL configuration directives and the services supported.
       
    • FireHOL Development,
      exchange of information between FireHOL developers or want-to-be developers.

       

Finally, you can send me a note at costa@tsaousis.gr.


$Id: support.html,v 1.5 2004/11/01 00:58:36 ktsaou Exp $

FireHOL, a firewall for humans...
© Copyright 2004 Costa Tsaousis <costa@tsaousis.gr> firehol-1.297/doc/trouble.html000066400000000000000000000167051225731333700163120ustar00rootroot00000000000000 FireHOL, Troubleshooting the firewall.

Troubleshooting a running firewall is relatively simple and for almost all iptables firewalls the means you have are the same: the system log.

The system log (usually at /var/log/messages) will log all the packets dropped implicitly by FireHOL. Implicitly means all packets that did not match any of the rules in FireHOL's configuration file.

FireHOL always logs all packets not matched by any rule, although it does not log every single packet, in order to protect you from an attack that could "eat" all of your free hard disk space.

The frequency packets are logged is controlled by the same means the optional rule parameter loglimit is controlled.

In the system log you will find entries that look like:

Dec 21 20:01:07 gateway kernel: IN-internet:IN=ppp0 OUT= MAC= SRC=200.75.88.187 DST=195.97.5.193 \
	LEN=78 TOS=0x00 PREC=0x00 TTL=111 ID=63816 PROTO=UDP SPT=34165 DPT=137 LEN=58 

Dec 21 22:25:39 gateway kernel: OUT-unknown:IN= OUT=ppp0 SRC=195.97.5.193 DST=192.168.23.1 \
	LEN=48 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=139 DPT=1255 WINDOW=2128 RES=0x00 ACK SYN URGP=0 
	
Dec 21 20:01:07 gateway kernel: PASS-unknown:IN=ppp0 OUT=eth0 SRC=200.75.88.187 DST=195.97.5.194 \
	LEN=78 TOS=0x00 PREC=0x00 TTL=110 ID=64840 PROTO=UDP SPT=34132 DPT=137 LEN=58 
Each of such lines represent one packet that did not satisfy the requirements of the configuration file rules.

The important things to look in these logs are:
 

  • Its reason text. In FireHOL this has the form IN-name, OUT-name, PASS-name.
     
    • IN-name matches packets that dropped at the end of the interface's name input. These are packets tried to come into this host (it is not routed traffic).
      Name matches the name given to a FireHOL interface. There is also the special name unknown that matches packets tried to come into this host but did not match any of the interfaces given in FireHOL's configuration file.
       
    • OUT-name matches packets that dropped at the end of the interface's name output. These are packets the host tried to send (it is not traffic routed).
      Name matches the name given to a FireHOL interface. There is also the special name unknown that matches packets tried to go out of this host but did not match any of the interfaces given in FireHOL's configuration file.
       
    • PASS-unknown matches packets that dropped at the end of all routers. This matches forwarded traffic.
      There is no name here, since all FireHOL routers have only one policy: RETURN. This makes all packets traverse all routers and then dropped at the end of the firewall.
       
  • IN= gives the real network interface name the packet came in from.
    It can be empty when the packet was generated locally.
     
  • OUT= gives the real network interface name the packet tried to use to go out of this host.
    It can be empty when the packet was to be received by the firewall host.
     
  • SRC= gives the IP address of the sender.
     
  • DST= gives the IP address of the packet's destination.
     
  • PROTO= gives the protocol this packet is using (TCP, UDP, ICMP, etc).
     
  • SPT= gives the source port number of this packet.
     
  • DPT= gives the destination port number of this packet.
     
Generally, you should monitor the system log for such entries and decide if each entry was something useful or not. If it was something useful, you should have added another service somewhere in your FireHOL configuration to match that packet and allow it to reach its destination. If it was not something useful, then FireHOL did the right job and dropped it.

Keep in mind that there are certain cases where packets get dropped even though FireHOL has specific rules that should allow them to pass. Such cases are not always errors, and here is why:

The iptables connection tracker has a mechanism for matching request packets and reply packets. When an allowed request comes in, the connection tracker keeps it in a list and then waits for a matching reply to come in the opposite direction. This list of active connections is available for you to see at /proc/net/ip_conntrack. Simply cat this file to see all the current connections your system has.

The connection tracker will wait for a reply a certain amount of time. This time is, for example, about 20 seconds for UDP traffic. After that time the connection tracker will remove the request from its list. A reply that is send after the connection tracker has removed the request from its list, will be dropped and therefore logged in the system log.

This situation may, for example, produce a few log entries in your DNS server for cases where the DNS server could not respond within the time limits set by iptables, but this is not a problem because the DNS client had already timed out in 2 or 3 seconds.

Note however that the above are common when the connection tracker is trying to keep a state on a stateless protocol (such as UDP or ICMP). Stateful protocols, such as TCP, always respond immediately to acknowledge the connection and therefore the time needed by the application server to respond does not make the connection tracker to remove the request from its list.


$Id: trouble.html,v 1.8 2004/10/31 23:43:25 ktsaou Exp $

FireHOL, a firewall for humans...
© Copyright 2004 Costa Tsaousis <costa@tsaousis.gr> firehol-1.297/doc/tutorial.html000066400000000000000000000500171225731333700164730ustar00rootroot00000000000000 FireHOL, Configuration tutorial

Since R5 v1.97 of FireHOL there is the command line argument helpme that will try to guess your configuration on the running machine. To use it, simply run:

/etc/init.d/firehol helpme >/tmp/firehol.conf (installed from RPM), or

firehol.sh helpme >/tmp/firehol.conf (installed from .tar.bz2)

The purpose of the helpme feature is to give you a configuration file that you can modify to get an operational firewall quickly, especially if your firewalling and iptables knowledge is limited. This feature does not stop or alter the running firewall of your machine.

Bellow is the procedure you should follow to manually design a secure FireHOL firewall.

1. Identify all the network interfaces your firewall host has

Network interfaces are there for some reason. You have to do something about all the interfaces of your host. If you don't do something at the firewall level with a network interface, then it depends of the firewall policy what will happen with traffic on this interface. By default FireHOL will drop all traffic coming in and going out via an undefined network interface, so the network interface will have no meaning to be up and running. This is a common mistake on some ADSL configurations, where users ignore the loop device that connects the linux router with the ADSL device.

To identify your network interfaces use the ip link show command. The example bellow shows my home router ip link show output:


[root@gateway /]# ip link show
1: lo:  mtu 16436 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0:  mtu 1500 qdisc pfifo_fast qlen 100
    link/ether 00:50:fc:21:9a:ab brd ff:ff:ff:ff:ff:ff
12: ppp0:  mtu 1500 qdisc pfifo_fast qlen 3
    link/ppp
There are a few important thinks to always remember:

  • lo exists on all machines and is used for communication between programs running on this machine. FireHOL handles this automatically. You don't have to do anything about lo.
     
  • Network interfaces (except the lo interface) are used for two purposes:
     
    • By the firewall host for its own communication with the rest of the world. This is the case when the firewall host requests something from some other host (a DNS lookup may be) for its own needs, or when some other host requests something from the firewall host, when the later is running some daemons (servers) too.
       
    • By other hosts as gateways in order to reach other hosts behind the firewall host. In this case, the firewall host simply passes traffic from one of its network interfaces to another. This is also called routing.
       
In the above example, it is clear that I have two network interfaces (except lo): eth0 and ppp0.

One extra step is to identify if the network interfaces appearing here might dynamically change during run-time. For example my ppp0 might become ppp1 or ppp2 in certain cases. To overcome this problem, I can say that my link to the outside world is not ppp0 but ppp+. The plus character matches all the interfaces that begin with the text given before the plus sign. In this case, it matches all the possible network interfaces that start with ppp.

Keep in mind that FireHOL (and iptables) does not really care if the interface defined in a firewall actually exists or not. This means that you can setup firewalls on interfaces that might become available later or altered during run time. This also means that if you define an interface with a wrong name, FireHOL and iptables will not complain.

2. Give a role to each interface identified

Now I have to assign a role to each network interface, i.e. what is the function of each of those interfaces?
For this, I create a table similar to the one bellow. It is important to focus on the REQUESTS; forget the replies.

interfacedescriptionincoming requestsoutgoing requestsrouting requests inrouting requests out
eth0 My home LAN Many services from my LAN workstations (i.e. dns, ftp, samba, squid, dhcp, http, ssh, icmp) A few services my LAN workstations provide (i.e. samba, icmp) All LAN workstations requests going to the internet Nothing
ppp+ The Internet I run a public mailer, a public web server and a public ftp server for my domain All the services my Linux could ask from the internet Nothing All LAN workstations requests going to the internet

Keep in mind that:

  • incoming requests represent servers running on the firewall host.
     
  • outgoing requests represent clients running on the firewall host.
     
  • routing requests in represent clients on hosts at the network interface in question.
     
  • routing requests out represent servers on hosts at the network interface in question.
     
So, the above could also be presented as:
interfacenameserversclientsrouting clientsrouting servers
eth0 home dns, ftp, samba, squid, dhcp, http, ssh, icmp samba, icmp all none
ppp+ internet smtp, http, ftp all none all

3. Create the FireHOL configuration structure

Now that you have a list of all the interfaces and their roles, it is time to start writing the FireHOL configuration file.

First write one interface statement for each network interface you identified above:


	version 5
	
	interface eth0 home
	
	
	interface ppp+ internet
	
	

Now, we can add the servers for each interface (based on the table above). Remember that these servers are all running on the firewall host:


	version 5
	
	interface eth0 home
		server dns	accept
		server ftp	accept
		server samba	accept
		server squid	accept
		server dhcp	accept
		server http	accept
		server ssh	accept
		server icmp	accept
	
	interface ppp+ internet
		server smtp	accept
		server http	accept
		server ftp	accept
	
Now, we can add the clients for each interface. Remember that these clients are all running on the firewall host:

	version 5
	
	interface eth0 home
		server dns	accept
		server ftp	accept
		server samba	accept
		server squid	accept
		server dhcp	accept
		server http	accept
		server ssh	accept
		server icmp	accept
		
		client samba	accept
		client icmp	accept
		
	
	interface ppp+ internet
		server smtp	accept
		server http	accept
		server ftp	accept
		
		client all	accept
		

At this point, everyone should be able to inter-operate correctly with the firewall host, but still we don't route any traffic. This means that the linux box can "see" all the workstations on the LAN and these workstations can "see" the linux box, also that the linux box can "see" the Internet and the Internet can "see" the servers of the ppp+ interface of the linux box, but the LAN workstations cannot "see" the Internet.

It is now time to setup routing. To do this we will have to define a set of routers for all the interface combinations. This means that if we have two interfaces we will have to define two routers. If we have 3 interfaces, we will have to define 6 routers, and so on.


	version 5
	
	interface eth0 home
		server dns	accept
		server ftp	accept
		server samba	accept
		server squid	accept
		server dhcp	accept
		server http	accept
		server ssh	accept
		server icmp	accept
		
		client samba	accept
		client icmp	accept
	
	
	interface ppp+ internet
		server smtp	accept
		server http	accept
		server ftp	accept
		
		client all	accept
	
	
	router home2internet inface eth0 outface ppp+
	
	
	router internet2home inface ppp+ outface eth0
	
	

Remember that inface and outface match the requests, not the replies. This means that the router home2internet matches all requests originated from eth0 and going out to ppp+ (and of course their relative replies in the opposite direction), while the router internet2home matches all the requests from the Internet to the home LAN (and their relative replies back).

Now, based on the roles table of the previous section we see that we should route all requests coming in from eth0 and going out to ppp+, and do not route any request coming from the internet and going out to the home LAN. Here it is:


	version 5
	
	interface eth0 home
		server dns	accept
		server ftp	accept
		server samba	accept
		server squid	accept
		server dhcp	accept
		server http	accept
		server ssh	accept
		server icmp	accept
		
		client samba	accept
		client icmp	accept
	
	
	interface ppp+ internet
		server smtp	accept
		server http	accept
		server ftp	accept
		
		client all	accept
	
	
	router home2internet inface eth0 outface ppp+
		route all accept
	
	
	router internet2home inface ppp+ outface eth0
	
	

This is it. We are done! (for the filtering part of the firewall. Look bellow for setting up NAT too.)

4. Optimizing the firewall

To save typing time, you can use this:


	version 5
	
	interface eth0 home
		server "dns ftp samba squid dhcp http ssh icmp"	accept
		client "samba icmp"				accept
	
	
	interface ppp+ internet
		server "smtp http ftp"	accept
		client all		accept
	
	
	router home2internet inface eth0 outface ppp+
		route all accept

Note that we can remove any router statements not having any rules in them, so the internet2home router has been eliminated.

We might want to have extra checks on each interface to prevent spoofing. To find the IPs of your network interfaces use ip addr show and to find the IP networks behind each interface use ip route show.


	version 5
	
	# The network of our eth0 LAN.
	home_ips="195.97.5.192/28"
	
	interface eth0 home src "${home_ips}"
		server "dns ftp samba squid dhcp http ssh icmp"	accept
		client "samba icmp"				accept
	
	
	interface ppp+ internet src not "${home_ips} ${UNROUTABLE_IPS}"
		server "smtp http ftp"	accept
		client all		accept
	
	
	router home2internet inface eth0 outface ppp+
		route all accept
UNROUTABLE_IPS is a variable defined by FireHOL and contains all the IPs that should not be routed on the internet.

If home LAN did not had real IP addresses, we would have to add a masquerade command in our router:


	version 5
	
	# The network of our eth0 LAN.
	home_ips="195.97.5.192/28"
	
	interface eth0 home src "${home_ips}"
		server "dns ftp samba squid dhcp http ssh icmp"	accept
		client "samba icmp"				accept
	
	
	interface ppp+ internet src not "${home_ips} ${UNROUTABLE_IPS}"
		server "smtp http ftp"	accept
		client all		accept
	
	
	router home2internet inface eth0 outface ppp+
		masquerade
		route all accept
The masquerade command sets up itself on the outface of a router.

We can now protect our ppp interface even further. For this we use the protection command:


	version 5
	
	# The network of our eth0 LAN.
	home_ips="195.97.5.192/28"
	
	interface eth0 home src "${home_ips}"
		server "dns ftp samba squid dhcp http ssh icmp"	accept
		client "samba icmp"				accept
	
	
	interface ppp+ internet src not "${home_ips} ${UNROUTABLE_IPS}"
		protection strong 10/sec 10
		server "smtp http ftp"	accept
		client all		accept
	
	
	router home2internet inface eth0 outface ppp+
		masquerade
		route all accept

It could be nice if instead of dropping wrong packets originated from the Ethernet, to reject them so that our workstations will not have to timeout if we do something that is not allowed. To do this we use the policy command:


	version 5
	
	# The network of our eth0 LAN.
	home_ips="195.97.5.192/28"
	
	interface eth0 home src "${home_ips}"
		policy reject
		server "dns ftp samba squid dhcp http ssh icmp"	accept
		client "samba icmp"				accept
	
	
	interface ppp+ internet src not "${home_ips} ${UNROUTABLE_IPS}"
		protection strong 10/sec 10
		server "smtp http ftp"	accept
		client all		accept
	
	
	router home2internet inface eth0 outface ppp+
		masquerade
		route all accept

Some servers on the Internet try to ident back the client to find information about the user requesting the service. With our current firewall, such servers will have to timeout before accepting our request. To speed thinks up we could write:


	version 5
	
	# The network of our eth0 LAN.
	home_ips="195.97.5.192/28"
	
	interface eth0 home src "${home_ips}"
		policy reject
		server "dns ftp samba squid dhcp http ssh icmp"	accept
		client "samba icmp"				accept
	
	
	interface ppp+ internet src not "${home_ips} ${UNROUTABLE_IPS}"
		protection strong 10/sec 10
		server "smtp http ftp"	accept
		
		server ident reject with tcp-reset
		
		client all		accept
	
	
	router home2internet inface eth0 outface ppp+
		masquerade
		route all accept
	
	
	router internet2home inface ppp+ outface eth0
		route ident reject with tcp-reset
	
Note that we now have added the router we eliminated above, since we need to add a service to it.

The whole routing schema could be rewritten as:


	version 5
	
	# The network of our eth0 LAN.
	home_ips="195.97.5.192/28"
	
	interface eth0 home src "${home_ips}"
		policy reject
		server "dns ftp samba squid dhcp http ssh icmp"	accept
		client "samba icmp"				accept
		
	
	interface ppp+ internet src not "${home_ips} ${UNROUTABLE_IPS}"
		protection strong 10/sec 10
		server "smtp http ftp"	accept
		
		server ident reject with tcp-reset
		
		client all		accept
	
	
	router internet2home inface ppp+ outface eth0
		masquerade reverse
		client all	accept
		server ident	reject with tcp-reset
	
Now we have elicited the first router, but we defined everything in the second. We have used the reverse keyword in masquerade to make it set up in inface this time.

We could use the first router (home2internet) to do everything, but then the client and server commands would need be reversed (server all, client ident) which would be confusing.


$Id: tutorial.html,v 1.16 2004/10/31 23:43:25 ktsaou Exp $

FireHOL, a firewall for humans...
© Copyright 2004 Costa Tsaousis <costa@tsaousis.gr> firehol-1.297/examples/000077500000000000000000000000001225731333700150105ustar00rootroot00000000000000firehol-1.297/examples/client-all.conf000066400000000000000000000010231225731333700176770ustar00rootroot00000000000000# # $Id: client-all.conf,v 1.2 2002/12/31 15:44:34 ktsaou Exp $ # # This configuration file will allow all requests originating from the # local machine to be send through all network interfaces. # # No requests are allowed to come from the network. The host will be # completely stealthed! It will not respond to anything, and it will # not be pingable, although it will be able to originate anything # (even pings to other hosts). # version 5 # Accept all client traffic on any interface interface any world client all accept firehol-1.297/examples/home-adsl.conf000066400000000000000000000066161225731333700175410ustar00rootroot00000000000000# # $Id: home-adsl.conf,v 1.6 2003/10/12 13:43:42 ktsaou Exp $ # # THIS IS AN OLD EXAMPLE SCRIPT, LEFT HERE FOR HISTORICAL REASONS # PLEASE USE THE lan-gateway.conf EXAMPLE. # # CASE: # Configuration file for a home router with two Ethernet interfaces: # one connected to an ADSL modem (loop) # another for the local LAN (hub / switch) # # Traffic is routed through a PPP interface # # The PPP interface gets a dynamic (random) IP address and the LAN works # with private IP addresses. # # The PCs on the local LAN are trusted. They can access all the services # this Linux box is running. # # This script can also setup a transparent cache for all the PCs on the # local LAN. version 5 # ---------------------------------------------------------------------- # The Ethernet interface your Linux is connected to the ADSL device. adsl_interface="eth0" # The IP address of the above interface. # If empty, this script will try to find it by itself. adsl_interface_ip="" # The IP address of your ADSL device. # If empty, the generated iptables rules will match any source IP # which is highly discouraged. adsl_modem_ip="" # The Ethernet interface your Linux talks with other PCs in your LAN. home_interface="eth1" # Public services for the Internet your linux box should allow. internet_services="smtp http" # At what frequency to accept requests from the internet? internet_requests="10/sec" # The port of a squid proxy server on this Linux box. If you set this # you will get a transparent web cache. # If you don't have this, empty this field. proxy_port="3128" # ---------------------------------------------------------------------- # Normally, you don't have to edit anything bellow. # ---------------------------------------------------------------------- # Code to do add some optional arguments to the ADSL interface. adsl_params= # Find the IP address of the ADSL interface in case # the user did not gave it to us. if [ -z "${adsl_interface_ip}" ] then adsl_interface_ip=`ifconfig | grep -A 1 ${adsl_interface} | grep "inet addr:" | cut -d ':' -f 2 | cut -d ' ' -f 1` fi # Build the optional rule parameters, if we have the adsl_interface_ip if [ -z "${adsl_interface_ip}" ] then error "Please set 'adsl_interface_ip' in the configuration file." else adsl_params="${adsl_params} dst ${adsl_interface_ip}" fi # Build the optional rule parameters, if we have the adsl_modem_ip if [ ! -z "${adsl_modem_ip}" ] then adsl_params="${adsl_params} src ${adsl_modem_ip}" fi # ---------------------------------------------------------------------- # Setup a transparent proxy on this host. if [ ! -z "${proxy_port}" ] then iptables -t nat -A PREROUTING -i ${home_interface} -p tcp --dport 80 -j REDIRECT --to-port ${proxy_port} fi # ADSL loop for connecting to the ADSL device interface "${adsl_interface}" loop ${adsl_params} # accept everything on the ADSL loop policy accept # Trusted LAN for local PCs interface "${home_interface}" home policy accept # ADSL ppp for internet traffic interface ppp+ internet src not "${UNROUTABLE_IPS}" protection strong ${internet_requests} # Public Services server "${internet_services}" accept # Speed up idents server ident reject with tcp-reset # This is a workstation client all accept # Route traffic for the clients on the LAN router myrouter inface ppp+ outface "${home_interface}" # masquerade on ppp+ masquerade reverse # route all client traffic client all accept firehol-1.297/examples/home-dialup.conf000066400000000000000000000037541225731333700200740ustar00rootroot00000000000000# # $Id: home-dialup.conf,v 1.4 2003/10/12 13:43:42 ktsaou Exp $ # # # THIS IS AN OLD EXAMPLE SCRIPT, LEFT HERE FOR HISTORICAL REASONS # PLEASE USE THE lan-gateway.conf EXAMPLE. # # # Configuration file for a home router with one ethernet interface (eth0) # for the home LAN and a PPP interface for connecting to the Internet. # # The PPP interface gets a dynamic (random) IP address and the LAN works # with private IP addresses. # # The PCs on the local LAN are trusted. They can access all the services # this Linux box is running. # # This script can also setup a transparent cache for all the PCs on the # local LAN. version 5 # ---------------------------------------------------------------------- # Public services for the Internet your linux box should allow. internet_services="smtp http" # At what frequency to accept requests from the internet? internet_requests="10/sec" # The Ethernet interface your Linux talks with other PCs in your LAN. home_interface="eth0" # The port of a squid proxy server on this Linux box. If you set this # you will get a transparent web cache. # If you don't have this, empty this field. proxy_port="3128" # ---------------------------------------------------------------------- # Normally, you don't have to edit anything bellow. # Setup a transparent proxy on this host. if [ ! -z "${proxy_port}" ] then iptables -t nat -A PREROUTING -i ${home_interface} -p tcp --dport 80 -j REDIRECT --to-port ${proxy_port} fi # trusted LAN for local clients interface "${home_interface}" home policy accept # PPP for internet traffic interface ppp+ internet src not "${UNROUTABLE_IPS}" protection strong ${internet_requests} # Speed up idents server ident reject with tcp-reset # Public Services server "${internet_services}" accept # This is a workstation client all accept # Route traffic for the clients on the LAN router myrouter inface ppp+ outface "${home_interface}" # masquerade on ppp+ masquerade reverse # route all client traffic client all accept firehol-1.297/examples/lan-gateway.conf000066400000000000000000000120101225731333700200620ustar00rootroot00000000000000# # $Id: lan-gateway.conf,v 1.3 2008/01/13 10:36:42 ktsaou Exp $ # # Configuration file for a LAN router with one ethernet interface (eth0) # for the LAN and a PPP interface for connecting to the Internet. # # The LAN works with private IP addresses. # # This script will also setup a transparent cache for all the PCs on the # local LAN. # ---------------------------------------------------------------------------- # CUSTOM SERVICES # ---------------------------------------------------------------------------- # See the section "Adding Services" in the documentation # Example service x, listening on port TCP/z # > server_x_ports="tcp/z" # > client_x_ports="default" # ---------------------------------------------------------------------------- # NETWORK DEFINITIONS - Normally, only these are to be touched by you. # ---------------------------------------------------------------------------- # You can define anything you like, assuming you are using it later. # --- HOME --- # The definition of our HOME LAN. HOME_MYIP="10.0.0.1" # The IP on our HOME LAN HOME_MYIF="eth0" # The HOME LAN interface HOME_BCAST="10.0.255.255" # The HOME LAN broadcast HOME_LAN="10.0.0.0/16" # The HOME LAN HOME_SERVICES="all" # Do we run a DHCP server on the HOME LAN? HOME_DHCP=1 # Set to 0 to disable # --- PUBLIC --- # The definition of our PUBLIC interface. PUBLIC_MYIP="" # Leave empty for dynamic IP PUBLIC_MYIF="ppp+" # The public interface PUBLIC_SERVICES="smtp http" # Is the PPP interface a DIAL-ON-DEMAND? DIAL_ON_DEMAND=1 # Set to 0 to disable # --- TRUSTED --- # Hosts in the internet I trust for accessing private services # Empty these to disable. TRUSTED_PCS="my-office-pc.example.com" TRUSTED_SERVICES="ssh http" # --- TRANSPARENT CACHE --- # Run a transparent cache? SQUID_PORT="3128" # Leave empty to disable SQUID SQUID_USERS="squid" # Users to be excluded from the cache SQUID_EXCLUDE="" # Web Server IPs to be excluded from the cache # --- BLACKLIST --- # A space-separated list of IPs to be blocked. blacklist="" # ---------------------------------------------------------------------------- # HELPERS # ---------------------------------------------------------------------------- # Block all traffic from/to certain IPs if [ ! -z "${blacklist}" ] then blacklist full "${blacklist}" fi # Setup a transparent squid, only if SQUID_PORT is set. if [ ! -z "${SQUID_PORT}" ] then transparent_squid "${SQUID_PORT}" "${SQUID_USERS}" \ inface "${HOME_MYIF}" src "${HOME_LAN}" \ `test ! -z "${SQUID_EXCLUDE}" && echo "dst not '${SQUID_EXCLUDE}'"` fi # ---------------------------------------------------------------------------- # NETWORK ADDRESS TRANSLATION # ---------------------------------------------------------------------------- # Change the source/destination of packets... # Should we do SNAT or MASQUERADE? # If there is a PUBLIC_MYIP defined, we should do SNAT, otherwise MASQ. # if [ ! -z "${PUBLIC_MYIP}" ] then snat to "${PUBLIC_MYIP}" \ outface "${PUBLIC_MYIF}" \ src "${HOME_LAN}" dst not "${UNROUTABLE_IPS}" else masquerade "${PUBLIC_MYIF}" fi # To have some public service hit an internal machine, do this: # (the example redirects external port TCP/26 to internal IP 10.0.0.2 port 25) # # > dnat to 10.0.0.2:25 \ # > inface "${PUBLIC_MYIF}" \ # > src not "${HOME_LAN} ${UNROUTABLE_IPS}" \ # > proto tcp dport 26 # # For each such statement, the router at the end has to support it. # ---------------------------------------------------------------------------- # PROTECT SELF # ---------------------------------------------------------------------------- # Protect the firewall host... # --- HOME --- # Protect us from the HOME LAN interface "${HOME_MYIF}" home src "${HOME_LAN}" dst "${HOME_MYIP} ${HOME_BCAST}" policy reject server "${HOME_SERVICES}" accept client all accept # DHCP needs 0.0.0.0/255.255.255.255 access. if [ ${HOME_DHCP} -eq 1 ] then interface "${HOME_MYIF}" dhcp server dhcp accept fi # --- PUBLIC --- # Protect us from the PUBLIC interface "${PUBLIC_MYIF}" internet \ src not "${UNROUTABLE_IPS}" \ `test ! -z "${PUBLIC_MYIP}" && echo "dst ${PUBLIC_MYIP}"` protection strong policy drop # Are there any trusted PCs/services? if [ ! -z "${TRUSTED_PCS}" -a ! -z "${TRUSTED_SERVICES}" ] then server "${TRUSTED_SERVICES}" accept src "${TRUSTED_PCS}" fi server "${PUBLIC_SERVICES}" accept client all accept # DIAL-ON-DEMAND needs this in case there is a PUBLIC_MYIP defined. if [ ${DIAL_ON_DEMAND} -eq 1 ] then interface "${PUBLIC_MYIF}" dialup client all accept fi # ---------------------------------------------------------------------------- # PROTECT ROUTING # ---------------------------------------------------------------------------- # Protect the LAN... # Route traffic for the clients on the LAN router internet2lan inface "${PUBLIC_MYIF}" outface "${HOME_MYIF}" \ src not "${UNROUTABLE_IPS}" dst "${HOME_LAN}" # route all client traffic client all accept # For the dnat example above, this is needed: # > server smtp accept dst 10.0.0.2 firehol-1.297/examples/office.conf000066400000000000000000000103631225731333700171150ustar00rootroot00000000000000# # $Id: office.conf,v 1.4 2002/12/31 15:44:34 ktsaou Exp $ # # CASE: # Firewall for a host with only one Ethernet interface connected to # a LAN where the traffic coming in is: # # source 10.0.0.0/16 intranet traffic # any other source internet traffic # # The host can reach the internet via a gateway that SNATs the fake # address this host has to its Ethernet interface to a real one. # We assume that this NAT is bi-directional, meaning that the # gateway will DNAT requests sent from the internet to the real IP # of our host in order to enter the intranet and reach our server. # # If this NAT is not bi-directional (only SNAT but no DNAT), then # the 'internet' and 'trusted' services bellow will simply not # work (FireHOL will not complain). # # SOLUTION: # The following FireHOL configuration script assumes there are a few # network zones with different roles: # # intranet our company's intranet # department our department within the intranet # personal our PCs within the company # internet the whole internet # trusted computers on the internet we need to provide # services to # # For each of the above, there are two definitions: # 1. The IP addresses or address space # 2. The services they can access on this host. # # If you want to disable something, simply comment out or empty the # variables defined for this. # # Other notes: # - idents are rejected # - our host is also a workstation that can run any client # - our host does not route any traffic version 5 # ---------------------------------------------------------------------- # Definitions # ---------------------------------------------------------------------- # The network the company's intranet is using intranet="10.0.0.0/16" intranet_servers="icmp http smtp dns" # The department must be a subnet of intranet # The department will also have access to the intranet servers, so just # add any additional servers for the department only. department="10.0.70.0/24" department_servers="samba imap pop3 lpd portmap" # Personal must be PCs within the intranet (not the department) # Personal PCs will have access to all services the intranet and the # department have access to, so just define the additional ones. personal="10.0.70.33 10.0.70.44" personal_servers="ssh mysql nfs" # Trusted must be real IPs # These clients will have access to all the servers the internet has # access, plus the ones defined bellow. trusted="1.1.1.1/28 2.2.2.2" trusted_servers="ssh http imap icmp telnet" # The rest of the traffic is internet. # Define here the servers for the internet traffic, if any internet_servers="smtp" # How many requests per second should we allow? intranet_requests="50/sec" internet_requests="10/sec" # ---------------------------------------------------------------------- # Normally, you don't have to do anything bellow this point. # ---------------------------------------------------------------------- # The intranet interface eth0 intranet src "${intranet}" policy reject # be friendly to the intranet to prevent timeouts protection strong ${intranet_requests} # Servers for the company's intranet if [ ! -z "${intranet_servers}" ] then server "${intranet_servers}" accept fi # Servers for our department if [ ! -z "${department}" -a ! -z "${department_servers}" ] then server "${department_servers}" accept src "${department}" fi # Servers for our PCs within the company if [ ! -z "${personal}" -a ! -z "${personal_servers}" ] then server "${personal_servers} ${department_servers}" accept src "${personal}" fi # Prevent ident from timing out server ident reject with tcp-reset # This is an Intranet workstation client all accept # To have good accounting, this should be last. # The internet interface eth0 internet src not "${intranet} ${UNROUTABLE_IPS}" policy drop # this is also the default protection strong ${internet_requests} # Public internet servers if [ ! -z "${internet_servers}" ] then server "${internet_servers}" accept fi # Servers for our trusted PCs if [ ! -z "${trusted}" -a ! -z "${trusted_servers}" ] then server "${trusted_servers}" accept src "${trusted}" fi # Prevent ident from timing out server ident reject with tcp-reset # This is an Internet workstation too client all accept # To have good accounting, this should be last. firehol-1.297/examples/server-dmz.conf000066400000000000000000000066461225731333700177710ustar00rootroot00000000000000# # $Id: server-dmz.conf,v 1.2 2003/01/07 02:03:09 ktsaou Exp $ # # CASE: # Configuration file for a dual path server. # # The first network interface is connected to the internet to accept # requests for services running on this server. # # The second network interface is connected to a private LAN, through # which a number of similar servers communicate with each other. # # The server will only be allowed to accept and send specific traffic # matching the servers and clients defined. version 5 # ---------------------------------------------------------------------- # The Ethernet interface this server is connected to the Internet. # You can use more than one (space separated) and if your server # has many aliases for the same interface, you can use the plus sign # to match them all (e.g. eth0+). internet_interface="eth0+" # Enter here all the IPs your server accepts requests from the internet. # This variable accepts a space separated list of IPs, hostnames, etc. # You can leave this empty if you don't want to restrict the IPs traffic # was targeting. internet_ips="" # The servers you wish to run on the internet side of this host. internet_servers="http smtp" # The clients you wish to run on the internet side of this host. internet_clients="dns" # At what frequency to accept requests from the internet? internet_requests="100/sec" # ---------------------------------------------------------------------- # Similar to the internet_interface, but this time for the private one. private_interface="eth1+" # Similar to the internet_ips, but this time for the private. private_ips="" # The address space of all the servers this host might communicate with, # in the private LAN. # Leaving this empty will not check the IPs of the private LAN. private_subnet="" # The servers you wish to run on the private side of this host. private_servers="ssh" # The clients you wish to run on the private side of this host. private_clients="http dns icmp" # At what frequency to accept requests from the private LAN? private_requests="20/sec" # ---------------------------------------------------------------------- # Normally, you don't have to edit anything bellow. # ---------------------------------------------------------------------- # A trick that adds "dst" in front of internet_ips only if it is not # empty. Otherwise, this does nothing. unset internet_params test ! -z "${internet_ips}" && internet_params=(dst "${internet_ips}") # Internet interface interface "${internet_interface}" internet \ src not "${UNROUTABLE_IPS}" "${internet_params[@]}" protection strong ${internet_requests} # The internet servers server "${internet_servers}" accept # The internet clients client "${internet_clients}" accept # Speed up idents by rejecting them server ident reject with tcp-reset # ---------------------------------------------------------------------- # Fix also the parameters for the private network. unset private_params test ! -z "${private_subnet}" && private_params=(src "${private_subnet}") unset private_params2 test ! -z "${private_ips}" && private_params2=(dst "${private_ips}") # Private interface interface "${private_interface}" private \ "${private_params[@]}" "${private_params2[@]}" protection strong ${private_requests} # The private servers server "${private_servers}" accept # The private clients client "${private_clients}" accept # Speed up idents by rejecting them server ident reject with tcp-reset firehol-1.297/firehol.sh000077500000000000000000006046621225731333700151770ustar00rootroot00000000000000#!/bin/bash # # Startup script to implement /etc/firehol/firehol.conf pre-defined rules. # # chkconfig: 2345 99 92 # # description: creates stateful iptables packet filtering firewalls. # # by Costa Tsaousis # # config: /etc/firehol/firehol.conf # # $Id: firehol.sh,v 1.297 2013/01/06 23:49:08 ktsaou Exp $ # # Make sure only root can run us. if [ ! "${UID}" = 0 ] then echo >&2 echo >&2 echo >&2 "Only user root can run FireHOL." echo >&2 fi # Remember who you are. FIREHOL_FILE="${0}" FIREHOL_DEFAULT_WORKING_DIRECTORY="${PWD}" # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # # EXTERNAL/SYSTEM COMMANDS MANAGEMENT # # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ export PATH="${PATH}:/bin:/usr/bin:/sbin:/usr/sbin" # External commands FireHOL will need. # If one of those is not found, FireHOL will refuse to run. which_cmd() { local block=1 if [ "a${1}" = "a-n" ] then local block=0 shift fi unalias $2 >/dev/null 2>&1 local cmd=`which $2 2>/dev/null | head -n 1` if [ $? -gt 0 -o ! -x "${cmd}" ] then if [ ${block} -eq 1 ] then echo >&2 echo >&2 "ERROR: Command '$2' not found in the system path." echo >&2 " FireHOL requires this command for its operation." echo >&2 " Please install the required package and retry." echo >&2 echo >&2 " Note that you need an operational 'which' command" echo >&2 " for FireHOL to find all the external programs it" echo >&2 " needs. Check it yourself. Run:" echo >&2 echo >&2 " which $2" exit 1 fi return 1 fi eval $1=${cmd} return 0 } # command on demand support. require_cmd() { local block=1 if [ "a$1" = "a-n" ] then local block=0 shift fi # if one is found, return success for x in "${@}" do eval var=`echo ${x} | tr 'a-z' 'A-Z'`_CMD eval val=\$\{${var}\} if [ -z "${val}" ] then which_cmd -n "${var}" "${x}" test $? -eq 0 && return 0 fi done if [ $block -eq 1 ] then echo >&2 echo >&2 "ERROR: FIREHOL REQUIRES THESE COMMANDS:" echo >&2 echo >&2 " ${@}" echo >&2 echo >&2 " You have requested the use of an optional FireHOL" echo >&2 " feature that requires certain external programs" echo >&2 " to be installed in the running system." echo >&2 echo >&2 " Please consult your Linux distribution manual to" echo >&2 " install the package(s) that provide these external" echo >&2 " programs and retry." echo >&2 echo >&2 " Note that you need an operational 'which' command" echo >&2 " for FireHOL to find all the external programs it" echo >&2 " needs. Check it yourself. Run:" echo >&2 for x in "${@}" do echo >&2 " which $x" done exit 1 fi return 1 } # Currently the following commands are required only when needed. # (i.e. Command on Demand) # # wget or curl (either is fine) # zcat or gzcat or gzip (either or none is fine) # less or more (either or none is fine) # ip # netstat # date # hostname # Commands that are mandatory for FireHOL operation: which_cmd CAT_CMD cat which_cmd CUT_CMD cut which_cmd CHOWN_CMD chown which_cmd CHMOD_CMD chmod which_cmd EGREP_CMD egrep which_cmd EXPR_CMD expr which_cmd FIND_CMD find which_cmd FOLD_CMD fold which_cmd GAWK_CMD gawk which_cmd GREP_CMD grep which_cmd HEAD_CMD head which_cmd IPTABLES_CMD iptables which_cmd IPTABLES_SAVE_CMD iptables-save which_cmd LSMOD_CMD lsmod which_cmd MKDIR_CMD mkdir which_cmd MV_CMD mv which_cmd MODPROBE_CMD modprobe which_cmd RENICE_CMD renice which_cmd RM_CMD rm which_cmd SED_CMD sed which_cmd SORT_CMD sort which_cmd SYSCTL_CMD sysctl which_cmd TOUCH_CMD touch which_cmd TR_CMD tr which_cmd UNAME_CMD uname which_cmd UNIQ_CMD uniq which_cmd LOGGER_CMD logger # Special commands pager_cmd() { if [ -z "${LESS_CMD}" ] then require_cmd -n less more test -z "${LESS_CMD}" && LESS_CMD="${MORE_CMD}" test -z "${LESS_CMD}" && LESS_CMD="${CAT_CMD}" fi "${LESS_CMD}" "${@}" } zcat_cmd() { require_cmd -n zcat gzcat gzip test -z "${ZCAT_CMD}" && ZCAT_CMD="${GZCAT_CMD}" if [ ! -z "${ZCAT_CMD}" ] then "${ZCAT_CMD}" "${@}" return $? elif [ ! -z "${GZIP_CMD}" ] then "${CAT_CMD}" "${@}" | "${GZIP_CMD}" -dc return $? fi echo >&2 " " echo >&2 " IMPORTANT WARNING:" echo >&2 " ------------------" echo >&2 " FireHOL cannot find any of the commands: zcat, gzcat, gzip." echo >&2 " Make sure you have one of these available in the system path." echo >&2 " " return 1 } # Concurrent run control FIREHOL_LOCK_FILE="/var/run/firehol.lck" # Time in secs to consider a lock stale FIREHOL_LOCK_FILE_TIMEOUT=600 firehol_concurrent_run_lock() { require_cmd -n lockfile if [ -f "${FIREHOL_LOCK_FILE}" ] then echo >&2 "FireHOL is already running. Waiting for the other process to exit..." fi if [ -z "${LOCKFILE_CMD}" ] then local c=0 while [ -f "${FIREHOL_LOCK_FILE}" ] do c=$[c + 1] test $c -gt ${FIREHOL_LOCK_FILE_TIMEOUT} && break sleep 1 done touch "${FIREHOL_LOCK_FILE}" else ${LOCKFILE_CMD} -1 -r ${FIREHOL_LOCK_FILE_TIMEOUT} -l ${FIREHOL_LOCK_FILE_TIMEOUT} "${FIREHOL_LOCK_FILE}" fi return 0 } # Make sure our generated files cannot be accessed by anyone else. umask 077 # Be nice on production environments ${RENICE_CMD} 10 $$ >/dev/null 2>/dev/null # Find our minor version firehol_minor_version() { ${CAT_CMD} <<"EOF" | ${CUT_CMD} -d ' ' -f 3 | ${CUT_CMD} -d '.' -f 2 $Id: firehol.sh,v 1.297 2013/01/06 23:49:08 ktsaou Exp $ EOF } FIREHOL_MINOR_VERSION=`firehol_minor_version` ${EXPR_CMD} ${FIREHOL_MINOR_VERSION} + 0 >/dev/null 2>&1 if [ $? -ne 0 ] then FIREHOL_MINOR_VERSION=257 fi # Initialize iptables ${IPTABLES_CMD} -nxvL >/dev/null 2>&1 # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # # GLOBAL DEFAULTS # # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # ---------------------------------------------------------------------- # Directories and files # These files will be created and deleted during our run. FIREHOL_DIR="/tmp/.firehol-tmp-$$-${RANDOM}-${RANDOM}" FIREHOL_CHAINS_DIR="${FIREHOL_DIR}/chains" FIREHOL_OUTPUT="${FIREHOL_DIR}/firehol-out.sh" FIREHOL_SAVED="${FIREHOL_DIR}/firehol-save.sh" FIREHOL_TMP="${FIREHOL_DIR}/firehol-tmp.sh" # Redhat like status info for startup script FIREHOL_LOCK_DIR="/var/lock/subsys" test ! -d "${FIREHOL_LOCK_DIR}" && FIREHOL_LOCK_DIR="/var/lock" FIREHOL_SPOOL_DIR="/var/spool/firehol" # The default configuration file # It can be changed on the command line FIREHOL_CONFIG_DIR="/etc/firehol" FIREHOL_CONFIG="${FIREHOL_CONFIG_DIR}/firehol.conf" # Where /etc/init.d/iptables expects its configuration? # Leave it empty for automatic detection FIREHOL_AUTOSAVE= # ------------------------------------------------------------------------------ # Make sure we automatically cleanup when we exit. # WHY: # Even a CTRL-C will call this and we will not leave temp files. # Also, if a configuration file breaks, we will detect this too. FIREHOL_ACTIVATED_SUCCESSFULLY=0 FIREHOL_SYSLOG_FACILITY="daemon" FIREHOL_NOTIFICATION_PROGRAM="" syslog() { local p="$1"; shift "${LOGGER_CMD}" -p ${FIREHOL_SYSLOG_FACILITY}.$p -t "FireHOL[$$]" "${@}" return 0 } firehol_exit() { local restored="NO" if [ -f "${FIREHOL_SAVED}" -a "${FIREHOL_MODE}" = "START" ] then echo echo -n $"FireHOL: Restoring old firewall:" iptables-restore <"${FIREHOL_SAVED}" if [ $? -eq 0 ] then local restored="OK" success $"FireHOL: Restoring old firewall:" else local restored="FAILED" failure $"FireHOL: Restoring old firewall:" fi echo fi # remove the temporary directory created for this session test -d "${FIREHOL_DIR}" && ${RM_CMD} -rf "${FIREHOL_DIR}" # syslog local result= local notify=0 case "${FIREHOL_MODE}" in START) if [ ${FIREHOL_ACTIVATED_SUCCESSFULLY} -eq 0 ] then syslog emerg "FAILED to activate the firewall from ${FIREHOL_CONFIG}. Last good firewall restoration: ${restored}." local result="FAILED" else syslog info "Successfully activated new firewall from ${FIREHOL_CONFIG}." local result="OK" fi local notify=1 ;; STOP) syslog emerg "Firewall has been stopped. Policy is ACCEPT EVERYTHING!" local notify=1 ;; PANIC) syslog emerg "PANIC! Machine has been locked. Policy is DROP EVERYTHING!" local notify=1 ;; *) # do nothing for the rest local notify=0 ;; esac # do we have to run a program? if [ ${notify} -eq 1 ] then if [ ! -z "${FIREHOL_NOTIFICATION_PROGRAM}" -a -x "${FIREHOL_NOTIFICATION_PROGRAM}" ] then # we just fork it, so that it will not depend on terminal conditions "${FIREHOL_NOTIFICATION_PROGRAM}" "${FIREHOL_CONFIG}" "${result}" "${restored}" "${work_error}" "${work_runtime_error}" >/dev/null 2>&1 &2 echo >&2 echo >&2 "NOTICE: Your config file /etc/firehol.conf has been moved to ${FIREHOL_CONFIG}" echo >&2 sleep 5 fi fi # Externally defined services can be placed in "${FIREHOL_CONFIG_DIR}/services/" if [ ! -d "${FIREHOL_CONFIG_DIR}/services" ] then "${MKDIR_CMD}" "${FIREHOL_CONFIG_DIR}/services" if [ $? -ne 0 ] then echo >&2 echo >&2 echo >&2 "FireHOL needs to create the directory '${FIREHOL_CONFIG_DIR}/services', but it cannot." echo >&2 "Possibly you have a file with this name, or something else is happening." echo >&2 "Please solve this issue and retry". echo >&2 exit 1 fi "${CHOWN_CMD}" root:root "${FIREHOL_CONFIG_DIR}/services" "${CHMOD_CMD}" 700 "${FIREHOL_CONFIG_DIR}/services" fi # Remove any old directories that might be there. if [ -d "${FIREHOL_DIR}" ] then "${RM_CMD}" -rf "${FIREHOL_DIR}" if [ $? -ne 0 -o -e "${FIREHOL_DIR}" ] then echo >&2 echo >&2 echo >&2 "Cannot clean temporary directory '${FIREHOL_DIR}'." echo >&2 exit 1 fi fi "${MKDIR_CMD}" "${FIREHOL_DIR}" || exit 1 "${MKDIR_CMD}" "${FIREHOL_CHAINS_DIR}" || exit 1 # prepare the file that will hold all modules to be loaded. # this is needed only when we are going to save the firewall # with iptables-save. cat >"${FIREHOL_DIR}/modules_to_load.sh" <&2 echo >&2 echo >&2 "WARNING " echo >&2 "Cannot find file '${FIREHOL_CONFIG_DIR}/${v}'." echo >&2 "Using internal default values for variable '${v}' and all inherited ones." echo >&2 if [ ! -z "${m}" ] then echo >&2 "${m}" echo >&2 fi fi eval "export ${v}=\"${d}\"" return 0 fi if [ ${dt} -gt 0 ] then local t=`${FIND_CMD} "${FIREHOL_CONFIG_DIR}/${v}" -mtime +${dt}` if [ ! -z "${t}" ] then echo >&2 echo >&2 echo >&2 "WARNING" echo >&2 "File '${FIREHOL_CONFIG_DIR}/${v}' is more than ${dt} days old." echo >&2 "You should update it to ensure proper operation of your firewall." echo >&2 if [ ! -z "${m}" ] then echo >&2 "${m}" echo >&2 fi fi fi local t=`${CAT_CMD} "${FIREHOL_CONFIG_DIR}/${v}" | ${EGREP_CMD} "^ *[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+ *$"` local t2= local i=0 for x in ${t} do i=$[i + 1] t2="${t2} ${x}" done if [ ${i} -eq 0 -o -z "${t2}" ] then echo >&2 echo >&2 echo >&2 "WARNING " echo >&2 "The file '${FIREHOL_CONFIG_DIR}/${v}' contains zero IP definitions." echo >&2 "Using internal default values for variable '${v}' and all inherited ones." echo >&2 if [ ! -z "${m}" ] then echo >&2 "${m}" echo >&2 fi eval "export ${v}=\"${d}\"" return 0 fi eval "export ${v}=\"${t2}\"" return 0 } # ------------------------------------------------------------------------------ # IP definitions # IANA Reserved IPv4 address space # Suggested by Fco.Felix Belmonte # Optimized (CIDR) by Marc 'HE' Brockschmidt # Further optimized and reduced by http://www.vergenet.net/linux/aggregate/ # The supplied get-iana.sh uses 'aggregate-flim' if it finds it in the path. RESERVED_IPS="0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 240.0.0.0/4 " #load_ips RESERVED_IPS "${RESERVED_IPS}" 90 "Run the supplied get-iana.sh script to generate this file." require-file load_ips RESERVED_IPS "${RESERVED_IPS}" 0 # Private IPv4 address space # Suggested by Fco.Felix Belmonte # Revised by me according to RFC 3330. Explanation: # 10.0.0.0/8 => RFC 1918: IANA Private Use # 169.254.0.0/16 => Link Local # 192.0.2.0/24 => Test Net # 192.88.99.0/24 => RFC 3068: 6to4 anycast & RFC 2544: Benchmarking addresses # 192.168.0.0/16 => RFC 1918: Private use PRIVATE_IPS="10.0.0.0/8 169.254.0.0/16 172.16.0.0/12 192.0.2.0/24 192.88.99.0/24 192.168.0.0/16" load_ips PRIVATE_IPS "${PRIVATE_IPS}" 0 # The multicast address space MULTICAST_IPS="224.0.0.0/4" load_ips MULTICAST_IPS "${MULTICAST_IPS}" 0 # A shortcut to have all the Internet unroutable addresses in one # variable UNROUTABLE_IPS="${RESERVED_IPS} ${PRIVATE_IPS}" load_ips UNROUTABLE_IPS "${UNROUTABLE_IPS}" 0 # ---------------------------------------------------------------------- # The default policy for the interface commands of the firewall. # This can be controlled on a per interface basis using the # policy interface subscommand. DEFAULT_INTERFACE_POLICY="DROP" # The default policy for the router commands of the firewall. # This can be controlled on a per interface basis using the # policy interface subscommand. DEFAULT_ROUTER_POLICY="RETURN" # Which is the filter table chains policy during firewall activation? FIREHOL_INPUT_ACTIVATION_POLICY="ACCEPT" FIREHOL_OUTPUT_ACTIVATION_POLICY="ACCEPT" FIREHOL_FORWARD_ACTIVATION_POLICY="ACCEPT" # Should we drop all INVALID packets always? FIREHOL_DROP_INVALID=0 # What to do with unmatched packets? # To change these, simply define them the configuration file. UNMATCHED_INPUT_POLICY="DROP" UNMATCHED_OUTPUT_POLICY="DROP" UNMATCHED_ROUTER_POLICY="DROP" # Options for iptables LOG action. # These options will be added to all LOG actions FireHOL will generate. # To change them, type such a line in the configuration file. # FIREHOL_LOG_OPTIONS="--log-tcp-sequence --log-tcp-options --log-ip-options" FIREHOL_LOG_OPTIONS="" FIREHOL_LOG_LEVEL="warning" FIREHOL_LOG_MODE="LOG" FIREHOL_LOG_FREQUENCY="1/second" FIREHOL_LOG_BURST="5" FIREHOL_LOG_PREFIX="" # If enabled, FireHOL will silently drop orphan TCP packets with ACK,FIN set. FIREHOL_DROP_ORPHAN_TCP_ACK_FIN=0 # The client ports to be used for "default" client ports when the # client specified is a foreign host. # We give all ports above 1000 because a few systems (like Solaris) # use this range. # Note that FireHOL will ask the kernel for default client ports of # the local host. This only applies to client ports of remote hosts. DEFAULT_CLIENT_PORTS="1024:65535" # Get the default client ports from the kernel configuration. # This is formed to a range of ports to be used for all "default" # client ports when the client specified is the localhost. LOCAL_CLIENT_PORTS_LOW=`${SYSCTL_CMD} net.ipv4.ip_local_port_range | ${CUT_CMD} -d '=' -f 2 | ${CUT_CMD} -f 1` LOCAL_CLIENT_PORTS_HIGH=`${SYSCTL_CMD} net.ipv4.ip_local_port_range | ${CUT_CMD} -d '=' -f 2 | ${CUT_CMD} -f 2` LOCAL_CLIENT_PORTS="${LOCAL_CLIENT_PORTS_LOW}:${LOCAL_CLIENT_PORTS_HIGH}" # ---------------------------------------------------------------------- # This is our version number. It is increased when the configuration # file commands and arguments change their meaning and usage, so that # the user will have to review it more precisely. FIREHOL_VERSION=5 # ---------------------------------------------------------------------- # The initial line number of the configuration file. FIREHOL_LINEID="INIT" # Variable kernel module requirements. # Suggested by Fco.Felix Belmonte # Note that each of the complex services # may add to this variable the kernel modules it requires. FIREHOL_KERNEL_MODULES="" # # In the configuration file you can write: # # require_kernel_module # # to have FireHOL require a specific module for the configurarion. # Set this to 1 in the configuration file to have FireHOL complex # services' rules load NAT kernel modules too. FIREHOL_NAT=0 # Set this to 1 in the configuration file if routing should be enabled # in the kernel. FIREHOL_ROUTING=0 # Services may add themeselves to this variable so that the service "all" will # also call them. # By default it is empty - only rules programmers should change this. ALL_SHOULD_ALSO_RUN= # ------------------------------------------------------------------------------ # Various Defaults # Valid modes: # START, DEBUG, EXPLAIN, WIZARD, STOP, PANIC FIREHOL_MODE="NONE" # If set to 1, the firewall will be saved for normal iptables processing. # Valid only for FIREHOL_MODE="START" FIREHOL_SAVE=0 # If set to 1, the firewall will be restored if you don't commit it. # Valid only for FIREHOL_MODE="START" FIREHOL_TRY=0 # If set to 0, FireHOL will not try to load the required kernel modules. # It can be set in the configuration file. FIREHOL_LOAD_KERNEL_MODULES=1 # If set to 1, FireHOL will output the commands of the configuration file # with variables expanded. FIREHOL_CONF_SHOW=1 # ------------------------------------------------------------------------------ # Keep information about the current primary command # Primary commands are: interface, router work_counter=0 work_cmd= work_realcmd=("(unset)") work_name= work_inface= work_outface= work_policy= work_error=0 work_function="Initializing" # ------------------------------------------------------------------------------ # Keep status information # 0 = no errors, >0 = there were errors in the script work_runtime_error=0 # This variable is used for generating dynamic chains when needed for # combined negative statements (AND) implied by the "not" parameter # to many FireHOL directives. # What FireHOL is doing to accomplish this, is to produce dynamically # a linked list of iptables chains with just one condition each, making # the packets to traverse from chain to chain when matched, to reach # their final destination. FIREHOL_DYNAMIC_CHAIN_COUNTER=1 # If set to 0, FireHOL will not trust interface lo for all traffic. # This means the admin could setup a firewall on lo. FIREHOL_TRUST_LOOPBACK=1 # Services API version FIREHOL_SERVICES_API="1" # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # # SIMPLE SERVICES DEFINITIONS # # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # The following are definitions for simple services. # We define as "simple" the services that are implemented using a single socket, # initiated by the client and used by the server. # # The following list is sorted by service name. server_AH_ports="51/any" client_AH_ports="any" # Check http://wiki.zmanda.com/index.php/Configuration_with_iptables server_amanda_ports="udp/10080" client_amanda_ports="default" helper_amanda="amanda" # Debian package proxy server_aptproxy_ports="tcp/9999" client_aptproxy_ports="default" # APC UPS Server (these ports have to be accessible on all machines NOT # directly connected to the UPS (e.g. the slaves) server_apcupsd_ports="tcp/6544" client_apcupsd_ports="default" server_apcupsdnis_ports="tcp/3551" client_apcupsdnis_ports="default" server_asterisk_ports="tcp/5038" client_asterisk_ports="default" server_cups_ports="tcp/631 udp/631" client_cups_ports="any" server_cvspserver_ports="tcp/2401" client_cvspserver_ports="default" server_darkstat_ports="tcp/666" client_darkstat_ports="default" server_daytime_ports="tcp/13" client_daytime_ports="default" server_dcc_ports="udp/6277" client_dcc_ports="default" server_dcpp_ports="tcp/1412 udp/1412" client_dcpp_ports="default" server_dns_ports="udp/53 tcp/53" client_dns_ports="any" # DHCP Relaying (server is the relay server which behaves like a client # towards the real DHCP Server); I'm not sure about this one... server_dhcprelay_ports="udp/67" client_dhcprelay_ports="67" server_dict_ports="tcp/2628" client_dict_ports="default" # DISTCC is the distributed gcc for Gentoo server_distcc_ports="tcp/3632" client_distcc_ports="default" server_eserver_ports="tcp/4661 udp/4661 udp/4665" client_eserver_ports="any" server_ESP_ports="50/any" client_ESP_ports="any" server_echo_ports="tcp/7" client_echo_ports="default" server_finger_ports="tcp/79" client_finger_ports="default" server_ftp_ports="tcp/21" client_ftp_ports="default" helper_ftp="ftp" ALL_SHOULD_ALSO_RUN="${ALL_SHOULD_ALSO_RUN} ftp" # giFT modules' ports # Gnutella = tcp/4302 # FastTrack = tcp/1214 # OpenFT = tcp/2182 tcp/2472 server_gift_ports="tcp/4302 tcp/1214 tcp/2182 tcp/2472" client_gift_ports="any" # giFT User Interface connections server_giftui_ports="tcp/1213" client_giftui_ports="default" # gkrellmd (from gkrellm.net) server_gkrellmd_ports="tcp/19150" client_gkrellmd_ports="default" server_GRE_ports="47/any" client_GRE_ports="any" helper_GRE="proto_gre" server_h323_ports="tcp/1720" client_h323_ports="default" helper_h323="h323" # We assume heartbeat uses ports in the range 690 to 699 server_heartbeat_ports="udp/690:699" client_heartbeat_ports="default" server_http_ports="tcp/80" client_http_ports="default" server_https_ports="tcp/443" client_https_ports="default" server_iax_ports="udp/5036" client_iax_ports="default" server_iax2_ports="udp/5469 udp/4569" client_iax2_ports="default" server_ICMP_ports="icmp/any" client_ICMP_ports="any" server_icmp_ports="icmp/any" client_icmp_ports="any" # ALL_SHOULD_ALSO_RUN="${ALL_SHOULD_ALSO_RUN} icmp" # Squid' ICP port server_icp_ports="udp/3130" client_icp_ports="3130" server_ident_ports="tcp/113" client_ident_ports="default" server_imap_ports="tcp/143" client_imap_ports="default" server_imaps_ports="tcp/993" client_imaps_ports="default" server_irc_ports="tcp/6667" client_irc_ports="default" helper_irc="irc" ALL_SHOULD_ALSO_RUN="${ALL_SHOULD_ALSO_RUN} irc" # for IPSec Key negotiation server_isakmp_ports="udp/500" client_isakmp_ports="any" # IPSec Nat Traversal server_ipsecnatt_ports="udp/4500" client_ipsecnatt_ports="any" server_jabber_ports="tcp/5222 tcp/5223" client_jabber_ports="default" server_jabberd_ports="tcp/5222 tcp/5223 tcp/5269" client_jabberd_ports="default" server_l2tp_ports="udp/1701" client_l2tp_ports="any" server_ldap_ports="tcp/389" client_ldap_ports="default" server_ldaps_ports="tcp/636" client_ldaps_ports="default" server_lpd_ports="tcp/515" client_lpd_ports="any" server_microsoft_ds_ports="tcp/445" client_microsoft_ds_ports="default" server_ms_ds_ports="tcp/445" client_ms_ds_ports="default" server_mms_ports="tcp/1755 udp/1755" client_mms_ports="default" helper_mms="mms" # this will produce warnings on most distribution # because the mms module is not there: # ALL_SHOULD_ALSO_RUN="${ALL_SHOULD_ALSO_RUN} mms" server_msn_ports="tcp/6891" client_msn_ports="default" server_mysql_ports="tcp/3306" client_mysql_ports="default" # Veritas NetBackup server_netbackup_ports="tcp/13701 tcp/13711 tcp/13720 tcp/13721 tcp/13724 tcp/13782 tcp/13783" client_netbackup_ports="any" server_netbios_ns_ports="udp/137" client_netbios_ns_ports="any" server_netbios_dgm_ports="udp/138" client_netbios_dgm_ports="any" server_netbios_ssn_ports="tcp/139" client_netbios_ssn_ports="default" server_nntp_ports="tcp/119" client_nntp_ports="default" server_nntps_ports="tcp/563" client_nntps_ports="default" server_ntp_ports="udp/123 tcp/123" client_ntp_ports="any" # Network UPS Tools server_nut_ports="tcp/3493 udp/3493" client_nut_ports="default" # NoMachine's NX server server_nxserver_ports="tcp/5000:5200" client_nxserver_ports="default" # Oracle database server_oracle_ports="tcp/1521" client_oracle_ports="default" server_OSPF_ports="89/any" client_OSPF_ports="any" server_pop3_ports="tcp/110" client_pop3_ports="default" server_pop3s_ports="tcp/995" client_pop3s_ports="default" # Portmap clients appear to use ports bellow 1024 server_portmap_ports="udp/111 tcp/111" client_portmap_ports="any" server_postgres_ports="tcp/5432" client_postgres_ports="default" server_pptp_ports="tcp/1723" client_pptp_ports="default" helper_pptp="pptp proto_gre" # ALL_SHOULD_ALSO_RUN="${ALL_SHOULD_ALSO_RUN} pptp" # Privacy Proxy server_privoxy_ports="tcp/8118" client_privoxy_ports="default" server_radius_ports="udp/1812 udp/1813" client_radius_ports="default" server_radiusproxy_ports="udp/1814" client_radiusproxy_ports="default" server_radiusold_ports="udp/1645 udp/1646" client_radiusold_ports="default" server_radiusoldproxy_ports="udp/1647" client_radiusoldproxy_ports="default" server_rdp_ports="tcp/3389" client_rdp_ports="default" server_rndc_ports="tcp/953" client_rndc_ports="default" server_rsync_ports="tcp/873 udp/873" client_rsync_ports="default" server_rtp_ports="udp/10000:20000" client_rtp_ports="any" server_sane_ports="tcp/6566" client_sane_ports="default" helper_sane="sane" server_sip_ports="udp/5060" client_sip_ports="5060 default" helper_sip="sip" server_socks_ports="tcp/1080 udp/1080" client_socks_ports="default" server_squid_ports="tcp/3128" client_squid_ports="default" server_smtp_ports="tcp/25" client_smtp_ports="default" server_smtps_ports="tcp/465" client_smtps_ports="default" server_snmp_ports="udp/161" client_snmp_ports="default" server_snmptrap_ports="udp/162" client_snmptrap_ports="any" server_ssh_ports="tcp/22" client_ssh_ports="default" server_stun_ports="udp/3478 udp/3479" client_stun_ports="any" # SMTP over SSL/TLS submission server_submission_ports="tcp/587" client_submission_ports="default" # Sun RCP is an alias for service portmap server_sunrpc_ports="${server_portmap_ports}" client_sunrpc_ports="${client_portmap_ports}" server_swat_ports="tcp/901" client_swat_ports="default" server_syslog_ports="udp/514" client_syslog_ports="syslog default" server_telnet_ports="tcp/23" client_telnet_ports="default" server_tftp_ports="udp/69" client_tftp_ports="default" helper_tftp="tftp" server_time_ports="tcp/37 udp/37" client_time_ports="default" server_upnp_ports="udp/1900 tcp/2869" client_upnp_ports="default" server_uucp_ports="tcp/540" client_uucp_ports="default" server_whois_ports="tcp/43" client_whois_ports="default" server_vmware_ports="tcp/902" client_vmware_ports="default" server_vmwareauth_ports="tcp/903" client_vmwareauth_ports="default" server_vmwareweb_ports="tcp/8222 tcp/8333" client_vmwareweb_ports="default" server_vnc_ports="tcp/5900:5903" client_vnc_ports="default" server_webcache_ports="tcp/8080" client_webcache_ports="default" server_webmin_ports="tcp/10000" client_webmin_ports="default" server_xdmcp_ports="udp/177" client_xdmcp_ports="default" # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # # COMPLEX SERVICES DEFINITIONS # # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # The following are definitions for complex services. # We define as "complex" the services that are implemented using multiple sockets. # Each function bellow is organized in three parts: # 1) A Header, common to each and every function # 2) The rules required for the INPUT of the server # 3) The rules required for the OUTPUT of the server # # The Header part, together with the "reverse" keyword can reverse the rules so # that if we are implementing a client the INPUT will become OUTPUT and vice versa. # # In most the cases the input and output rules are the same with the following # differences: # # a) The output rules begin with the "reverse" keyword, which reverses: # inface/outface, src/dst, sport/dport # b) The output rules use ${out}_${mychain} instead of ${in}_${mychain} # c) The state rules match the client operation, not the server. # --- XBOX --------------------------------------------------------------------- # Contributed by andrex@alumni.utexas.net # Following is the (complex) service definition function for xbox, the Xbox live # service. With this definition our Xbox connects and plays from behind a NAT # firewall with no trouble. Andrew. rules_xbox() { local mychain="${1}"; shift local type="${1}"; shift local in=in local out=out if [ "${type}" = "client" ] then in=out out=in fi local client_ports="${DEFAULT_CLIENT_PORTS}" if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] then client_ports="${LOCAL_CLIENT_PORTS}" fi # ---------------------------------------------------------------------- set_work_function "Setting up rules for Xbox live" rule ${in} action "$@" chain "${in}_${mychain}" proto udp dport "88 3074" sport "${client_ports}" state NEW,ESTABLISHED || return 1 rule ${out} reverse action "$@" chain "${out}_${mychain}" proto udp dport "88 3074" sport "${client_ports}" state ESTABLISHED || return 1 rule ${in} action "$@" chain "${in}_${mychain}" proto tcp dport 3074 sport "${client_ports}" state NEW,ESTABLISHED || return 1 rule ${out} reverse action "$@" chain "${out}_${mychain}" proto tcp dport 3074 sport "${client_ports}" state ESTABLISHED || return 1 rule ${in} action "$@" chain "${in}_${mychain}" proto udp sport 3074 dport "${client_ports}" state NEW,ESTABLISHED || return 1 rule ${out} reverse action "$@" chain "${out}_${mychain}" proto udp sport 3074 dport "${client_ports}" state ESTABLISHED || return 1 return 0 } # --- DHCP -------------------------------------------------------------------- rules_dhcp() { local mychain="${1}"; shift local type="${1}"; shift local in=in local out=out if [ "${type}" = "client" ] then in=out out=in fi local client_ports="${DEFAULT_CLIENT_PORTS}" if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] then client_ports="${LOCAL_CLIENT_PORTS}" fi # ---------------------------------------------------------------------- set_work_function "Setting up rules for DHCP (${type})" rule ${in} action "$@" chain "${in}_${mychain}" proto "udp" sport "68" dport "67" || return 1 rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "udp" sport "68" dport "67" || return 1 return 0 } # --- EMULE -------------------------------------------------------------------- rules_emule() { local mychain="${1}"; shift local type="${1}"; shift local in=in local out=out if [ "${type}" = "client" ] then in=out out=in fi local client_ports="${DEFAULT_CLIENT_PORTS}" if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] then client_ports="${LOCAL_CLIENT_PORTS}" fi # ---------------------------------------------------------------------- # allow incomming to server tcp/4662 set_work_function "Setting up rules for EMULE/client-to-server tcp/4662 (${type})" rule ${in} action "$@" chain "${in}_${mychain}" proto "tcp" sport any dport 4662 state NEW,ESTABLISHED || return 1 rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "tcp" sport any dport 4662 state ESTABLISHED || return 1 # allow outgoing to client tcp/4662 set_work_function "Setting up rules for EMULE/server-to-client tcp/4662 (${type})" rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "tcp" dport any sport 4662 state NEW,ESTABLISHED || return 1 rule ${in} action "$@" chain "${in}_${mychain}" proto "tcp" dport any sport 4662 state ESTABLISHED || return 1 # allow incomming to server udp/4672 set_work_function "Setting up rules for EMULE/client-to-server udp/4672 (${type})" rule ${in} action "$@" chain "${in}_${mychain}" proto "udp" sport any dport 4672 state NEW,ESTABLISHED || return 1 rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "udp" sport any dport 4672 state ESTABLISHED || return 1 # allow outgoing to client udp/4672 set_work_function "Setting up rules for EMULE/server-to-client udp/4672 (${type})" rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "udp" dport any sport 4672 state NEW,ESTABLISHED || return 1 rule ${in} action "$@" chain "${in}_${mychain}" proto "udp" dport any sport 4672 state ESTABLISHED || return 1 # allow incomming to server tcp/4661 set_work_function "Setting up rules for EMULE/client-to-server tcp/4661 (${type})" rule ${in} action "$@" chain "${in}_${mychain}" proto "tcp" sport any dport 4661 state NEW,ESTABLISHED || return 1 rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "tcp" sport any dport 4661 state ESTABLISHED || return 1 # allow incomming to server udp/4665 set_work_function "Setting up rules for EMULE/client-to-server udp/4665 (${type})" rule ${in} action "$@" chain "${in}_${mychain}" proto "udp" sport any dport 4665 state NEW,ESTABLISHED || return 1 rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "udp" sport any dport 4665 state ESTABLISHED || return 1 return 0 } # --- HYLAFAX ------------------------------------------------------------------ # Written by: Franscisco Javier Felix rules_hylafax() { local mychain="${1}"; shift local type="${1}"; shift local in=in local out=out if [ "${type}" = "client" ] then in=out out=in fi local client_ports="${DEFAULT_CLIENT_PORTS}" if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] then client_ports="${LOCAL_CLIENT_PORTS}" fi # ---------------------------------------------------------------------- # allow incomming to server tcp/4559 set_work_function "Setting up rules for HYLAFAX/client-to-server tcp/4559 (${type})" rule ${in} action "$@" chain "${in}_${mychain}" proto "tcp" sport any dport 4559 state NEW,ESTABLISHED || return 1 rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "tcp" sport any dport 4559 state ESTABLISHED || return 1 # allow outgoing to client from server tcp/4558 set_work_function "Setting up rules for HYLAFAX/server-to-client from server tcp/4558 (${type})" rule ${out} action "$@" chain "${out}_${mychain}" proto "tcp" sport 4558 dport any state NEW,ESTABLISHED || return 1 rule ${in} reverse action "$@" chain "${in}_${mychain}" proto "tcp" sport 4558 dport any state ESTABLISHED || return 1 return 0 } # --- SAMBA -------------------------------------------------------------------- rules_samba() { local mychain="${1}"; shift local type="${1}"; shift local in=in local out=out if [ "${type}" = "client" ] then in=out out=in fi local client_ports="${DEFAULT_CLIENT_PORTS}" if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] then client_ports="${LOCAL_CLIENT_PORTS}" fi # ---------------------------------------------------------------------- set_work_function "Setting up rules for SAMBA/NETBIOS-NS (${type})" rule ${in} action "$@" chain "${in}_${mychain}" proto "udp" sport "137 ${client_ports}" dport 137 state NEW,ESTABLISHED || return 1 # NETBIOS initiates based on the broadcast address of an interface # (request goes to broadcast address) but the server responds from # its own IP address. This makes the server samba accept statement # drop the server reply. # Bellow is a hack, that allows a linux samba server to respond # correctly, as it allows new outgoing connections from the well # known netbios-ns port to the clients high ports. # For clients and routers this hack is not applied because it # would be a huge security hole. if [ "${type}" = "server" -a "${work_cmd}" = "interface" ] then rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "udp" sport "137 ${client_ports}" dport 137 state NEW,ESTABLISHED || return 1 else rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "udp" sport "137 ${client_ports}" dport 137 state ESTABLISHED || return 1 fi set_work_function "Setting up rules for SAMBA/NETBIOS-DGM (${type})" rule ${in} action "$@" chain "${in}_${mychain}" proto "udp" sport "138 ${client_ports}" dport 138 state NEW,ESTABLISHED || return 1 rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "udp" sport "138 ${client_ports}" dport 138 state ESTABLISHED || return 1 set_work_function "Setting up rules for SAMBA/NETBIOS-SSN (${type})" rule ${in} action "$@" chain "${in}_${mychain}" proto "tcp" sport "${client_ports}" dport 139 state NEW,ESTABLISHED || return 1 rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "tcp" sport "${client_ports}" dport 139 state ESTABLISHED || return 1 set_work_function "Setting up rules for SAMBA/MICROSOFT_DS (${type})" rule ${in} action "$@" chain "${in}_${mychain}" proto "tcp" sport "${client_ports}" dport 445 state NEW,ESTABLISHED || return 1 rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "tcp" sport "${client_ports}" dport 445 state ESTABLISHED || return 1 return 0 } # --- PPTP -------------------------------------------------------------------- # THIS IS OLD # THE NEW ONE USES THE KERNEL HELPER TO DO IT, AND THEREFORE IS A SIMPLE SERVICE # #rules_pptp() { # local mychain="${1}"; shift # local type="${1}"; shift # # local in=in # local out=out # if [ "${type}" = "client" ] # then # in=out # out=in # fi # # local client_ports="${DEFAULT_CLIENT_PORTS}" # if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] # then # client_ports="${LOCAL_CLIENT_PORTS}" # fi # # # ---------------------------------------------------------------------- # # set_work_function "Setting up rules for PPTP/initial connection (${type})" # rule ${in} action "$@" chain "${in}_${mychain}" proto "tcp" sport "${client_ports}" dport "1723" state NEW,ESTABLISHED || return 1 # rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "tcp" sport "${client_ports}" dport "1723" state ESTABLISHED || return 1 # # set_work_function "Setting up rules for PPTP/tunnel GRE traffic (${type})" # rule ${in} action "$@" chain "${in}_${mychain}" proto "47" || return 1 # rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "47" || return 1 # # return 0 #} # --- NFS ---------------------------------------------------------------------- rules_nfs() { local mychain="${1}"; shift local type="${1}"; shift local in=in local out=out if [ "${type}" = "client" ] then in=out out=in fi local client_ports="${DEFAULT_CLIENT_PORTS}" if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] then client_ports="${LOCAL_CLIENT_PORTS}" fi # ---------------------------------------------------------------------- # This command requires in the client or route subcommands, # the first argument after the policy/action is a dst. local action="${1}"; shift local servers="localhost" if [ "${type}" = "client" -o ! "${work_cmd}" = "interface" ] then case "${1}" in dst|DST|destination|DESTINATION) shift local servers="${1}" shift ;; *) error "Please re-phrase to: ${type} nfs ${action} dst [other rules]" return 1 ;; esac fi local x= for x in ${servers} do local tmp="${FIREHOL_DIR}/firehol.rpcinfo.$$.${RANDOM}" set_work_function "Getting RPC information from server '${x}'" rpcinfo -p ${x} >"${tmp}" if [ $? -gt 0 -o ! -s "${tmp}" ] then error "Cannot get rpcinfo from host '${x}' (using the previous firewall rules)" ${RM_CMD} -f "${tmp}" return 1 fi local server_rquotad_ports="`${CAT_CMD} "${tmp}" | ${GREP_CMD} " rquotad$" | ( while read a b proto port s; do echo "$proto/$port"; done ) | ${SORT_CMD} | ${UNIQ_CMD}`" local server_mountd_ports="`${CAT_CMD} "${tmp}" | ${GREP_CMD} " mountd$" | ( while read a b proto port s; do echo "$proto/$port"; done ) | ${SORT_CMD} | ${UNIQ_CMD}`" local server_lockd_ports="`${CAT_CMD} "${tmp}" | ${GREP_CMD} " nlockmgr$" | ( while read a b proto port s; do echo "$proto/$port"; done ) | ${SORT_CMD} | ${UNIQ_CMD}`" local server_statd_ports="`${CAT_CMD} "${tmp}" | ${GREP_CMD} " status$" | ( while read a b proto port s; do echo "$proto/$port"; done ) | ${SORT_CMD} | ${UNIQ_CMD}`" local server_nfsd_ports="`${CAT_CMD} "${tmp}" | ${GREP_CMD} " nfs$" | ( while read a b proto port s; do echo "$proto/$port"; done ) | ${SORT_CMD} | ${UNIQ_CMD}`" test -z "${server_mountd_ports}" && error "Cannot find mountd ports for nfs server '${x}'" && return 1 test -z "${server_lockd_ports}" && error "Cannot find lockd ports for nfs server '${x}'" && return 1 test -z "${server_statd_ports}" && error "Cannot find statd ports for nfs server '${x}'" && return 1 test -z "${server_nfsd_ports}" && error "Cannot find nfsd ports for nfs server '${x}'" && return 1 local dst= if [ ! "${x}" = "localhost" ] then dst="dst ${x}" fi if [ ! -z "${server_rquotad_ports}" ] then set_work_function "Processing rquotad rules for server '${x}'" rules_custom "${mychain}" "${type}" nfs-rquotad "${server_rquotad_ports}" "500:65535" "${action}" $dst "$@" fi set_work_function "Processing mountd rules for server '${x}'" rules_custom "${mychain}" "${type}" nfs-mountd "${server_mountd_ports}" "500:65535" "${action}" $dst "$@" set_work_function "Processing lockd rules for server '${x}'" rules_custom "${mychain}" "${type}" nfs-lockd "${server_lockd_ports}" "500:65535" "${action}" $dst "$@" set_work_function "Processing statd rules for server '${x}'" rules_custom "${mychain}" "${type}" nfs-statd "${server_statd_ports}" "500:65535" "${action}" $dst "$@" set_work_function "Processing nfsd rules for server '${x}'" rules_custom "${mychain}" "${type}" nfs-nfsd "${server_nfsd_ports}" "500:65535" "${action}" $dst "$@" ${RM_CMD} -f "${tmp}" echo >&2 "" echo >&2 "WARNING:" echo >&2 "This firewall must be restarted if NFS server ${x} is restarted!" echo >&2 "" done return 0 } # --- NIS ---------------------------------------------------------------------- # These rules work for client access only! # # Pushing changes to slave servers won't work if these rules are active # somewhere between the master and its slaves, because it is impossible to # predict the ports where "yppush" will be listening on each push. # # Pulling changes directly on the slaves will work, and could be improved # performance-wise if these rules are modified to open "fypxfrd". This wasn't # done because it doesn't make that much sense since pushing changes on the # master server is the most common, and recommended, way to replicate maps. # # Created by Carlos Rodrigues # Feature Requests item #1050951 rules_nis() { local mychain="${1}"; shift local type="${1}"; shift local in=in local out=out if [ "${type}" = "client" ] then in=out out=in fi local client_ports="${DEFAULT_CLIENT_PORTS}" if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] then client_ports="${LOCAL_CLIENT_PORTS}" fi # ---------------------------------------------------------------------- # This command requires in the client or route subcommands, # the first argument after the policy/action is a dst. local action="${1}"; shift local servers="localhost" if [ "${type}" = "client" -o ! "${work_cmd}" = "interface" ] then case "${1}" in dst|DST|destination|DESTINATION) shift local servers="${1}" shift ;; *) error "Please re-phrase to: ${type} nis ${action} dst [other rules]" return 1 ;; esac fi local x= for x in ${servers} do local tmp="${FIREHOL_DIR}/firehol.rpcinfo.$$.${RANDOM}" set_work_function "Getting RPC information from server '${x}'" rpcinfo -p ${x} >"${tmp}" if [ $? -gt 0 -o ! -s "${tmp}" ] then error "Cannot get rpcinfo from host '${x}' (using the previous firewall rules)" ${RM_CMD} -f "${tmp}" return 1 fi local server_ypserv_ports="`${CAT_CMD} "${tmp}" | ${GREP_CMD} " ypserv$" | ( while read a b proto port s; do echo "$proto/$port"; done ) | ${SORT_CMD} | ${UNIQ_CMD}`" local server_yppasswdd_ports="`${CAT_CMD} "${tmp}" | ${GREP_CMD} " yppasswdd$" | ( while read a b proto port s; do echo "$proto/$port"; done ) | ${SORT_CMD} | ${UNIQ_CMD}`" test -z "${server_ypserv_ports}" && error "Cannot find ypserv ports for nis server '${x}'" && return 1 local dst= if [ ! "${x}" = "localhost" ] then dst="dst ${x}" fi if [ ! -z "${server_yppasswdd_ports}" ] then set_work_function "Processing yppasswd rules for server '${x}'" rules_custom "${mychain}" "${type}" nis-yppasswd "${server_yppasswdd_ports}" "500:65535" "${action}" $dst "$@" fi set_work_function "Processing ypserv rules for server '${x}'" rules_custom "${mychain}" "${type}" nis-ypserv "${server_ypserv_ports}" "500:65535" "${action}" $dst "$@" ${RM_CMD} -f "${tmp}" echo >&2 "" echo >&2 "WARNING:" echo >&2 "This firewall must be restarted if NIS server ${x} is restarted!" echo >&2 "" done return 0 } # --- AMANDA ------------------------------------------------------------------- # THIS IS OLD # THE NEW ONE USES THE KERNEL HELPER TO DO IT, AND THEREFORE IS A SIMPLE SERVICE # #FIREHOL_AMANDA_PORTS="850:859" # #rules_amanda() { # local mychain="${1}"; shift # local type="${1}"; shift # # local in=in # local out=out # if [ "${type}" = "client" ] # then # in=out # out=in # fi # # local client_ports="${DEFAULT_CLIENT_PORTS}" # if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] # then # client_ports="${LOCAL_CLIENT_PORTS}" # fi # # # ---------------------------------------------------------------------- # # set_work_function "*** AMANDA: See http://amanda.sourceforge.net/fom-serve/cache/139.html" # # # set_work_function "Setting up rules for initial amanda server-to-client connection" # rule ${out} action "$@" chain "${out}_${mychain}" proto "udp" dport 10080 state NEW,ESTABLISHED || return 1 # rule ${in} reverse action "$@" chain "${in}_${mychain}" proto "udp" dport 10080 state ESTABLISHED || return 1 # # # set_work_function "Setting up rules for amanda data exchange client-to-server" # rule ${in} action "$@" chain "${in}_${mychain}" proto "tcp udp" dport "${FIREHOL_AMANDA_PORTS}" state NEW,ESTABLISHED || return 1 # rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "tcp udp" dport "${FIREHOL_AMANDA_PORTS}" state ESTABLISHED || return 1 # # return 0 #} # --- FTP ---------------------------------------------------------------------- # THIS IS OLD # THE NEW ONE USES THE KERNEL HELPER TO DO IT, AND THEREFORE IS A SIMPLE SERVICE # #ALL_SHOULD_ALSO_RUN="${ALL_SHOULD_ALSO_RUN} ftp" # #rules_ftp() { # local mychain="${1}"; shift # local type="${1}"; shift # # local in=in # local out=out # if [ "${type}" = "client" ] # then # in=out # out=in # fi # # local client_ports="${DEFAULT_CLIENT_PORTS}" # if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] # then # client_ports="${LOCAL_CLIENT_PORTS}" # fi # # # For an explanation of how FTP connections work, see # # http://slacksite.com/other/ftp.html # # # ---------------------------------------------------------------------- # # # allow new and established incoming, and established outgoing # # accept port ftp new connections # set_work_function "Setting up rules for initial FTP connection ${type}" # rule ${in} action "$@" chain "${in}_${mychain}" proto tcp sport "${client_ports}" dport ftp state NEW,ESTABLISHED || return 1 # rule ${out} reverse action "$@" chain "${out}_${mychain}" proto tcp sport "${client_ports}" dport ftp state ESTABLISHED || return 1 # # set_work_function "Match anything related to the kernel ftp helper" # rule ${in} action "$@" chain "${in}_${mychain}" custom "-m helper --helper ftp" state ESTABLISHED,RELATED || return 1 # rule ${out} reverse action "$@" chain "${out}_${mychain}" custom "-m helper --helper ftp" state ESTABLISHED,RELATED || return 1 # # this is old code - replaced by the two helper statements above # # Active FTP # # send port ftp-data related connections # set_work_function "Setting up rules for Active FTP ${type}" # rule ${out} reverse action "$@" chain "${out}_${mychain}" proto tcp sport "${client_ports}" dport ftp-data state ESTABLISHED,RELATED || return 1 # rule ${in} action "$@" chain "${in}_${mychain}" proto tcp sport "${client_ports}" dport ftp-data state ESTABLISHED || return 1 # # # ---------------------------------------------------------------------- # # # A hack for Passive FTP only # local s_client_ports="${DEFAULT_CLIENT_PORTS}" # local c_client_ports="${DEFAULT_CLIENT_PORTS}" # # if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] # then # c_client_ports="${LOCAL_CLIENT_PORTS}" # elif [ "${type}" = "server" -a "${work_cmd}" = "interface" ] # then # s_client_ports="${LOCAL_CLIENT_PORTS}" # fi # # # Passive FTP # # accept high-ports related connections # set_work_function "Setting up rules for Passive FTP ${type}" # rule ${in} action "$@" chain "${in}_${mychain}" proto tcp sport "${c_client_ports}" dport "${s_client_ports}" state ESTABLISHED,RELATED || return 1 # rule ${out} reverse action "$@" chain "${out}_${mychain}" proto tcp sport "${c_client_ports}" dport "${s_client_ports}" state ESTABLISHED || return 1 # # require_kernel_module nf_conntrack_ftp # test ${FIREHOL_NAT} -eq 1 && require_kernel_module nf_nat_ftp # # return 0 #} # --- TFTP --------------------------------------------------------------------- # THIS IS OLD # THE NEW ONE USES THE KERNEL HELPER TO DO IT, AND THEREFORE IS A SIMPLE SERVICE # # Written by: Goetz Bock # #rules_tftp() { # local mychain="${1}"; shift # local type="${1}"; shift # # local in=in # local out=out # if [ "${type}" = "client" ] # then # in=out # out=in # fi # # local client_ports="${DEFAULT_CLIENT_PORTS}" # if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] # then # client_ports="${LOCAL_CLIENT_PORTS}" # fi # # # --------------------------------------------------------------------- # # TFTP is a broken protokol. It works like this: # # # # 1. The client sends from a high port (a) to the server's tftp port an # # udp packet with "give me file 'bla'". # # # # 2. The server replies from a high port (b) to the highport the client # # used (a) with "this is part 0 if your file" # # # # 3. The client now has to send a reply (from his highport a) to the # # servers high port (b): "got part 0, send next part 1". # # # # 4. repeat 2. and 3. till file transmitted # # # allow the initial TFTP connection # set_work_function "Setting up rules for initial TFTP connection (${type})" # rule ${in} action "$@" chain "${in}_${mychain}" proto "udp" sport "${client_ports}" dport tftp state NEW,ESTABLISHED || return 1 ## rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "udp" sport "${client_ports}" dport tftp state ESTABLISHED || return 1 # # # We now need both server and client port ranges # local s_client_ports="${DEFAULT_CLIENT_PORTS}" # local c_client_ports="${DEFAULT_CLIENT_PORTS}" # # if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] # then # c_client_ports="${LOCAL_CLIENT_PORTS}" # elif [ "${type}" = "server" -a "${work_cmd}" = "interface" ] # then # s_client_ports="${LOCAL_CLIENT_PORTS}" # fi # # # allow the TFTP server to establish a new connection to the client # set_work_function "Setting up rules for server-to-client TFTP connection (${type})" # rule ${out} reverse action "$@" chain "${out}_${mychain}" proto "udp" sport "${c_client_ports}" dport "${s_client_ports}" state RELATED,ESTABLISHED || return 1 # rule ${in} action "$@" chain "${in}_${mychain}" proto "udp" sport "${c_client_ports}" dport "${s_client_ports}" state ESTABLISHED || return 1 # # require_kernel_module nf_conntrack_tftp # test ${FIREHOL_NAT} -eq 1 && require_kernel_module nf_nat_tftp # # return 0 #} # --- PING --------------------------------------------------------------------- rules_ping() { local mychain="${1}"; shift local type="${1}"; shift local in=in local out=out if [ "${type}" = "client" ] then in=out out=in fi local client_ports="${DEFAULT_CLIENT_PORTS}" if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] then client_ports="${LOCAL_CLIENT_PORTS}" fi # ---------------------------------------------------------------------- # allow incoming new and established PING packets rule ${in} action "$@" chain "${in}_${mychain}" proto icmp custom "--icmp-type echo-request" state NEW,ESTABLISHED || return 1 # allow outgoing established packets rule ${out} reverse action "$@" chain "${out}_${mychain}" proto icmp custom "--icmp-type echo-reply" state ESTABLISHED || return 1 return 0 } # --- TIMESTAMP ---------------------------------------------------------------- rules_timestamp() { local mychain="${1}"; shift local type="${1}"; shift local in=in local out=out if [ "${type}" = "client" ] then in=out out=in fi local client_ports="${DEFAULT_CLIENT_PORTS}" if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] then client_ports="${LOCAL_CLIENT_PORTS}" fi # ---------------------------------------------------------------------- # allow incoming new and established PING packets rule ${in} action "$@" chain "${in}_${mychain}" proto icmp custom "--icmp-type timestamp-request" state NEW,ESTABLISHED || return 1 # allow outgoing established packets rule ${out} reverse action "$@" chain "${out}_${mychain}" proto icmp custom "--icmp-type timestamp-reply" state ESTABLISHED || return 1 return 0 } # --- ALL ---------------------------------------------------------------------- rules_all() { local mychain="${1}"; shift local type="${1}"; shift local in=in local out=out if [ "${type}" = "client" ] then in=out out=in fi local client_ports="${DEFAULT_CLIENT_PORTS}" if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] then client_ports="${LOCAL_CLIENT_PORTS}" fi # ---------------------------------------------------------------------- # allow new and established incoming packets rule ${in} action "$@" chain "${in}_${mychain}" state NEW,ESTABLISHED || return 1 # allow outgoing established packets rule ${out} reverse action "$@" chain "${out}_${mychain}" state ESTABLISHED || return 1 local ser= for ser in ${ALL_SHOULD_ALSO_RUN} do "${type}" ${ser} "$@" || return 1 done return 0 } # --- ANY ---------------------------------------------------------------------- rules_any() { local mychain="${1}"; shift local type="${1}"; shift local name="${1}"; shift # a special case: service any gets a name local in=in local out=out if [ "${type}" = "client" ] then in=out out=in fi local client_ports="${DEFAULT_CLIENT_PORTS}" if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] then client_ports="${LOCAL_CLIENT_PORTS}" fi # ---------------------------------------------------------------------- # allow new and established incoming packets rule ${in} action "$@" chain "${in}_${mychain}" state NEW,ESTABLISHED || return 1 # allow outgoing established packets rule ${out} reverse action "$@" chain "${out}_${mychain}" state ESTABLISHED || return 1 return 0 } # --- ANYSTATELESS ------------------------------------------------------------- rules_anystateless() { local mychain="${1}"; shift local type="${1}"; shift local name="${1}"; shift # a special case: service any gets a name local in=in local out=out if [ "${type}" = "client" ] then in=out out=in fi local client_ports="${DEFAULT_CLIENT_PORTS}" if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] then client_ports="${LOCAL_CLIENT_PORTS}" fi # ---------------------------------------------------------------------- # allow new and established incoming packets rule ${in} action "$@" chain "${in}_${mychain}" || return 1 # allow outgoing established packets rule ${out} reverse action "$@" chain "${out}_${mychain}" || return 1 return 0 } # --- MULTICAST ---------------------------------------------------------------- rules_multicast() { local mychain="${1}"; shift local type="${1}"; shift local in=in local out=out if [ "${type}" = "client" ] then in=out out=in fi local client_ports="${DEFAULT_CLIENT_PORTS}" if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] then client_ports="${LOCAL_CLIENT_PORTS}" fi # ---------------------------------------------------------------------- # match multicast packets in both directions rule ${out} action "$@" chain "${out}_${mychain}" dst "224.0.0.0/4" proto 2 || return 1 rule ${in} reverse action "$@" chain "${in}_${mychain}" src "224.0.0.0/4" proto 2 || return 1 rule ${out} action "$@" chain "${out}_${mychain}" dst "224.0.0.0/4" proto udp || return 1 rule ${in} reverse action "$@" chain "${in}_${mychain}" src "224.0.0.0/4" proto udp || return 1 return 0 } # --- CUSTOM ------------------------------------------------------------------- rules_custom() { local mychain="${1}"; shift local type="${1}"; shift local server="${1}"; shift local my_server_ports="${1}"; shift local my_client_ports="${1}"; shift local helpers= if [ "$1" = "helpers" ] then local helpers="$2" shift 2 fi local in=in local out=out if [ "${type}" = "client" ] then in=out out=in fi local client_ports="${DEFAULT_CLIENT_PORTS}" if [ "${type}" = "client" -a "${work_cmd}" = "interface" ] then client_ports="${LOCAL_CLIENT_PORTS}" fi # ---------------------------------------------------------------------- local sp= for sp in ${my_server_ports} do local proto= local sport= IFS="/" read proto sport </dev/null` do cd "${FIREHOL_CONFIG_DIR}/services" || exit 1 if [ ! -O "${f}" ] then echo >&2 " >>> Ignoring service in '${FIREHOL_CONFIG_DIR}/services/${f}' because it is not owned by root." continue fi n=`"${HEAD_CMD}" -n 1 "${f}" | "${CUT_CMD}" -d ':' -f 2` "${EXPR_CMD}" ${n} + 0 >/dev/null 2>&1 if [ $? -ne 0 ] then echo >&2 " >>> Ignoring service in '${FIREHOL_CONFIG_DIR}/services/${f}' due to malformed header." elif [ ${n} -ne ${FIREHOL_SERVICES_API} ] then echo >&2 " >>> Ignoring service '${FIREHOL_CONFIG_DIR}/services/${f}' due to incompatible API version." else n=`"${HEAD_CMD}" -n 1 "${f}" | "${CUT_CMD}" -d ':' -f 3` "${EXPR_CMD}" ${n} + 0 >/dev/null 2>&1 if [ $? -ne 0 ] then echo >&2 " >>> Ignoring service in '${FIREHOL_CONFIG_DIR}/services/${f}' due to malformed API minor number." else if [ ${n} -gt ${FIREHOL_MINOR_VERSION} ] then echo >&2 " >>> Ignoring service in '${FIREHOL_CONFIG_DIR}/services/${f}' because the required MINOR version (${n}) is higher than the one provided by FireHOL (${FIREHOL_MINOR_VERSION})." else source ${f} ret=$? if [ ${ret} -ne 0 ] then echo >&2 " >>> Service in '${FIREHOL_CONFIG_DIR}/services/${f}' returned code ${ret}." continue fi fi fi fi done cd "${FIREHOL_DEFAULT_WORKING_DIRECTORY}" || exit 1 # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # # HELPER FUNCTIONS BELLOW THIS POINT # # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # Fetch a URL and output it to the standard output. firehol_wget() { local url="${1}" require_cmd wget curl if [ ! -z "${WGET_CMD}" ] then ${WGET_CMD} -O - "${url}" 2>/dev/null return $? elif [ ! -z "${CURL_CMD}" ] then ${CURL_CMD} -s "${url}" return $? fi error "Cannot use either 'wget' or 'curl' to fetch '${url}'." return 1 } FIREHOL_ECN_SHAME_URL="http://urchin.earth.li/cgi-bin/ecn.pl?output=ip" ecn_shame() { work_realcmd_helper ${FUNCNAME} "$@" set_work_function -ne "Initializing $FUNCNAME" require_work clear || ( error "$FUNCNAME cannot be used in '${work_cmd}'. Put it before any '${work_cmd}' definition."; return 1 ) if [ `${CAT_CMD} /proc/sys/net/ipv4/tcp_ecn` -eq 1 ] then set_work_function "Fetching '${FIREHOL_ECN_SHAME_URL}'." # Reads in list of ip address and makes iptables rules to drop ecn # from packets destined for those hosts. # http://urchin.earth.li/ecn/ local tmp="${FIREHOL_DIR}/ecn_shame.ips" firehol_wget "${FIREHOL_ECN_SHAME_URL}" | ${SORT_CMD} | ${UNIQ_CMD} >"${tmp}" if [ $? -ne 0 -o ! -s "${tmp}" ] then softwarning "Cannot fetch '${FIREHOL_ECN_SHAME_URL}'." else ${MV_CMD} -f "${tmp}" "${FIREHOL_SPOOL_DIR}/ecn_shame.ips" fi set_work_function "Removing ECN for all communication from/to SHAME ECN list." local count=0 for ip in `${CAT_CMD} "${FIREHOL_SPOOL_DIR}/ecn_shame.ips"` do local count=$[count + 1] iptables -t mangle -A POSTROUTING -p tcp -d ${ip} -j ECN --ecn-tcp-remove done test ${count} -eq 0 && softwarning "No ECN SHAME IPs found." && return 1 else softwarning "TCP_ECN is not enabled in the kernel. ECN_SHAME helper is ignored." return 0 fi return 0 } # define custom actions action() { work_realcmd_helper $FUNCNAME "$@" set_work_function -ne "Initializing $FUNCNAME" require_work clear || ( error "$FUNCNAME cannot be used in '${work_cmd}'. Put it before any '${work_cmd}' definition."; return 1 ) while [ ! -z "${1}" ] do local what="${1}"; shift case "${what}" in chain) local name="${1}"; shift local act="${1}"; shift if [ -z "${name}" ] then error "Cannot create an action chain without a name." return 1 fi if [ -z "${act}" ] then error "Cannot create the action chain(s) '$name' without a default action." return 1 fi local nm= for nm in $name do create_chain filter ${nm} rule table filter chain ${nm} action "${act}" done ;; *) error "Cannot understand $FUNCNAME '${what}'." return 1 ;; esac done return 0 } masquerade() { work_realcmd_helper ${FUNCNAME} "$@" set_work_function -ne "Initializing $FUNCNAME" local f="${work_outface}" test "${1}" = "reverse" && f="${work_inface}" && shift test -z "${f}" && local f="${1}" && shift test -z "${f}" && error "masquerade requires an interface set or as argument" && return 1 set_work_function "Initializing masquerade on interface '${f}'" rule noowner table nat chain POSTROUTING "$@" inface any outface "${f}" action MASQUERADE || return 1 FIREHOL_NAT=1 FIREHOL_ROUTING=1 return 0 } transparent_proxy_count=0 transparent_proxy() { work_realcmd_helper $FUNCNAME "$@" set_work_function -ne "Initializing $FUNCNAME" require_work clear || ( error "$FUNCNAME cannot be used in '${work_cmd}'. Put it before any '${work_cmd}' definition."; return 1 ) local ports="${1}"; shift local redirect="${1}"; shift local user="${1}"; shift test -z "${redirect}" && error "Proxy listening port is empty" && return 1 transparent_proxy_count=$[transparent_proxy_count + 1] set_work_function "Setting up rules for catching routed tcp/${ports} traffic" create_chain nat "in_trproxy.${transparent_proxy_count}" PREROUTING noowner "$@" outface any proto tcp sport "${DEFAULT_CLIENT_PORTS}" dport "${ports}" || return 1 # rule table nat chain "in_trproxy.${transparent_proxy_count}" proto tcp dport "${ports}" action REDIRECT to-port ${redirect} || return 1 rule table nat chain "in_trproxy.${transparent_proxy_count}" proto tcp action REDIRECT to-port ${redirect} || return 1 if [ ! -z "${user}" ] then set_work_function "Setting up rules for catching outgoing tcp/${ports} traffic" create_chain nat "out_trproxy.${transparent_proxy_count}" OUTPUT "$@" uid not "${user}" nosoftwarnings inface any outface any src any proto tcp sport "${LOCAL_CLIENT_PORTS}" dport "${ports}" || return 1 # do not catch traffic for localhost servers rule table nat chain "out_trproxy.${transparent_proxy_count}" dst "127.0.0.1" action RETURN || return 1 # rule table nat chain "out_trproxy.${transparent_proxy_count}" proto tcp dport "${ports}" action REDIRECT to-port ${redirect} || return 1 rule table nat chain "out_trproxy.${transparent_proxy_count}" proto tcp action REDIRECT to-port ${redirect} || return 1 fi FIREHOL_NAT=1 FIREHOL_ROUTING=1 return 0 } transparent_squid() { transparent_proxy 80 "$@" } nat_count=0 nat_helper() { # work_realcmd_helper $FUNCNAME "$@" set_work_function -ne "Initializing $FUNCNAME" require_work clear || ( error "NAT cannot be used in '${work_cmd}'. Put all NAT related commands before any '${work_cmd}' definition."; return 1 ) local type="${1}"; shift local to="${1}"; shift nat_count=$[nat_count + 1] set_work_function -ne "Setting up rules for NAT type: '${type}'" case ${type} in to-source) create_chain nat "nat.${nat_count}" POSTROUTING nolog "$@" inface any || return 1 local action=snat ;; to-destination) create_chain nat "nat.${nat_count}" PREROUTING noowner nolog "$@" outface any || return 1 local action=dnat ;; redirect-to) create_chain nat "nat.${nat_count}" PREROUTING noowner nolog "$@" outface any || return 1 local action=redirect ;; *) error "$FUNCNAME requires a type (i.e. to-source, to-destination, redirect-to, etc) as its first argument. '${type}' is not understood." return 1 ;; esac set_work_function "Taking the NAT action: '${action}'" # we now need to keep the protocol rule table nat chain "nat.${nat_count}" noowner "$@" action "${action}" to "${to}" nosoftwarnings src any dst any inface any outface any sport any dport any || return 1 FIREHOL_NAT=1 FIREHOL_ROUTING=1 return 0 } nat() { work_realcmd_helper $FUNCNAME "$@" set_work_function -ne "Initializing $FUNCNAME" nat_helper "$@" } snat() { work_realcmd_helper $FUNCNAME "$@" set_work_function -ne "Initializing $FUNCNAME" local to="${1}"; shift test "${to}" = "to" && local to="${1}" && shift nat_helper "to-source" "${to}" "$@" } dnat() { work_realcmd_helper $FUNCNAME "$@" set_work_function -ne "Initializing $FUNCNAME" local to="${1}"; shift test "${to}" = "to" && local to="${1}" && shift nat_helper "to-destination" "${to}" "$@" } redirect() { work_realcmd_helper $FUNCNAME "$@" set_work_function -ne "Initializing $FUNCNAME" local to="${1}"; shift test "${to}" = "to" -o "${to}" = "to-port" && local to="${1}" && shift nat_helper "redirect-to" "${to}" "$@" } wrongmac_chain=0 mac() { work_realcmd_helper $FUNCNAME "$@" set_work_function -ne "Initializing $FUNCNAME" require_work clear || ( error "$FUNCNAME cannot be used in '${work_cmd}'. Put it before any '${work_cmd}' definition."; return 1 ) if [ ${wrongmac_chain} -eq 0 ] then set_work_function "Creating the MAC-MISSMATCH chain (only once)" iptables -t filter -N WRONGMAC rule table filter chain WRONGMAC loglimit "MAC MISSMATCH" action DROP || return 1 wrongmac_chain=1 fi set_work_function "If the source IP ${1} does not match MAC ${2}, drop the packet" iptables -t filter -A INPUT -s "${1}" -m mac --mac-source ! "${2}" -j WRONGMAC iptables -t filter -A FORWARD -s "${1}" -m mac --mac-source ! "${2}" -j WRONGMAC return 0 } # blacklist creates two types of blacklists: unidirectional or bidirectional blacklist_chain=0 blacklist() { work_realcmd_helper ${FUNCNAME} "$@" set_work_function -ne "Initializing $FUNCNAME" require_work clear || ( error "$FUNCNAME cannot be used in '${work_cmd}'. Put it before any '${work_cmd}' definition."; return 1 ) local full=1 if [ "${1}" = "them" -o "${1}" = "him" -o "${1}" = "her" -o "${1}" = "it" -o "${1}" = "this" -o "${1}" = "these" -o "${1}" = "input" ] then shift full=0 elif [ "${1}" = "all" -o "${1}" = "full" ] then shift full=1 fi if [ ${blacklist_chain} -eq 0 ] then set_work_function "Generating blacklist chains" # Blacklist INPUT unidirectional iptables -t filter -N BL_IN_UNI # INPUT iptables -A BL_IN_UNI -m state --state NEW -j DROP iptables -A BL_IN_UNI -j DROP # No need for OUTPUT/FORWARD unidirectional # Blacklist INPUT bidirectional iptables -t filter -N BL_IN_BI # INPUT iptables -A BL_IN_BI -m state --state NEW -j DROP iptables -A BL_IN_BI -j DROP # Blacklist OUTPUT/FORWARD bidirectional iptables -t filter -N BL_OUT_BI # OUTPUT and FORWARD iptables -A BL_OUT_BI -m state --state NEW -p tcp -j REJECT #--reject-with tcp-reset iptables -A BL_OUT_BI -m state --state NEW -j REJECT --reject-with icmp-host-unreachable iptables -A BL_OUT_BI -j REJECT blacklist_chain=1 fi set_work_function "Generating blacklist rules" local z= for z in $@ do local x= for x in ${z} do set_work_function "Blacklisting '${x}'" if [ ${full} -eq 1 ] then iptables -I INPUT -s ${x} -j BL_IN_BI iptables -I FORWARD -s ${x} -j BL_IN_BI iptables -I OUTPUT -d ${x} -j BL_OUT_BI iptables -I FORWARD -d ${x} -j BL_OUT_BI else iptables -I INPUT -s ${x} -j BL_IN_UNI iptables -I FORWARD -s ${x} -j BL_IN_UNI fi done done return 0 } classify_count=0 classify() { work_realcmd_helper $FUNCNAME "$@" set_work_function -ne "Initializing $FUNCNAME" require_work clear || ( error "$FUNCNAME cannot be used in '${work_cmd}'. Put it before any '${work_cmd}' definition."; return 1 ) local class="${1}"; shift classify_count=$[classify_count + 1] set_work_function "Setting up rules for CLASSIFY" create_chain mangle "classify.${classify_count}" POSTROUTING "$@" || return 1 iptables -t mangle -A "classify.${classify_count}" -j CLASSIFY --set-class ${class} return 0 } connmark_count=0 connmark() { work_realcmd_helper $FUNCNAME "$@" set_work_function -ne "Initializing $FUNCNAME" require_work clear || ( error "$FUNCNAME cannot be used in '${work_cmd}'. Put it before any '${work_cmd}' definition."; return 1 ) local num="${1}"; shift local where="${1}"; shift test -z "${where}" && where=OUTPUT connmark_count=$[connmark_count + 1] set_work_function "Setting up rules for CONNMARK" create_chain mangle "connmark.${connmark_count}" "${where}" "$@" || return 1 case "${num}" in save) iptables -t mangle -A "connmark.${connmark_count}" -j CONNMARK --save-mark ;; restore) iptables -t mangle -A "connmark.${connmark_count}" -j CONNMARK --restore-mark ;; *) iptables -t mangle -A "connmark.${connmark_count}" -j CONNMARK --set-mark ${num} ;; esac return 0 } mark_count=0 mark() { work_realcmd_helper $FUNCNAME "$@" set_work_function -ne "Initializing $FUNCNAME" require_work clear || ( error "$FUNCNAME cannot be used in '${work_cmd}'. Put it before any '${work_cmd}' definition."; return 1 ) local num="${1}"; shift local where="${1}"; shift test -z "${where}" && where=OUTPUT mark_count=$[mark_count + 1] set_work_function "Setting up rules for MARK" create_chain mangle "mark.${mark_count}" "${where}" "$@" || return 1 iptables -t mangle -A "mark.${mark_count}" -j MARK --set-mark ${num} return 0 } tos_count=0 tos() { work_realcmd_helper $FUNCNAME "$@" set_work_function -ne "Initializing $FUNCNAME" require_work clear || ( error "$FUNCNAME cannot be used in '${work_cmd}'. Put it before any '${work_cmd}' definition."; return 1 ) local num="${1}"; shift local where="${1}"; shift test -z "${where}" && where=OUTPUT tos_count=$[tos_count + 1] set_work_function "Setting up rules for TOS" create_chain mangle "tos.${tos_count}" "${where}" "$@" || return 1 iptables -t mangle -A "tos.${tos_count}" -j TOS --set-tos ${num} return 0 } # from http://blog.edseek.com/~jasonb/articles/traffic_shaping/scenarios.html tosfix() { work_realcmd=($FUNCNAME "$@") set_work_function -ne "Initializing $FUNCNAME" require_work clear || ( error "$FUNCNAME cannot be used in '${work_cmd}'. Put it before any '${work_cmd}' definition."; return 1 ) set_work_function "Fixing TOS for TCP ACK packets" iptables -t mangle -N ackfix iptables -t mangle -A ackfix -m tos ! --tos Normal-Service -j RETURN iptables -t mangle -A ackfix -p tcp -m length --length 0:128 -j TOS --set-tos Minimize-Delay iptables -t mangle -A ackfix -p tcp -m length --length 128: -j TOS --set-tos Maximize-Throughput iptables -t mangle -A ackfix -j RETURN iptables -t mangle -I POSTROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK ACK -j ackfix set_work_function "Fixing TOS for Minimize-Delay packets" iptables -t mangle -N tosfix iptables -t mangle -A tosfix -p tcp -m length --length 0:512 -j RETURN iptables -t mangle -A tosfix -m limit --limit 2/s --limit-burst 10 -j RETURN iptables -t mangle -A tosfix -j TOS --set-tos Maximize-Throughput iptables -t mangle -A tosfix -j RETURN iptables -t mangle -I POSTROUTING -p tcp -m tos --tos Minimize-Delay -j tosfix return 0 } dscp_count=0 dscp() { work_realcmd=($FUNCNAME "$@") set_work_function -ne "Initializing $FUNCNAME" require_work clear || ( error "$FUNCNAME cannot be used in '${work_cmd}'. Put it before any '${work_cmd}' definition."; return 1 ) local value="${1}"; shift local class="" if [ "${value}" = "class" ] then local value="" local class="${1}"; shift fi local where="${1}"; shift test -z "${where}" && where=OUTPUT dscp_count=$[dscp_count + 1] set_work_function "Setting up rules for setting DSCP" create_chain mangle "dscp.${dscp_count}" "${where}" "$@" || return 1 if [ ! -z "${class}" ] then iptables -t mangle -A "dscp.${dscp_count}" -j DSCP --set-dscp-class ${class} else iptables -t mangle -A "dscp.${dscp_count}" -j DSCP --set-dscp ${value} fi return 0 } tcpmss() { work_realcmd_helper $FUNCNAME "$@" set_work_function -ne "Initializing $FUNCNAME" local what_to_do=error if [ "${work_cmd}" = "router" ] then if [ -z "${work_outface}" ] then local what_to_do=public else local what_to_do=interface fi elif [ -z "${work_cmd}" ] then local what_to_do=public else local what_to_do=error fi # work only if this helper is called before any primary command # or within routers. if [ "${what_to_do}" = "public" ] then set_work_function "Initializing tcpmss for all interfaces" case $1 in auto) iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu ;; [0-9]*) iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss $1 ;; *) error "$FUNCNAME requires either the word 'auto' or a numeric argument." return 1 ;; esac elif [ "${what_to_do}" = "interface" ] then local f= for f in ${work_outface} do set_work_function "Initializing tcpmss for interface '${f}'" case $1 in auto) iptables -t mangle -A POSTROUTING -o ${f} -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu ;; [0-9]*) iptables -t mangle -A POSTROUTING -o ${f} -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss $1 ;; *) error "$FUNCNAME requires either the word 'auto' or a numeric argument." return 1 ;; esac done else error "$FUNCNAME cannot be used in '${work_cmd}'. Put it before any '${work_cmd}' definition or in 'router' definitions." return 1 fi return 0 } # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # # INTERNAL FUNCTIONS BELLOW THIS POINT - Primary commands # # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # Check the version required by the configuration file # WHY: # We have to make sure the configuration file has been written for this version # of FireHOL. Note that the version command does not actually check the version # of firehol.sh. It checks only its release number (R5 currently). version() { work_realcmd_helper ${FUNCNAME} "$@" if [ ${1} -gt ${FIREHOL_VERSION} ] then error "Wrong version. FireHOL is v${FIREHOL_VERSION}, your script requires v${1}." fi } # ------------------------------------------------------------------------------ # PRIMARY COMMAND: interface # Setup rules specific to an interface (physical or logical) interface() { work_realcmd_primary ${FUNCNAME} "$@" # --- close any open command --- close_cmd || return 1 # --- test prerequisites --- require_work clear || return 1 set_work_function -ne "Initializing $FUNCNAME" # --- get paramaters and validate them --- # Get the interface local inface="${1}"; shift test -z "${inface}" && error "real interface is not set" && return 1 # Get the name for this interface local name="${1}"; shift test -z "${name}" && error "$FUNCNAME name is not set" && return 1 # --- do the job --- work_cmd="${FUNCNAME}" work_name="${name}" work_realcmd=("(unset)") set_work_function -ne "Initializing $FUNCNAME '${work_name}'" create_chain filter "in_${work_name}" INPUT in set_work_inface "$@" inface "${inface}" outface any || return 1 create_chain filter "out_${work_name}" OUTPUT out set_work_outface reverse "$@" inface "${inface}" outface any || return 1 return 0 } router() { work_realcmd_helper ${FUNCNAME} "$@" # --- close any open command --- close_cmd || return 1 # --- test prerequisites --- require_work clear || return 1 set_work_function -ne "Initializing $FUNCNAME" # --- get paramaters and validate them --- # Get the name for this router local name="${1}"; shift test -z "${name}" && error "$FUNCNAME name is not set" && return 1 # --- do the job --- work_cmd="${FUNCNAME}" work_name="${name}" work_realcmd=("(unset)") set_work_function -ne "Initializing $FUNCNAME '${work_name}'" create_chain filter "in_${work_name}" FORWARD in set_work_inface set_work_outface "$@" || return 1 create_chain filter "out_${work_name}" FORWARD out reverse "$@" || return 1 FIREHOL_ROUTING=1 return 0 } postprocess() { # work_realcmd_helper ${FUNCNAME} "$@" local check="error" test "A${1}" = "A-ne" && shift && local check="none" test "A${1}" = "A-warn" && shift && local check="warn" test "${FIREHOL_MODE}" = "DEBUG" && local check="none" test "${FIREHOL_MODE}" = "EXPLAIN" && local check="none" if [ ! ${check} = "none" ] then printf "runcmd '${check}' '${FIREHOL_LINEID}' " >>${FIREHOL_OUTPUT} fi printf "%q " "$@" >>${FIREHOL_OUTPUT} printf "\n" >>${FIREHOL_OUTPUT} if [ "${FIREHOL_MODE}" = "EXPLAIN" ] then ${CAT_CMD} ${FIREHOL_OUTPUT} ${RM_CMD} -f ${FIREHOL_OUTPUT} fi return 0 } runcmd() { local check="${1}"; shift local line="${1}"; shift local cmd="${1}"; shift "${cmd}" "$@" >${FIREHOL_OUTPUT}.log 2>&1 local r=$? test ${r} -gt 0 && runtime_error ${check} ${r} ${line} "${cmd}" "$@" return 0 } FIREHOL_COMMAND_COUNTER=0 iptables() { # work_realcmd_helper ${FUNCNAME} "$@" postprocess "${IPTABLES_CMD}" "$@" FIREHOL_COMMAND_COUNTER=$[FIREHOL_COMMAND_COUNTER + 1] return 0 } # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # # INTERNAL FUNCTIONS BELLOW THIS POINT - Sub-commands # # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # Change the policy of an interface # WHY: # Not all interfaces have the same policy. The admin must have control over it. # Here we just set what the admin wants. At the interface finalization we # produce the iptables rules. policy() { work_realcmd_secondary ${FUNCNAME} "$@" require_work set any || return 1 set_work_function "Setting policy of ${work_name} to ${1}" work_policy="$*" return 0 } server() { work_realcmd_secondary ${FUNCNAME} "$@" require_work set any || return 1 smart_function server "$@" return $? } client() { work_realcmd_secondary ${FUNCNAME} "$@" require_work set any || return 1 smart_function client "$@" return $? } route() { work_realcmd_secondary ${FUNCNAME} "$@" require_work set router || return 1 smart_function server "$@" return $? } # --- protection --------------------------------------------------------------- protection() { work_realcmd_secondary ${FUNCNAME} "$@" require_work set any || return 1 local in="in" local prface="${work_inface}" local pre="pr" local reverse= if [ "${1}" = "reverse" ] then local reverse="reverse" # needed to recursion local pre="prr" # in case a router has protections # both ways, the second needs to # have different chain names local in="out" # reverse the interface prface="${work_outface}" shift fi local type="${1}" local rate="${2}" local burst="${3}" test -z "${rate}" && rate="100/s" test -z "${burst}" && burst="50" set_work_function -ne "Generating protections on '${prface}' for ${work_cmd} '${work_name}'" local x= for x in ${type} do case "${x}" in none|NONE) return 0 ;; bad-packets|BAD-PACKETS) protection ${reverse} "fragments new-tcp-w/o-syn malformed-xmas malformed-null malformed-bad invalid" "${rate}" "${burst}" return $? ;; strong|STRONG|full|FULL|all|ALL) protection ${reverse} "fragments new-tcp-w/o-syn icmp-floods syn-floods malformed-xmas malformed-null malformed-bad invalid" "${rate}" "${burst}" return $? ;; invalid|INVALID) iptables -A "${in}_${work_name}" -m state --state INVALID -j DROP || return 1 ;; fragments|FRAGMENTS) local mychain="${pre}_${work_name}_fragments" create_chain filter "${mychain}" "${in}_${work_name}" in custom "-f" || return 1 set_work_function "Generating rules to be protected from packet fragments on '${prface}' for ${work_cmd} '${work_name}'" rule in chain "${mychain}" loglimit "PACKET FRAGMENTS" action drop || return 1 ;; new-tcp-w/o-syn|NEW-TCP-W/O-SYN) local mychain="${pre}_${work_name}_nosyn" create_chain filter "${mychain}" "${in}_${work_name}" in proto tcp state NEW custom "! --syn" || return 1 set_work_function "Generating rules to be protected from new TCP connections without the SYN flag set on '${prface}' for ${work_cmd} '${work_name}'" rule in chain "${mychain}" loglimit "NEW TCP w/o SYN" action drop || return 1 ;; icmp-floods|ICMP-FLOODS) local mychain="${pre}_${work_name}_icmpflood" create_chain filter "${mychain}" "${in}_${work_name}" in proto icmp custom "--icmp-type echo-request" || return 1 set_work_function "Generating rules to be protected from ICMP floods on '${prface}' for ${work_cmd} '${work_name}'" rule in chain "${mychain}" limit "${rate}" "${burst}" action return || return 1 rule in chain "${mychain}" loglimit "ICMP FLOOD" action drop || return 1 ;; syn-floods|SYN-FLOODS) local mychain="${pre}_${work_name}_synflood" create_chain filter "${mychain}" "${in}_${work_name}" in proto tcp custom "--syn" || return 1 set_work_function "Generating rules to be protected from TCP SYN floods on '${prface}' for ${work_cmd} '${work_name}'" rule in chain "${mychain}" limit "${rate}" "${burst}" action return || return 1 rule in chain "${mychain}" loglimit "SYN FLOOD" action drop || return 1 ;; all-floods|ALL-FLOODS) local mychain="${pre}_${work_name}_allflood" create_chain filter "${mychain}" "${in}_${work_name}" in state NEW || return 1 set_work_function "Generating rules to be protected from ALL floods on '${prface}' for ${work_cmd} '${work_name}'" rule in chain "${mychain}" limit "${rate}" "${burst}" action return || return 1 rule in chain "${mychain}" loglimit "ALL FLOOD" action drop || return 1 ;; malformed-xmas|MALFORMED-XMAS) local mychain="${pre}_${work_name}_malxmas" create_chain filter "${mychain}" "${in}_${work_name}" in proto tcp custom "--tcp-flags ALL ALL" || return 1 set_work_function "Generating rules to be protected from packets with all TCP flags set on '${prface}' for ${work_cmd} '${work_name}'" rule in chain "${mychain}" loglimit "MALFORMED XMAS" action drop || return 1 ;; malformed-null|MALFORMED-NULL) local mychain="${pre}_${work_name}_malnull" create_chain filter "${mychain}" "${in}_${work_name}" in proto tcp custom "--tcp-flags ALL NONE" || return 1 set_work_function "Generating rules to be protected from packets with all TCP flags unset on '${prface}' for ${work_cmd} '${work_name}'" rule in chain "${mychain}" loglimit "MALFORMED NULL" action drop || return 1 ;; malformed-bad|MALFORMED-BAD) local mychain="${pre}_${work_name}_malbad" create_chain filter "${mychain}" "${in}_${work_name}" in proto tcp custom "--tcp-flags SYN,FIN SYN,FIN" || return 1 set_work_function "Generating rules to be protected from packets with illegal TCP flags on '${prface}' for ${work_cmd} '${work_name}'" rule in chain "${in}_${work_name}" action "${mychain}" proto tcp custom "--tcp-flags SYN,RST SYN,RST" || return 1 rule in chain "${in}_${work_name}" action "${mychain}" proto tcp custom "--tcp-flags ALL SYN,RST,ACK,FIN,URG" || return 1 rule in chain "${in}_${work_name}" action "${mychain}" proto tcp custom "--tcp-flags ALL FIN,URG,PSH" || return 1 rule in chain "${mychain}" loglimit "MALFORMED BAD" action drop || return 1 ;; *) error "Protection '${x}' does not exists." return 1 ;; esac done return 0 } # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # # KERNEL MODULE MANAGEMENT # # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # Manage kernel modules # WHY: # We need to load a set of kernel modules during postprocessing, and after the # new firewall has been activated. # The whole point of the following code, is not to attempt loading modules when # they are compiled into the kernel. # Try to find the current kernel configuration KERNEL_CONFIG= if [ -f "/proc/config" ] then KERNEL_CONFIG="/proc/config" ${CAT_CMD} /proc/config >"${FIREHOL_DIR}/kcfg" || KERNEL_CONFIG= fi if [ -z "${KERNEL_CONFIG}" -a -f "/proc/config.gz" ] then KERNEL_CONFIG="/proc/config.gz" zcat_cmd /proc/config.gz >"${FIREHOL_DIR}/kcfg" || KERNEL_CONFIG= fi if [ -z "${KERNEL_CONFIG}" -a -f "/lib/modules/`${UNAME_CMD} -r`/build/.config" ] then KERNEL_CONFIG="/lib/modules/`${UNAME_CMD} -r`/build/.config" "${CAT_CMD}" "${KERNEL_CONFIG}" >"${FIREHOL_DIR}/kcfg" || KERNEL_CONFIG= fi if [ -z "${KERNEL_CONFIG}" -a -f "/boot/config-`${UNAME_CMD} -r`" ] then KERNEL_CONFIG="/boot/config-`${UNAME_CMD} -r`" "${CAT_CMD}" "${KERNEL_CONFIG}" >"${FIREHOL_DIR}/kcfg" || KERNEL_CONFIG= fi if [ -z "${KERNEL_CONFIG}" -a -f "/usr/src/linux/.config" ] then KERNEL_CONFIG="/usr/src/linux/.config" "${CAT_CMD}" "${KERNEL_CONFIG}" >"${FIREHOL_DIR}/kcfg" || KERNEL_CONFIG= fi # Did we managed to find the kernel configuration? if [ ! -z "{$KERNEL_CONFIG}" -a -s "${FIREHOL_DIR}/kcfg" ] then # We found a kernel configuration # Load all the definitions for CONFIG_*_NF_* variables # We grep what we care for, to make sure there is no garbage or malicious code # in the file we will run. "${CAT_CMD}" "${FIREHOL_DIR}/kcfg" | ${GREP_CMD} -e "^CONFIG_[A-Z0-9_]\+_NF_[A-Z0-9_]\+=[ynm]$" >"${FIREHOL_DIR}/kcfg.nf" # run it to get the variables source "${FIREHOL_DIR}/kcfg.nf" else # We could not find a kernel configuration KERNEL_CONFIG= echo >&2 " " echo >&2 " IMPORTANT WARNING:" echo >&2 " ------------------" echo >&2 " FireHOL cannot find your current kernel configuration." echo >&2 " Please, either compile your kernel with /proc/config," echo >&2 " or make sure there is a valid kernel config in:" echo >&2 " /usr/src/linux/.config" echo >&2 " " echo >&2 " Because of this, FireHOL will simply attempt to load" echo >&2 " all kernel modules for the services used, without" echo >&2 " being able to detect failures." echo >&2 " " sleep 2 fi # activation-phase command to check for the existance of # a kernel configuration directive. It returns: # 0 = module is already in the kernel # 1 = module can be loaded with modprobe # 2 = no info about this module in the kernel check_kernel_config() { # In kernels 2.6.20+ _IP_ was removed from kernel iptables config names. # A few kernels have _CONNTRACT_ replaced with _CT_ for certain modules. # Try all versions. # the original way eval local kcfg1="\$${1}" # without _IP_ local t=`echo ${1} | sed "s/_IP_//g"` eval local kcfg2="\$${t}" # _CONNTRACK_ as _CT_ local t=`echo ${1} | sed "s/_CONNTRACK_/_CT_/g"` eval local kcfg3="\$${t}" # prefer the kernel 2.6.20+ way if [ ! -z "${kcfg2}" ] then kcfg="${kcfg2}" elif [ ! -z "${kcfg3}" ] then kcfg="${kcfg3}" else kcfg="${kcfg1}" fi case ${kcfg} in y) return 0 ;; m) return 1 ;; *) return 2 ;; esac return 2 } # activation-phase command to check for the existance of # a kernel module. It returns: # 0 = module is already in the kernel # 1 = module can be loaded with modprobe # 2 = no info about this module in the kernel check_kernel_module() { local mod="${1}" case ${mod} in ip_tables) test -f /proc/net/ip_tables_names && return 0 check_kernel_config CONFIG_IP_NF_IPTABLES return $? ;; ip_conntrack|nf_conntrack) test -f /proc/net/ip_conntrack -o -f /proc/net/nf_conntrack && return 0 check_kernel_config CONFIG_IP_NF_CONNTRACK return $? ;; ip_conntrack_*|nf_conntrack_*) local mnam="CONFIG_IP_NF_`echo ${mod} | ${CUT_CMD} -d '_' -f 3- | ${TR_CMD} a-z A-Z`" check_kernel_config ${mnam} return $? ;; ip_nat_*|nf_nat_*) local mnam="CONFIG_IP_NF_NAT_`echo ${mod} | ${CUT_CMD} -d '_' -f 3- | ${TR_CMD} a-z A-Z`" check_kernel_config ${mnam} return $? ;; *) return 2 ;; esac return 2 } # activation-phase command to load a kernel module. load_kernel_module() { local mod="${1}" if [ ! ${FIREHOL_LOAD_KERNEL_MODULES} -eq 0 ] then check_kernel_module ${mod} if [ $? -gt 0 ] then echo >>"${FIREHOL_DIR}/modules_to_load.sh" "${MODPROBE_CMD} ${mod} -q" runcmd warn ${FIREHOL_LINEID} ${MODPROBE_CMD} ${mod} -q fi fi return 0 } # Processing-phase command to tell FireHOL to find one or more # kernel modules to load, during activation-phase. require_kernel_module() { local new="${1}" local m= for m in ${FIREHOL_KERNEL_MODULES} do test "${m}" = "${new}" && return 0 done set_work_function "Adding kernel module '${new}' in the list of kernel modules to load" FIREHOL_KERNEL_MODULES="${FIREHOL_KERNEL_MODULES} ${new}" return 0 } # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # # INTERNAL FUNCTIONS BELLOW THIS POINT - FireHOL internals # # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ set_work_function() { local show_explain=1 test "$1" = "-ne" && shift && local show_explain=0 work_function="$*" if [ "${FIREHOL_MODE}" = "EXPLAIN" ] then test ${show_explain} -eq 1 && printf "\n# %s\n" "$*" elif [ ${FIREHOL_CONF_SHOW} -eq 1 ] then test ${show_explain} -eq 1 && printf "\n# INFO>>> %s\n" "$*" >>${FIREHOL_OUTPUT} fi } # ------------------------------------------------------------------------------ # Check the status of the current primary command. # WHY: # Some sanity check for the order of commands in the configuration file. # Each function has a "require_work type command" in order to check that it is # placed in a valid point. This means that if you place a "route" command in an # interface section (and many other combinations) it will fail. require_work() { local type="${1}" local cmd="${2}" case "${type}" in clear) test ! -z "${work_cmd}" && error "Previous work was not applied." && return 1 ;; set) test -z "${work_cmd}" && error "The command used requires that a primary command is set." && return 1 test ! "${work_cmd}" = "${cmd}" -a ! "${cmd}" = "any" && error "Primary command is '${work_cmd}' but '${cmd}' is required." && return 1 ;; *) error "Unknown work status '${type}'." return 1 ;; esac return 0 } # ------------------------------------------------------------------------------ # Finalizes the rules of the last primary command. # WHY: # At the end of an interface or router we need to add some code to apply its # policy, accept all related packets, etc. # Finalization occures automatically when a new primary command is executed and # when the configuration file finishes. close_cmd() { set_work_function -ne "Closing last open primary command (${work_cmd}/${work_name})" case "${work_cmd}" in interface) close_interface || return 1 ;; router) close_router || return 1 ;; '') ;; *) error "Unknown work '${work_cmd}'." return 1 ;; esac # Reset the current status variables to empty/default work_counter=0 work_cmd= work_realcmd=("(unset)") work_name= work_inface= work_outface= work_policy= return 0 } # ------------------------------------------------------------------------------ # close_interface # WHY: # Finalizes the rules for the last interface(). close_interface() { require_work set interface || return 1 close_all_groups set_work_function "Finilizing interface '${work_name}'" # Accept all related traffic to the established connections rule chain "in_${work_name}" state RELATED action ACCEPT || return 1 rule chain "out_${work_name}" state RELATED action ACCEPT || return 1 # make sure we have a policy test -z "${work_policy}" && work_policy="${DEFAULT_INTERFACE_POLICY}" case "${work_policy}" in return|RETURN) return 0 ;; accept|ACCEPT) ;; *) if [ "${FIREHOL_DROP_ORPHAN_TCP_ACK_FIN}" = "1" ] then # Silently drop orphan TCP/ACK FIN packets rule chain "in_${work_name}" proto tcp custom "--tcp-flags ALL ACK,FIN" action DROP || return 1 rule reverse chain "out_${work_name}" proto tcp custom "--tcp-flags ALL ACK,FIN" action DROP || return 1 fi local -a inlog=(loglimit "IN-${work_name}") local -a outlog=(loglimit "OUT-${work_name}") ;; esac rule chain "in_${work_name}" "${inlog[@]}" action ${work_policy} || return 1 rule reverse chain "out_${work_name}" "${outlog[@]}" action ${work_policy} || return 1 return 0 } # ------------------------------------------------------------------------------ # close_router # WHY: # Finalizes the rules for the last router(). close_router() { require_work set router || return 1 close_all_groups set_work_function "Finilizing router '${work_name}'" # Accept all related traffic to the established connections rule chain "in_${work_name}" state RELATED action ACCEPT || return 1 rule chain "out_${work_name}" state RELATED action ACCEPT || return 1 # make sure we have a policy test -z "${work_policy}" && work_policy="${DEFAULT_ROUTER_POLICY}" case "${work_policy}" in return|RETURN) return 0 ;; accept|ACCEPT) ;; *) if [ "${FIREHOL_DROP_ORPHAN_TCP_ACK_FIN}" = "1" ] then # Silently drop orphan TCP/ACK FIN packets rule chain "in_${work_name}" proto tcp custom "--tcp-flags ALL ACK,FIN" action DROP || return 1 rule reverse chain "out_${work_name}" proto tcp custom "--tcp-flags ALL ACK,FIN" action DROP || return 1 fi local -a inlog=(loglimit "PASS-${work_name}") local -a outlog=(loglimit "PASS-${work_name}") ;; esac rule chain "in_${work_name}" "${inlog[@]}" action ${work_policy} || return 1 rule reverse chain "out_${work_name}" "${outlog[@]}" action ${work_policy} || return 1 return 0 } # ------------------------------------------------------------------------------ # close_master # WHY: # Finalizes the rules for the whole firewall. # It assummes there is not primary command open. close_master() { set_work_function "Finilizing firewall policies" # Accept all related traffic to the established connections rule chain INPUT state RELATED action ACCEPT || return 1 rule chain OUTPUT state RELATED action ACCEPT || return 1 rule chain FORWARD state RELATED action ACCEPT || return 1 if [ "${FIREHOL_DROP_ORPHAN_TCP_ACK_FIN}" = "1" ] then # Silently drop orphan TCP/ACK FIN packets rule chain INPUT proto tcp custom "--tcp-flags ALL ACK,FIN" action DROP || return 1 rule chain OUTPUT proto tcp custom "--tcp-flags ALL ACK,FIN" action DROP || return 1 rule chain FORWARD proto tcp custom "--tcp-flags ALL ACK,FIN" action DROP || return 1 fi rule chain INPUT loglimit "IN-unknown" action ${UNMATCHED_INPUT_POLICY} || return 1 rule chain OUTPUT loglimit "OUT-unknown" action ${UNMATCHED_OUTPUT_POLICY} || return 1 rule chain FORWARD loglimit "PASS-unknown" action ${UNMATCHED_ROUTER_POLICY} || return 1 return 0 } FIREHOL_GROUP_COUNTER=0 FIREHOL_GROUP_DEPTH=0 FIREHOL_GROUP_STACK=() group() { work_realcmd_primary ${FUNCNAME} "$@" require_work set any || return 1 local type="${1}"; shift case $type in with|start|begin) # increase the counter FIREHOL_GROUP_COUNTER=$[FIREHOL_GROUP_COUNTER + 1] set_work_function "Starting new group No ${FIREHOL_GROUP_COUNTER}, under '${work_name}'" # put the current name in the stack FIREHOL_GROUP_STACK[$FIREHOL_GROUP_DEPTH]=${work_name} FIREHOL_GROUP_DEPTH=$[FIREHOL_GROUP_DEPTH + 1] # name for the new chain mychain="group${FIREHOL_GROUP_COUNTER}" # create the new chain create_chain filter "in_${mychain}" "in_${work_name}" in "$@" || return 1 create_chain filter "out_${mychain}" "out_${work_name}" out reverse "$@" || return 1 # set a new name for new rules work_name=${mychain} ;; end|stop|close) if [ ${FIREHOL_GROUP_DEPTH} -eq 0 ] then error "There is no group open to close." return 1 fi # pop one name from the stack FIREHOL_GROUP_DEPTH=$[FIREHOL_GROUP_DEPTH - 1] set_work_function "Closing group '${work_name}'. Now working under '${FIREHOL_GROUP_STACK[$FIREHOL_GROUP_DEPTH]}'" work_name=${FIREHOL_GROUP_STACK[$FIREHOL_GROUP_DEPTH]} ;; *) error "Statement 'group' requires the first argument to be one of with, start, begin, end, stop, close." return 1 ;; esac return 0 } close_all_groups() { while [ ${FIREHOL_GROUP_DEPTH} -gt 0 ] do group close || return 1 done return 0 } # ------------------------------------------------------------------------------ # rule - the heart of FireHOL - iptables commands generation # WHY: # This is the function that gives all the magic to FireHOL. Actually it is a # wrapper for iptables, producing multiple iptables commands based on its # arguments. The rest of FireHOL is simply a "driver" for this function. # rule_action_param() is a function - part of rule() - to create the final iptables cmd # taking into account the "action_param" parameter of the action. # rule_action_param() should only be used within rule() - no other place FIREHOL_ACCEPT_CHAIN_COUNT=0 rule_action_param() { local action="${1}"; shift local protocol="${1}"; shift local statenot="${1}"; shift local state="${1}"; shift local table="${1}"; shift local -a action_param=() # All arguments until the separator are the parameters of the action local count=0 while [ ! -z "${1}" -a ! "A${1}" = "A--" ] do action_param[$count]="${1}" shift count=$[count + 1] done # If we don't have a seperator, generate an error local sep="${1}"; shift if [ ! "A${sep}" = "A--" ] then error "Internal Error, in parsing action_param parameters ($FUNCNAME '${action}' '${protocol}' '${statenot}' '${state}' '${table}' '${action_param[@]}' ${sep} '$@')." return 1 fi # Do the rule case "${action}" in NONE) return 0 ;; ACCEPT) # do we have any options for this accept? if [ ! -z "${action_param[0]}" ] then # find the options we have case "${action_param[0]}" in "limit") # limit NEW connections to the specified rate local freq="${action_param[1]}" local burst="${action_param[2]}" local overflow="REJECT" # if we have a custom overflow action, parse it. test "${action_param[3]}" = "overflow" && local overflow="`echo "${action_param[4]}" | tr "a-z" "A-Z"`" # unset the action_param, so that if this rule does not include NEW connections, # we will not append anything to the generated iptables statements. local -a action_param=() # find is this rule matches NEW connections local has_new=`echo "${state}" | grep -i NEW` local do_accept_limit=0 if [ -z "${statenot}" ] then test ! -z "${has_new}" && local do_accept_limit=1 else test -z "${has_new}" && local do_accept_limit=1 fi # we have a match for NEW connections. # redirect the traffic to a new chain, which will control # the NEW connections while allowing all the other traffic # to pass. if [ "${do_accept_limit}" = "1" ] then local accept_limit_chain="`echo "ACCEPT LIMIT ${freq} ${burst} ${overflow}" | tr " /." "___"`" # does the chain we need already exist? if [ ! -f "${FIREHOL_CHAINS_DIR}/${accept_limit_chain}" ] then # the chain does not exist. create it. iptables ${table} -N "${accept_limit_chain}" touch "${FIREHOL_CHAINS_DIR}/${accept_limit_chain}" # first, if the traffic is not a NEW connection, allow it. # doing this first will speed up normal traffic. iptables ${table} -A "${accept_limit_chain}" -m state ! --state NEW -j ACCEPT # accept NEW connections within the given limits. iptables ${table} -A "${accept_limit_chain}" -m limit --limit "${freq}" --limit-burst "${burst}" -j ACCEPT # log the overflow NEW connections reaching this step within the new chain local -a logopts_arg=() if [ "${FIREHOL_LOG_MODE}" = "ULOG" ] then local -a logopts_arg=("--ulog-prefix=${FIREHOL_LOG_PREFIX}LIMIT_OVERFLOW:") elif [ "${FIREHOL_LOG_MODE}" = "NFLOG" ] then local -a logopts_arg=("--nflog-prefix=${FIREHOL_LOG_PREFIX}LIMIT_OVERFLOW:") else local -a logopts_arg=("--log-level" "${FIREHOL_LOG_LEVEL}" "--log-prefix=${FIREHOL_LOG_PREFIX}LIMIT_OVERFLOW:") fi iptables ${table} -A "${accept_limit_chain}" -m limit --limit "${FIREHOL_LOG_FREQUENCY}" --limit-burst "${FIREHOL_LOG_BURST}" -j ${FIREHOL_LOG_MODE} ${FIREHOL_LOG_OPTIONS} "${logopts_arg[@]}" # if the overflow is to be rejected is tcp, reject it with TCP-RESET if [ "${overflow}" = "REJECT" ] then iptables ${table} -A "${accept_limit_chain}" -p tcp -j REJECT --reject-with tcp-reset fi # do the specified action on the overflow iptables ${table} -A "${accept_limit_chain}" -j ${overflow} fi # send the rule to be generated to this chain local action=${accept_limit_chain} fi ;; "recent") # limit NEW connections to the specified rate local name="${action_param[1]}" local seconds="${action_param[2]}" local hits="${action_param[3]}" # unset the action_param, so that if this rule does not include NEW connections, # we will not append anything to the generated iptables statements. local -a action_param=() # find is this rule matches NEW connections local has_new=`echo "${state}" | grep -i NEW` local do_accept_recent=0 if [ -z "${statenot}" ] then test ! -z "${has_new}" && local do_accept_recent=1 else test -z "${has_new}" && local do_accept_recent=1 fi # we have a match for NEW connections. # redirect the traffic to a new chain, which will control # the NEW connections while allowing all the other traffic # to pass. if [ "${do_accept_recent}" = "1" ] then local accept_recent_chain="`echo "ACCEPT RECENT $name $seconds $hits" | tr " /." "___"`" # does the chain we need already exist? if [ ! -f "${FIREHOL_CHAINS_DIR}/${accept_recent_chain}" ] then # the chain does not exist. create it. iptables ${table} -N "${accept_recent_chain}" touch "${FIREHOL_CHAINS_DIR}/${accept_recent_chain}" # first, if the traffic is not a NEW connection, allow it. # doing this first will speed up normal traffic. iptables ${table} -A "${accept_recent_chain}" -m state ! --state NEW -j ACCEPT # accept NEW connections within the given limits. iptables ${table} -A "${accept_recent_chain}" -m recent --set --name "${name}" local t1= test ! -z $seconds && local t1="--seconds ${seconds}" local t2= test ! -z $hits && local t2="--hitcount ${hits}" iptables ${table} -A "${accept_recent_chain}" -m recent --update ${t1} ${t2} --name "${name}" -j RETURN iptables ${table} -A "${accept_recent_chain}" -j ACCEPT fi # send the rule to be generated to this chain local action=${accept_recent_chain} fi ;; 'knock') # the name of the knock local name="knock_${action_param[1]}" # unset the action_param, so that if this rule does not include NEW connections, # we will not append anything to the generated iptables statements. local -a action_param=() # does the knock chain exists? if [ ! -f "${FIREHOL_CHAINS_DIR}/${name}" ] then # the chain does not exist. create it. iptables ${table} -N "${name}" touch "${FIREHOL_CHAINS_DIR}/${name}" iptables -A "${name}" -m state --state ESTABLISHED -j ACCEPT # knockd (http://www.zeroflux.org/knock/) # will create more rules inside this chain to match NEW packets. fi # send the rule to be generated to this knock chain local action=${name} ;; *) error "Internal error. Cannot understand action ${action} with parameter '${action_param[0]}'." return 1 ;; esac fi ;; REJECT) if [ "${action_param[1]}" = "auto" ] then if [ "${protocol}" = "tcp" -o "${protocol}" = "TCP" ] then action_param=("--reject-with" "tcp-reset") else action_param=() fi fi ;; esac iptables "$@" -j "${action}" "${action_param[@]}" local ret=$? test $ret -gt 0 && failed=$[failed + 1] return $ret } rule() { local table= local chain= local inface=any local infacenot= local outface=any local outfacenot= local physin=any local physinnot= local physout=any local physoutnot= local mac=any local macnot= local src=any local srcnot= local dst=any local dstnot= local srctype= local srctypenot= local dsttype= local dsttypenot= local sport=any local sportnot= local dport=any local dportnot= local proto=any local protonot= local uid=any local uidnot= local gid=any local gidnot= local pid=any local pidnot= local sid=any local sidnot= local cmd=any local cmdnot= local mark=any local marknot= local dscp=any local dscptype= local despnot= local tos=any local tosnot= local log= local logtxt= local loglevel= local limit= local burst= local iplimit= local iplimit_mask= local action= local state= local statenot= local failed=0 local reverse=0 local swi=0 local swo=0 local custom= # if set to 1, all owner module options will be ignored local noowner=0 # if set to 1, all mac options will be ignored local nomac=0 # if set to 1, MIRROR will be converted to REJECT local nomirror=0 # if set to 1, log and loglimit are ignored. local nolog=0 # if set to 1, detection algorithm about overwritting optional rule # parameters will take place. local softwarnings=1 # set it, in order to be local local -a action_param=() while [ ! -z "${1}" ] do case "${1}" in reverse|REVERSE) reverse=1 shift ;; table|TABLE) test ${softwarnings} -eq 1 -a ! -z "${table}" && softwarning "Overwritting param: ${1} '${chain}' becomes '${2}'" table="-t ${2}" shift 2 ;; chain|CHAIN) test ${softwarnings} -eq 1 -a ! -z "${chain}" && softwarning "Overwritting param: ${1} '${chain}' becomes '${2}'" chain="${2}" shift 2 ;; inface|INFACE) shift if [ ${reverse} -eq 0 ] then infacenot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift infacenot="!" else if [ $swi -eq 1 ] then work_inface="${1}" fi fi test ${softwarnings} -eq 1 -a ! "${inface}" = "any" && softwarning "Overwritting param: inface '${inface}' becomes '${1}'" inface="${1}" else outfacenot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift outfacenot="!" else if [ ${swo} -eq 1 ] then work_outface="$1" fi fi test ${softwarnings} -eq 1 -a ! "${outface}" = "any" && softwarning "Overwritting param: outface '${outface}' becomes '${1}'" outface="${1}" fi shift ;; outface|OUTFACE) shift if [ ${reverse} -eq 0 ] then outfacenot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift outfacenot="!" else if [ ${swo} -eq 1 ] then work_outface="${1}" fi fi test ${softwarnings} -eq 1 -a ! "${outface}" = "any" && softwarning "Overwritting param: outface '${outface}' becomes '${1}'" outface="${1}" else infacenot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift infacenot="!" else if [ ${swi} -eq 1 ] then work_inface="${1}" fi fi test ${softwarnings} -eq 1 -a ! "${inface}" = "any" && softwarning "Overwritting param: inface '${inface}' becomes '${1}'" inface="${1}" fi shift ;; physin|PHYSIN) shift if [ ${reverse} -eq 0 ] then physinnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift physinnot="!" fi test ${softwarnings} -eq 1 -a ! "${physin}" = "any" && softwarning "Overwritting param: physin '${physin}' becomes '${1}'" physin="${1}" else physoutnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift physoutnot="!" fi test ${softwarnings} -eq 1 -a ! "${physout}" = "any" && softwarning "Overwritting param: physout '${physout}' becomes '${1}'" physout="${1}" fi shift ;; physout|PHYSOUT) shift if [ ${reverse} -eq 0 ] then physoutnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift physoutnot="!" fi test ${softwarnings} -eq 1 -a ! "${physout}" = "any" && softwarning "Overwritting param: physout '${physout}' becomes '${1}'" physout="${1}" else physinnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift physinnot="!" fi test ${softwarnings} -eq 1 -a ! "${physin}" = "any" && softwarning "Overwritting param: physin '${physin}' becomes '${1}'" physin="${1}" fi shift ;; mac|MAC) shift macnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift test ${nomac} -eq 0 && macnot="!" fi test ${softwarnings} -eq 1 -a ! "${mac}" = "any" && softwarning "Overwritting param: mac '${mac}' becomes '${1}'" test ${nomac} -eq 0 && mac="${1}" shift ;; src|SRC|source|SOURCE) shift if [ ${reverse} -eq 0 ] then srcnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift srcnot="!" fi test ${softwarnings} -eq 1 -a ! "${src}" = "any" && softwarning "Overwritting param: src '${src}' becomes '${1}'" src="${1}" else dstnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift dstnot="!" fi test ${softwarnings} -eq 1 -a ! "${dst}" = "any" && softwarning "Overwritting param: dst '${dst}' becomes '${1}'" dst="${1}" fi shift ;; dst|DST|destination|DESTINATION) shift if [ ${reverse} -eq 0 ] then dstnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift dstnot="!" fi test ${softwarnings} -eq 1 -a ! "${dst}" = "any" && softwarning "Overwritting param: dst '${dst}' becomes '${1}'" dst="${1}" else srcnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift srcnot="!" fi test ${softwarnings} -eq 1 -a ! "${src}" = "any" && softwarning "Overwritting param: src '${src}' becomes '${1}'" src="${1}" fi shift ;; srctype|SRCTYPE|sourcetype|SOURCETYPE) shift if [ ${reverse} -eq 0 ] then srctypenot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift srctypenot="!" fi test ${softwarnings} -eq 1 -a ! "${srctype}" = "" && softwarning "Overwritting param: srctype '${srctype}' becomes '${1}'" srctype="`echo ${1} | sed "s|^ \+||" | sed "s| \+\$||" | sed "s| \+|,|g" | tr a-z A-Z`" else dsttypenot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift dsttypenot="!" fi test ${softwarnings} -eq 1 -a ! "${dsttype}" = "" && softwarning "Overwritting param: dsttype '${dsttype}' becomes '${1}'" dsttype="`echo ${1} | sed "s|^ \+||" | sed "s| \+\$||" | sed "s| \+|,|g" | tr a-z A-Z`" fi shift ;; dsttype|DSTTYPE|destinationtype|DESTINATIONTYPE) shift if [ ${reverse} -eq 0 ] then dsttypenot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift dsttypenot="!" fi test ${softwarnings} -eq 1 -a ! "${dsttype}" = "" && softwarning "Overwritting param: dsttype '${dsttype}' becomes '${1}'" dsttype="`echo ${1} | sed "s|^ \+||" | sed "s| \+\$||" | sed "s| \+|,|g" | tr a-z A-Z`" else srctypenot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift srctypenot="!" fi test ${softwarnings} -eq 1 -a ! "${srctype}" = "" && softwarning "Overwritting param: srctype '${srctype}' becomes '${1}'" srctype="`echo ${1} | sed "s|^ \+||" | sed "s| \+\$||" | sed "s| \+|,|g" | tr a-z A-Z`" fi shift ;; sport|SPORT|sourceport|SOURCEPORT) shift if [ ${reverse} -eq 0 ] then sportnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift sportnot="!" fi test ${softwarnings} -eq 1 -a ! "${sport}" = "any" && softwarning "Overwritting param: sport '${sport}' becomes '${1}'" sport="${1}" else dportnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift dportnot="!" fi test ${softwarnings} -eq 1 -a ! "${dport}" = "any" && softwarning "Overwritting param: dport '${dport}' becomes '${1}'" dport="${1}" fi shift ;; dport|DPORT|destinationport|DESTINATIONPORT) shift if [ ${reverse} -eq 0 ] then dportnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift dportnot="!" fi test ${softwarnings} -eq 1 -a ! "${dport}" = "any" && softwarning "Overwritting param: dport '${dport}' becomes '${1}'" dport="${1}" else sportnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift sportnot="!" fi test ${softwarnings} -eq 1 -a ! "${sport}" = "any" && softwarning "Overwritting param: sport '${sport}' becomes '${1}'" sport="${1}" fi shift ;; proto|PROTO|protocol|PROTOCOL) shift protonot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift protonot="!" fi test ${softwarnings} -eq 1 -a ! "${proto}" = "any" && softwarning "Overwritting param: proto '${proto}' becomes '${1}'" proto="${1}" shift ;; mark|MARK) shift marknot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift marknot="!" fi test ${softwarnings} -eq 1 -a ! "${mark}" = "any" && softwarning "Overwritting param: mark '${mark}' becomes '${1}'" mark="${1}" shift ;; tos|TOS) shift tosnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift tosnot="!" fi test ${softwarnings} -eq 1 -a ! "${tos}" = "any" && softwarning "Overwritting param: tos '${tos}' becomes '${1}'" tos="${1}" shift ;; dscp|DSCP) shift dscpnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift dscpnot="!" fi test ${softwarnings} -eq 1 -a ! "${dscp}" = "any" && softwarning "Overwritting param: dscp '${dscp}' becomes '${1}'" dscp="${1}" shift if [ "${dscp}" = "class" ] then dscptype="-class" dscp="${1}" shift fi ;; action|ACTION) test ${softwarnings} -eq 1 -a ! -z "${action}" && softwarning "Overwritting param: action '${action}' becomes '${2}'" action="${2}" shift 2 local -a action_param=() local action_is_chain=0 case "${action}" in accept|ACCEPT) action="ACCEPT" if [ "${1}" = "with" ] then shift case "${1}" in limit|LIMIT) local -a action_param=("limit" "${2}" "${3}") shift 3 if [ "${1}" = "overflow" ] then action_param[3]="overflow" action_param[4]="${2}" shift 2 fi ;; recent|RECENT) local -a action_param=("recent" "${2}" "${3}" "${4}") shift 4 ;; knock|KNOCK) local -a action_param=("knock" "${2}") shift 2 ;; *) error "Cannot understand action's '${action}' directive '${1}'" return 1 ;; esac fi ;; deny|DENY|drop|DROP) action="DROP" ;; reject|REJECT) action="REJECT" if [ "${1}" = "with" ] then local -a action_param=("--reject-with" "${2}") shift 2 else local -a action_param=("--reject-with" "auto") fi ;; return|RETURN) action="RETURN" ;; mirror|MIRROR) action="MIRROR" test $nomirror -eq 1 && action="REJECT" ;; none|NONE) action="NONE" ;; snat|SNAT) action="SNAT" if [ "${1}" = "to" ] then local -a action_param=() local x= for x in ${2} do action_param=(${action_param[@]} "--to-source" "${x}") done shift 2 else error "${action} requires a 'to' argument." return 1 fi if [ ! "A${table}" = "A-t nat" ] then error "${action} must on a the 'nat' table." return 1 fi ;; dnat|DNAT) action="DNAT" if [ "${1}" = "to" ] then local -a action_param=() local x= for x in ${2} do action_param=(${action_param[@]} "--to-destination" "${x}") done shift 2 else error "${action} requires a 'to' argument" return 1 fi if [ ! "A${table}" = "A-t nat" ] then error "${action} must on a the 'nat' table." return 1 fi ;; redirect|REDIRECT) action="REDIRECT" if [ "${1}" = "to-port" -o "${1}" = "to" ] then local -a action_param=("--to-ports" "${2}") shift 2 else error "${action} requires a 'to-port' or 'to' argument." return 1 fi if [ ! "A${table}" = "A-t nat" ] then error "${action} must on a the 'nat' table." return 1 fi ;; tos|TOS) action="TOS" if [ "${1}" = "to" ] then local -a action_param=("--set-tos" "${2}") shift 2 else error "${action} requires a 'to' argument" return 1 fi if [ ! "A${table}" = "A-t mangle" ] then error "${action} must on a the 'mangle' table." return 1 fi ;; mark|MARK) action="MARK" if [ "${1}" = "to" ] then local -a action_param=("--set-mark" "${2}") shift 2 else error "${action} requires a 'to' argument" return 1 fi if [ ! "A${table}" = "A-t mangle" ] then error "${action} must on a the 'mangle' table." return 1 fi ;; dscp|DSCP) action="DSCP" if [ "${1}" = "to" ] then if [ "${2}" = "class" ] then local -a action_param=("--set-dscp-class" "${2}") shift else local -a action_param=("--set-dscp" "${2}") fi shift 2 else error "${action} requires a 'to' argument" return 1 fi if [ ! "A${table}" = "A-t mangle" ] then error "${action} must on a the 'mangle' table." return 1 fi ;; tarpit|TARPIT) action="TARPIT" ;; *) chain_exists "${action}" local action_is_chain=$? ;; esac ;; state|STATE) shift statenot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift statenot="!" fi test ${softwarnings} -eq 1 -a ! -z "${state}" && softwarning "Overwritting param: state '${state}' becomes '${1}'" state="${1}" shift ;; user|USER|uid|UID) shift uidnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift test ${noowner} -eq 0 && uidnot="!" fi test ${softwarnings} -eq 1 -a ! "${uid}" = "any" && softwarning "Overwritting param: uid '${uid}' becomes '${1}'" test ${noowner} -eq 0 && uid="${1}" shift ;; group|GROUP|gid|GID) shift gidnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift test ${noowner} -eq 0 && gidnot="!" fi test ${softwarnings} -eq 1 -a ! "${gid}" = "any" && softwarning "Overwritting param: gid '${gid}' becomes '${1}'" test ${noowner} -eq 0 && gid="${1}" shift ;; process|PROCESS|pid|PID) shift pidnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift test ${noowner} -eq 0 && pidnot="!" fi test ${softwarnings} -eq 1 -a ! "${pid}" = "any" && softwarning "Overwritting param: pid '${pid}' becomes '${1}'" test ${noowner} -eq 0 && pid="${1}" shift ;; session|SESSION|sid|SID) shift sidnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift test ${noowner} -eq 0 && sidnot="!" fi test ${softwarnings} -eq 1 -a ! "${sid}" = "any" && softwarning "Overwritting param: sid '${sid}' becomes '${1}'" test ${noowner} -eq 0 && sid="${1}" shift ;; command|COMMAND|cmd|CMD) shift cmdnot= if [ "${1}" = "not" -o "${1}" = "NOT" ] then shift test ${noowner} -eq 0 && cmdnot="!" fi test ${softwarnings} -eq 1 -a ! "${cmd}" = "any" && softwarning "Overwritting param: cmd '${cmd}' becomes '${1}'" test ${noowner} -eq 0 && cmd="${1}" shift ;; custom|CUSTOM) test ${softwarnings} -eq 1 -a ! -z "${custom}" && softwarning "Overwritting param: custom '${custom}' becomes '${2}'" custom="${2}" shift 2 ;; log|LOG) if [ ${nolog} -eq 0 ] then test ${softwarnings} -eq 1 -a ! -z "${log}" && softwarning "Overwritting param: log '${log}/${logtxt}' becomes 'normal/${2}'" log=normal logtxt="${2}" fi shift 2 if [ "${1}" = "level" ] then loglevel="${2}" shift 2 else loglevel="${FIREHOL_LOG_LEVEL}" fi ;; loglimit|LOGLIMIT) if [ ${nolog} -eq 0 ] then test ${softwarnings} -eq 1 -a ! -z "${log}" && softwarning "Overwritting param: log '${log}/${logtxt}' becomes 'limit/${2}'" log=limit logtxt="${2}" fi shift 2 if [ "${1}" = "level" ] then loglevel="${2}" shift 2 else loglevel="${FIREHOL_LOG_LEVEL}" fi ;; limit|LIMIT) test ${softwarnings} -eq 1 -a ! -z "${limit}" && softwarning "Overwritting param: limit '${limit}' becomes '${2}'" limit="${2}" burst="${3}" shift 3 ;; iplimit|IPLIMIT) test ${softwarnings} -eq 1 -a ! -z "${iplimit}" && softwarning "Overwritting param: iplimit '${iplimit}' becomes '${2}'" iplimit="${2}" iplimit_mask="${3}" shift 3 ;; in) # this is incoming traffic - ignore packet ownership local noowner=1 local nomirror=0 local nomac=0 shift ;; out) # this is outgoing traffic - ignore packet ownership if not in an interface if [ ! "${work_cmd}" = "interface" ] then local noowner=1 else local nomirror=1 fi local nomac=1 shift ;; nolog) local nolog=1 shift ;; noowner) local noowner=1 shift ;; softwarnings) local softwarnings=1 shift ;; nosoftwarnings) local softwarnings=0 shift ;; set_work_inface|SET_WORK_INFACE) swi=1 shift ;; set_work_outface|SET_WORK_OUTFACE) swo=1 shift ;; *) error "Cannot understand directive '${1}'." return 1 ;; esac done test -z "${table}" && table="-t filter" # If the user did not specified a rejection message, # we have to be smart and produce a tcp-reset if the protocol # is TCP and an ICMP port unreachable in all other cases. # The special case here is the protocol "any". # To accomplish the differentiation based on protocol we have # to change the protocol "any" to "tcp any" test "${action}" = "REJECT" -a "${action_param[1]}" = "auto" -a "${proto}" = "any" && proto="tcp any" # we cannot accept empty strings to a few parameters, since this # will prevent us from generating a rule (due to nested BASH loops). test -z "${inface}" && error "Cannot accept an empty 'inface'." && return 1 test -z "${outface}" && error "Cannot accept an empty 'outface'." && return 1 test -z "${physin}" && error "Cannot accept an empty 'physin'." && return 1 test -z "${physout}" && error "Cannot accept an empty 'physout'." && return 1 test -z "${mac}" && error "Cannot accept an empty 'mac'." && return 1 test -z "${src}" && error "Cannot accept an empty 'src'." && return 1 test -z "${dst}" && error "Cannot accept an empty 'dst'." && return 1 test -z "${sport}" && error "Cannot accept an empty 'sport'." && return 1 test -z "${dport}" && error "Cannot accept an empty 'dport'." && return 1 test -z "${proto}" && error "Cannot accept an empty 'proto'." && return 1 test -z "${uid}" && error "Cannot accept an empty 'uid'." && return 1 test -z "${gid}" && error "Cannot accept an empty 'gid'." && return 1 test -z "${pid}" && error "Cannot accept an empty 'pid'." && return 1 test -z "${sid}" && error "Cannot accept an empty 'sid'." && return 1 test -z "${cmd}" && error "Cannot accept an empty 'cmd'." && return 1 # ---------------------------------------------------------------------------------- # Do we have negative contitions? # If yes, we have to: # # case 1: If the action is a chain. # Add to this chain positive RETURN statements matching all the negatives. # The positive rules will be added bellow to the same chain and will be # matched only if all RETURNs have not been matched. # # case 2: If the action is not a chain. # Create a temporary chain, then add to this chain positive RETURN rules # matching the negatives, and append at its end the final action (which is # not a chain), then change the action of the positive rules to jump to # this temporary chain. # ignore 'statenot', 'srctypenot', 'dsttypenot' since it is negated in the positive rules if [ ! -z "${infacenot}${outfacenot}${physinnot}${physoutnot}${macnot}${srcnot}${dstnot}${sportnot}${dportnot}${protonot}${uidnot}${gidnot}${pidnot}${sidnot}${cmdnot}${marknot}${tosnot}${dscpnot}" ] then if [ ${action_is_chain} -eq 1 ] then # if the action is a chain name, then just add the negative # expressions to this chain. Nothing more. local negative_chain="${action}" local negative_action= else # if the action is a native iptables action, then create # an intermidiate chain to store the negative expression, # and change the action of the rule to point to this action. # In this case, bellow we add after all negatives, the original # action of the rule. local negative_chain="${chain}.${FIREHOL_DYNAMIC_CHAIN_COUNTER}" FIREHOL_DYNAMIC_CHAIN_COUNTER="$[FIREHOL_DYNAMIC_CHAIN_COUNTER + 1]" iptables ${table} -N "${negative_chain}" local negative_action="${action}" local action="${negative_chain}" fi if [ ! -z "${infacenot}" ] then local inf= for inf in ${inface} do iptables ${table} -A "${negative_chain}" -i "${inf}" -j RETURN done infacenot= inface=any fi if [ ! -z "${outfacenot}" ] then local outf= for outf in ${outface} do iptables ${table} -A "${negative_chain}" -o "${outf}" -j RETURN done outfacenot= outface=any fi if [ ! -z "${physinnot}" ] then local inph= for inph in ${physin} do iptables ${table} -A "${negative_chain}" -m physdev --physdev-in "${inph}" -j RETURN done physinnot= physin=any fi if [ ! -z "${physoutnot}" ] then local outph= for outph in ${physout} do iptables ${table} -A "${negative_chain}" -m physdev --physdev-out "${outph}" -j RETURN done physoutnot= physout=any fi if [ ! -z "${macnot}" ] then local m= for m in ${mac} do iptables ${table} -A "${negative_chain}" -m mac --mac-source "${m}" -j RETURN done macnot= mac=any fi if [ ! -z "${srcnot}" ] then local s= for s in ${src} do iptables ${table} -A "${negative_chain}" -s "${s}" -j RETURN done srcnot= src=any fi if [ ! -z "${dstnot}" ] then local d= for d in ${dst} do iptables ${table} -A "${negative_chain}" -d "${d}" -j RETURN done dstnot= dst=any fi if [ ! -z "${protonot}" ] then if [ ! -z "${sportnot}" -o ! -z "${dportnot}" ] then error "Cannot have negative protocol(s) and source/destination port(s)." return 1 fi local pr= for pr in ${proto} do iptables ${table} -A "${negative_chain}" -p "${pr}" -j RETURN done protonot= proto=any fi if [ ! -z "${sportnot}" ] then if [ "${proto}" = "any" ] then error "Cannot have negative source port specification without protocol." return 1 fi local sp= for sp in ${sport} do local pr= for pr in ${proto} do iptables ${table} -A "${negative_chain}" -p "${pr}" --sport "${sp}" -j RETURN done done sportnot= sport=any fi if [ ! -z "${dportnot}" ] then if [ "${proto}" = "any" ] then error "Cannot have negative destination port specification without protocol." return 1 fi local dp= for dp in ${dport} do local pr= for pr in ${proto} do iptables ${table} -A "${negative_chain}" -p "${pr}" --dport "${dp}" -j RETURN done done dportnot= dport=any fi if [ ! -z "${uidnot}" ] then local tuid= for tuid in ${uid} do iptables ${table} -A "${negative_chain}" -m owner --uid-owner "${tuid}" -j RETURN done uidnot= uid=any fi if [ ! -z "${gidnot}" ] then local tgid= for tgid in ${gid} do iptables ${table} -A "${negative_chain}" -m owner --gid-owner "${tgid}" -j RETURN done gidnot= gid=any fi if [ ! -z "${pidnot}" ] then local tpid= for tpid in ${pid} do iptables ${table} -A "${negative_chain}" -m owner --pid-owner "${tpid}" -j RETURN done pidnot= pid=any fi if [ ! -z "${sidnot}" ] then local tsid= for tsid in ${sid} do iptables ${table} -A "${negative_chain}" -m owner --sid-owner "${tsid}" -j RETURN done sidnot= sid=any fi if [ ! -z "${cmdnot}" ] then local tcmd= for tcmd in ${cmd} do iptables ${table} -A "${negative_chain}" -m owner --cmd-owner "${tcmd}" -j RETURN done cmdnot= cmd=any fi if [ ! -z "${marknot}" ] then local tmark= for tmark in ${mark} do iptables ${table} -A "${negative_chain}" -m mark --mark "${tmark}" -j RETURN done marknot= mark=any fi if [ ! -z "${tosnot}" ] then local ttos= for ttos in ${tos} do iptables ${table} -A "${negative_chain}" -m tos --tos "${ttos}" -j RETURN done tosnot= tos=any fi if [ ! -z "${dscpnot}" ] then local tdscp= for tdscp in ${dscp} do iptables ${table} -A "${negative_chain}" -m dscp --dscp${dscptype} "${tdscp}" -j RETURN done dscp=any dscpnot= fi # in case this is temporary chain we created for the negative expression, # just make it have the final action of the rule. if [ ! -z "${negative_action}" ] then local pr= for pr in ${proto} do local -a proto_arg=() case ${pr} in any|ANY) ;; *) local -a proto_arg=("-p" "${pr}") ;; esac rule_action_param "${negative_action}" "${pr}" "" "" "${table}" "${action_param[@]}" -- ${table} -A "${negative_chain}" "${proto_arg[@]}" local -a action_param=() done fi fi # ---------------------------------------------------------------------------------- # Process the positive rules # uid local tuid= for tuid in ${uid} do local -a uid_arg=() local -a owner_arg=() case ${tuid} in any|ANY) ;; *) local -a owner_arg=("-m" "owner") local -a uid_arg=("--uid-owner" "${tuid}") ;; esac # gid local tgid= for tgid in ${gid} do local -a gid_arg=() case ${tgid} in any|ANY) ;; *) local -a owner_arg=("-m" "owner") local -a gid_arg=("--gid-owner" "${tgid}") ;; esac # pid local tpid= for tpid in ${pid} do local -a pid_arg=() case ${tpid} in any|ANY) ;; *) local -a owner_arg=("-m" "owner") local -a pid_arg=("--pid-owner" "${tpid}") ;; esac # sid local tsid= for tsid in ${sid} do local -a sid_arg=() case ${tsid} in any|ANY) ;; *) local -a owner_arg=("-m" "owner") local -a sid_arg=("--sid-owner" "${tsid}") ;; esac # cmd local tcmd= for tcmd in ${cmd} do local -a cmd_arg=() case ${tcmd} in any|ANY) ;; *) local -a owner_arg=("-m" "owner") local -a cmd_arg=("--cmd-owner" "${tcmd}") ;; esac # mark local tmark= for tmark in ${mark} do local -a mark_arg=() case ${tmark} in any|ANY) ;; *) local -a mark_arg=("-m" "mark" "--mark" "${tmark}") ;; esac # tos local ttos= for ttos in ${tos} do local -a tos_arg=() case ${ttos} in any|ANY) ;; *) local -a tos_arg=("-m" "tos" "--tos" "${ttos}") ;; esac # dscp local tdscp= for tdscp in ${dscp} do local -a dscp_arg=() case ${tdscp} in any|ANY) ;; *) local -a dscp_arg=("-m" "dscp" "--dscp${dscptype}" "${tdscp}") ;; esac # proto local pr= for pr in ${proto} do local -a proto_arg=() case ${pr} in any|ANY) ;; *) local -a proto_arg=("-p" "${pr}") ;; esac # inface local inf= for inf in ${inface} do local -a inf_arg=() case ${inf} in any|ANY) ;; *) local -a inf_arg=("-i" "${inf}") ;; esac # outface local outf= for outf in ${outface} do local -a outf_arg=() case ${outf} in any|ANY) ;; *) local -a outf_arg=("-o" "${outf}") ;; esac # physin local inph= for inph in ${physin} do local -a inph_arg=() case ${inph} in any|ANY) ;; *) local -a physdev_arg=("-m" "physdev") local -a inph_arg=("--physdev-in" "${inph}") ;; esac # physout local outph= for outph in ${physout} do local -a outph_arg=() case ${outph} in any|ANY) ;; *) local -a physdev_arg=("-m" "physdev") local -a outph_arg=("--physdev-out" "${outph}") ;; esac # sport local sp= for sp in ${sport} do local -a sp_arg=() case ${sp} in any|ANY) ;; *) local -a sp_arg=("--sport" "${sp}") ;; esac # dport local dp= for dp in ${dport} do local -a dp_arg=() case ${dp} in any|ANY) ;; *) local -a dp_arg=("--dport" "${dp}") ;; esac # mac local mc= for mc in ${mac} do local -a mc_arg=() case ${mc} in any|ANY) ;; *) local -a mc_arg=("-m" "mac" "--mac-source" "${mc}") ;; esac # src local s= for s in ${src} do local -a s_arg=() case ${s} in any|ANY) ;; *) local -a s_arg=("-s" "${s}") ;; esac # dst local d= for d in ${dst} do local -a d_arg=() case ${d} in any|ANY) ;; *) local -a d_arg=("-d" "${d}") ;; esac # addrtype (srctype, dsttype) local -a addrtype_arg=() local -a stp_arg=() local -a dtp_arg=() if [ ! -z "${srctype}${dsttype}" ] then local -a addrtype_arg=("-m" "addrtype") if [ ! -z "${srctype}" ] then local -a stp_arg=(${srctypenot} "--src-type" "${srctype}") fi if [ ! -z "${dsttype}" ] then local -a dtp_arg=(${dsttypenot} "--dst-type" "${dsttype}") fi fi # state local -a state_arg=() if [ ! -z "${state}" ] then local -a state_arg=("-m" "state" ${statenot} "--state" "${state}") fi # limit local -a limit_arg=() if [ ! -z "${limit}" ] then local -a limit_arg=("-m" "limit" "--limit" "${limit}" "--limit-burst" "${burst}") fi # iplimit local -a iplimit_arg=() if [ ! -z "${iplimit}" ] then local -a iplimit_arg=("-m" "iplimit" "--iplimit-above" "${iplimit}" "--iplimit-mask" "${iplimit_mask}") fi # build the command declare -a basecmd=("${inf_arg[@]}" "${outf_arg[@]}" "${physdev_arg[@]}" "${inph_arg[@]}" "${outph_arg[@]}" "${limit_arg[@]}" "${iplimit_arg[@]}" "${proto_arg[@]}" "${s_arg[@]}" "${sp_arg[@]}" "${d_arg[@]}" "${dp_arg[@]}" "${owner_arg[@]}" "${uid_arg[@]}" "${gid_arg[@]}" "${pid_arg[@]}" "${sid_arg[@]}" "${cmd_arg[@]}" "${addrtype_arg[@]}" "${stp_arg[@]}" "${dtp_arg[@]}" "${state_arg[@]}" "${mc_arg[@]}" "${mark_arg[@]}" "${tos_arg[@]}" "${dscp_arg[@]}") # log mode selection local -a logopts_arg=() if [ "${FIREHOL_LOG_MODE}" = "ULOG" ] then local -a logopts_arg=("--ulog-prefix=${FIREHOL_LOG_PREFIX}${logtxt}:") elif [ "${FIREHOL_LOG_MODE}" = "NFLOG" ] then local -a logopts_arg=("--nflog-prefix=${FIREHOL_LOG_PREFIX}${logtxt}:") else local -a logopts_arg=("--log-level" "${loglevel}" "--log-prefix=${FIREHOL_LOG_PREFIX}${logtxt}:") fi # log / loglimit case "${log}" in '') ;; limit) iptables ${table} -A "${chain}" "${basecmd[@]}" ${custom} -m limit --limit "${FIREHOL_LOG_FREQUENCY}" --limit-burst "${FIREHOL_LOG_BURST}" -j ${FIREHOL_LOG_MODE} ${FIREHOL_LOG_OPTIONS} "${logopts_arg[@]}" ;; normal) iptables ${table} -A "${chain}" "${basecmd[@]}" ${custom} -j ${FIREHOL_LOG_MODE} ${FIREHOL_LOG_OPTIONS} "${logopts_arg[@]}" ;; *) error "Unknown log value '${log}'." ;; esac # do it! rule_action_param "${action}" "${pr}" "${statenot}" "${state}" "${table}" "${action_param[@]}" -- ${table} -A "${chain}" "${basecmd[@]}" ${custom} done # dst done # src done # mac done # dport done # sport done # physout done # physin done # outface done # inface done # proto done # dscp done # tos done # mark done # cmd done # sid done # pid done # gid done # uid test ${failed} -gt 0 && error "There are ${failed} failed commands." && return 1 return 0 } softwarning() { echo >&2 echo >&2 "--------------------------------------------------------------------------------" echo >&2 "WARNING" echo >&2 "WHAT : ${work_function}" echo >&2 "WHY :" "$@" printf >&2 "COMMAND: "; printf >&2 "%q " "${work_realcmd[@]}"; echo >&2 echo >&2 "SOURCE : line ${FIREHOL_LINEID} of ${FIREHOL_CONFIG}" echo >&2 return 0 } # ------------------------------------------------------------------------------ # error - error reporting while still parsing the configuration file # WHY: # This is the error handler that presents to the user detected errors during # processing FireHOL's configuration file. # This command is directly called by other functions of FireHOL. error() { test "${FIREHOL_MODE}" = "START" && syslog err "Error '${@}' when '${work_function}' at ${FIREHOL_CONFIG} line ${FIREHOL_LINEID}" work_error=$[work_error + 1] echo >&2 echo >&2 "--------------------------------------------------------------------------------" echo >&2 "ERROR #: ${work_error}" echo >&2 "WHAT : ${work_function}" echo >&2 "WHY :" "$@" printf >&2 "COMMAND: "; printf >&2 "%q " "${work_realcmd[@]}"; echo >&2 echo >&2 "SOURCE : line ${FIREHOL_LINEID} of ${FIREHOL_CONFIG}" echo >&2 return 0 } # ------------------------------------------------------------------------------ # runtime_error - postprocessing evaluation of commands run # WHY: # The generated iptables commands must be checked for errors in case they fail. # This command is executed after every postprocessing command to find out # if it has been successfull or failed. runtime_error() { local type="ERROR" local id= case "${1}" in error) local type="ERROR " work_runtime_error=$[work_runtime_error + 1] local id="# ${work_runtime_error}." ;; warn) local type="WARNING" local id="This might or might not affect the operation of your firewall." ;; *) work_runtime_error=$[work_runtime_error + 1] local id="# ${work_runtime_error}." echo >&2 echo >&2 echo >&2 "*** unsupported final status type '${1}'. Assuming it is 'ERROR'" echo >&2 echo >&2 ;; esac shift local ret="${1}"; shift local line="${1}"; shift syslog err "Runtime ${type} '${id}'. Source ${FIREHOL_CONFIG} line ${line}" echo >&2 echo >&2 echo >&2 "--------------------------------------------------------------------------------" echo >&2 "${type} : ${id}" echo >&2 "WHAT : A runtime command failed to execute (returned error ${ret})." echo >&2 "SOURCE : line ${line} of ${FIREHOL_CONFIG}" printf >&2 "COMMAND : " printf >&2 "%q " "$@" printf >&2 "\n" echo >&2 "OUTPUT : " echo >&2 ${CAT_CMD} ${FIREHOL_OUTPUT}.log echo >&2 return 0 } # ------------------------------------------------------------------------------ # chain_exists - find if chain name has already being specified # WHY: # We have to make sure each service gets its own chain. # Although FireHOL chain naming makes chains with unique names, this is just # an extra sanity check. chain_exists() { local chain="${1}" test -f "${FIREHOL_CHAINS_DIR}/${chain}" && return 1 return 0 } # ------------------------------------------------------------------------------ # create_chain - create a chain and link it to the firewall # WHY: # When a chain is created it must somehow to be linked to the rest of the # firewall apropriately. This function first creates the chain and then # it links it to its final position within the generated firewall. create_chain() { local table="${1}" local newchain="${2}" local oldchain="${3}" shift 3 set_work_function "Creating chain '${newchain}' under '${oldchain}' in table '${table}'" chain_exists "${newchain}" test $? -eq 1 && error "Chain '${newchain}' already exists." && return 1 iptables -t ${table} -N "${newchain}" || return 1 ${TOUCH_CMD} "${FIREHOL_CHAINS_DIR}/${newchain}" if [ ! -z "${oldchain}" ] then rule table ${table} chain "${oldchain}" action "${newchain}" "$@" || return 1 fi return 0 } # ------------------------------------------------------------------------------ # smart_function - find the valid service definition for a service # WHY: # FireHOL supports simple and complex services. This function first tries to # detect if there are the proper variables set for a simple service, and if # they do not exist, it then tries to find the complex function definition for # the service. # # Additionally, it creates a chain for the subcommand. smart_function() { local type="${1}" # The current subcommand: server/client/route local services="${2}" # The services to implement shift 2 local service= for service in $services do local servname="${service}" test "${service}" = "custom" && local servname="${1}" set_work_function "Preparing for service '${service}' of type '${type}' under interface '${work_name}'" # Increase the command counter, to make all chains within a primary # command, unique. work_counter=$[work_counter + 1] local suffix="u${work_counter}" case "${type}" in client) suffix="c${work_counter}" ;; server) suffix="s${work_counter}" ;; route) suffix="r${work_counter}" ;; *) error "Cannot understand type '${type}'." return 1 ;; esac local mychain="${work_name}_${servname}_${suffix}" create_chain filter "in_${mychain}" "in_${work_name}" || return 1 create_chain filter "out_${mychain}" "out_${work_name}" || return 1 # Try the simple services first simple_service "${mychain}" "${type}" "${service}" "$@" local ret=$? # simple service completed succesfully. test $ret -eq 0 && continue # simple service exists but failed. if [ $ret -ne 127 ] then error "Simple service '${service}' returned an error ($ret)." return 1 fi # Try the custom services local fn="rules_${service}" set_work_function "Running complex rules function ${fn}() for ${type} '${service}'" "${fn}" "${mychain}" "${type}" "$@" local ret=$? test $ret -eq 0 && continue if [ $ret -eq 127 ] then error "There is no service '${service}' defined." else error "Complex service '${service}' returned an error ($ret)." fi return 1 done return 0 } # ------------------------------------------------------------------------------ # simple_service - convert a service definition to an inline service definition # WHY: # When a simple service is detected, there must be someone to call # rules_custom() with the appropriate service definition parameters. simple_service() { local mychain="${1}"; shift local type="${1}"; shift local server="${1}"; shift local server_varname="server_${server}_ports" eval local server_ports="\$${server_varname}" local client_varname="client_${server}_ports" eval local client_ports="\$${client_varname}" if [ ! -z "${server_ports}" -a -z "${client_ports}" ] then error "Simple service '${service}' has server ports, but no client ports defined." return 1 elif [ -z "${server_ports}" -a ! -z "${client_ports}" ] then error "Simple service '${service}' has client ports, but no server ports defined." return 1 elif [ -z "${server_ports}" -a -z "${client_ports}" ] then # this will make the caller attempt to find a complex service return 127 fi local varname="helper_${server}" eval local helpers="\$${varname}" local x= local varname="require_${server}_modules" eval local value="\$${varname}" for x in ${value} do require_kernel_module $x || return 1 done if [ ${FIREHOL_NAT} -eq 1 ] then local varname="require_${server}_nat_modules" eval local value="\$${varname}" for x in ${value} do require_kernel_module $x || return 1 done fi # load the helper modules for x in ${helpers} do case "${x}" in snmp_basic) # this does not exist in conntrack ;; *) require_kernel_module nf_conntrack_$x ;; esac if [ ${FIREHOL_NAT} -eq 1 ] then case "${x}" in netbios_ns|netlink|sane) # these do not exist in nat ;; *) require_kernel_module nf_nat_$x ;; esac fi done set_work_function "Running simple rules for ${type} '${service}'" rules_custom "${mychain}" "${type}" "${server}" "${server_ports}" "${client_ports}" helpers "${helpers}" "$@" return $? } show_work_realcmd() { test "${FIREHOL_MODE}" = "EXPLAIN" && return 0 ( printf "\n\n" printf "# === CONFIGURATION STATEMENT =================================================\n" printf "# CONF:%3s>>> " ${FIREHOL_LINEID} case $1 in 2) printf " " ;; *) ;; esac printf "%q " "${work_realcmd[@]}" printf "\n\n" ) >>${FIREHOL_OUTPUT} } work_realcmd_primary() { work_realcmd=("$@") test ${FIREHOL_CONF_SHOW} -eq 1 && show_work_realcmd 1 } work_realcmd_secondary() { work_realcmd=("$@") test ${FIREHOL_CONF_SHOW} -eq 1 && show_work_realcmd 2 } work_realcmd_helper() { work_realcmd=("$@") test ${FIREHOL_CONF_SHOW} -eq 1 && show_work_realcmd 3 } # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # # START UP SCRIPT PROCESSING # # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # On non RedHat machines we need success() and failure() success() { printf " OK" } failure() { echo " FAILED" } # ------------------------------------------------------------------------------ # A small part bellow is copied from /etc/init.d/iptables # On RedHat systems this will define success() and failure() test -f /etc/init.d/functions && . /etc/init.d/functions if [ -z "${IPTABLES_CMD}" -o ! -x "${IPTABLES_CMD}" ]; then echo >&2 "Cannot find an executable iptables command." exit 0 fi KERNELMAJ=`${UNAME_CMD} -r | ${SED_CMD} -e 's,\..*,,'` KERNELMIN=`${UNAME_CMD} -r | ${SED_CMD} -e 's,[^\.]*\.,,' -e 's,\..*,,'` if [ "$KERNELMAJ" -lt 2 ] ; then echo >&2 "FireHOL requires a kernel version higher than 2.3." exit 0 fi if [ "$KERNELMAJ" -eq 2 -a "$KERNELMIN" -lt 3 ] ; then echo >&2 "FireHOL requires a kernel version higher than 2.3." exit 0 fi if ${LSMOD_CMD} 2>/dev/null | ${GREP_CMD} -q ipchains ; then # Don't do both echo >&2 "ipchains is loaded in the kernel. Please remove ipchains to run iptables." exit 0 fi # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # # COMMAND LINE ARGUMENTS PROCESSING # # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ me="${0}" arg="${1}" shift case "${arg}" in explain) test ! -z "${1}" && softwarning "Arguments after parameter '${arg}' are ignored." FIREHOL_MODE="EXPLAIN" ;; helpme|wizard) test ! -z "${1}" && softwarning "Arguments after parameter '${arg}' are ignored." FIREHOL_MODE="WIZARD" ;; try) test ! -z "${1}" && softwarning "Arguments after parameter '${arg}' are ignored." FIREHOL_MODE="START" FIREHOL_TRY=1 ;; start) test ! -z "${1}" && softwarning "Arguments after parameter '${arg}' are ignored." FIREHOL_MODE="START" FIREHOL_TRY=0 ;; stop) FIREHOL_MODE="STOP" test ! -z "${1}" && softwarning "Arguments after parameter '${arg}' are ignored." test -f "${FIREHOL_LOCK_DIR}/firehol" && ${RM_CMD} -f "${FIREHOL_LOCK_DIR}/firehol" test -f "${FIREHOL_LOCK_DIR}/iptables" && ${RM_CMD} -f "${FIREHOL_LOCK_DIR}/iptables" echo -n $"FireHOL: Clearing Firewall:" load_kernel_module ip_tables tables=`${CAT_CMD} /proc/net/ip_tables_names` for t in ${tables} do ${IPTABLES_CMD} -t "${t}" -F ${IPTABLES_CMD} -t "${t}" -X ${IPTABLES_CMD} -t "${t}" -Z # Find all default chains in this table. chains=`${IPTABLES_CMD} -t "${t}" -nL | ${GREP_CMD} "^Chain " | ${CUT_CMD} -d ' ' -f 2` for c in ${chains} do ${IPTABLES_CMD} -t "${t}" -P "${c}" ACCEPT done done success $"FireHOL: Clearing Firewall:" echo exit 0 ;; restart|force-reload) test ! -z "${1}" && softwarning "Arguments after parameter '${arg}' are ignored." FIREHOL_MODE="START" ;; condrestart) test ! -z "${1}" && softwarning "Arguments after parameter '${arg}' are ignored." test -f "${FIREHOL_LOCK_DIR}/firehol" && exit 0 FIREHOL_MODE="START" ;; status) test ! -z "${1}" && softwarning "Arguments after parameter '${arg}' are ignored." ( echo echo "--- MANGLE ---------------------------------------------------------------------" echo ${IPTABLES_CMD} -t mangle -nxvL echo echo echo "--- NAT ------------------------------------------------------------------------" echo ${IPTABLES_CMD} -t nat -nxvL echo echo echo "--- FILTER ---------------------------------------------------------------------" echo ${IPTABLES_CMD} -nxvL ) | pager_cmd exit $? ;; panic) FIREHOL_MODE="PANIC" ssh_src= ssh_sport="0:65535" ssh_dport="0:65535" if [ ! -z "${SSH_CLIENT}" ] then set -- ${SSH_CLIENT} ssh_src="${1}" ssh_sport="${2}" ssh_dport="${3}" elif [ ! -z "${1}" ] then ssh_src="${1}" fi syslog info "Starting PANIC mode (SSH SOURCE_IP=${ssh_src} SOURCE_PORTS=${ssh_sport} DESTINATION_PORTS=${ssh_dport})" echo -n $"FireHOL: Blocking all communications:" load_kernel_module ip_tables tables=`${CAT_CMD} /proc/net/ip_tables_names` for t in ${tables} do ${IPTABLES_CMD} -t "${t}" -F ${IPTABLES_CMD} -t "${t}" -X ${IPTABLES_CMD} -t "${t}" -Z # Find all default chains in this table. chains=`${IPTABLES_CMD} -t "${t}" -nL | ${GREP_CMD} "^Chain " | ${CUT_CMD} -d ' ' -f 2` for c in ${chains} do ${IPTABLES_CMD} -t "${t}" -P "${c}" ACCEPT if [ ! -z "${ssh_src}" ] then ${IPTABLES_CMD} -t "${t}" -A "${c}" -p tcp -s "${ssh_src}" --sport "${ssh_sport}" --dport "${ssh_dport}" -m state --state ESTABLISHED -j ACCEPT ${IPTABLES_CMD} -t "${t}" -A "${c}" -p tcp -d "${ssh_src}" --dport "${ssh_sport}" --sport "${ssh_dport}" -m state --state ESTABLISHED -j ACCEPT fi ${IPTABLES_CMD} -t "${t}" -A "${c}" -j DROP done done success $"FireHOL: Blocking all communications:" echo exit 0 ;; save) test ! -z "${1}" && softwarning "Arguments after parameter '${arg}' are ignored." FIREHOL_MODE="START" FIREHOL_SAVE=1 ;; debug) test ! -z "${1}" && softwarning "Arguments after parameter '${arg}' are ignored." FIREHOL_MODE="DEBUG" ;; *) if [ ! -z "${arg}" -a -f "${arg}" ] then FIREHOL_MODE="START" FIREHOL_TRY=1 FIREHOL_CONFIG="${arg}" arg="${1}" test "${arg}" = "--" && arg="" && shift test -z "${arg}" && arg="try" case "${arg}" in start) FIREHOL_TRY=0 ;; try) FIREHOL_TRY=1 ;; debug) FIREHOL_MODE="DEBUG" FIREHOL_TRY=0 ;; *) echo "Cannot accept command line argument '${arg}' here." exit 1 ;; esac else ${CAT_CMD} < FireHOL is distributed under GPL. EOF ${CAT_CMD} < a different configuration file. If not other argument is given, the configuration will be "tried" (default = try). Otherwise the argument next to the filename can be one of 'start', 'debug' and 'try'. ------------------------------------------------------------------------- FireHOL supports the following services (sorted by name): EOF ( # The simple services ${CAT_CMD} "${me}" |\ ${GREP_CMD} -e "^server_.*_ports=" |\ ${CUT_CMD} -d '=' -f 1 |\ ${SED_CMD} "s/^server_//" |\ ${SED_CMD} "s/_ports\$//" # The complex services ${CAT_CMD} "${me}" |\ ${GREP_CMD} -e "^rules_.*()" |\ ${CUT_CMD} -d '(' -f 1 |\ ${SED_CMD} "s/^rules_/(*) /" ) | ${SORT_CMD} | ${UNIQ_CMD} |\ ( x=0 while read do x=$[x + 1] if [ $x -gt 4 ] then printf "\n" x=1 fi printf "% 16s |" "$REPLY" done printf "\n\n" ) ${CAT_CMD} </tmp/firehol.conf and you will get the configuration written to /tmp/firehol.conf EOF exit 1 fi ;; esac # Remove the next arg if it is -- test "${1}" = "--" && shift if [ "${FIREHOL_MODE}" = "START" -o "${FIREHOL_MODE}" = "DEBUG" ] then if [ ! -f "${FIREHOL_CONFIG}" ] then echo -n $"FireHOL config ${FIREHOL_CONFIG} not found:" failure $"FireHOL config ${FIREHOL_CONFIG} not found:" echo exit 1 fi fi # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # # MAIN PROCESSING - Interactive mode # # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ if [ "${FIREHOL_MODE}" = "EXPLAIN" ] then FIREHOL_CONFIG="Interactive User Input" FIREHOL_LINEID="1" FIREHOL_TEMP_CONFIG="${FIREHOL_DIR}/firehol.conf" echo "version ${FIREHOL_VERSION}" >"${FIREHOL_TEMP_CONFIG}" version ${FIREHOL_VERSION} ${CAT_CMD} < FireHOL is distributed under GPL. Home Page: http://firehol.sourceforge.net -------------------------------------------------------------------------------- FireHOL controls your firewall. You should want to get updates quickly. Subscribe (at the home page) to get notified of new releases. -------------------------------------------------------------------------------- You can now start typing FireHOL configuration directives. Special interactive commands: help, show, quit EOF while [ 1 = 1 ] do read -p "# FireHOL [${work_cmd}:${work_name}] > " -e -r test -z "${REPLY}" && continue set_work_function -ne "Executing user input" while [ 1 = 1 ] do set -- ${REPLY} case "${1}" in help) ${CAT_CMD} < FAILED <\n" else if [ "${1}" = "interface" -o "${1}" = "router" ] then echo >>"${FIREHOL_TEMP_CONFIG}" else printf " " >>"${FIREHOL_TEMP_CONFIG}" fi printf "%s\n" "${REPLY}" >>"${FIREHOL_TEMP_CONFIG}" FIREHOL_LINEID=$[FIREHOL_LINEID + 1] printf "\n# > OK <\n" fi break ;; esac break done done exit 0 fi # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # # MAIN PROCESSING - help wizard # # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ if [ "${FIREHOL_MODE}" = "WIZARD" ] then # require commands for wizard mode require_cmd ip require_cmd netstat require_cmd date require_cmd hostname wizard_ask() { local prompt="${1}"; shift local def="${1}"; shift echo while [ 1 = 1 ] do printf >&2 "%s [%s] > " "${prompt}" "${def}" read local ans="${REPLY}" test -z "${ans}" && ans="${def}" local c=0 while [ $c -le $# ] do eval local t="\${${c}}" test "${ans}" = "${t}" && break c=$[c + 1] done test $c -le $# && return $c printf >&2 "*** '${ans}' is not a valid answer. Pick one of " printf >&2 "%s " "$@" echo >&2 echo >&2 done return 0 } ip_in_net() { local ip="${1}"; shift local net="${1}"; shift if [ -z "${ip}" -o -z "${net}" ] then return 1 fi test "${net}" = "default" && net="0.0.0.0/0" set -- `echo ${ip} | ${TR_CMD} './' ' '` local i1=${1} local i2=${2} local i3=${3} local i4=${4} set -- `echo ${net} | ${TR_CMD} './' ' '` local n1=${1} local n2=${2} local n3=${3} local n4=${4} local n5=${5:-32} local i=$[i1*256*256*256 + i2*256*256 + i3*256 + i4] local n=$[n1*256*256*256 + n2*256*256 + n3*256 + n4] # echo "IP : '${i1}' . '${i2}' . '${i3}' . '${i4}'" # echo "NET: '${n1}' . '${n2}' . '${n3}' . '${n4}' / '${n5}'" local d=1 local c=${n5} while [ $c -lt 32 ] do c=$[c + 1] d=$[d * 2] done local nm=$[n + d - 1] printf "# INFO: Is ${ip} part of network ${net}? " if [ ${i} -ge ${n} -a ${i} -le ${nm} ] then echo "yes" return 0 else echo "no" return 1 fi } ip_is_net() { local ip="${1}"; shift local net="${1}"; shift if [ -z "${ip}" -o -z "${net}" ] then return 1 fi test "${net}" = "default" && net="0.0.0.0/0" set -- `echo ${ip} | ${TR_CMD} './' ' '` local i1=${1} local i2=${2} local i3=${3} local i4=${4} local i5=${5:-32} set -- `echo ${net} | ${TR_CMD} './' ' '` local n1=${1} local n2=${2} local n3=${3} local n4=${4} local n5=${5:-32} local i=$[i1*256*256*256 + i2*256*256 + i3*256 + i4] local n=$[n1*256*256*256 + n2*256*256 + n3*256 + n4] if [ ${i} -eq ${n} -a ${i5} -eq ${n5} ] then return 0 else return 1 fi } ip2net() { local ip="${1}"; shift if [ -z "${ip}" ] then return 0 fi if [ "${ip}" = "default" ] then echo "default" return 0 fi set -- `echo ${ip} | ${TR_CMD} './' ' '` local i1=${1} local i2=${2} local i3=${3} local i4=${4} local i5=${5:-32} if [ "${i5}" = "32" ] then echo ${i1}.${i2}.${i3}.${i4} else echo ${i1}.${i2}.${i3}.${i4}/${i5} fi } ips2net() { ( if [ "A${1}" = "A-" ] then while read ip do ip2net ${ip} done else while [ ! -z "${1}" ] do ip2net ${1} shift done fi ) | ${SORT_CMD} | ${UNIQ_CMD} | ${TR_CMD} "\n" " " } cd "${FIREHOL_DIR}" "${MKDIR_CMD}" ports "${MKDIR_CMD}" keys cd ports "${MKDIR_CMD}" tcp "${MKDIR_CMD}" udp "${CAT_CMD}" >&2 < FireHOL is distributed under GPL. Home Page: http://firehol.sourceforge.net -------------------------------------------------------------------------------- FireHOL controls your firewall. You should want to get updates quickly. Subscribe (at the home page) to get notified of new releases. -------------------------------------------------------------------------------- FireHOL will now try to figure out its configuration file on this system. Please have all the services and network interfaces on this system running. Your running firewall will not be stopped or altered. You can re-run the same command with output redirection to get the config to a file. Example: EOF echo >&2 "${FIREHOL_FILE} helpme >/tmp/firehol.conf" echo >&2 echo >&2 echo >&2 echo >&2 "Building list of known services." echo >&2 "Please wait..." ${CAT_CMD} /etc/services |\ ${TR_CMD} '\t' ' ' |\ ${SED_CMD} "s/ \+/ /g" >services for c in `echo ${!server_*} | ${TR_CMD} ' ' '\n' | ${GREP_CMD} "_ports$"` do serv=`echo $c | ${SED_CMD} "s/server_//" | ${SED_CMD} "s/_ports//"` eval "ret=\${$c}" for x in ${ret} do proto=`echo $x | ${CUT_CMD} -d '/' -f 1` port=`echo $x | ${CUT_CMD} -d '/' -f 2` test ! -d "${proto}" && continue nport=`${EGREP_CMD} "^${port}[[:space:]][0-9]+/${proto}" services | ${CUT_CMD} -d ' ' -f 2 | ${CUT_CMD} -d '/' -f 1` test -z "${nport}" && nport="${port}" echo "server ${serv}" >"${proto}/${nport}" done done echo "server ftp" >tcp/21 echo "server nfs" >udp/2049 echo "client amanda" >udp/10080 echo "server dhcp" >udp/67 echo "server dhcp" >tcp/67 echo "client dhcp" >udp/68 echo "client dhcp" >tcp/68 echo "server emule" >tcp/4662 echo "server pptp" >tcp/1723 echo "server samba" >udp/137 echo "server samba" >udp/138 echo "server samba" >tcp/139 wizard_ask "Press RETURN to start." "continue" "continue" echo >&2 echo >&2 "--- snip --- snip --- snip --- snip ---" echo >&2 ${CAT_CMD} < protection strong" echo echo " # Here are the services listening on ${iface}." echo " # TODO: Normally, you will have to remove those not needed." ( local x= local ports= for x in `${NETSTAT_CMD} -an | ${EGREP_CMD} "^tcp" | ${SED_CMD} "s|:::|0.0.0.0:|g" | ${GREP_CMD} "0.0.0.0:*" | ${EGREP_CMD} " (${ifip}|0.0.0.0):[0-9]+" | ${CUT_CMD} -d ':' -f 2 | ${CUT_CMD} -d ' ' -f 1 | ${SORT_CMD} -n | ${UNIQ_CMD}` do if [ -f "tcp/${x}" ] then echo " `${CAT_CMD} tcp/${x}` accept" else ports="${ports} tcp/${x}" fi done for x in `${NETSTAT_CMD} -an | ${EGREP_CMD} "^udp" | ${SED_CMD} "s|:::|0.0.0.0:|g" | ${GREP_CMD} "0.0.0.0:*" | ${EGREP_CMD} " (${ifip}|0.0.0.0):[0-9]+" | ${CUT_CMD} -d ':' -f 2 | ${CUT_CMD} -d ' ' -f 1 | ${SORT_CMD} -n | ${UNIQ_CMD}` do if [ -f "udp/${x}" ] then echo " `${CAT_CMD} udp/${x}` accept" else ports="${ports} udp/${x}" fi done echo " server ICMP accept" echo "${ports}" | ${TR_CMD} " " "\n" | ${SORT_CMD} -n | ${UNIQ_CMD} | ${TR_CMD} "\n" " " >unknown.ports ) | ${SORT_CMD} | ${UNIQ_CMD} echo echo " # The following ${iface} services are not known by FireHOL:" ${CAT_CMD} unknown.ports | ${FOLD_CMD} -s -w 65 | ${SED_CMD} "s|^ *|\t# |" echo echo echo " # Custom service definitions for the above unknown services." local ts= local tscount=0 for ts in `${CAT_CMD} unknown.ports` do local tscount=$[tscount + 1] echo " server custom if${i}_${tscount} ${ts} any accept" done echo echo " # The following means that this machine can REQUEST anything via ${iface}." echo " # TODO: On production servers, avoid this and allow only the" echo " # client services you really need." echo " client all accept" echo } interfaces=`${IP_CMD} link show | ${EGREP_CMD} "^[0-9A-Za-z]+:" | ${CUT_CMD} -d ':' -f 2 | ${SED_CMD} "s/^ //" | ${GREP_CMD} -v "^lo$" | ${SORT_CMD} | ${UNIQ_CMD} | ${TR_CMD} "\n" " "` gw_if=`${IP_CMD} route show | ${GREP_CMD} "^default" | ${SED_CMD} "s/dev /dev:/g" | ${TR_CMD} " " "\n" | ${GREP_CMD} "^dev:" | ${CUT_CMD} -d ':' -f 2` gw_ip=`${IP_CMD} route show | ${GREP_CMD} "^default" | ${SED_CMD} "s/via /via:/g" | ${TR_CMD} " " "\n" | ${GREP_CMD} "^via:" | ${CUT_CMD} -d ':' -f 2 | ips2net -` i=0 for iface in ${interfaces} do echo "# INFO: Processing interface '${iface}'" ips=`${IP_CMD} addr show dev ${iface} | ${SED_CMD} "s/ \+/ /g" | ${GREP_CMD} "^ inet " | ${CUT_CMD} -d ' ' -f 3 | ${CUT_CMD} -d '/' -f 1 | ips2net -` peer=`${IP_CMD} addr show dev ${iface} | ${SED_CMD} "s/ \+/ /g" | ${SED_CMD} "s/peer /peer:/g" | ${TR_CMD} " " "\n" | ${GREP_CMD} "^peer:" | ${CUT_CMD} -d ':' -f 2 | ips2net -` nets=`${IP_CMD} route show dev ${iface} | ${CUT_CMD} -d ' ' -f 1 | ips2net -` if [ -z "${ips}" -o -z "${nets}" ] then echo echo "# IMPORTANT: " echo "# Ignoring interface '${iface}' because does not have an IP or route." echo continue fi for ip in ${ips} do echo "# INFO: Processing IP ${ip} of interface '${iface}'" ifreason="" # find all the networks this IP can access directly # or through its peer netcount=0 ifnets= ofnets= for net in ${nets} do test "${net}" = "default" && continue found=1 ip_in_net ${ip} ${net} found=$? if [ ${found} -gt 0 -a ! -z "${peer}" ] then ip_in_net ${peer} ${net} found=$? fi if [ ${found} -eq 0 ] then # Add it to ifnets f=0; ff=0 while [ $f -lt $netcount ] do if ip_in_net ${net} ${ifnets[$f]} then # Already satisfied ff=1 elif ip_in_net ${ifnets[$f]} ${net} then # New one is superset of old ff=1 ifnets[$f]=${net} fi f=$[f + 1] done if [ $ff -eq 0 ] then # Add it netcount=$[netcount + 1] ifnets=(${net} ${ifnets[@]}) fi else ofnets=(${net} ${ofnets[@]}) fi done # find all the networks this IP can access through gateways if [ ! -z "${ofnets[*]}" ] then for net in ${ofnets[@]} do test "${net}" = "default" && continue nn=`echo "${net}" | ${CUT_CMD} -d "/" -f 1` gw=`${IP_CMD} route show ${nn} dev ${iface} | ${EGREP_CMD} "^${nn}[[:space:]]+via[[:space:]][0-9\.]+" | ${CUT_CMD} -d ' ' -f 3 | ips2net -` test -z "${gw}" && continue for nn in ${ifnets[@]} do test "${nn}" = "default" && continue if ip_in_net ${gw} ${nn} then echo "# INFO: Route ${net} is accessed through ${gw}" # Add it to ifnets f=0; ff=0 while [ $f -lt $netcount ] do if ip_in_net ${net} ${ifnets[$f]} then # Already satisfied ff=1 elif ip_in_net ${ifnets[$f]} ${net} then # New one is superset of old ff=1 ifnets[$f]=${net} fi f=$[f + 1] done if [ $ff -eq 0 ] then # Add it netcount=$[netcount + 1] ifnets=(${net} ${ifnets[@]}) fi break fi done done fi # Don't produce an interface if this is just a peer that is also the default gw def_ignore_ifnets=0 if (test ${netcount} -eq 1 -a "${gw_if}" = "${iface}" && ip_is_net "${peer}" "${ifnets[*]}" && ip_is_net "${gw_ip}" "${peer}") then echo "# INFO: Skipping ${iface} peer ${ifnets[*]} only interface (default gateway)." echo def_ignore_ifnets=1 else i=$[i + 1] helpme_iface route $i "${iface}" "${ip}" "${ifnets[*]}" "${ifreason}" fi # Is this interface the default gateway too? if [ "${gw_if}" = "${iface}" ] then for nn in ${ifnets[@]} do if ip_in_net "${gw_ip}" ${nn} then echo "# INFO: Default gateway ${gw_ip} is part of network ${nn}" i=$[i + 1] helpme_iface route $i "${iface}" "${ip}" "default" "from/to unknown networks behind the default gateway ${gw_ip}" "`test ${def_ignore_ifnets} -eq 0 && echo "${ifnets[*]}"`" break fi done fi done done echo echo "# The above $i interfaces were found active at this moment." echo "# Add more interfaces that can potentially be activated in the future." echo "# FireHOL will not complain if you setup a firewall on an interface that is" echo "# not active when you activate the firewall." echo "# If you don't setup an interface, FireHOL will drop all traffic from or to" echo "# this interface, if and when it becomes available." echo "# Also, if an interface name dynamically changes (i.e. ppp0 may become ppp1)" echo "# you can use the plus (+) character to match all of them (i.e. ppp+)." echo if [ "1" = "`${CAT_CMD} /proc/sys/net/ipv4/ip_forward`" ] then x=0 i=0 while [ $i -lt ${#found_interfaces[*]} ] do i=$[i + 1] inface="${found_interfaces[$i]}" src="${found_nets[$i]}" case "${src}" in "default") src="not \"\${UNROUTABLE_IPS} ${found_excludes[$i]}\"" ;; *) src="\"${src}\"" ;; esac j=0 while [ $j -lt ${#found_interfaces[*]} ] do j=$[j + 1] test $j -eq $i && continue outface="${found_interfaces[$j]}" dst="${found_nets[$j]}" dst_ip="${found_ips[$j]}" case "${dst}" in "default") dst="not \"\${UNROUTABLE_IPS} ${found_excludes[$j]}\"" ;; *) dst="\"${dst}\"" ;; esac # Make sure we are not routing to the same subnet test "${inface}" = "${outface}" -a "${src}" = "${dst}" && continue # Make sure this is not a duplicate router key="`echo ${inface}/${src}-${outface}/${dst} | ${TR_CMD} "/ \\\$\\\"{}" "______"`" test -f "${FIREHOL_DIR}/keys/${key}" && continue ${TOUCH_CMD} "${FIREHOL_DIR}/keys/${key}" x=$[x + 1] echo echo "# Router No ${x}." echo "# Clients on ${inface} (from ${src}) accessing servers on ${outface} (to ${dst})." echo "# TODO: Change \"router${x}\" to something with meaning to you." echo "# TODO: Check the optional rule parameters (src/dst)." echo "router router${x} inface ${inface} outface ${outface} src ${src} dst ${dst}" echo echo " # If you don't trust the clients on ${inface} (from ${src}), or" echo " # if you want to protect the servers on ${outface} (to ${dst})," echo " # uncomment the following line." echo " # > protection strong" echo echo " # To NAT client requests on the output of ${outface}, add this." echo " # > masquerade" echo " # Alternatively, you can SNAT them by placing this at the top of this config:" echo " # > snat to ${dst_ip} outface ${outface} src ${src} dst ${dst}" echo " # SNAT commands can be enhanced using 'proto', 'sport', 'dport', etc in order to" echo " # NAT only some specific traffic." echo echo " # TODO: This will allow all traffic to pass." echo " # If you remove it, no REQUEST will pass matching this traffic." echo " route all accept" echo done done if [ ${x} -eq 0 ] then echo echo echo "# No router statements have been produced, because your server" echo "# does not seem to need any." echo fi else echo echo echo "# No router statements have been produced, because your server" echo "# is not configured for forwarding traffic." echo fi exit 0 fi # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # # MAIN PROCESSING # # ------------------------------------------------------------------------------ # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # ------------------------------------------------------------------------------ # make sure we are alone firehol_concurrent_run_lock # --- Initialization ----------------------------------------------------------- fixed_iptables_save() { local tmp="${FIREHOL_DIR}/iptables-save-$$" local err= load_kernel_module ip_tables ${IPTABLES_SAVE_CMD} -c >$tmp err=$? if [ ! $err -eq 0 ] then ${RM_CMD} -f $tmp >/dev/null 2>&1 return $err fi ${CAT_CMD} ${tmp} |\ ${SED_CMD} "s/--uid-owner !/! --uid-owner /g" |\ ${SED_CMD} "s/--gid-owner !/! --gid-owner /g" |\ ${SED_CMD} "s/--pid-owner !/! --pid-owner /g" |\ ${SED_CMD} "s/--sid-owner !/! --sid-owner /g" |\ ${SED_CMD} "s/--cmd-owner !/! --cmd-owner /g" err=$? ${RM_CMD} -f $tmp >/dev/null 2>&1 return $err } echo -n $"FireHOL: Saving your old firewall to a temporary file:" fixed_iptables_save >${FIREHOL_SAVED} if [ $? -eq 0 ] then success $"FireHOL: Saving your old firewall to a temporary file:" echo else test -f "${FIREHOL_SAVED}" && ${RM_CMD} -f "${FIREHOL_SAVED}" failure $"FireHOL: Saving your old firewall to a temporary file:" echo exit 1 fi # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # Place all the statements bellow to the beginning of the final firewall script. ${CAT_CMD} >"${FIREHOL_OUTPUT}" <${FIREHOL_OUTPUT}.log 2>&1 r=\$?; test ! \${r} -eq 0 && runtime_error error \${r} INIT ${IPTABLES_CMD} -t "\${t}" -F ${IPTABLES_CMD} -t "\${t}" -X >${FIREHOL_OUTPUT}.log 2>&1 r=\$?; test ! \${r} -eq 0 && runtime_error error \${r} INIT ${IPTABLES_CMD} -t "\${t}" -X ${IPTABLES_CMD} -t "\${t}" -Z >${FIREHOL_OUTPUT}.log 2>&1 r=\$?; test ! \${r} -eq 0 && runtime_error error \${r} INIT ${IPTABLES_CMD} -t "\${t}" -Z # Find all default chains in this table. chains=\`${IPTABLES_CMD} -t "\${t}" -nL | ${GREP_CMD} "^Chain " | ${CUT_CMD} -d ' ' -f 2\` # If this is the 'filter' table, remember the default chains. # This will be used at the end to make it DROP all packets. test "\${t}" = "filter" && firehol_filter_chains="\${chains}" # Set the policy to ACCEPT on all default chains. for c in \${chains} do ${IPTABLES_CMD} -t "\${t}" -P "\${c}" ACCEPT >${FIREHOL_OUTPUT}.log 2>&1 r=\$?; test ! \${r} -eq 0 && runtime_error error \${r} INIT ${IPTABLES_CMD} -t "\${t}" -P "\${c}" ACCEPT done done ${IPTABLES_CMD} -t filter -P INPUT "\${FIREHOL_INPUT_ACTIVATION_POLICY}" >${FIREHOL_OUTPUT}.log 2>&1 r=\$?; test ! \${r} -eq 0 && runtime_error error \${r} INIT ${IPTABLES_CMD} -t filter -P INPUT "\${FIREHOL_INPUT_ACTIVATION_POLICY}" ${IPTABLES_CMD} -t filter -P OUTPUT "\${FIREHOL_OUTPUT_ACTIVATION_POLICY}" >${FIREHOL_OUTPUT}.log 2>&1 r=\$?; test ! \${r} -eq 0 && runtime_error error \${r} INIT ${IPTABLES_CMD} -t filter -P OUTPUT "\${FIREHOL_OUTPUT_ACTIVATION_POLICY}" ${IPTABLES_CMD} -t filter -P FORWARD "\${FIREHOL_FORWARD_ACTIVATION_POLICY}" >${FIREHOL_OUTPUT}.log 2>&1 r=\$?; test ! \${r} -eq 0 && runtime_error error \${r} INIT ${IPTABLES_CMD} -t filter -P FORWARD "\${FIREHOL_FORWARD_ACTIVATION_POLICY}" # Accept everything in/out the loopback device. if [ "\${FIREHOL_TRUST_LOOPBACK}" = "1" ] then ${IPTABLES_CMD} -A INPUT -i lo -j ACCEPT ${IPTABLES_CMD} -A OUTPUT -o lo -j ACCEPT fi # Drop all invalid packets. # Netfilter HOWTO suggests to DROP all INVALID packets. if [ "\${FIREHOL_DROP_INVALID}" = "1" ] then ${IPTABLES_CMD} -A INPUT -m state --state INVALID -j DROP ${IPTABLES_CMD} -A OUTPUT -m state --state INVALID -j DROP ${IPTABLES_CMD} -A FORWARD -m state --state INVALID -j DROP fi EOF # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX echo -n $"FireHOL: Processing file ${FIREHOL_CONFIG}:" ret=0 # ------------------------------------------------------------------------------ # Create a small awk script that inserts line numbers in the configuration file # just before each known directive. # These line numbers will be used for debugging the configuration script. ${CAT_CMD} >"${FIREHOL_TMP}.awk" <<"EOF" /^[[:space:]]*action[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*blacklist[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*classify[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*client[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*connmark[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*dnat[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*dscp[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*ecn_shame[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*group[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*interface[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*iptables[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*mac[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*mark[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*masquerade[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*nat[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*policy[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*postprocess[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*protection[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*redirect[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*require_kernel_module[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*router[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*route[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*server[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*snat[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*tcpmss[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*tos[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*transparent_squid[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*transparent_proxy[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } /^[[:space:]]*version[[:space:]]/ { printf "FIREHOL_LINEID=${LINENO} " } { print } EOF # at the same time, replace all ${IPTABLES_CMD} references with just # the word 'iptables' to protect the currently running firewall ${CAT_CMD} ${FIREHOL_CONFIG} | ${SED_CMD} "s|${IPTABLES_CMD}|iptables|g" | ${GAWK_CMD} -f "${FIREHOL_TMP}.awk" >${FIREHOL_TMP} ${RM_CMD} -f "${FIREHOL_TMP}.awk" # ------------------------------------------------------------------------------ # Run the configuration file. enable -n trap # Disable the trap buildin shell command. enable -n exit # Disable the exit buildin shell command. source ${FIREHOL_TMP} "$@" # Run the configuration as a normal script. FIREHOL_LINEID="FIN" enable trap # Enable the trap buildin shell command. enable exit # Enable the exit buildin shell command. close_cmd || ret=$[ret + 1] close_master || ret=$[ret + 1] # ------------------------------------------------------------------------------ # append commands to close the firewall according to policies ${CAT_CMD} >>"${FIREHOL_OUTPUT}" <${FIREHOL_OUTPUT}.log 2>&1 r=\$?; test ! \${r} -eq 0 && runtime_error error \${r} INIT ${IPTABLES_CMD} -t filter -P "\${c}" DROP done EOF if [ ${work_error} -gt 0 -o $ret -gt 0 ] then echo >&2 echo >&2 "NOTICE: No changes made to your firewall." failure $"FireHOL: Processing file ${FIREHOL_CONFIG}:" echo exit 1 fi success $"FireHOL: Processing file ${FIREHOL_CONFIG}:" echo # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # append commands to load the kernel modules for m in ${FIREHOL_KERNEL_MODULES} do postprocess -ne load_kernel_module $m done # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # append command to activate routing if [ $FIREHOL_ROUTING -eq 1 ] then postprocess ${SYSCTL_CMD} -w "net.ipv4.ip_forward=1" fi # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # if we just debugging things, do not proceed further if [ "${FIREHOL_MODE}" = "DEBUG" ] then ${CAT_CMD} ${FIREHOL_OUTPUT} exit 1 fi # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX syslog info "Activating new firewall from ${FIREHOL_CONFIG} (translated to ${FIREHOL_COMMAND_COUNTER} iptables rules)." echo -n $"FireHOL: Activating new firewall (${FIREHOL_COMMAND_COUNTER} rules):" source ${FIREHOL_OUTPUT} "$@" if [ ${work_runtime_error} -gt 0 ] then failure $"FireHOL: Activating new firewall:" echo syslog err "Activation of new firewall failed." # The trap will restore the firewall we saved above. exit 1 fi success $"FireHOL: Activating new firewall (${FIREHOL_COMMAND_COUNTER} rules):" echo syslog info "Activation of new firewall succeeded." if [ ${FIREHOL_TRY} -eq 1 ] then syslog info "Waiting user to commit the new firewall." read -p "Keep the firewall? (type 'commit' to accept - 30 seconds timeout) : " -t 30 -e ret=$? echo if [ ! $ret -eq 0 -o ! "${REPLY}" = "commit" ] then syslog err "User did not confirm the new firewall." # The trap will restore the firewall. exit 1 else echo "Successfull activation of FireHOL firewall." syslog info "User committed new firewall." fi fi # Remove the saved firewall, so that the trap will not restore it. ${RM_CMD} -f "${FIREHOL_SAVED}" FIREHOL_ACTIVATED_SUCCESSFULLY=1 # Startup service locking. if [ -d "${FIREHOL_LOCK_DIR}" ] then ${TOUCH_CMD} "${FIREHOL_LOCK_DIR}/iptables" ${TOUCH_CMD} "${FIREHOL_LOCK_DIR}/firehol" fi # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX if [ ${FIREHOL_SAVE} -eq 1 ] then if [ -z "${FIREHOL_AUTOSAVE}" ] then if [ -d "/etc/sysconfig" ] then # RedHat FIREHOL_AUTOSAVE="/etc/sysconfig/iptables" elif [ -d "/var/lib/iptables" ] then if [ -f /etc/conf.d/iptables ] then # Gentoo IPTABLES_SAVE= . /etc/conf.d/iptables FIREHOL_AUTOSAVE="${IPTABLES_SAVE}" fi if [ -z "${FIREHOL_AUTOSAVE}" ] then # Debian FIREHOL_AUTOSAVE="/var/lib/iptables/autosave" fi else error "Cannot find where to save iptables file. Please set FIREHOL_AUTOSAVE." echo exit 1 fi fi echo -n $"FireHOL: Saving firewall to ${FIREHOL_AUTOSAVE}:" fixed_iptables_save >"${FIREHOL_AUTOSAVE}" if [ ! $? -eq 0 ] then syslog err "Failed to save new firewall to '${FIREHOL_AUTOSAVE}'." failure $"FireHOL: Saving firewall to ${FIREHOL_AUTOSAVE}:" echo exit 1 fi syslog info "New firewall saved to '${FIREHOL_AUTOSAVE}'." success $"FireHOL: Saving firewall to ${FIREHOL_AUTOSAVE}:" echo # Save the list of modules we need to run to restore the firewall. if [ -f "${FIREHOL_SPOOL_DIR}/last_save_modules.sh" ] then mv "${FIREHOL_SPOOL_DIR}/last_save_modules.sh" "${FIREHOL_SPOOL_DIR}/last_save_modules.sh.old" fi mv "${FIREHOL_DIR}/modules_to_load.sh" "${FIREHOL_SPOOL_DIR}/last_save_modules.sh" if [ $? -gt 0 ] then error "Cannot save modules restoration script to '${FIREHOL_SPOOL_DIR}/last_save_modules.sh'." else chown root:root "${FIREHOL_SPOOL_DIR}/last_save_modules.sh" chmod 700 "${FIREHOL_SPOOL_DIR}/last_save_modules.sh" fi exit 0 fi firehol-1.297/get-iana.sh000066400000000000000000000121041225731333700152110ustar00rootroot00000000000000#!/bin/bash # $Id: get-iana.sh,v 1.15 2013/01/06 23:49:08 ktsaou Exp $ # # $Log: get-iana.sh,v $ # Revision 1.15 2013/01/06 23:49:08 ktsaou # Removed depedency to get-iana.sh # It is not usefull any more. # # Revision 1.14 2010/06/07 15:44:09 ktsaou # Made get-iana.sh support the latest IANA format. # # Revision 1.13 2010/04/08 22:03:08 ktsaou # Removed --proxy=off for wget. # # Revision 1.12 2008/03/17 22:08:43 ktsaou # Updated for latest IANA reservations format. # # Revision 1.11 2007/06/13 14:40:04 ktsaou # *** empty log message *** # # Revision 1.10 2007/05/05 23:38:31 ktsaou # Added support for external definitions of: # # RESERVED_IPS # PRIVATE_IPS # MULTICAST_IPS # UNROUTABLE_IPS # # in files under the same name in /etc/firehol/. # Only RESERVED_IPS is mandatory (firehol will complain if it is not there, # but it will still work without it), and is also the only file that firehol # checks how old is it. If it is 90+ days old, firehol will complain again. # # Changed the supplied get-iana.sh script to generate the RESERVED_IPS file. # FireHOL also instructs the user to use this script if the file is missing # or is too old. # # Revision 1.9 2007/04/29 19:34:11 ktsaou # *** empty log message *** # # Revision 1.8 2005/06/02 15:48:52 ktsaou # Allowed 127.0.0.1 to be in RESERVED_IPS # # Revision 1.7 2005/05/08 23:27:23 ktsaou # Updated RESERVED_IPS to current IANA reservations. # # Revision 1.6 2004/01/10 18:44:39 ktsaou # Further optimized and reduced PRIVATE_IPS using: # http://www.vergenet.net/linux/aggregate/ # # The supplied get-iana.sh uses 'aggregate-flim' if it finds it in the path. # (aggregate-flim is the name of this program when installed on Gentoo) # # Revision 1.5 2003/08/23 23:26:50 ktsaou # Bug #793889: # Change #!/bin/sh to #!/bin/bash to allow FireHOL run on systems that # bash is not linked to /bin/sh. # # Revision 1.4 2002/10/27 12:44:42 ktsaou # CVS test # # # Program that downloads the IPv4 address space allocation by IANA # and creates a list with all reserved address spaces. # # IPV4_ADDRESS_SPACE_URL="http://www.iana.org/assignments/ipv4-address-space" IPV4_ADDRESS_SPACE_URL="http://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.txt" # The program will match all rows in the file which start with a number, have a slash, # followed by another number, for which the following pattern will also match on the # same rows IANA_RESERVED="(RESERVED|UNALLOCATED)" # which rows that are matched by the above, to ignore # (i.e. not include them in RESERVED_IPS)? #IANA_IGNORE="(Multicast|Private use|Loopback|Local Identification)" IANA_IGNORE="Multicast" tempfile="/tmp/iana.$$.$RANDOM" AGGREGATE="`which aggregate-flim 2>/dev/null`" if [ -z "${AGGREGATE}" ] then AGGREGATE="`which aggregate 2>/dev/null`" fi if [ -z "${AGGREGATE}" ] then echo >&2 echo >&2 echo >&2 "WARNING" echo >&2 "Please install 'aggregate-flim' to shrink the list of IPs." echo >&2 echo >&2 fi echo >&2 echo >&2 "Fetching IANA IPv4 Address Space, from:" echo >&2 "${IPV4_ADDRESS_SPACE_URL}" echo >&2 wget -O - "${IPV4_ADDRESS_SPACE_URL}" |\ egrep "^ *[0-9]+/[0-9]+.*${IANA_RESERVED}" |\ egrep -vi "${IANA_IGNORE}" |\ sed "s/^ \+//g" |\ cut -d ' ' -f 1 |\ ( while IFS="/" read range net do # echo >&2 "$range/$net" if [ ! $net -eq 8 ] then echo >&2 "Cannot handle network masks of $net bits ($range/$net)" continue fi first=`echo $range | cut -d '-' -f 1` first=`expr $first + 0` last=`echo $range | cut -d '-' -f 2` last=`expr $last + 0` x=$first while [ ! $x -gt $last ] do # test $x -ne 127 && echo "$x.0.0.0/$net" echo "$x.0.0.0/$net" x=$[x + 1] done done ) | \ ( if [ ! -z "${AGGREGATE}" -a -x "${AGGREGATE}" ] then "${AGGREGATE}" else cat fi ) >"${tempfile}" echo >&2 echo >&2 echo >&2 "FOUND THE FOLLOWING RESERVED IP RANGES:" printf "RESERVED_IPS=\"" i=0 for x in `cat ${tempfile}` do i=$[i + 1] printf "${x} " done printf "\"\n" if [ $i -eq 0 ] then echo >&2 echo >&2 echo >&2 "Failed to find reserved IPs." echo >&2 "Possibly the file format has been changed, or I cannot fetch the URL." echo >&2 rm -f ${tempfile} exit 1 fi echo >&2 echo >&2 echo >&2 "Differences between the fetched list and the list installed in" echo >&2 "/etc/firehol/RESERVED_IPS:" echo >&2 "# diff /etc/firehol/RESERVED_IPS ${tempfile}" diff /etc/firehol/RESERVED_IPS ${tempfile} if [ $? -eq 0 ] then touch /etc/firehol/RESERVED_IPS echo >&2 echo >&2 "No differences found." echo >&2 rm -f ${tempfile} exit 0 fi echo >&2 echo >&2 echo >&2 "Would you like to save this list to /etc/firehol/RESERVED_IPS" echo >&2 "so that FireHOL will automatically use it from now on?" echo >&2 while [ 1 = 1 ] do printf >&2 "yes or no > " read x case "${x}" in yes) cp -f /etc/firehol/RESERVED_IPS /etc/firehol/RESERVED_IPS.old 2>/dev/null cat "${tempfile}" >/etc/firehol/RESERVED_IPS || exit 1 echo >&2 "New RESERVED_IPS written to '/etc/firehol/RESERVED_IPS'." break ;; no) echo >&2 "Saved nothing." break ;; *) echo >&2 "Cannot understand '${x}'." ;; esac done rm -f ${tempfile} firehol-1.297/man/000077500000000000000000000000001225731333700137455ustar00rootroot00000000000000firehol-1.297/man/firehol.1000066400000000000000000000171501225731333700154630ustar00rootroot00000000000000.de Sp .if t .sp .5v .if n .sp .. .hy 0 .IX Title "FIREHOL 1" .TH FIREHOL 1 "2003-04-30" .SH "NAME" firehol \- An easy to use but powerful iptables stateful firewall .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBfirehol\fR start|try|stop|restart|condrestart|status|panic|save|debug|helpme .PP \&\fBfirehol\fR \fIconfigfile\fR [start|debug|try] .PP \&\fBfirehol\fR \fInothing\fR .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBfirehol\fR is an \fBiptables\fR firewall generator producing stateful \&\fBiptables\fR packet filtering firewalls, on Linux hosts and routers with any number of network interfaces, any number of routes, any number of services served, any number of complexity between variations of the services (including positive and negative expressions). .PP \&\fBfirehol\fR is a language to express firewalling rules, not just a script that produces some kind of a firewall. .PP The goals of \fBfirehol\fR are: .IP "\(bu Being as easy as possible" 4 .IX Item "Being as easy as possible" Independently of the security skills he/she has, \fBfirehol\fR allows to create and understand complex firewalls in just a few seconds. The configuration files are very easy to type and read. .IP "\(bu Being as secure as possible." 4 .IX Item "Being as secure as possible." By allowing explicitly only the wanted traffic to flow \fBfirehol\fR secures your system. \fBfirehol\fR produces stateful rules for any service or protocol, in both directions of the firewall. .IP "\(bu Being as open as possible." 4 .IX Item "Being as open as possible." Althoug \fBfirehol\fR is pre-configured for a large number of services, you can configure any service you like and \fBfirehol\fR will turn it into a client, a server, or a router. .IP "\(bu Being as flexible as possible." 4 .IX Item "Being as flexible as possible." \&\fBfirehol\fR can be used by end users and guru administrators requiring extremely complex firewalls. \fBfirehol\fR configuration files are \s-1BASH\s0 scripts; you can write in them anything \s-1BASH\s0 accepts, including variables, pipes, loops, conditions, calls to external programs, run other \s-1BASH\s0 scripts with \fBfirehol\fR directives in them, etc. .IP "\(bu Being as simple as possible." 4 .IX Item "Being as simple as possible." \&\fBfirehol\fR is easy to install on any modern Linux system; only one file is required, no compilations involved. .SH "Options" .IX Header "Options" .IP "start" 4 .IX Item "start" Activates the firewall configuration. The configuration is expected to be found in \fI/etc/firehol/firehol.conf\fR. .IP "try" 4 .IX Item "try" Activates the firewall, but waits until the user types the word commit. If this word is not typed within 30 seconds, the previous firewall is restored. .IP "stop" 4 .IX Item "stop" Stops a running \fBiptables\fR firewall by running \f(CW\*(C`/etc/init.d/iptables stop\*(C'\fR. This will allow all traffic to pass unchecked. .IP "restart" 4 .IX Item "restart" This is an alias for start and is given for compatibility with \&\fB/etc/init.d/iptables\fR. .IP "condrestart" 4 .IX Item "condrestart" Starts the \fBfirehol\fR firewall only if it is not already active. It does not detect a modified configuration file, only verifies that \&\fBfirehol\fR has been started in the past and not stopped yet. .IP "status" 4 .IX Item "status" Shows the running firewall, as in \f(CW\*(C`/sbin/iptables \-nxvL | less\*(C'\fR .IP "panic" 4 .IX Item "panic" It removes all rules from the running firewall and then it DROPs all traffic on all \fBiptables\fR tables (mangle, nat, filter) and pre-defined chains (\s-1PREROUTING\s0, \s-1INPUT\s0, \s-1FORWARD\s0, \s-1OUTPUT\s0, \s-1POSTROUTING\s0), thus blocking all \s-1IP\s0 communication. DROPing is not done by changing the default policy to \s-1DROP\s0, but by adding just one rule per table/chain to drop all traffic, because the default iptables scripts supplied by many systems (including RedHat 8) do not reset all the chains to \s-1ACCEPT\s0 when starting (\fBfirehol\fR resets them correctly). .Sp When activating panic mode, \fBfirehol\fR checks for the existance of the \&\fB\s-1SSH_CLIENT\s0\fR shell environment variable (set by \s-1SSH\s0). If it find this, then panic mode will allow the established \s-1SSH\s0 connection specified in this variable to operate. Notice that in order for this to work, you should have su without the minus (\-) sign, since su \- overwrites the shell variables and therefore the \s-1SSH_CLIENT\s0 variable is lost. .Sp Alternativelly, after the panic argument you can specify an \s-1IP\s0 address in which case all established connections between this \s-1IP\s0 address and the host in panic will be allowed. .IP "save" 4 .IX Item "save" Start the firewall and then save it using \fB/sbin/iptables\-save\fR to \&\fI/etc/sysconfig/iptables\fR. .Sp Since v1.64, this is not implemented using \f(CW\*(C`/etc/init.d/iptables save\*(C'\fR because there is a bug in some versions of iptables-save that save invalid commands (\f(CW\*(C`! \-\-uid\-owner A\*(C'\fR is saved as \f(CW\*(C`\-\-uid\-owner !A\*(C'\fR) which cannot be restored. \fBfirehol\fR fixes this problem (by saving it, and then replacing \f(CW\*(C`\-\-uid\-owner !\*(C'\fR with \f(CW\*(C`! \-\-uid\-owner\*(C'\fR). .Sp Note that not all \fBfirehol\fR firewalls will work if restored with: \&\f(CW\*(C`/etc/init.d/iptables start\*(C'\fR because FireHOL handles kernel modules and might have queried \s-1RPC\s0 servers (used by the \s-1NFS\s0 service) before starting the firewall. Also, \fBfirehol\fR automatically checks current kernel configuration for client ports range. If you restore a firewall using the iptables service your firewall may not work as expected. .IP "debug" 4 .IX Item "debug" Parses the configuration file but instead of activating it, it shows the generated iptables statements. .IP "explain" 4 .IX Item "explain" Enters an interactive mode where it accepts normal configuration commands and presents the generated iptables commands for each of them, together with some reasoning for its purpose. Additionally, it automatically generates a configuration script based on the successfull commands given. .Sp When in directive mode, \fBfirehol\fR has the following special commands: .RS 4 .IP "\(bu help" 4 .IX Item "help" Present some help .PD 0 .IP "\(bu show" 4 .IX Item "show" Present the generated \fBfirehol\fR configuration .IP "\(bu quit" 4 .IX Item "quit" Exit interactive mode and quit \fBfirehol\fR .RE .IP "helpme" 4 .IX Item "helpme" .PD Tries to guess the \fBfirehol\fR configuration needed for the current machine. \fBfirehol\fR will not stop or alter the running firewall. The configuration file is given in the standard output of \fBfirehol\fR, thus .Sp .Vb 1 \& /etc/init.d/firehol helpme >/tmp/firehol.conf .Ve .Sp will produce the output in \fI/tmp/firehol.conf\fR. .Sp The generated \fBfirehol\fR configuration should and must be edited before used on your systems. You are required to take many decisions and the comments of the generated file will instruct you for many of them. .IP "\fIconfigfile\fR" 4 .IX Item "configfile" A different configuration file. If no other argument is given, the configuration file will be \*(L"tried\*(R" (default = \*(L"try\*(R"). Otherwise the argument next to the filename can be one of \*(L"start\*(R", \*(L"debug\*(R", \&\*(L"try\*(R". .IP "\fInothing\fR" 4 .IX Item "nothing" Presents help about \fBfirehol\fR usage. .SH "FILES" .IX Header "FILES" .RS 4 .IP "\fI/etc/firehol/firehol.conf\fR" 4 .IX Item "/etc/firehol/firehol.conf" .RE .SH "AUTHOR" .IX Header "AUTHOR" \fBfirehol\fR written by Costa Tsaousis . Man page written by Marc Brockschmidt . .SH "SEE ALSO" .IX Header "SEE ALSO" firehol.conf(5), iptables(8), bash(1) firehol-1.297/man/firehol.conf.5000066400000000000000000001310571225731333700164160ustar00rootroot00000000000000.\" Automatically generated by Pod::Man v1.34, Pod::Parser v1.13 .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. | will give a .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' .\" expand to `' in nroff, nothing in troff, for use with C<>. .tr \(*W-|\(bv\*(Tr .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .\" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .hy 0 .if n .na .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "FIREHOL.CONF 5" .TH FIREHOL.CONF 5 "2003-06-09" .SH "NAME" firehol.conf \- Configuration file for firehol(1) .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fIfirehol.conf\fR is the configuration file for \fIfirehol\fR\|(1), which creates an iptables firewall from the simple rules in this file. .PP This file is parsed as a \fIbash\fR\|(1) script, so it's no problem to use variables or complex bashisms. .SH "Commands" .IX Header "Commands" .Sh "interface [optional rule parameters]" .IX Subsection "interface [optional rule parameters]" .RS 2 The interface command creates a firewall for protecting the host the firewall is running, from the given interface. The default interface policy is drop, so that if no subcommands are given, the firewall will just drop all incoming and outgoing traffic using this interface. .Sp \fIParameters\fR .IX Subsection "Parameters" .IP "\(bu real interface" 2 .IX Item "real interface" This is the interface name as shown by ip link show. Generally anything iptables accepts, including the pattern character + (the plus sign), is valid. The plus sign after some text will match all interfaces that start with this text. It is allowed to use more than one interfaces separated by spaces, but all of them should be given within one quoted argument. Example: .RS 2 .Sp .RS 2 interface \*(L"eth0 eth1 ppp0\*(R" myname .RE .RE .RS 2 .RE .IP "\(bu name" 2 .IX Item "name" This is a name for this interface. Generally you should use short names (10 characters max) without spaces or other symbols. You should not use the same name more than once in FireHOL primary commands. .IP "\(bu optional rule parameters" 2 .IX Item "optional rule parameters" This is a set of rules that allow further restriction of the traffic that gets matched for this interface. See section \fBOptional Rules Parameters\fR for more information. Examples: .RS 2 .Sp .RS 2 interface eth0 intranet src 10.0.0.0/16 .Sp interface eth0 internet src not \*(L"$UNROUTABLE_IPS\*(R" (note: \s-1UNROUTABLE_IPS\s0 is a variable defined by FireHOL that includes all IPs that should not be routable by the Internet). .RE .RE .RS 2 .RE .RE .RS 2 .RE .Sh "router [optional rule parameters]" .IX Subsection "router [optional rule parameters]" .RS 2 The router command creates a firewall for the traffic passing through the host running the firewall. The only acceptable policy on all router commands is return and therefore the policy subcommand cannot be used on routers. This means that no packets are dropped in a router. Packets not matched by any router command will be dropped at the end of the firewall. .Sp \fIParameters\fR .IX Subsection "Parameters" .IP "\(bu name" 2 .IX Item "name" This is a name for this router. The same restrictions of interface names apply here too. .IP "\(bu optional rule parameters" 2 .IX Item "optional rule parameters" This is a set of rules that allow further restriction of the traffic that gets matched for this router. See section \fBOptional Rules Parameters\fR for more information. .RE .RS 2 .Sp \fIDescription\fR .IX Subsection "Description" .Sp .RS 2 Router statements produce similar iptables commands the interface statements produce. For each router statement an in_\fIname\fR and an out_\fIname\fR chain are produced to match the traffic in both directions of the router. .Sp To match some client or server traffic the administrator has to specify the input/output interface or the source/destination of the request. All inface/outface, src/dst optional rule parameters can be given either on the router statement in which case will be applied to all subcommands for this router, or on each subcommand within a router. Both are valid. .Sp For example: .Sp .RS 2 router mylan inface ppp+ outface eth0 server http accept client smtp accept .RE .RE .RS 2 .Sp The above says: Define a router that matches all requests that originate from some \s-1PPP\s0 interface and go out to eth0. There is an \s-1HTTP\s0 server in eth0 that client from the \s-1PPP\s0 interfaces are allowed to reach. Clients on eth0 are allowed to get \s-1SMTP\s0 traffic from the \s-1PPP\s0 interfaces. .Sp While: .Sp .RS 2 router mylan server http accept inface ppp+ outface eth0 server smtp accept inface eth0 outface ppp+ .RE .RE .RS 2 .Sp The above says: Define a router that matches any kind of forwarded traffic. For \s-1HTTP\s0 traffic the clients are on a \s-1PPP\s0 interface and the servers on eth0. For \s-1SMTP\s0 traffic the clients are on a eth0 interface and the servers o a \&\s-1PPP\s0 interface. .Sp Please note that in the second example the \s-1SMTP\s0 traffic is matched again with a server subcommand, not a client (as in the first example). .Sp The client subcommand reverses all the optional rules that are applied indirectly to it. Indirect rule parameters are those that are inherited from the parent command (router in this case). To make it simple, for FireHOL a client is: \*(L"a server with all the implicit optional rule parameters reversed\*(R". .Sp So, in the first example, the client simply flipped the inface and outface rules defined at the router and became an \s-1SMTP\s0 server. In the second example there is nothing to be flipped, so server and client are exactly the same. .Sp I suggest to use client subcommands in routers only if you have inface/outface or src/dst in the router statements. If you are building routers like the second example, don't use client, it is confusing. .Sp Older versions of FireHOL did not allow server and client subcommands in routers. Only the route subcommand was allowed. Today, route is just an alias for server and can be used only in routers, not interfaces. .Sp Any number of router statements can exist. Since the policy is \s-1RETURN\s0 on all of them, any traffic not matched by a router will continue to be checked against the second. .RE .RE .RS 2 .RE .SH "Subcommands" .IX Header "Subcommands" Subcommands must be given within Primary commands. .Sh "policy " .IX Subsection "policy " .RS 2 The policy subcommand defines the default policy for an interface. .Sp This directive accepts all the actions specified in the section \&\fBActions\fR. .Sp The policy of routers cannot be changed and is always \s-1RETURN\s0. .RE .Sh "protection [reverse] " .IX Subsection "protection [reverse] " .RS 2 The protection subcommand sets a number of protection rules on an interface. .Sp In router configurations, protections are setup on inface. .Sp \fIParameters\fR .IX Subsection "Parameters" .IP "reverse" 2 .IX Item "reverse" The reverse keyword will make the protections setup on outface. .IP "type" 2 .IX Item "type" One of the following values: .RS 2 .IP "strong, full or all" 2 .IX Item "strong, full or all" Turns on all known protections .IP "fragments" 2 .IX Item "fragments" Drops all packet fragments. Please note that most probably this rule will never match anything since iptables reconstructs all packets automatically, before the iptables firewall rules are processed, when its connection tracker is running. .IP "new\-tcp\-w/o\-syn" 2 .IX Item "new-tcp-w/o-syn" Drops all \s-1TCP\s0 packets that initiate a socket but have no the \s-1SYN\s0 bit set. .IP "syn-floods [requests/sec [burst]]" 2 .IX Item "syn-floods [requests/sec [burst]]" Allows only a certain amount of new \s-1TCP\s0 connections per second. The optional two arguments [requests/sec] and [burst] are used by this rule in order to provide control on the number of connections to be allowed. The default is 100 connections per second that can match 50 (it was 4 in v1.38 and before) packets initially (this is implemented using the limit module of iptables: see man iptables for more). Note that this rule applies to all connections attempted regardless of their final result (rejected, dropped, established, etc). Therefore it might not be a good idea to set it too low. .IP "icmp-floods [requests/sec [burst]]" 2 .IX Item "icmp-floods [requests/sec [burst]]" Allows only a certain amount of \s-1ICMP\s0 echo requests per second. The optional two arguments [requests/sec] and [burst] are used by this rule in order to provide control on the number of connections to be allowed. The default is 100 connections per second that can match 50 (it was 4 in v1.38 and before) packets initially (this is implemented using the limit module of iptables: see man iptables for more). .IP "malformed-xmas" 2 .IX Item "malformed-xmas" Drops all \s-1TCP\s0 packets that have all \s-1TCP\s0 flags set. .IP "malformed-null" 2 .IX Item "malformed-null" Drops all \s-1TCP\s0 packets that have all \s-1TCP\s0 flags unset. .IP "malformed-bad" 2 .IX Item "malformed-bad" Drops all \s-1TCP\s0 packets that have illegal combinations of \s-1TCP\s0 flags set. .RE .RS 2 .RE .RE .RS 2 .RE .Sh "server [optional rule parameters]" .IX Subsection "server [optional rule parameters]" .RS 2 The server subcommand defines a server of a service. For FireHOL a server is the destination of a request, and even if this is more complex for multi-socket services, for FireHOL a server always accepts requests. .Sp The optional rule parameters given to the parent primary command (interface or router) are inherited by the server as they have been given. .Sp This subcommand can be used on both interfaces and routers. .Sp \fIParameters\fR .IX Subsection "Parameters" .IP "service" 2 .IX Item "service" This is one of the supported service names. The command accepts more than one services in the same argument if they are separated by space and quoted as a single argument. Example: .RS 2 .Sp .RS 2 server smtp accept .Sp server \*(L"smtp pop3 imap\*(R" accept .RE .RE .RS 2 .RE .IP "action" 2 .IX Item "action" This tells FireHOL what to do with the traffic matching this rule. .Sp FireHOL supports the actions defined in the section \fBActions\fR. .IP "optional rule parameters" 2 .IX Item "optional rule parameters" This is a set of rules that allow further restriction of the traffic that gets matched by this rule. See section \&\fBOptional Rules Parameters\fR for more information. Examples: .RS 2 .Sp .RS 2 server smtp accept src 1.2.3.4 .Sp server smtp accept log \*(L"its mail\*(R" src 1.2.3.4 .RE .RE .RS 2 .RE .RE .RS 2 .RE .Sh "client [optional rule parameters]" .IX Subsection "client [optional rule parameters]" .RS 2 The client subcommand defines a client of a service. For FireHOL a client is the source of a request. FireHOL follows this simple rule even on multi-socket complex protocols, so that for FireHOL a client always sends requests. The parameters are exactly the same with the server subcommand. .Sp The optional rule parameters given to the parent primary command (interface or router) are inherited by the client, but they are reversed. For an explanation of this please refer to the documentation of the router primary command. .Sp This subcommand can be used on both interfaces and routers. .RE .Sh "route [optional rule parameters]" .IX Subsection "route [optional rule parameters]" .RS 2 The route subcommand is an alias for the server command that can be used only on routers, not interfaces. .RE .SH "Helper commands" .IX Header "Helper commands" .Sh "version " .IX Subsection "version " .RS 2 The version command states the FireHOL release the configuration file was created for. In case the configuration file is newer than FireHOL, FireHOL will deny to run it. .Sp This command is here to allow you or anyone else design and distribute FireHOL configuration files, while ensuring that the correct FireHOL version is going to run them. .Sp The FireHOL release is increased every time the format of the configuration file and the internals of FireHOL are changed. .Sp Since FireHOL v1.67 version is not required to be present in every configuration file. .RE .Sh "iptables " .IX Subsection "iptables " .RS 2 The iptables command passes all its arguments to the real iptables command, during run\-time. .Sp You should not use /sbin/iptables directly to alter a FireHOL firewall in its configurations. If you do, your commands will be run before FireHOL activates its firewall and while the previous firewall is still running. Also, since FireHOL will delete all previous firewall rules in order to activate the new firewall, any changes you will make, will be deleted too. .Sp Always use the iptables directive to hook iptables commands in a FireHOL firewall. Nothing else. .RE .Sh "masquerade [reverse | interface] [optional rule parameters]" .IX Subsection "masquerade [reverse | interface] [optional rule parameters]" .RS 2 Masquerading is a special from of \s-1SNAT\s0 (Source \s-1NAT\s0) that changes the source of requests when they go out and replaces their original source when replies come in. This way a Linux box can become an internet router for a \s-1LAN\s0 of clients having unroutable \s-1IP\s0 addresses. Masquerading takes care to re-map \s-1IP\s0 addresses and ports as required. .Sp Masquerading is \*(L"expensive\*(R" compared to \s-1SNAT\s0 because it checks the \s-1IP\s0 address of the ougoing interface every time for every packet, and therefore it is suggested that if you connect to the internet with a static \s-1IP\s0 address, to prefer \s-1SNAT\s0. .Sp The masquerade helper sets up masquerading on the output of a network interface (not the interface command, but a real network interface). .Sp If the masquerade command is placed within an interface command, its network interface[s] will be used. .Sp If the masquerade command is placed within a router command that has an outface defined, then the outface network interface[s] will be used. .Sp If placed within a router command but the keyword reverse is specified and the router command has an inface defined, then the inface network interface[s] will be used. .Sp If placed outside and before all primary commands, an interface (or list of space separated interfaces, within double quotes) can be specified on the masquerade command. .Sp In all cases, masquerade will setup itself on the output of the given interface[s]. .Sp Please note that if masquerade is used within some interface or router, it does not respect the optional rule parameters given to this interface or router command. Masquerade uses only its own optional rule parameters. .Sp inface and outface should not be given as parameters to masquerade (inface because iptables does not support this in the \s-1POSTROUTING\s0 chain, and outface because it will be overwritten by the interface(s) mentioned above). .Sp Finally, the masquerade helper will turn on \s-1FIREHOL_NAT\s0 and instruct the kernel to do packet forwarding (like the router commands do). .Sp Examples: .Sp .RS 2 Before the first interface or router: masquerade eth0 src 10.0.0.0/8 dst not 10.0.0.0/8 .Sp Within an interface rule to masquerade on the output of this interface: masquerade .Sp Within a router rule to masquerade on the output of the router's inface: masquerade reverse .RE .RE .RS 2 .RE .Sh "transparent_squid [optional rule parameters]" .IX Subsection "transparent_squid [optional rule parameters]" .RS 2 The transparent_squid helper sets up trasparent caching for \s-1HTTP\s0 traffic. The squid proxy is assumed to be running on the firewall host at port \&\fIport\fR (\fIport\fR defaults to squid), with the credentials of the local user \fIuser\fR (\fIuser\fR defaults to squid). .Sp The transparent_squid helper can be used for two kinds of traffic: .IP "\(bu Incoming \s-1HTTP\s0 traffic" 2 .IX Item "Incoming HTTP traffic" Incoming \s-1HTTP\s0 traffic, which is either targeted to the firewall host or passing through the firewall host. .Sp The optional rule parameters can be used to specify which kind of incoming traffic to be catched (by using inface, src, dst, etc \*(-- outface should not be used here, because the rules generated are placed before the routing decision and therefore the outgoing interface is not yet known). .Sp If no optional rule parameters are given, then the transparent cache will be setup on all network interfaces for all \s-1HTTP\s0 traffic (use this with care since you are risking to serve requests from the internet using your squid). .IP "\(bu Locally \s-1HTTP\s0 traffic" 2 .IX Item "Locally HTTP traffic" Locally generated \s-1HTTP\s0 traffic except traffic generated by processes running as user \fIuser\fR. The optional rule parameters inface, outface and src are ignored for this type of traffic. .Sp This kind of matching makes it possible to support transparent caching for \s-1WEB\s0 browsers running on the firewall host, as far as they do not run as the user excluded. More than one users can be specified by space-separating and enclosing them in double quotes. .Sp This rule can be disabled by specifing as user the empty string: "" .RE .RS 2 .Sp Examples: .Sp .RS 2 transparent_squid 3128 squid inface eth0 src 10.0.0.0/8 .Sp transparent_squid 8080 \*(L"squid privoxy root bin\*(R" inface not \*(L"ppp+ ipsec+\*(R" dst not \*(L"a.not.proxied.server\*(R" .RE .RE .RS 2 .RE .Sh "nat [optional rule parameters]" .IX Subsection "nat [optional rule parameters]" .RS 2 The nat helper sets up a \s-1NAT\s0 rule for routed traffic. .Sp The type parameter can be: .IP "to-source" 2 .IX Item "to-source" Defines a Source \s-1NAT\s0 (created in \s-1NAT/POSTROUTING\s0). .Sp The \fItarget\fR in this case is the source address to be set in packets matching the optional rule parameters (if no optional rule parameters, all forwarded traffic will be matched). \fItarget\fR accepts all \&\-\-to\-source values iptables accepts (see iptables \-j \s-1SNAT\s0 \-\-help). Multiple \-\-to\-source values can be given, if separated by space and quoted as a single argument. .Sp inface should not be used in \s-1SNAT\s0, because iptables does provide this information at this point. .IP "to-destination" 2 .IX Item "to-destination" Defines a Destination \s-1NAT\s0 (created in \s-1NAT/PREROUTING\s0). .Sp The \fItarget\fR in this case is the destination address to be set in packets matching the optional rule parameters (if no optional rule parameters, all forwarded traffic will be matched). \fItarget\fR accepts all \-\-to\-destination values iptables accepts (see iptables \-j \s-1DNAT\s0 \-\-help). Multiple \&\-\-to\-destination values can be given, if separated by space and quoted as a single argument. .Sp outface should not be used in \s-1DNAT\s0, because iptables does provide this information at this point. .IP "redirect-to" 2 .IX Item "redirect-to" Catches traffic comming in and send it to the local machine (created in \s-1NAT/PREROUTING\s0). .Sp The \fItarget\fR in this case is a port or a range of ports (\s-1XXX\-YYY\s0) that packets matching the rule will be redirected to (if no optional rule parameters are given, all incomming traffic will be matched). \fItarget\fR accepts all \-\-to\-ports values iptables accepts (see iptables \-j \&\s-1REDIRECT\s0 \-\-help). .Sp outface should not be used in \s-1REDIRECT\s0, because iptables does provide this information at this point. .RE .RS 2 .Sp Please understand that the optional rule parameters are used only to limit the traffic to be matched. Consider these examples: .IP "Sends to 1.1.1.1 all traffic comming in or passing trhough the firewall host:" 2 .IX Item "Sends to 1.1.1.1 all traffic comming in or passing trhough the firewall host:" nat to-destination 1.1.1.1 .IP "Redirects to 1.1.1.1 all traffic comming in or passing through, and going to 2.2.2.2:" 2 .IX Item "Redirects to 1.1.1.1 all traffic comming in or passing through, and going to 2.2.2.2:" .Vb 1 \& nat to-destination 1.1.1.1 dst 2.2.2.2 .Ve .IP "Redirects to 1.1.1.1 all \s-1TCP\s0 traffic comming in or passing through and going to 2.2.2.2:" 2 .IX Item "Redirects to 1.1.1.1 all TCP traffic comming in or passing through and going to 2.2.2.2:" .Vb 1 \& nat to-destination 1.1.1.1 proto tcp dst 2.2.2.2 .Ve .IP "Redirects to 1.1.1.1 all traffic comming in or passing through and going to 2.2.2.2 to port tcp/25:" 2 .IX Item "Redirects to 1.1.1.1 all traffic comming in or passing through and going to 2.2.2.2 to port tcp/25:" .Vb 1 \& nat to-destination 1.1.1.1 proto tcp dport 25 dst 2.2.2.2 .Ve .RE .RS 2 .Sp More examples: .Sp .RS 2 nat to-source 1.1.1.1 outface eth0 src 2.2.2.2 dst 3.3.3.3 .Sp nat to-destination 4.4.4.4 inface eth0 src 5.5.5.5 dst 6.6.6.6 .Sp nat redirect-to 8080 inface eth0 src 2.2.2.0/24 proto tcp dport 80 .RE .RE .RS 2 .RE .Sh "snat [to] [optional rule parameters]" .IX Subsection "snat [to] [optional rule parameters]" .RS 2 The snat helper sets up a Source \s-1NAT\s0 rule for routed traffic, by calling nat to-source \fItarget\fR [optional rule parameters] .Sp See the nat helper. .Sp Example: .Sp .RS 2 snat to 1.1.1.1 outface eth0 src 2.2.2.2 dst 3.3.3.3 .RE .RE .RS 2 .RE .Sh "dnat [to] [optional rule parameters]" .IX Subsection "dnat [to] [optional rule parameters]" .RS 2 The dnat helper sets up a Destination \s-1NAT\s0 rule for routed traffic, by calling nat to-destination \fItarget\fR [optional rule parameters] .Sp See the nat helper. .Sp Example: .Sp .RS 2 dnat to 1.1.1.1 inface eth0 src 2.2.2.2 dst 3.3.3.3 .RE .RE .RS 2 .RE .Sh "redirect [to] [optional rule parameters]" .IX Subsection "redirect [to] [optional rule parameters]" .RS 2 The redirect helper catches all incomming traffic matching the optional rule parameters given and redirects it to ports on the local host, by calling nat redirect-to \fItarget\fR [optional rule parameters] .Sp See the nat helper. .Sp Example: .Sp .RS 2 nat redirect-to 8080 inface eth0 src 2.2.2.0/24 proto tcp dport 80 .RE .RE .RS 2 .RE .SH "Actions" .IX Header "Actions" Actions are the actions to be taken on services and traffic described by other commands and functions. Please note that normally, FireHOL will pass-through to the generated iptables statements all the possible actions iptables accepts, but only the ones defined here can be used with lower case letters and currently it will be impossible to pass arguments to some unknown action. Also, keep in mind that the iptables action \s-1LOG\s0 is a FireHOL optional rule parameter (see log and loglimit) that can be defined together with one of the following actions and FireHOL will actually produce multiple iptables statements to achieve both the logging and the action. .Sh "accept" .IX Subsection "accept" .RS 2 accept allows the traffic matching the rules to reach its destination. .Sp Example: .Sp .RS 2 server smtp accept, to allow \s-1SMTP\s0 requests and their replies to flow. .RE .RE .RS 2 .RE .Sh "reject [with message]" .IX Subsection "reject [with message]" .RS 2 reject discards the matching traffic but sends a rejecting message back to the sender. .Sp with is used to offer control on the message to be returned to the sender. with accepts all the arguments the \-\-reject\-with iptables expression accepts. For an updated list of these messages type iptables \-j \s-1REJECT\s0 \-\-help. .Sp Examples: .Sp .RS 2 policy reject with host-unreach .Sp server ident reject with tcp-reset .Sp UNMATCHED_INPUT_POLICY=\*(L"reject with host\-prohib\*(R" .RE .RE .RS 2 .RE .Sh "drop" .IX Subsection "drop" .RS 2 drop silently discards the matching traffic. The fact that the traffic is silently discarded makes the sender timeout in order to conclude that it is not possible to use the wanted service. .Sp Example: .Sp .RS 2 server smtp drop, to silently discard \s-1SMTP\s0 requests and their replies. .RE .RE .RS 2 .RE .Sh "deny" .IX Subsection "deny" .RS 2 deny is just an alias for drop, made for those who are used to ipchains terminology. .Sp Example: .Sp .RS 2 server smtp deny, to silently discard \s-1SMTP\s0 requests and their replies. .RE .RE .RS 2 .RE .Sh "return" .IX Subsection "return" .RS 2 return will return the flow of processing to the parent of the current command. Currently, it has meaning to specify the action return only as a policy to some interface. .Sp Example: .IP "policy return" 2 .IX Item "policy return" Traffic not matched by any rule within an interface continues traveling through the firewall and is possibly matched by other interfaces bellow. .RE .RS 2 .RE .Sh "mirror" .IX Subsection "mirror" .RS 2 \&\fImirror\fR will return the traffic to the wanted port, back to the sending host. Use this with care, and only if you understand what you doing. Keep also in mind that FireHOL will apply this action to both requests and replies comming in or passing through, and will replace it with \&\s-1REJECT\s0 for traffic generated by the local host. .RE .Sh "redirect [to\-port port]" .IX Subsection "redirect [to-port port]" .RS 2 \&\fIredirect\fR is used internally by FireHOL Helper Commands to redirect traffic to ports on the local host. Unless you are a developer, you will never need to use this directly. .RE .SH "Optional Rule Parameters" .IX Header "Optional Rule Parameters" Optional rule parameters are accepted by many commands to narrow the match they do by default. The parameters described bellow are all that FireHOL supports. You should check the documentation of each command to find which parameters should not be used with it. Normally, all FireHOL commands are designed so that if you specify a parameters that is also used internally, the internal one will overwrite the one given in the configuration file. In such a case, FireHOL will present you a warning with the old and the new value. .PP Not all parameters should be used in all cases. For example \fIsport\fR and \fIdport\fR should not be used in normal server and client commands since such ports are internally defined by the services themselves. In any case, FireHOL will complain about optional rule parameters that should not be used in certain commands. .Sh "src [not] " .IX Subsection "src [not] " .RS 2 \&\fIsrc\fR defines the source \s-1IP\s0 address of the \s-1REQUEST\s0. If \fIsrc\fR is defined on a server statement it matches the source of the request which is the remote host, while if it is defined on a client statement it matches again the source of the request, but this time it is the local host. Focus on the \s-1REQUEST\s0!!! Forget the reply. .Sp \fIParameters\fR .IX Subsection "Parameters" .IP "not" 2 .IX Item "not" Optional argument that reverses the match. When defined, the rule will match all hosts except the ones defined. Example: server smtp accept src not 1.2.3.4 .IP "\fIhost\fR" 2 .IX Item "host" An \s-1IP\s0 address, a hostname, or a subnet. Multiple hosts/networks can be defined if separated by space and quoted as a single argument. Examples: server smtp accept src 1.2.3.4 server smtp accept src not \*(L"1.2.3.0/24 5.6.7.8 badhost.example.com\*(R" .RE .RS 2 .RE .Sh "dst [not] " .IX Subsection "dst [not] " .RS 2 \&\fIdst\fR defines the destination of the \s-1REQUEST\s0. If dst is defined on a server statement it matches the destination of the request which is the local host, while if it is defined on a client statement it matches again the destination of the request, but this time it is the remote host. Focus on the \s-1REQUEST\s0!!! Forget the reply. .Sp \&\fIdst\fR accepts the same parameters as src. .RE .Sh "inface [not] " .IX Subsection "inface [not] " .RS 2 \&\fIinface\fR defines the interface the \s-1REQUEST\s0 is received via. inface cannot be used in interface commands. .Sp \fIParameters\fR .IX Subsection "Parameters" .IP "not" 2 .IX Item "not" An optional argument that reverses the match. When defined, the rule will match all interfaces except the ones defined. Example: server smtp accept inface not eth0 .IP "\fIinterface\fR" 2 .IX Item "interface" if an interface name in the same format the interface command accepts. Multiple interfaces can be defined if separated by space and quoted as a single argument. Examples: server smtp accept inface not eth0 server smtp accept inface not \*(L"eth0 eth1\*(R" .RE .RS 2 .RE .Sh "outface [not] " .IX Subsection "outface [not] " .RS 2 \&\fIoutface\fR defines the interface the \s-1REQUEST\s0 is send via. outface cannot be used in interface commands. .Sp \&\fIoutface\fR accepts the same parameters as inface. .RE .Sh "custom " .IX Subsection "custom " .RS 2 \&\fIcustom\fR passes its arguments to the generated iptables commands. .Sp It is required to quote all the parameters given to custom. If the parameters include a space character between some text that is required to be given to iptables as one argument, it is required to escape another set of quotes in order. Another way is to use double quotes externally and single quotes internally. .Sp Examples: .Sp .Vb 1 \& server smtp accept custom "--some-iptables-option and_its_value" .Ve .Sp .Vb 1 \& server smtp accept custom "--some-iptables-option 'one_value another_value' .Ve .RE .ie n .Sh "log """" [level a_level]" .el .Sh "log ``'' [level a_level]" .IX Subsection "log """" [level a_level]" .RS 2 \&\fIlog\fR will log the matching packets to syslog. Note that this is not an action (in iptables it is). FireHOL will actually produce multiple iptables commands to accomplish both the action for the rule and the logging. You can control how logging works, by altering the variables \&\s-1FIREHOL_LOG_OPTIONS\s0 and \s-1FIREHOL_LOG_LEVEL\s0. You can also change the level of just one rule by using the level argument of the log parameter. .Sp FireHOL logs traffic, exactly the same way iptables does. Many users have complained about packet logs appearing at their console. To avoid this you will have to: .IP "\(bu setup klogd to log only more important traffic" 2 .IX Item "setup klogd to log only more important traffic" .PD 0 .IP "\(bu change \s-1FIREHOL_LOG_LEVEL\s0 to log at a not so important log-level" 2 .IX Item "change FIREHOL_LOG_LEVEL to log at a not so important log-level" .RE .RS 2 .PD .Sp Actually klogd's \-c option and iptables' \-\-log\-level option are the same thing (iptables accepts also the numeric values klogd accepts). If iptables logs at a higher priority than klogd is configured to use, then your packets will appear in the console too. .RE .ie n .Sh "loglimit """"" .el .Sh "loglimit ``''" .IX Subsection "loglimit """"" .RS 2 \&\fIloglimit\fR is the same with log but limits the frequency of logging according to the setting of \s-1FIREHOL_LOG_FREQUENCY\s0 and \s-1FIREHOL_LOG_BURST\s0. .RE .Sh "proto [not] " .IX Subsection "proto [not] " .RS 2 \&\fIproto\fR sets the required protocol for the traffic. This command accepts anything iptables accepts as protocols. .RE .Sh "limit " .IX Subsection "limit " .RS 2 \&\fIlimit\fR will limit the match in both directions of the traffic (request and reply). This is used internally by FireHOL and its effects has not been tested in the high level configuration file directives. .RE .Sh "sport " .IX Subsection "sport " .RS 2 \&\fIsport\fR defines the source port of a request. It accepts port names, port numbers, port ranges (\s-1FROM:TO\s0) and multiple ports (or ranges) seperated by spaces and quoted as a single argument. This parameter should not be used in normal services definitions (client and server commands) or interface and router definitions, unless you really understand what you are doing. .RE .Sh "dport " .IX Subsection "dport " .RS 2 \&\fIdport\fR defines the destination port of a request. It accepts port names, port numbers, port ranges (\s-1FROM:TO\s0) and multiple ports (or ranges) seperated by spaces and quoted as a single argument. This parameter should not be used in normal services definitions (client and server commands) or interface and router definitions, unless you really understand what you are doing. .RE .Sh "uid [not] =head2 user [not] " .IX Subsection "uid [not] =head2 user [not] " .RS 2 \&\fIuid\fR or \fIuser\fR define the operating system user sending this traffic. The parameter can be a username, a user number or a list of these two, seperated by spaces and quoted as a single argument. .Sp This parameter can be used only in services (client and server commands) defined within interfaces, not routers. FireHOL is \&\*(L"smart\*(R" enough to apply this parameter only to traffic send by the localhost, i.e. the replies of servers and requests of clients. It is not possible, and FireHOL will simply ignore this parameter, on traffic coming in or passign through the firewall host. .Sp Example 1: .Sp .Vb 1 \& client "pop3 imap" accept user not "user1 user2 user3" dst mymailer.example.com .Ve .RE .RS 2 .Sp The above will allow local users except user1, user2 and user3 to use \&\s-1POP3\s0 and \s-1IMAP\s0 services on mymailer.example.com. You can use this, for example, to allow only a few of the local users use the fetchmail program to fetch their mail from the mail server. .Sp Example 2: .Sp .Vb 1 \& server http accept user apache .Ve .RE .RS 2 .Sp The above will allow all \s-1HTTP\s0 to reach the local http server, but only if the web server is running as user apache the replies will be send back to the \s-1HTTP\s0 client. .RE .Sh "gid =head2 group " .IX Subsection "gid =head2 group " .RS 2 \&\fIgid\fR or \fIgroup\fR define the operating system user group sending this traffic. The parameter can be a group name, a group number or a list of these two, seperated by spaces and quoted as a single argument. .Sp This parameter can be used only in services (client and server commands) defined within interfaces, not routers. FireHOL is \*(L"smart\*(R" enough to apply this parameter only to traffic send by the localhost, i.e. the replies of servers and requests of clients. It is not possible, and FireHOL will simply ignore this parameter, on traffic coming in or passing through the firewall host. .RE .Sh "pid =head2 process " .IX Subsection "pid =head2 process " .RS 2 \&\fIpid\fR or \fIprocess\fR define the operating system process \s-1ID\s0 (or \s-1PID\s0) sending this traffic. The parameter can be a \s-1PID\s0 or a list of PIDs, seperated by spaces and quoted as a single argument. .Sp This parameter can be used only in services (client and server commands) defined within interfaces, not routers. FireHOL is \*(L"smart\*(R" enough to apply this parameter only to traffic send by the localhost, i.e. the replies of servers and requests of clients. It is not possible, and FireHOL will simply ignore this parameter, on traffic coming in or passign through the firewall host. .RE .Sh "sid =head2 session " .IX Subsection "sid =head2 session " .RS 2 \&\fIsid\fR or \fIsession\fR define the operating system session \s-1ID\s0 of the process sending this traffic (The session \s-1ID\s0 of a process is the process group \s-1ID\s0 of the session leader). The parameter can be a list of such IDs, seperated by spaces and quoted as a single argument. .Sp This parameter can be used only in services (client and server commands) defined within interfaces, not routers. FireHOL is \*(L"smart\*(R" enough to apply this parameter only to traffic send by the localhost, i.e. the replies of servers and requests of clients. It is not possible, and FireHOL will simply ignore this parameter, on traffic coming in or passign through the firewall host. .RE .SH "Variables that control FireHOL" .IX Header "Variables that control FireHOL" .Sh "\s-1DEFAULT_INTERFACE_POLICY\s0" .IX Subsection "DEFAULT_INTERFACE_POLICY" .RS 2 \&\fI\s-1DEFAULT_INTERFACE_POLICY\s0\fR controls the default action to be taken on traffic not matched by any rule within an interface. Actually, this is a global setting for what policy does for an interface. .Sp All packets that reach the end of an interface are logged only if the action is not return or accept. You can control the frequency of this logging by altering the frequency loglimit uses. .Sp .Vb 1 \& Default: DEFAULT_INTERFACE_POLICY="DROP" .Ve .Sp .Vb 1 \& Example: DEFAULT_INTERFACE_POLICY="REJECT" .Ve .RE .Sh "\s-1UNMATCHED_INPUT_POLICY\s0" .IX Subsection "UNMATCHED_INPUT_POLICY" .Sh "\s-1UNMATCHED_OUTPUT_POLICY\s0" .IX Subsection "UNMATCHED_OUTPUT_POLICY" .Sh "\s-1UNMATCHED_FORWARD_POLICY\s0" .IX Subsection "UNMATCHED_FORWARD_POLICY" .RS 2 \&\fI\s-1UNMATCHED_INPUT_POLICY\s0\fR controls the default action to be taken for incoming traffic not matched by any interface command. .Sp \&\fI\s-1UNMATCHED_OUTPUT_POLICY\s0\fR controls the default action to be taken for outgoing traffic not matched by any interface command. .Sp \&\fI\s-1UNMATCHED_FORWARD_POLICY\s0\fR controls the default action to be taken for forwarded traffic not matched by any router command. .Sp All variables accept all the Actions FireHOL supports. .Sp All packets that reach the end of firewall in all three chains are logged (always, regardless of these settings). You can control the frequency of this logging by altering the frequency loglimit uses. .Sp .Vb 1 \& Default: UNMATCHED_INPUT_POLICY="DROP" .Ve .Sp .Vb 1 \& Default: UNMATCHED_OUTPUT_POLICY="DROP" .Ve .Sp .Vb 1 \& Default: UNMATCHED_FORWARD_POLICY="DROP" .Ve .Sp .Vb 1 \& Example: UNMATCHED_INPUT_POLICY="REJECT" .Ve .Sp .Vb 1 \& Example: UNMATCHED_OUTPUT_POLICY="REJECT" .Ve .Sp .Vb 1 \& Example: UNMATCHED_FORWARD_POLICY="REJECT" .Ve .RE .Sh "\s-1FIREHOL_LOG_LEVEL\s0 =head2 \s-1FIREHOL_LOG_OPTIONS\s0 =head2 \s-1FIREHOL_LOG_FREQUENCY\s0 =head2 \s-1FIREHOL_LOG_BURST\s0" .IX Subsection "FIREHOL_LOG_LEVEL =head2 FIREHOL_LOG_OPTIONS =head2 FIREHOL_LOG_FREQUENCY =head2 FIREHOL_LOG_BURST" .RS 2 \&\fI\s-1FIREHOL_LOG_LEVEL\s0\fR controls the level at which iptables will log things to the syslog. For a description of the possible values supported and for per-rule control of log level, see the log optional rule parameter. .Sp \&\fI\s-1FIREHOL_LOG_OPTIONS\s0\fR controls the way iptables will log things to the syslog. The value of this variable is passed as is to iptables, so use exact iptables parameters. .Sp \&\fI\s-1FIREHOL_LOG_FREQUENCY\s0\fR and \fI\s-1FIREHOL_LOG_BURST\s0\fR (added in v1.39 of FireHOL) control the frequency at each each logging rule will write packets to the syslog. \s-1FIREHOL_LOG_FREQUENCY\s0 is set to the maximum average frequency and \s-1FIREHOL_LOG_BURST\s0 specifies the maximum initial number of packets to match. .Sp .Vb 1 \& Default: FIREHOL_LOG_OPTIONS="--log-level warning" .Ve .Sp .Vb 1 \& Default: FIREHOL_LOG_FREQUENCY="1/second" .Ve .Sp .Vb 1 \& Default: FIREHOL_LOG_BURST="5" .Ve .Sp .Vb 1 \& Example: FIREHOL_LOG_OPTIONS="--log-level info --log-tcp-options --log-ip-options" .Ve .Sp .Vb 1 \& Example: FIREHOL_LOG_FREQUENCY="30/minute" .Ve .Sp .Vb 1 \& Example: FIREHOL_LOG_BURST="2" .Ve .Sp To see the available iptables log options, run \f(CW\*(C`/sbin/iptables \-j LOG \-\-help\*(C'\fR To see what iptables accepts as frequencies and bursts, run \&\f(CW\*(C`/sbin/iptables \-m limit \-\-help\*(C'\fR .Sp You can also check man iptables. .RE .Sh "\s-1DEFAULT_CLIENT_PORTS\s0" .IX Subsection "DEFAULT_CLIENT_PORTS" .RS 2 \&\fI\s-1DEFAULT_CLIENT_PORTS\s0\fR controls the port range to be used when a remote client is specified. For localhost clients, FireHOL finds the exact client ports by querying the kernel options. .Sp .Vb 1 \& Default: 1000:65535 .Ve .Sp .Vb 1 \& Example: DEFAULT_CLIENT_PORTS="0:65535" .Ve .RE .Sh "\s-1FIREHOL_NAT\s0" .IX Subsection "FIREHOL_NAT" .RS 2 If \fI\s-1FIREHOL_NAT\s0\fR is set to 1, FireHOL will load \s-1NAT\s0 kernel modules for those services that they are require such. FireHOL sets this to 1 automatically if you use the Helper Commands that do \s-1NAT\s0. .Sp .Vb 1 \& Default: FIREHOL_NAT="0" .Ve .Sp .Vb 1 \& Example: FIREHOL_NAT="1" .Ve .RE .Sh "\s-1FIREHOL_AUTOSAVE\s0" .IX Subsection "FIREHOL_AUTOSAVE" .RS 2 \&\s-1FIREHOL_AUTOSAVE\s0 controls the file that will be created when FireHOL is called with the save command line argument. If this variable is empty (the default), FireHOL will try to detect where to save the file. Currently, the RedHat way (/etc/sysconfig/iptables) and the Debian way (/var/lib/iptables/autosave) are automatically detected (in the order given here) based on the existance of the directory this file should be created in. .Sp Default: FIREHOL_AUTOSAVE="\*(L" Example: FIREHOL_AUTOSAVE=\*(R"/tmp/firehol\-saved.txt" .RE .SH "Variables that FireHOL offers" .IX Header "Variables that FireHOL offers" .Sh "\s-1RESERVED_IPS\s0" .IX Subsection "RESERVED_IPS" .RS 2 This variable includes all the \s-1IP\s0 addresses defined as \s-1IANA\s0 \- Reserved by \s-1IANA\s0. .Sp .Vb 1 \& Example: interface eth0 internet src not "${RESERVED_IPS}" .Ve .RE .Sh "\s-1PRIVATE_IPS\s0" .IX Subsection "PRIVATE_IPS" .RS 2 This variable includes all the \s-1IP\s0 addresses defined as Private or Test by \s-1RFC\s0 3330. .Sp .Vb 1 \& Example: interface eth0 internet src not "${PRIVATE_IPS}" .Ve .RE .Sh "\s-1UNROUTABLE_IPS\s0" .IX Subsection "UNROUTABLE_IPS" .RS 2 This variable is both \fI\s-1RESERVED_IPS\s0\fR and \fI\s-1PRIVATE_IPS\s0\fR together. I suggest to use this variable on interfaces and routers accepting Internet traffic. .Sp .Vb 1 \& Example: interface eth0 internet src not "${UNROUTABLE_IPS}" .Ve .RE .SH "FILES" .IX Header "FILES" \&\fI/etc/firehol/firehol.conf\fR .SH "AUTHOR" .IX Header "AUTHOR" firehol written by Costa Tsaousis . .PP Man page written by Marc Brockschmidt <. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIfirehol\fR\|(1), \fIiptables\fR\|(8), \fIbash\fR\|(1) firehol-1.297/man/firehol.conf.pod000066400000000000000000001071611225731333700170330ustar00rootroot00000000000000=pod =head1 NAME firehol.conf - Configuration file for firehol(1) =head1 DESCRIPTION F is the configuration file for firehol(1), which creates an iptables firewall from the simple rules in this file. This file is parsed as a bash(1) script, so it's no problem to use variables or complex bashisms. =head1 Commands =head2 interface Ereal interfaceE EnameE [optional rule parameters] =over 2 The interface command creates a firewall for protecting the host the firewall is running, from the given interface. The default interface policy is drop, so that if no subcommands are given, the firewall will just drop all incoming and outgoing traffic using this interface. =head3 Parameters =over 2 =item * real interface This is the interface name as shown by ip link show. Generally anything iptables accepts, including the pattern character + (the plus sign), is valid. The plus sign after some text will match all interfaces that start with this text. It is allowed to use more than one interfaces separated by spaces, but all of them should be given within one quoted argument. Example: interface "eth0 eth1 ppp0" myname =item * name This is a name for this interface. Generally you should use short names (10 characters max) without spaces or other symbols. You should not use the same name more than once in FireHOL primary commands. =item * optional rule parameters This is a set of rules that allow further restriction of the traffic that gets matched for this interface. See section B for more information. Examples: =over 2 interface eth0 intranet src 10.0.0.0/16 interface eth0 internet src not "$UNROUTABLE_IPS" (note: UNROUTABLE_IPS is a variable defined by FireHOL that includes all IPs that should not be routable by the Internet). =back =back =back =head2 router EnameE [optional rule parameters] =over 2 The router command creates a firewall for the traffic passing through the host running the firewall. The only acceptable policy on all router commands is return and therefore the policy subcommand cannot be used on routers. This means that no packets are dropped in a router. Packets not matched by any router command will be dropped at the end of the firewall. =head3 Parameters =over 2 =item * name This is a name for this router. The same restrictions of interface names apply here too. =item * optional rule parameters This is a set of rules that allow further restriction of the traffic that gets matched for this router. See section B for more information. =back =head3 Description =over 2 Router statements produce similar iptables commands the interface statements produce. For each router statement an in_I and an out_I chain are produced to match the traffic in both directions of the router. To match some client or server traffic the administrator has to specify the input/output interface or the source/destination of the request. All inface/outface, src/dst optional rule parameters can be given either on the router statement in which case will be applied to all subcommands for this router, or on each subcommand within a router. Both are valid. For example: =over 2 router mylan inface ppp+ outface eth0 server http accept client smtp accept =back The above says: Define a router that matches all requests that originate from some PPP interface and go out to eth0. There is an HTTP server in eth0 that client from the PPP interfaces are allowed to reach. Clients on eth0 are allowed to get SMTP traffic from the PPP interfaces. While: =over 2 router mylan server http accept inface ppp+ outface eth0 server smtp accept inface eth0 outface ppp+ =back The above says: Define a router that matches any kind of forwarded traffic. For HTTP traffic the clients are on a PPP interface and the servers on eth0. For SMTP traffic the clients are on a eth0 interface and the servers o a PPP interface. Please note that in the second example the SMTP traffic is matched again with a server subcommand, not a client (as in the first example). The client subcommand reverses all the optional rules that are applied indirectly to it. Indirect rule parameters are those that are inherited from the parent command (router in this case). To make it simple, for FireHOL a client is: "a server with all the implicit optional rule parameters reversed". So, in the first example, the client simply flipped the inface and outface rules defined at the router and became an SMTP server. In the second example there is nothing to be flipped, so server and client are exactly the same. I suggest to use client subcommands in routers only if you have inface/outface or src/dst in the router statements. If you are building routers like the second example, don't use client, it is confusing. Older versions of FireHOL did not allow server and client subcommands in routers. Only the route subcommand was allowed. Today, route is just an alias for server and can be used only in routers, not interfaces. Any number of router statements can exist. Since the policy is RETURN on all of them, any traffic not matched by a router will continue to be checked against the second. =back =back =head1 Subcommands Subcommands must be given within Primary commands. =head2 policy EactionE =over 2 The policy subcommand defines the default policy for an interface. This directive accepts all the actions specified in the section B. The policy of routers cannot be changed and is always RETURN. =back =head2 protection [reverse] =over 2 The protection subcommand sets a number of protection rules on an interface. In router configurations, protections are setup on inface. =head3 Parameters =over 2 =item reverse The reverse keyword will make the protections setup on outface. =item type One of the following values: =over 2 =item strong, full or all Turns on all known protections =item fragments Drops all packet fragments. Please note that most probably this rule will never match anything since iptables reconstructs all packets automatically, before the iptables firewall rules are processed, when its connection tracker is running. =item new-tcp-w/o-syn Drops all TCP packets that initiate a socket but have no the SYN bit set. =item syn-floods [requests/sec [burst]] Allows only a certain amount of new TCP connections per second. The optional two arguments [requests/sec] and [burst] are used by this rule in order to provide control on the number of connections to be allowed. The default is 100 connections per second that can match 50 (it was 4 in v1.38 and before) packets initially (this is implemented using the limit module of iptables: see man iptables for more). Note that this rule applies to all connections attempted regardless of their final result (rejected, dropped, established, etc). Therefore it might not be a good idea to set it too low. =item icmp-floods [requests/sec [burst]] Allows only a certain amount of ICMP echo requests per second. The optional two arguments [requests/sec] and [burst] are used by this rule in order to provide control on the number of connections to be allowed. The default is 100 connections per second that can match 50 (it was 4 in v1.38 and before) packets initially (this is implemented using the limit module of iptables: see man iptables for more). =item malformed-xmas Drops all TCP packets that have all TCP flags set. =item malformed-null Drops all TCP packets that have all TCP flags unset. =item malformed-bad Drops all TCP packets that have illegal combinations of TCP flags set. =back =back =back =head2 server EserviceE EactionE [optional rule parameters] =over 2 The server subcommand defines a server of a service. For FireHOL a server is the destination of a request, and even if this is more complex for multi-socket services, for FireHOL a server always accepts requests. The optional rule parameters given to the parent primary command (interface or router) are inherited by the server as they have been given. This subcommand can be used on both interfaces and routers. =head3 Parameters =over 2 =item service This is one of the supported service names. The command accepts more than one services in the same argument if they are separated by space and quoted as a single argument. Example: =over 2 server smtp accept server "smtp pop3 imap" accept =back =item action This tells FireHOL what to do with the traffic matching this rule. FireHOL supports the actions defined in the section B. =item optional rule parameters This is a set of rules that allow further restriction of the traffic that gets matched by this rule. See section B for more information. Examples: =over 2 server smtp accept src 1.2.3.4 server smtp accept log "its mail" src 1.2.3.4 =back =back =back =head2 client EserviceE EactionE [optional rule parameters] =over 2 The client subcommand defines a client of a service. For FireHOL a client is the source of a request. FireHOL follows this simple rule even on multi-socket complex protocols, so that for FireHOL a client always sends requests. The parameters are exactly the same with the server subcommand. The optional rule parameters given to the parent primary command (interface or router) are inherited by the client, but they are reversed. For an explanation of this please refer to the documentation of the router primary command. This subcommand can be used on both interfaces and routers. =back =head2 route EserviceE EactionE [optional rule parameters] =over 2 The route subcommand is an alias for the server command that can be used only on routers, not interfaces. =back =head1 Helper commands =head2 version EnumberE =over 2 The version command states the FireHOL release the configuration file was created for. In case the configuration file is newer than FireHOL, FireHOL will deny to run it. This command is here to allow you or anyone else design and distribute FireHOL configuration files, while ensuring that the correct FireHOL version is going to run them. The FireHOL release is increased every time the format of the configuration file and the internals of FireHOL are changed. Since FireHOL v1.67 version is not required to be present in every configuration file. =back =head2 iptables EargumentsE =over 2 The iptables command passes all its arguments to the real iptables command, during run-time. You should not use /sbin/iptables directly to alter a FireHOL firewall in its configurations. If you do, your commands will be run before FireHOL activates its firewall and while the previous firewall is still running. Also, since FireHOL will delete all previous firewall rules in order to activate the new firewall, any changes you will make, will be deleted too. Always use the iptables directive to hook iptables commands in a FireHOL firewall. Nothing else. =back =head2 masquerade [reverse | interface] [optional rule parameters] =over 2 Masquerading is a special from of SNAT (Source NAT) that changes the source of requests when they go out and replaces their original source when replies come in. This way a Linux box can become an internet router for a LAN of clients having unroutable IP addresses. Masquerading takes care to re-map IP addresses and ports as required. Masquerading is "expensive" compared to SNAT because it checks the IP address of the ougoing interface every time for every packet, and therefore it is suggested that if you connect to the internet with a static IP address, to prefer SNAT. The masquerade helper sets up masquerading on the output of a network interface (not the interface command, but a real network interface). If the masquerade command is placed within an interface command, its network interface[s] will be used. If the masquerade command is placed within a router command that has an outface defined, then the outface network interface[s] will be used. If placed within a router command but the keyword reverse is specified and the router command has an inface defined, then the inface network interface[s] will be used. If placed outside and before all primary commands, an interface (or list of space separated interfaces, within double quotes) can be specified on the masquerade command. In all cases, masquerade will setup itself on the output of the given interface[s]. Please note that if masquerade is used within some interface or router, it does not respect the optional rule parameters given to this interface or router command. Masquerade uses only its own optional rule parameters. inface and outface should not be given as parameters to masquerade (inface because iptables does not support this in the POSTROUTING chain, and outface because it will be overwritten by the interface(s) mentioned above). Finally, the masquerade helper will turn on FIREHOL_NAT and instruct the kernel to do packet forwarding (like the router commands do). Examples: =over 2 Before the first interface or router: masquerade eth0 src 10.0.0.0/8 dst not 10.0.0.0/8 Within an interface rule to masquerade on the output of this interface: masquerade Within a router rule to masquerade on the output of the router's inface: masquerade reverse =back =back =head2 transparent_squid EportE EuserE [optional rule parameters] =over 2 The transparent_squid helper sets up trasparent caching for HTTP traffic. The squid proxy is assumed to be running on the firewall host at port I (I defaults to squid), with the credentials of the local user I (I defaults to squid). The transparent_squid helper can be used for two kinds of traffic: =over 2 =item * Incoming HTTP traffic Incoming HTTP traffic, which is either targeted to the firewall host or passing through the firewall host. The optional rule parameters can be used to specify which kind of incoming traffic to be catched (by using inface, src, dst, etc -- outface should not be used here, because the rules generated are placed before the routing decision and therefore the outgoing interface is not yet known). If no optional rule parameters are given, then the transparent cache will be setup on all network interfaces for all HTTP traffic (use this with care since you are risking to serve requests from the internet using your squid). =item * Locally HTTP traffic Locally generated HTTP traffic except traffic generated by processes running as user I. The optional rule parameters inface, outface and src are ignored for this type of traffic. This kind of matching makes it possible to support transparent caching for WEB browsers running on the firewall host, as far as they do not run as the user excluded. More than one users can be specified by space-separating and enclosing them in double quotes. This rule can be disabled by specifing as user the empty string: "" =back Examples: =over 2 transparent_squid 3128 squid inface eth0 src 10.0.0.0/8 transparent_squid 8080 "squid privoxy root bin" inface not "ppp+ ipsec+" dst not "a.not.proxied.server" =back =back =head2 nat EtypeE EtargetE [optional rule parameters] =over 2 The nat helper sets up a NAT rule for routed traffic. The type parameter can be: =over 2 =item to-source Defines a Source NAT (created in NAT/POSTROUTING). The I in this case is the source address to be set in packets matching the optional rule parameters (if no optional rule parameters, all forwarded traffic will be matched). I accepts all --to-source values iptables accepts (see iptables -j SNAT --help). Multiple --to-source values can be given, if separated by space and quoted as a single argument. inface should not be used in SNAT, because iptables does provide this information at this point. =item to-destination Defines a Destination NAT (created in NAT/PREROUTING). The I in this case is the destination address to be set in packets matching the optional rule parameters (if no optional rule parameters, all forwarded traffic will be matched). I accepts all --to-destination values iptables accepts (see iptables -j DNAT --help). Multiple --to-destination values can be given, if separated by space and quoted as a single argument. outface should not be used in DNAT, because iptables does provide this information at this point. =item redirect-to Catches traffic comming in and send it to the local machine (created in NAT/PREROUTING). The I in this case is a port or a range of ports (XXX-YYY) that packets matching the rule will be redirected to (if no optional rule parameters are given, all incomming traffic will be matched). I accepts all --to-ports values iptables accepts (see iptables -j REDIRECT --help). outface should not be used in REDIRECT, because iptables does provide this information at this point. =back Please understand that the optional rule parameters are used only to limit the traffic to be matched. Consider these examples: =over 2 =item Sends to 1.1.1.1 all traffic comming in or passing trhough the firewall host: nat to-destination 1.1.1.1 =item Redirects to 1.1.1.1 all traffic comming in or passing through, and going to 2.2.2.2: nat to-destination 1.1.1.1 dst 2.2.2.2 =item Redirects to 1.1.1.1 all TCP traffic comming in or passing through and going to 2.2.2.2: nat to-destination 1.1.1.1 proto tcp dst 2.2.2.2 =item Redirects to 1.1.1.1 all traffic comming in or passing through and going to 2.2.2.2 to port tcp/25: nat to-destination 1.1.1.1 proto tcp dport 25 dst 2.2.2.2 =back More examples: =over 2 nat to-source 1.1.1.1 outface eth0 src 2.2.2.2 dst 3.3.3.3 nat to-destination 4.4.4.4 inface eth0 src 5.5.5.5 dst 6.6.6.6 nat redirect-to 8080 inface eth0 src 2.2.2.0/24 proto tcp dport 80 =back =back =head2 snat [to] EtargetE [optional rule parameters] =over 2 The snat helper sets up a Source NAT rule for routed traffic, by calling nat to-source I [optional rule parameters] See the nat helper. Example: =over 2 snat to 1.1.1.1 outface eth0 src 2.2.2.2 dst 3.3.3.3 =back =back =head2 dnat [to] EtargetE [optional rule parameters] =over 2 The dnat helper sets up a Destination NAT rule for routed traffic, by calling nat to-destination I [optional rule parameters] See the nat helper. Example: =over 2 dnat to 1.1.1.1 inface eth0 src 2.2.2.2 dst 3.3.3.3 =back =back =head2 redirect [to] EtargetE [optional rule parameters] =over 2 The redirect helper catches all incomming traffic matching the optional rule parameters given and redirects it to ports on the local host, by calling nat redirect-to I [optional rule parameters] See the nat helper. Example: =over 2 nat redirect-to 8080 inface eth0 src 2.2.2.0/24 proto tcp dport 80 =back =back =head1 Actions Actions are the actions to be taken on services and traffic described by other commands and functions. Please note that normally, FireHOL will pass-through to the generated iptables statements all the possible actions iptables accepts, but only the ones defined here can be used with lower case letters and currently it will be impossible to pass arguments to some unknown action. Also, keep in mind that the iptables action LOG is a FireHOL optional rule parameter (see log and loglimit) that can be defined together with one of the following actions and FireHOL will actually produce multiple iptables statements to achieve both the logging and the action. =head2 accept =over 2 accept allows the traffic matching the rules to reach its destination. Example: =over 2 server smtp accept, to allow SMTP requests and their replies to flow. =back =back =head2 reject [with message] =over 2 reject discards the matching traffic but sends a rejecting message back to the sender. with is used to offer control on the message to be returned to the sender. with accepts all the arguments the --reject-with iptables expression accepts. For an updated list of these messages type iptables -j REJECT --help. Examples: =over 2 policy reject with host-unreach server ident reject with tcp-reset UNMATCHED_INPUT_POLICY="reject with host-prohib" =back =back =head2 drop =over 2 drop silently discards the matching traffic. The fact that the traffic is silently discarded makes the sender timeout in order to conclude that it is not possible to use the wanted service. Example: =over 2 server smtp drop, to silently discard SMTP requests and their replies. =back =back =head2 deny =over 2 deny is just an alias for drop, made for those who are used to ipchains terminology. Example: =over 2 server smtp deny, to silently discard SMTP requests and their replies. =back =back =head2 return =over 2 return will return the flow of processing to the parent of the current command. Currently, it has meaning to specify the action return only as a policy to some interface. Example: =over 2 =item policy return Traffic not matched by any rule within an interface continues traveling through the firewall and is possibly matched by other interfaces bellow. =back =back =head2 mirror =over 2 I will return the traffic to the wanted port, back to the sending host. Use this with care, and only if you understand what you doing. Keep also in mind that FireHOL will apply this action to both requests and replies comming in or passing through, and will replace it with REJECT for traffic generated by the local host. =back =head2 redirect [to-port port] =over 2 I is used internally by FireHOL Helper Commands to redirect traffic to ports on the local host. Unless you are a developer, you will never need to use this directly. =back =head1 Optional Rule Parameters Optional rule parameters are accepted by many commands to narrow the match they do by default. The parameters described bellow are all that FireHOL supports. You should check the documentation of each command to find which parameters should not be used with it. Normally, all FireHOL commands are designed so that if you specify a parameters that is also used internally, the internal one will overwrite the one given in the configuration file. In such a case, FireHOL will present you a warning with the old and the new value. Not all parameters should be used in all cases. For example I and I should not be used in normal server and client commands since such ports are internally defined by the services themselves. In any case, FireHOL will complain about optional rule parameters that should not be used in certain commands. =head2 src [not] EhostE =over 2 I defines the source IP address of the REQUEST. If I is defined on a server statement it matches the source of the request which is the remote host, while if it is defined on a client statement it matches again the source of the request, but this time it is the local host. Focus on the REQUEST!!! Forget the reply. =head3 Parameters =over 2 =item not Optional argument that reverses the match. When defined, the rule will match all hosts except the ones defined. Example: server smtp accept src not 1.2.3.4 =item I An IP address, a hostname, or a subnet. Multiple hosts/networks can be defined if separated by space and quoted as a single argument. Examples: server smtp accept src 1.2.3.4 server smtp accept src not "1.2.3.0/24 5.6.7.8 badhost.example.com" =back =back =head2 dst [not] EhostE =over 2 I defines the destination of the REQUEST. If dst is defined on a server statement it matches the destination of the request which is the local host, while if it is defined on a client statement it matches again the destination of the request, but this time it is the remote host. Focus on the REQUEST!!! Forget the reply. I accepts the same parameters as src. =back =head2 inface [not] EinterfaceE =over 2 I defines the interface the REQUEST is received via. inface cannot be used in interface commands. =head3 Parameters =over 2 =item not An optional argument that reverses the match. When defined, the rule will match all interfaces except the ones defined. Example: server smtp accept inface not eth0 =item I if an interface name in the same format the interface command accepts. Multiple interfaces can be defined if separated by space and quoted as a single argument. Examples: server smtp accept inface not eth0 server smtp accept inface not "eth0 eth1" =back =back =head2 outface [not] EinterfaceE =over 2 I defines the interface the REQUEST is send via. outface cannot be used in interface commands. I accepts the same parameters as inface. =back =head2 custom EparametersE =over 2 I passes its arguments to the generated iptables commands. It is required to quote all the parameters given to custom. If the parameters include a space character between some text that is required to be given to iptables as one argument, it is required to escape another set of quotes in order. Another way is to use double quotes externally and single quotes internally. Examples: server smtp accept custom "--some-iptables-option and_its_value" server smtp accept custom "--some-iptables-option 'one_value another_value' =back =head2 log "Esome textE" [level a_level] =over 2 I will log the matching packets to syslog. Note that this is not an action (in iptables it is). FireHOL will actually produce multiple iptables commands to accomplish both the action for the rule and the logging. You can control how logging works, by altering the variables FIREHOL_LOG_OPTIONS and FIREHOL_LOG_LEVEL. You can also change the level of just one rule by using the level argument of the log parameter. FireHOL logs traffic, exactly the same way iptables does. Many users have complained about packet logs appearing at their console. To avoid this you will have to: =over 2 =item * setup klogd to log only more important traffic =item * change FIREHOL_LOG_LEVEL to log at a not so important log-level =back Actually klogd's -c option and iptables' --log-level option are the same thing (iptables accepts also the numeric values klogd accepts). If iptables logs at a higher priority than klogd is configured to use, then your packets will appear in the console too. =back =head2 loglimit "Esome textE" =over 2 I is the same with log but limits the frequency of logging according to the setting of FIREHOL_LOG_FREQUENCY and FIREHOL_LOG_BURST. =back =head2 proto [not] EprotocolE =over 2 I sets the required protocol for the traffic. This command accepts anything iptables accepts as protocols. =back =head2 limit EfrequencyE EburstE =over 2 I will limit the match in both directions of the traffic (request and reply). This is used internally by FireHOL and its effects has not been tested in the high level configuration file directives. =back =head2 sport EportE =over 2 I defines the source port of a request. It accepts port names, port numbers, port ranges (FROM:TO) and multiple ports (or ranges) seperated by spaces and quoted as a single argument. This parameter should not be used in normal services definitions (client and server commands) or interface and router definitions, unless you really understand what you are doing. =back =head2 dport EportE =over 2 I defines the destination port of a request. It accepts port names, port numbers, port ranges (FROM:TO) and multiple ports (or ranges) seperated by spaces and quoted as a single argument. This parameter should not be used in normal services definitions (client and server commands) or interface and router definitions, unless you really understand what you are doing. =back =head2 uid [not] EuserE =head2 user [not] EuserE =over 2 I or I define the operating system user sending this traffic. The parameter can be a username, a user number or a list of these two, seperated by spaces and quoted as a single argument. This parameter can be used only in services (client and server commands) defined within interfaces, not routers. FireHOL is "smart" enough to apply this parameter only to traffic send by the localhost, i.e. the replies of servers and requests of clients. It is not possible, and FireHOL will simply ignore this parameter, on traffic coming in or passign through the firewall host. Example 1: =over 2 client "pop3 imap" accept user not "user1 user2 user3" dst mymailer.example.com =back The above will allow local users except user1, user2 and user3 to use POP3 and IMAP services on mymailer.example.com. You can use this, for example, to allow only a few of the local users use the fetchmail program to fetch their mail from the mail server. Example 2: =over 2 server http accept user apache =back The above will allow all HTTP to reach the local http server, but only if the web server is running as user apache the replies will be send back to the HTTP client. =back =head2 gid EgroupE =head2 group EgroupE =over 2 I or I define the operating system user group sending this traffic. The parameter can be a group name, a group number or a list of these two, seperated by spaces and quoted as a single argument. This parameter can be used only in services (client and server commands) defined within interfaces, not routers. FireHOL is "smart" enough to apply this parameter only to traffic send by the localhost, i.e. the replies of servers and requests of clients. It is not possible, and FireHOL will simply ignore this parameter, on traffic coming in or passing through the firewall host. =back =head2 pid EprocessE =head2 process EprocessE =over 2 I or I define the operating system process ID (or PID) sending this traffic. The parameter can be a PID or a list of PIDs, seperated by spaces and quoted as a single argument. This parameter can be used only in services (client and server commands) defined within interfaces, not routers. FireHOL is "smart" enough to apply this parameter only to traffic send by the localhost, i.e. the replies of servers and requests of clients. It is not possible, and FireHOL will simply ignore this parameter, on traffic coming in or passign through the firewall host. =back =head2 sid EsessionE =head2 session EsessionE =over 2 I or I define the operating system session ID of the process sending this traffic (The session ID of a process is the process group ID of the session leader). The parameter can be a list of such IDs, seperated by spaces and quoted as a single argument. This parameter can be used only in services (client and server commands) defined within interfaces, not routers. FireHOL is "smart" enough to apply this parameter only to traffic send by the localhost, i.e. the replies of servers and requests of clients. It is not possible, and FireHOL will simply ignore this parameter, on traffic coming in or passign through the firewall host. =back =head1 Variables that control FireHOL =head2 DEFAULT_INTERFACE_POLICY =over 2 I controls the default action to be taken on traffic not matched by any rule within an interface. Actually, this is a global setting for what policy does for an interface. All packets that reach the end of an interface are logged only if the action is not return or accept. You can control the frequency of this logging by altering the frequency loglimit uses. Default: DEFAULT_INTERFACE_POLICY="DROP" Example: DEFAULT_INTERFACE_POLICY="REJECT" =back =head2 UNMATCHED_INPUT_POLICY =head2 UNMATCHED_OUTPUT_POLICY =head2 UNMATCHED_FORWARD_POLICY =over 2 I controls the default action to be taken for incoming traffic not matched by any interface command. I controls the default action to be taken for outgoing traffic not matched by any interface command. I controls the default action to be taken for forwarded traffic not matched by any router command. All variables accept all the Actions FireHOL supports. All packets that reach the end of firewall in all three chains are logged (always, regardless of these settings). You can control the frequency of this logging by altering the frequency loglimit uses. Default: UNMATCHED_INPUT_POLICY="DROP" Default: UNMATCHED_OUTPUT_POLICY="DROP" Default: UNMATCHED_FORWARD_POLICY="DROP" Example: UNMATCHED_INPUT_POLICY="REJECT" Example: UNMATCHED_OUTPUT_POLICY="REJECT" Example: UNMATCHED_FORWARD_POLICY="REJECT" =back =head2 FIREHOL_LOG_LEVEL =head2 FIREHOL_LOG_OPTIONS =head2 FIREHOL_LOG_FREQUENCY =head2 FIREHOL_LOG_BURST =over 2 I controls the level at which iptables will log things to the syslog. For a description of the possible values supported and for per-rule control of log level, see the log optional rule parameter. I controls the way iptables will log things to the syslog. The value of this variable is passed as is to iptables, so use exact iptables parameters. I and I (added in v1.39 of FireHOL) control the frequency at each each logging rule will write packets to the syslog. FIREHOL_LOG_FREQUENCY is set to the maximum average frequency and FIREHOL_LOG_BURST specifies the maximum initial number of packets to match. Default: FIREHOL_LOG_OPTIONS="--log-level warning" Default: FIREHOL_LOG_FREQUENCY="1/second" Default: FIREHOL_LOG_BURST="5" Example: FIREHOL_LOG_OPTIONS="--log-level info --log-tcp-options --log-ip-options" Example: FIREHOL_LOG_FREQUENCY="30/minute" Example: FIREHOL_LOG_BURST="2" To see the available iptables log options, run C To see what iptables accepts as frequencies and bursts, run C You can also check man iptables. =back =head2 DEFAULT_CLIENT_PORTS =over 2 I controls the port range to be used when a remote client is specified. For localhost clients, FireHOL finds the exact client ports by querying the kernel options. Default: 1000:65535 Example: DEFAULT_CLIENT_PORTS="0:65535" =back =head2 FIREHOL_NAT =over 2 If I is set to 1, FireHOL will load NAT kernel modules for those services that they are require such. FireHOL sets this to 1 automatically if you use the Helper Commands that do NAT. Default: FIREHOL_NAT="0" Example: FIREHOL_NAT="1" =back =head2 FIREHOL_AUTOSAVE =over 2 FIREHOL_AUTOSAVE controls the file that will be created when FireHOL is called with the save command line argument. If this variable is empty (the default), FireHOL will try to detect where to save the file. Currently, the RedHat way (/etc/sysconfig/iptables) and the Debian way (/var/lib/iptables/autosave) are automatically detected (in the order given here) based on the existance of the directory this file should be created in. Default: FIREHOL_AUTOSAVE="" Example: FIREHOL_AUTOSAVE="/tmp/firehol-saved.txt" =back =head1 Variables that FireHOL offers =head2 RESERVED_IPS =over 2 This variable includes all the IP addresses defined as IANA - Reserved by IANA. Example: interface eth0 internet src not "${RESERVED_IPS}" =back =head2 PRIVATE_IPS =over 2 This variable includes all the IP addresses defined as Private or Test by RFC 3330. Example: interface eth0 internet src not "${PRIVATE_IPS}" =back =head2 UNROUTABLE_IPS =over 2 This variable is both I and I together. I suggest to use this variable on interfaces and routers accepting Internet traffic. Example: interface eth0 internet src not "${UNROUTABLE_IPS}" =back =head1 FILES F =head1 AUTHOR firehol written by Costa Tsaousis Ecosta@tsaousis.grE. Man page written by Marc Brockschmidt E. =head1 SEE ALSO firehol(1), iptables(8), bash(1) =cut firehol-1.297/prettyconf.sh000077500000000000000000000011711225731333700157260ustar00rootroot00000000000000#!/bin/bash COMMS="http://firehol.sourceforge.net/commands.html" if [ ! -f "$1" ] then echo "$0 filename" exit 1 fi CONF="/tmp/prettyconf.sed" rm -f "${CONF}" touch "${CONF}" keyword() { cat <>"${CONF}" s|^$1[[:space:]]|$1 |g s|[[:space:]]$1[[:space:]]| $1 |g EOF } keyword interface keyword router keyword server keyword client keyword route keyword protection keyword iptables keyword accept keyword reject keyword src keyword dst keyword inface keyword outface #echo >"${CONF}" "s/\//a/g" #echo >>"${CONF}" "s/e/a/g" cat $1 | sed -f "${CONF}" cat "${CONF}"