pax_global_header00006660000000000000000000000064142350025610014510gustar00rootroot0000000000000052 comment=6fcf3c7784595764f1b51e3b652830ba0d6f2616 MaxKellermann-ferm-ac22aa2/000077500000000000000000000000001423500256100156525ustar00rootroot00000000000000MaxKellermann-ferm-ac22aa2/.gitignore000066400000000000000000000001551423500256100176430ustar00rootroot00000000000000.dotest *~ \#*# .#* .stgit* build doc/ferm.1 doc/ferm.html doc/ferm.txt doc/import-ferm.1 ferm.service *.tmp MaxKellermann-ferm-ac22aa2/.travis.yml000066400000000000000000000002471423500256100177660ustar00rootroot00000000000000env: global: - MAKEFLAGS="-j 2" language: perl perl: - "5.30" - "5.26" - "5.24" install: - cpanm --notest Net::DNS::Resolver::Mock script: make check MaxKellermann-ferm-ac22aa2/AUTHORS000066400000000000000000000025001423500256100167170ustar00rootroot00000000000000Authors of this package * Max Kellermann * Auke Kok People who contributed to this package * Marc A. Volovic * Gergely Tamas * Daniel R. Bidwell * Yannick Le Briquer * John Auer * Klaus Lichtenwalder * Friedrich Lobenstock * Nick K. Kozubsky * Tommi Virtanen * Bastian Hoyer * Glenn Zenker * Carl D. Roth * Alexander Demenshin * Arjan Filius * Oivvio Polite * Andras Korn * Brian Manning * Kelly Martin * David Coe * Thomas Zeeman * Matthias Zeeman * Leonard Michlmayr * Dave Baker * Wolf-Agathon Schal * Boris Zentner * Florian Friesdorf <42ff@gmx.net> * Julien Soula * Maximilian Gass * Marc Haber * Faidon Liambotis And many, many more... MaxKellermann-ferm-ac22aa2/COPYING000066400000000000000000000432541423500256100167150ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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) year 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 Lesser General Public License instead of this License. MaxKellermann-ferm-ac22aa2/Makefile000066400000000000000000000127621423500256100173220ustar00rootroot00000000000000# # Makefile for ferm # TOPDIR = . include $(TOPDIR)/config.mk VERSION := $(shell $(PERL) src/ferm --version | awk '{print $$2}' | head -1 | tr -d ',') DISTDIR = build/ferm-$(VERSION) .PHONY: all clean all: doc/ferm.txt doc/ferm.html doc/ferm.1 doc/import-ferm.1 ferm.service clean: rm -rf build rm -f doc/ferm.txt doc/ferm.html doc/ferm.1 doc/import-ferm.1 *.tmp rm -f ferm.service ferm.service: ferm.service.in sed 's|@prefix@|$(PREFIX)|g' $< > $@ # # documentation # doc/ferm.txt: doc/ferm.pod pod2text $< > $@ doc/ferm.html: doc/ferm.pod pod2html $< --title="ferm - Firewall rules made easy" --flush > $@ doc/ferm.1: doc/ferm.pod pod2man --section=1 --release="ferm $(VERSION)" \ --center="FIREWALL RULES MADE EASY" \ --official $< > $@ doc/import-ferm.1: src/import-ferm pod2man --section=1 --release="ferm $(VERSION)" \ --center="FIREWALL RULES MADE EASY" \ --official $< > $@ # # test suite # STAMPDIR = $(TOPDIR)/build/test STAMPDIR_20 = $(TOPDIR)/build/test2 # a list of all ferm scripts which should be tested with iptables FERM_SCRIPTS = FERM_SCRIPTS += $(wildcard test/modules/*.ferm) $(wildcard test/targets/*.ferm) FERM_SCRIPTS += $(wildcard test/protocols/*.ferm) $(wildcard test/misc/*.ferm) FERM_SCRIPTS += $(wildcard test/glob/*.ferm) FERM_SCRIPTS += $(wildcard test/ipv6/*.ferm) FERM_SCRIPTS += $(wildcard test/resolve/*.ferm) FERM_SCRIPTS += $(wildcard test/arptables/*.ferm) $(wildcard test/ebtables/*.ferm) EXCLUDE_IMPORT = IMPORT_SCRIPTS = $(filter-out $(EXCLUDE_IMPORT) test/arptables/% test/ebtables/%,$(FERM_SCRIPTS)) PRESERVE_SCRIPTS += $(wildcard test/preserve/*.ferm) # just a hack RESULT_SED += -e 's,--protocol,-p,g' RESULT_SED += -e 's,--in-interface,-i,g' RESULT_SED += -e 's,--out-interface,-o,g' RESULT_SED += -e 's,--destination ,-d ,g' RESULT_SED += -e 's,--source ,-s ,g' RESULT_SED += -e 's,--match ,-m ,g' RESULT_SED += -e 's,--jump,-j,g' RESULT_SED += -e 's,--goto,-g,g' RESULT_SED += -e 's,--fragment,-f,g' RESULT_SED += -e '/^\#/d' EB_ARP_RESULT_SED = -e 's,--jump,-j,g' $(STAMPDIR)/test/arptables/%.result: test/arptables/%.ferm src/ferm @mkdir -p $(dir $@) $(PERL) src/ferm --test --slow $< |sed $(EB_ARP_RESULT_SED) >$@ $(STAMPDIR)/test/ebtables/%.result: test/ebtables/%.ferm src/ferm @mkdir -p $(dir $@) $(PERL) src/ferm --test --slow $< |$(PERL) test/ebtables_tempfile_rename.pl |sed $(EB_ARP_RESULT_SED) >$@ $(STAMPDIR)/%.result: %.ferm src/ferm test/sort.pl @mkdir -p $(dir $@) $(PERL) src/ferm --test --slow --noflush $< |$(PERL) test/sort.pl |sed $(RESULT_SED) >$@ $(STAMPDIR)/%.SAVE: %.ferm src/ferm test/sort.pl @mkdir -p $(dir $@) $(PERL) src/ferm --test $< |$(PERL) test/sort.pl >$@ $(STAMPDIR)/%.IMPORT: $(STAMPDIR)/%.SAVE src/import-ferm $(PERL) src/import-ferm $< >$@ $(STAMPDIR)/%.SAVE2: $(STAMPDIR)/%.IMPORT src/ferm test/sort.pl $(PERL) src/ferm --test --fast $< |$(PERL) test/sort.pl >$@ $(STAMPDIR)/%.sort: %.result test/sort.pl @mkdir -p $(dir $@) $(PERL) test/sort.pl <$< >$@ $(STAMPDIR)/%.check: $(STAMPDIR)/%.sort $(STAMPDIR)/%.result diff -u $^ @touch $@ $(STAMPDIR)/%.check-import: $(STAMPDIR)/%.SAVE $(STAMPDIR)/%.SAVE2 diff -u $^ @touch $@ $(STAMPDIR)/test/preserve/%.preserved: test/preserve/%.ferm src/ferm test/sort.pl $(STAMPDIR)/test/mock/preserve.SAVE2 @mkdir -p $(dir $@) $(PERL) src/ferm --test --test-mock-previous=ip=$(STAMPDIR)/test/mock/preserve.SAVE2 $< |$(PERL) test/sort.pl |sed $(RESULT_SED) >$@ $(STAMPDIR)/test/preserve/%.expected: test/preserve/%.result @mkdir -p $(dir $@) sed $(RESULT_SED) $< >$@ $(STAMPDIR)/test/preserve/%.check-preserve: $(STAMPDIR)/test/preserve/%.preserved $(STAMPDIR)/test/preserve/%.expected diff -u $^ @touch $@ .PHONY : check-ferm check-import check check-ferm: $(patsubst %.ferm,$(STAMPDIR)/%.check,$(FERM_SCRIPTS)) check-import: $(patsubst %.ferm,$(STAMPDIR)/%.check-import,$(IMPORT_SCRIPTS)) check-preserve: $(patsubst %.ferm,$(STAMPDIR)/%.check-preserve,$(PRESERVE_SCRIPTS)) check: check-ferm check-import check-preserve @echo "All ferm unit tests finished successfully." # # distribution # .PHONY: dist build/ferm-$(VERSION).tar.gz: all rm -rf $(DISTDIR) install -d -m 755 $(DISTDIR) $(DISTDIR)/src $(DISTDIR)/doc $(DISTDIR)/examples install -m 755 src/ferm src/import-ferm $(DISTDIR)/src install -m 644 ferm.service $(DISTDIR) install -m 644 doc/ferm.pod doc/ferm.txt doc/ferm.html doc/ferm.1 doc/import-ferm.1 $(DISTDIR)/doc install -m 644 config.mk Makefile AUTHORS COPYING NEWS README.rst TODO $(DISTDIR) install -m 644 $(wildcard examples/*.ferm) $(DISTDIR)/examples cd build && tar czf ferm-$(VERSION).tar.gz ferm-$(VERSION) dist: build/ferm-$(VERSION).tar.gz # # installation # .PHONY: install uninstall install: all install -d -m 755 $(DOCDIR)/examples $(PREFIX)/sbin $(SERVICEDIR) install -m 644 AUTHORS COPYING NEWS README.rst TODO $(DOCDIR) install -m 644 examples/*.ferm $(DOCDIR)/examples install -m 755 src/ferm src/import-ferm $(PREFIX)/sbin/ install -m 644 ferm.service $(SERVICEDIR) install -d -m 755 $(DOCDIR) $(MANDIR) install -m 644 doc/ferm.txt doc/ferm.html $(DOCDIR) install -m 644 doc/ferm.1 doc/import-ferm.1 $(MANDIR) gzip -f9 $(MANDIR)/ferm.1 $(MANDIR)/import-ferm.1 uninstall: rm -rf $(DOCDIR) rm -f $(MANDIR)/ferm.1 $(MANDIR)/import-ferm.1 rm -f $(SERVICEDIR)/ferm.service rm -f $(PREFIX)/sbin/ferm $(PREFIX)/sbin/import-ferm # # misc targets # .PHONY: upload upload: doc/ferm.html scp NEWS doc/ferm.html foo-projects.org:/var/www/ferm.foo-projects.org/download/2.5/ scp examples/*.ferm foo-projects.org:/var/www/ferm.foo-projects.org/download/examples/ MaxKellermann-ferm-ac22aa2/NEWS000066400000000000000000000537341423500256100163650ustar00rootroot00000000000000 CHANGES version history for ferm Max Kellermann Auke Kok v2.7 - 5 May 2022 - updated netfilter modules: - MASQUERADE: support "--random-fully" - support nfacct module - fix @resolve() wrapped in @ipfilter() and @cat() - fix @resolve() with empty result v2.6 - 30 Jan 2021 - apply $PREFIX to systemd service file during install - support netfilter targets: * JOOL, JOOL_SIIT (out-of-tree) - updated netfilter modules: * CT: support "--zone-orig", "--zone-reply" - fix (deferred) functions within target arguments - "@preserve" supports regular expressions - fix negated @ipfilter/@resolve - @resolve filters out numeric IP addresses for the wrong domain - @resolve allows numeric IP address with netmask prefix v2.5.1 - 24 Jan 2020 - adjust multiport splicing for port ranges - fix lazy subchain protocol propagation for all protocols - default to --fast when Getopt::Long is not installed - fix $LINE after function call - add shortcuts "sports", "dports", "comment" v2.5 - 22 Nov 2019 - support netfilter targets: - RTPENGINE - updated netfilter modules: * ipv4options * time: support "--kerneltz", remove "--localtz" - make chain name length validation an error not a warning - support empty NOERROR responses in @resolve - use atomic table update with ebtables - fix $TABLE and $CHAIN evaluation in multi-table/multi-chain rules - copy protocol specification to subchains only if needed - make @resolve dual stack - allow passing arrays to @cat - add function @join - call "legacy" xtables tools because nft based tools are incompatible v2.4.1 - 1 Aug 2017 - updated netfilter modules: * SYNPROXY: rename "timestamps" back to "timestamp" * recent: "--mask" has a value v2.4 - 2 Apr 2017 - support netfilter match modules: * cgroup - updated netfilter modules: * recent: add mask, reap - sort domains and tables in --fast output - "@preserve" preserves existing chains - import-ferm: translate "-f" to "fragment" v2.3.1 - 5 Jan 2017 - support netfilter match modules: * devgroup * geoip * socket - updated netfilter modules: * connlimit: add connlimit-upto, connlimit-saddr, connlimit-daddr * set: add return-nomatch, update-counters, update-subcounters, packets-eq, packets-lt, packets-gt, bytes-eq, bytes-lt, bytes-gt * SYNPROXY: rename "timestamp" to "timestamps" * TPROXY: add on-ip - @resolve returns IP addresses as-is - import-ferm: Perl 5.24 compatibility v2.3 - 30 Mar 2016 - rename "realgoto" to "goto" - new keyword @gotosubchain - new functions @defined, @glob - support netfilter match modules: * bpf * connlabel * cpu * dst * ipvs * rpfilter - support netfilter targets: * CHECKSUM * CONNMARK: support set-xmark, nfmask, and-mark, or-mark, xor-mark * DNPT * HMARK * IDLETIMER * LED * NFQUEUE: support queue-balance, queue-bypass, queue-cpu-fanout * RATEEST * SET: support timeout, exist * SNPT * TCPOPTSTRIP - recognize BROUTING as built-in chain (for ebtables) - check exit status of included shell commands - documentation * fixed wrongly used quotation marks in piped @include example v2.2 - 1 Jul 2013 - support netfilter modules: * CT * TEE - automatically apply @ipfilter on dual-stack config v2.1.2 - 17 Dec 2012 - support netfilter modules: * osf - updated netfilter modules: * hashlimit: allow list after hashlimit-mode - fix functions containing mixed domains - check function parameter types - allow policy QUEUE and RETURN - support setting policy of non-builtin chains v2.1.1 - 29 Jul 2012 - updated netfilter modules: * conntrack: support ctorigsrcport, ctorigdstport - new netfilter modules: * TPROXY target - allow folding @resolve value into a string v2.1 - 17 Jul 2011 - new functions @basename, @dirname, @ipfilter - add automatic variables $FILENAME, $LINE - updated netfilter modules: * pkg-type: support negation * set: "--match set" support for newer iptables - updated ebtables support: * use per-protocol options * add support for -p ARP --arp-gratuitous * support abbreviations in arguments * add support for matching IPv6 * add support for "among" match * add support for the "limit" match - honor --noflush in fast mode - discard previous specifications when @if fails - use the --domain argument as the default domain - keep track of line numbers within custom function calls v2.0.9 - 26 Feb 2011 - updated netfilter modules: * state: support negation * icmp: translate "icmp-type" to "icmpv6-type" in domain "ip6" - add functions @cat, @substr, @length - subchain names can now be expanded - import-ferm: support empty string parameters v2.0.8 - 4 Nov 2010 - added automatic variable $DIRNAME - implement confirmation/rollback for --shell --interactive - added the "type" parameter to @resolve() - new functions @eq, @ne, @not - updated netfilter modules: * ebtables/snat: support --snat-arp - add parameter --timeout for rollback v2.0.7 - 2 Jan 2010 - fix post and flush hooks with --lines - always prefix the negation operator - updated netfilter modules: * addrtype: support negation and --limit-iface-{in,out} * conntrack: support negation and --ctdir * owner: support negation and --socket-exists * policy: support negation v2.0.6 - 18 Jul 2009 - support negation in mark/connmark - support negation in set - added automatic variable $FILENAME - allow @subchain as the first keyword in a closure - don't allow semicolon after empty rule - enable @include to run a program - removed superfluous tokens from error message - create a new stack frame for @subchain (fixes $CHAIN) v2.0.5 - 28 Feb 2009 - detect double negation - improved detection of negated arrays - ignore dpkg's backup/temporary files on @include - renamed "hook" to "@hook" - disable "pre" and "post" hooks with --flush - added "flush" hooks v2.0.4 - 2 Dec 2008 - enable policy-only domains (no rules, just policy declarations) - don't list custom chains in --flush --fast mode v2.0.3 - 30 Sep 2008 - create chains and subchains even if they are empty - fix includes within a rule ("Missing semicolon...") - fix subchain in include ("Died at [...] line 1493") - "protocol" is an alias for "proto", to fix the keyword conflict with the "policy" module v2.0.2 - 26 Jul 2008 - allow duplicate specification of "table" and "chain", for better 1.3.x compatibility. Support for this will be removed in a later release. This does not apply to "domain". v2.0.1 - 24 Jul 2008 - generate "COMMIT" lines when flushing in fast mode - don't hard-code the path of iptables-save - install manpages in PREFIX/share/man v2.0 - 22 Jul 2008 - don't hard code built-in match modules - support for arptables and ebtables - removed support for deprecated ferm 1.1 syntax - removed the "set" and the "option" keyword - removed support for array-in-string - cleared the deprecated keyword translation table - removed TOS parameter shortcuts - don't default to policy if no action is specified - don't allow lower case built-in chain or policy names - removed --automod, --use, --clearall, --flushall, --flushchains, --createchains, --location, --debug, --verbose - comma in array is forbidden - removed "source" and "destination" as prefix for "addr" and "port" - don't allow match rules before and after "policy" - removed support for deprecated netfilter modules - dst - frag - iplimit - rewrote the internal rule storage - honor the order of match modules - import-ferm rewrite - use module data from ferm - write policy in chain block - do not generate implicit protocol modules - do not allow targets options after "jump" - fixed rollback when there is no iptables-save - enable fast mode by default, can be disabled with --slow v1.3.5 - 21 Jul 2008 - don't ignore unknown keywords after target (reported by Kai Sassmannshausen) - don't include hidden files (reported by Florian Reitmeir) v1.3.4 - 28 May 2008 - fixed single quote escaping - escape empty strings - reset module list after semicolon handler (reported by Ralph Oesker) - import-ferm: ignore the position of the negation marker; this allows us to parse invalid save files generated by iptables-save (reported by Andri Moell) - fixed REDIRECT example in the manual v1.3.3 - 22 Jan 2008 - updated netfilter modules: * recent: support --rsource, --rdest * time: support --monthday, --weekdays, --utc, --localtz * u32: support negated --u3 * DNAT: support --random * MARK: support --set-xmark, --and-mark, --or-mark, --xor-mark * MASQUERADE: support --random * REDIRECT: support --random * SNAT: support --random * TOS: support --and-tos, --or-tos, --xor-tos - check if chain was specified before @subchain - suppress "not declared" warnings on empty custom chains v1.3.2 - 19 Dec 2007 - bugfix: emit "--proto" instead of "--protocol" for xt_policy "proto" - bugfix: handle array after DNAT/to-destination correctly - target options cannot have arrays by default - support netfilter modules: * ipv4options * string - support netfilter targets: * CLASSIFY (documentation) * CLUSTERIP * IPV4OPTSSTRIP * SAME (--random, documentation) v1.3.1 - 9 Dec 2007 - require IO::Handle, this fixes the interactive mode - configure test mode properly when running on microperl v1.3 - 6 Dec 2007 - reserve tokens starting with "@" as ferm keywords - implemented conditionals with @if/@else - added @include/@def/@subchain as alias to include/def/subchain - redirect STDOUT into STDERR --shell mode; this way, iptables warnings are separated from the ferm shell script output - microperl compatibility: - don't require strict.pm / vars.pm - don't use IO::File - added simple Getopt::Long emulation - look for iptables in PATH - added function @resolve which resolves host names to IPv4 addresses - import-ferm supports ip6tables-save files - support "proto icmp" in the ip6 domain - make "goto" deprecated to remap it to "--goto" later - implemented "--goto" support, keyword is "realgoto" - don't default to policy if rule action is missing - support protocol modules * mh * udplite (sport, dport, mod multiport) - support netfilter modules: * connbytes * connlimit * u32 - support netfilter targets: * CONNSECMARK * SECMARK - abort when there is an unrecognized command line option (reported by Han Holl) - import-ferm: don't generate NOP action before a block - import-ferm: quote array values - quote the ampersand v1.2.5 - 14 Oct 2007 - make --flush do something in fast mode (reported by Hans-Georg Bork) - fix automatic protocol modules when used in an expanded array (reported by Ralph Oesker) v1.2.4 - 24 May 2007 - support netfilter modules: * hashlimit * ipset (patch by Martin Schuster) - ignore empty lines in backticks result (reported by Martin Klozik) - the match module for protocol "icmpv6" is named "icmp6" - implemented basic hooks (suggested by Joerg Jaspert) - documentation: * targets CONNMARK v1.2.3 - 14 Feb 2007 - subchains may be named - don't copy module references to subchain (patch by Alex Metelka) - override variables on the command line with "--def" - auto-load modules only when their parameters are used - documentation: * targets MIRROR, NETMAP, NFQUEUE, NOTRACK, QUEUE v1.2.2 - 15 Nov 2006 - documentation: * warn against using iptables 1.2 with import-ferm * extended the transition section in the manpage - support netfilter modules: account - bugfix: don't clear variable value when used as parameter in multiport/destination-ports (reported by Bill Goudie) v1.2.1 - 25 Sep 2006 - bugfix: reset domains after all rules were parsed and don't forget to reset a table; this bug only affects users who run ferm on a remote machine - reset policy on all guessed built-in chains if no authoritative information about built-in chains is available - support netfilter modules: condition, fuzzy, hbh, hl, ipv6header, rt, quota, HL - extended module support * ah now supports the IPv6 options - added missing documentation * target ECN * match modules: dst, eui64, frag - disabled array after ttl-lt, ttl-gt - allow "length", "physdev", "tos" negation - translate sports, dports to source-ports, destination-ports in import-ferm - added the "--remote" option v1.2 - 13 Sep 2006 - import-ferm runs iptables-save if no input file is provided v1.2beta2 - 9 Sep 2006 - added --flush - added --shell which generates a shell script - don't check available netfilter modules - read iptables-save in initialize_netfilter() - option --location is deprecated, ferm now calls /sbin/iptables - whitespace fix in import-ferm - allow late chain/table specification again - set a second alarm in the confirmation dialog - enable rollback feature even in non-interactive mode v1.2beta1 - 28 Aug 2006 - perl strict mode - removed support for ipfwadm and ipchains - get a list of netfilter table names from /proc/net/ip_tables_names - error messages go to STDERR - full support for the match extensions: recent, comment, conntrack, addrtype, ah, owner, time, dscp, ecn, helper, iprange, iplimit, length, multiport, physdev, policy, realm, tcpmss, dst, frag - full support for the targets: BALANCE, CLASSIFY, CONNMARK, NETMAP, ROUTE, SNAT, TARPIT, NFQUEUE, SAME, DSCP - support the protocols: dccp, sctp - implemented variables and functions with 'def' * variables and functions are local to their containing block - stricter syntax checks, e.g.: * some built-in targets must be uppercase * only one target is allowed * target parameters are only recognized after the target name, protocol parameters only after the protocol match etc. * referenced variables must exist * list item negation is not possible * only ACCEPT and DROP are allowed as policy * tables and chains must be specified first - deprecated syntax: * using a policy as default target for a rule * target MASQ, use MASQUERADE instead * lower-case built-in chain names and targets * lists must be specified with parentheses and no commas (old syntax is deprecated, but still supported) * variables declared with 'set' and referenced with '%NAME' * many shortcuts like 'mac' and 'tosrc' * shortcuts without the dash like 'tcpflags' ('tcp-flags') * "option iptables"; only iptables is supported * source/destination * option automod * policy within a rule declaration - fixed the double-module bug - show filename and line number in error message - implemented the 'include' command - more shortcuts for command line options - better set-tos parameter parser - reimplemented backticks - reimplemented tokenizer and parser - escape shell parameters - warn about unused custom chains - ignore empty rules - options --clearall, --createchains are implied and deprecated - options --debug and --verbose are deprecated - reset all policies to ACCEPT - variables expansion happens within double quotes - implemented automatic variables: $TABLE, $CHAIN - IPv6/ip6tables support - raw table support - print line number when iptables reports an error - write error messages to STDERR - replaced the old samples with new ones - check which match and target modules are available - generate output iptables-save format when --fast is specified - semi-automatic sub chains with the 'subchain' keyword - support tcp-flags negation - added interactive mode v1.1 - 5 May 2003 - Removed 'mark' as possible target due to nameclash - Fixed typo in tos values with missing space - Added support for shell escapes - Updated manual page - Fixed bug with ! before variable lists - Added support for multiple variables inside a value - Changed variable character from '$' to '%' to allow system variables - Split up the pod stuff from the ferm source - Fixed word splitter to more a serious approach - Removed internal proxy variable, replaced with 'to' and 'toports' for clarity - Removed the 'relaxed' option, for it wasn't used at it's potential (once) - Added location option for the meek - Have ferm prescan input to look for the kernel program and location - Modified $(DOCDIR) to /usr/share/doc/ferm - Added debug (--debug or -d) parameter for even more output - Added --length,ttl, ttl[set|inc|dec] and ttl-[eq|lt|gt], --[every|counter|start|packet], --average, --pkt-type, --string --time[start|stop] and --days, ip-limit-[above|mask] --psd-[weight-threshold|delay-threshold|[lo|hi]-ports-weight] --to-[source|ports|destination], --set-ftos - Added BALANCE, FTOS, SAME, TCPMSS targets and more - Fixed bug on log/goto combination (missing space) -debian bugs - Allow lists in set statements -debian bugs - Added several patches from misc sources (thanks everyone) - Cleaned up order of builtin targets (now alphabetically ordered) v1.0pl8 - 13 july 2001 - Fixed nonexistent parameter values for log-[ip|tcp]-... - Made keyword pattern matching strict, better for finding typo's - Added NOP action (for match-counting) - Added option automodule for automatically loading correct modules - Fixed -m for mark in iptables mixo - Fixed relaxed matching tos values, still relaxed now though - Fixed mark missing as normal target - Added variable support - Updated manual page partly v1.0pl7 - 21 may 2001 - Added support for multiple modules v1.0pl6 - 19 may 2001 - Fixed wrongly flushing of chains - Fixed bug which infected policies already set - Updated manual to distinguish between 'log' and 'LOG' - Fixed lower case mismatching targets due to faulty substring expression matching v1.0pl5 - 16 may 2001 - Fixed policy keyword bug - Added consistency check for missing semicolons before section closing - Fixed flushall target for multiple tables - Reworked policy system to allow multiple policy settings for single chains - Changed syntax to allow "--state A,B", adapted "--tcp-flags" syntax to do exactly the same (see manual) v1.0pl4 - 11 may 2001 - Fixed order of TOS targets/params for iptables - Added correct flushing in combination with policy-setting only - Stripped trailing spaces on rule - Fixed a small grammar error in description - Removed SNAT and DNAT as valid policy targets - Added QUEUE, MARK, MIRROR and RETURN as valid (policy) targets - Added PRE/POSTROUTING chains as valid for policy - Added set-mark parameter, moved 'mark' in ipchains to 'setmark' - Added MASQUERADE syntax for iptables v1.0pl3 - 9 may 2001 - Fixed DENY rule appearing uncapitalized v1.0pl2 - 8 may 2001 - Added support for SNAT and DNAT targets - Added support for the tcp-flags option v1.0pl1 - 3 May 2001 - Fixed redirection to host vs port in iptables section - Fixed chain clearing in all tables - Switched to Makefiles for install & uninstall script v1.0 - 2 May 2001 - Fixed iptables addr/port combination errors (iptables lacks ipchains shorthand method for this) - Removed 'reverse' for iptables (misses capability) - Added filter and nat cleaning for 'clearall' option - Major update on chain-administration in iptables v0.0.18 - 18 Apr 2001 - Fixed two minor bugs (typo/parm ordering) - Added ttl-* options for iptables - Fixed log-tcp-*, which don't want parameters - Return of default kernel program, now checked for at first rule generation moment. Default is ipchains (again) - Added PRE- and POSTROUTING targets for iptables v0.0.17 - 19 Feb 2001 - Added better literal string handling enclosed in quotes - Added "module" parameter for iptables - Added "LOG" target for iptables, the "log" option still works the old way, so "proto tcp log ACCEPT;" works fine - Fixed table parameter in clearing/policy/creation of chains - Added a special iptables example - Added support for "! syn" and "! fragment" syntax - Fixed fragment parameter bug v0.0.16 - 12 Feb 2001 - Fixed default ipchains option- removed the default kernel interface program - Fixed 5 iptables/ipchains copy-paste typo's v0.0.15 - 7 Feb 2001 - Added possibility of "" parameters including spaces and special characters, handy for 'log-prefix' - Fixed minor 'rejectt' bug - Added a realistic ferm config example - Fixed iptables log error (Klaus Lichtenwalder) v0.0.14 - 28 Jan 2001 - Fixed tos and set-tos parameter switches for iptables - Added install script - Updated manual page to reflect changes in 0.0.13 - Fixed flushing/clearing in iptables v0.0.13 - 10 Jan 2001 - Improved iptables support: the following parameters: * table, out-interface, tcp-option, mac-source, limit, limit-burst, all owner-parameters, state, logging options, reject-with - Changed 'tos' into 'settos' to allow 'tos' matching in iptables - Implemented the ! operator, partly by John Auer v0.0.12 - 8 Jan 2001 - Fixed an incredibly stupid bug created in 0.0.11 v0.0.11 - 5 Jan 2001 - Fixed a lot of silly bugs with the policy system (uc/lc, wrong targets) - Allows empty files v0.0.10 - 4 Jan 2001 - Policy can now be specified as a single statement, like "chain input policy ACCEPT;", allowing policies to be shut down and opened in the process of loading - Added the 'reverse' option - Fixed fqdn specification (Yannick Le Briquer) - Package contains man page in html v0.0.9 - 14 Dec 2000 - REDIRECT option corrected, you can now specify the port number that you are redirecting to (D. Bidwell) - Added basic iptables support - fixed typo error between 's' and 'd' for portspec - Updated manual page v0.0.8 - 12 Dec 2000 - initial release, features: * ipchains support * ipfwadm support * complete man page * examples MaxKellermann-ferm-ac22aa2/README.rst000066400000000000000000000040171423500256100173430ustar00rootroot00000000000000ferm README =========== Description ----------- ferm is a frontend for ``iptables``. It reads the rules from a structured configuration file and calls iptables(8) to insert them into the running kernel. ferm's goal is to make firewall rules easy to write and easy to read. It tries to reduce the tedious task of writing down rules, thus enabling the firewall administrator to spend more time on developing good rules than the proper implementation of the rule. To achieve this, ferm uses a simple but powerful configuration language, which allows variables, functions, arrays, blocks. It also allows you to include other files, allowing you to create libraries of commonly used structures and functions. ferm, pronounced "firm", stands for "For Easy Rule Making". Installing ferm --------------- make install The package does not need to be compiled, just make sure you have ``perl`` (which is present in any base Linux system) and ``iptables`` (including ``iptables-save`` and ``iptables-restore``), and a kernel supporting ``netfilter``. Run the make install script as root to install the package in its best location so it can be reached from the command line when called. The manual page will also be installed. That's all! Uninstalling ferm ----------------- make uninstall Ferm can now be quickly removed from the system by issuing a "make uninstall" command (as root, of course). This will not remove any configuration files of course! Getting started --------------- The ferm(1) man page provides extensive documentation about the ferm syntax. To get started, try one of the example files, and modify it for your needs. If your machine is already firewalled and you wish to switch to ferm, the ``import-ferm`` script comes handy. It converts the current firewall rules to a ferm configuration file: import-ferm > /etc/ferm/ferm.conf After that, let ferm install the new ruleset: ferm /etc/ferm/ferm.conf Be careful, don't lock yourself out of remote machines! Use the interactive mode (``--interactive``, ``-i``) often! MaxKellermann-ferm-ac22aa2/TODO000066400000000000000000000001261423500256100163410ustar00rootroot00000000000000TODO ==== Roadmap for ferm 3.0 -------------------- * support tc (traffic control) MaxKellermann-ferm-ac22aa2/config.mk000066400000000000000000000002111423500256100174420ustar00rootroot00000000000000PERL = perl PREFIX = /usr SERVICEDIR = $(PREFIX)/lib/systemd/system MANDIR = $(PREFIX)/share/man/man1 DOCDIR = $(PREFIX)/share/doc/ferm MaxKellermann-ferm-ac22aa2/doc/000077500000000000000000000000001423500256100164175ustar00rootroot00000000000000MaxKellermann-ferm-ac22aa2/doc/ferm.pod000066400000000000000000001533521423500256100200650ustar00rootroot00000000000000# # ferm pod manual file # # # ferm, a firewall setup program that makes firewall rules easy! # # Copyright 2001-2021 Max Kellermann, Auke Kok # # Bug reports and patches for this program may be sent to the GitHub # repository: L # # # 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., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301 USA. # =head1 NAME B - a firewall rule parser for linux =head1 SYNOPSIS B I I =head1 DESCRIPTION B is a frontend for B. It reads the rules from a structured configuration file and calls iptables(8) to insert them into the running kernel. B's goal is to make firewall rules easy to write and easy to read. It tries to reduce the tedious task of writing down rules, thus enabling the firewall administrator to spend more time on developing good rules than the proper implementation of the rule. To achieve this, B uses a simple but powerful configuration language, which allows variables, functions, arrays, and blocks. It also allows you to include other files, allowing you to create libraries of commonly used structures and functions. B, pronounced "firm", stands for "For Easy Rule Making". =head1 CAUTION This manual page does I intend to teach you how firewalling works and how to write good rules. There is already enough documentation on this topic. =head1 INTRODUCTION Let's start with a simple example: chain INPUT { proto tcp ACCEPT; } This will add a rule to the predefined input chain, matching and accepting all TCP packets. Ok, let's make it more complicated: chain (INPUT OUTPUT) { proto (udp tcp) ACCEPT; } This will insert 4 rules, namely 2 in chain input, and 2 in chain output, matching and accepting both UDP and TCP packets. Normally you would type this: iptables -A INPUT -p tcp -j ACCEPT iptables -A OUTPUT -p tcp -j ACCEPT iptables -A INPUT -p udp -j ACCEPT iptables -A OUTPUT -p udp -j ACCEPT Note how much less typing we need to do? :-) Basically, this is all there is to it, although you can make it quite more complex. Something to look at: chain INPUT { policy ACCEPT; daddr 10.0.0.0/8 proto tcp dport ! ftp jump mychain sport :1023 TOS 4 settos 8 mark 2; daddr 10.0.0.0/8 proto tcp dport ftp REJECT; } My point here is, that *you* need to make nice rules, keep them readable to you and others, and not make it into a mess. It would aid the reader if the resulting firewall rules were placed here for reference. Also, you could include the nested version with better readability. Try using comments to show what you are doing: # this line enables transparent http-proxying for the internal network: proto tcp if eth0 daddr ! 192.168.0.0/255.255.255.0 dport http REDIRECT to-ports 3128; You will be thankful for it later! chain INPUT { policy ACCEPT; interface (eth0 ppp0) { # deny access to notorious hackers, return here if no match # was found to resume normal firewalling jump badguys; protocol tcp jump fw_tcp; protocol udp jump fw_udp; } } The more you nest, the better it looks. Make sure the order you specify is correct, you would not want to do this: chain FORWARD { proto ! udp DROP; proto tcp dport ftp ACCEPT; } because the second rule will never match. The best way is to first specify everything that is allowed, and then deny everything else. Look at the examples for more good snapshots. Most people do something like this: proto tcp { dport ( ssh http ftp ) ACCEPT; dport 1024:65535 ! syn ACCEPT; DROP; } =head1 STRUCTURE OF A FIREWALL FILE The structure of a proper firewall file looks like simplified C-code. Only a few syntactic characters are used in ferm- configuration files. Besides these special characters, ferm uses 'keys' and 'values', think of them as options and parameters, or as variables and values, whatever. With these words, you define the characteristics of your firewall. Every firewall consists of two things: First, look if network traffic matches certain conditions, and second, what to do with that traffic. You may specify conditions that are valid for the kernel interface program you are using, probably iptables(8). For instance, in iptables, when you are trying to match TCP packets, you would say: iptables --protocol tcp In ferm, this will become: protocol tcp; Just typing this in ferm doesn't do anything, you need to tell ferm (actually, you need to tell iptables(8) and the kernel) what to do with any traffic that matches this condition: iptables --protocol tcp -j ACCEPT Or, translated to B: protocol tcp ACCEPT; The B<;> character is at the end of every ferm rule. Ferm ignores line breaks, meaning the above example is identical to the following: protocol tcp ACCEPT; Here's a list of the special characters: =over 8 =item B<;> This character finalizes a rule. Separated by semicolons, you may write multiple rules in one line, although this decreases readability: protocol tcp ACCEPT; protocol udp DROP; =item B<{}> The nesting symbol defines a 'block' of rules. The curly brackets contain any number of nested rules. All matches before the block are carried forward to these. The closing curly bracket finalizes the rule set. You should not write a ';' after that because that would be an empty rule. Example: chain INPUT proto icmp { icmp-type echo-request ACCEPT; DROP; } This block shows two rules inside a block, which will both be merged with anything in front of it so you will get two rules: iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT iptables -A INPUT -p icmp -j DROP There can be multiple nesting levels: chain INPUT { proto icmp { icmp-type echo-request ACCEPT; DROP; } daddr 172.16.0.0/12 REJECT; } Note that the 'REJECT' rule is not affected by 'proto icmp', although there is no ';' after the closing curly brace. Translated to iptables: iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT iptables -A INPUT -p icmp -j DROP iptables -A INPUT -d 172.16.0.0/12 -j REJECT =item B<$> Variable expansion. Replaces '$FOO' by the value of the variable. See the section I for details. =item B<&> Function call. See the section I for details. =item B<()> The array symbol. Using the parentheses, you can define a 'list' of values that should be applied for the key to the left of it. Example: protocol ( tcp udp icmp ) this will result in three rules: ... -p tcp ... ... -p udp ... ... -p icmp ... Only values can be 'listed', so you cannot do something like this: proto tcp ( ACCEPT LOG ); but you can do this: chain (INPUT OUTPUT FORWARD) proto (icmp udp tcp) DROP; (which will result in nine rules!) Values are separated by spaces. The array symbol is both left- and right-associative, in contrast with the nesting block, which is left-associative only. =item C< # > The comment symbol. Anything that follows this symbol up to the end of the line is ignored. =item C<`command`> Execute the command in a shell, and insert the process output. See the section I for details. =item C<'string'> Quote a string which may contain whitespaces, the dollar sign etc. LOG log-prefix ' hey, this is my log prefix!'; =item C<"string"> Quote a string (see above), but variable references with a dollar sign are evaluated: DNAT to "$myhost:$myport"; =back =head2 Keywords In the previous section, we already introduced some basic keywords like "chain", "protocol" and "ACCEPT". Let's explore their nature. There are three kinds of keywords: =over 8 =item B keywords define where a rule will be created. Example: "table", "chain". =item B keywords perform a test on all passing packets. The current rule is without effect if one (or more) of the matches does not pass. Example: "proto", "daddr". Most matches are followed by a parameter: "proto tcp", "daddr 172.16.0.0/12". =item B keywords state what to do with a packet. Example: "ACCEPT", "REJECT", "jump". Some targets define more keywords to specify details: "REJECT reject-with icmp-net-unreachable". =back Every rule consists of a B and a B, plus any number of B: table filter # location proto tcp dport (http https) # match ACCEPT; # target Strictly speaking, there is a fourth kind: B keywords (which control ferm's internal behaviour), but they will be explained later. =head2 Parameters Many keywords take parameters. These can be specified as literals, variable references or lists (arrays): proto udp saddr $TRUSTED_HOSTS; proto tcp dport (http https ssh); LOG log-prefix "funky wardriver alert: "; Some of them can be negated (lists cannot be negated): proto !esp; proto udp dport !domain; Keywords which take no parameters are negated by a prefixed '!': proto tcp !syn; Read iptables(8) to see where the B can be used. =head1 BASIC KEYWORDS =head2 Location keywords =over 8 =item B Set the domain. "ip" means "IPv4" (iptables) and "ip6" is for IPv6 support, using "ip6tables". The default is the one specified with B<--domain> or "ip" if the option was not specified. =item B Specifies which netfilter table this rule will be inserted into: "filter" (default), "nat" or "mangle". =item B Specifies the netfilter chain (within the current table) this rule will be inserted to. Common predefined chain names are "INPUT", "OUTPUT", "FORWARD", "PREROUTING", "POSTROUTING", depending on the table. See the netfilter documentation for details. If you specify a non-existing chain here, ferm will add the rule to a custom chain with that name. =item B Specifies the default policy for the current chain (built-in only). Can be one of the built-in targets (ACCEPT, DROP, REJECT, ...). A packet that matches no rules in a chain will be treated as specified by the policy. To avoid ambiguity, always specify the policies of all predefined chains explicitly. =item B<@subchain ["CHAIN-NAME"] { ... }> Works like the normal block operators (i.e. without the I<@subchain> keyword), except that B moves rules within the curly braces into a new custom chain. The name for this chain is chosen automatically by ferm. In many cases, this is faster than just a block, because the kernel may skip a huge block of rules when a precondition is false. Imagine the following example: table filter chain INPUT { saddr (1.2.3.4 2.3.4.5 3.4.5.6 4.5.6.7 5.6.7.8) { proto tcp dport (http https ssh) ACCEPT; proto udp dport domain ACCEPT; } } This generates 20 rules. When a packet arrives which does not pass the B match, it nonetheless checks all 20 rules. With B<@subchain>, this check is done once, resulting in faster network filtering and less CPU load: table filter chain INPUT { saddr (1.2.3.4 2.3.4.5 3.4.5.6 4.5.6.7 5.6.7.8) @subchain { proto tcp dport (http https ssh) ACCEPT; proto udp dport domain ACCEPT; } } Optionally, you may define the name of the sub chain: saddr (1.2.3.4 2.3.4.5 3.4.5.6) @subchain "foobar" { proto tcp dport (http https ssh) ACCEPT; proto udp dport domain ACCEPT; } The name can either be a quoted string literal, or an expanded ferm expression such as @cat("interface_", $iface) or @substr($var,0,20). You can achieve the same by explicitly declaring a custom chain, but you may feel that using B<@subchain> requires less typing. =item B<@gotosubchain ["CHAIN-NAME"] { ... }> Works like B<@subchain> except that instead of using B target it uses B target. See discussion below for the difference between these two targets. =item B<@preserve> Preserve existing rules of the current chain: chain (foo bar) @preserve; With this option, B loads the previous rule set using B, extracts all "preserved" chains and inserts their data into the output. "Preserved" chains must not be modified with B: no rules and no policies. If the chain name starts and ends with a slash, B will interpret it as as Perl regular expression and preserve all matching chains. For example, the following preserves all chains with the prefix KUBE-SEP-: chain "/^KUBE-SEP-.*/" @preserve; =back =head2 Basic iptables match keywords =over 8 =item B Define the interface name, your outside network card, like eth0, or dialup like ppp1, or whatever device you want to match for passing packets. It is equivalent to the C<-i> switch in iptables(8). =item B Same as interface, only for matching the outgoing interface for a packet, as in iptables(8). =item B Currently supported by the kernel are TCP, UDP and ICMP, or their respective numbers. Instead of B, you can also use the shortcut B. =item B Matches on packets originating from the specified address (saddr) or targeted at the address (daddr). Examples: saddr 192.168.0.0/24 ACCEPT; # (identical to the next one:) saddr 192.168.0.0/255.255.255.0 ACCEPT; daddr my.domain.com ACCEPT; =item B Specify that only fragmented IP packets should be matched. When packets are larger than the maximum packet size your system can handle (called Maximum Transmission Unit or MTU) they will be chopped into bits and sent one by one as single packets. See ifconfig(8) if you want to find the MTU for your system (the default is usually 1500 bytes). Fragments are frequently used in DOS attacks because there is no way of finding out the origin of a fragment packet. =item B Matches on packets on the specified TCP or UDP port. "sport" matches the source port, and dport matches the destination port. This match can be used only after you specified "protocol tcp" or "protocol udp" because only these two protocols actually have ports. And some examples of valid ports/ranges: dport 80 ACCEPT; dport http ACCEPT; dport ssh:http ACCEPT; dport 0:1023 ACCEPT; # equivalent to :1023 dport 1023:65535 ACCEPT; =item B Specify that the SYN flag in a TCP package should be matched, which are used to build new TCP connections. You can identify incoming connections with this, and decide whether you want to allow it or not. Packets that do not have this flag are probably from an already established connection, so it's considered reasonably safe to let these through. =item B Load an iptables module. Most modules provide more match keywords. We'll get to that later. Instead of B, you can also use the shortcut B. =back =head2 Basic target keywords =over 8 =item B Jumps to a custom chain. If no rule in the custom chain matched, netfilter returns to the next rule in the previous chain. =item B Go to a custom chain. Unlike the B option, B will not continue processing in this chain but instead in the chain that called us via B. =item B Accepts matching packets. =item B Drop matching packets without further notice. =item B Rejects matching packets, i.e. send an ICMP packet to the sender, which is port-unreachable by default. You may specify another ICMP type. REJECT; # default to icmp-port-unreachable REJECT reject-with icmp-net-unreachable; Type "iptables -j REJECT -h" for details. =item B Finish the current chain and return to the calling chain (if "jump [custom-chain-name]" was used). =item B No action at all. =back =head1 ADDITIONAL KEYWORDS Netfilter is modular. Modules may provide additional targets and match keywords. The list of netfilter modules is constantly growing, and ferm tries to keep up with supporting them all. This chapter describes modules which are currently supported. =head2 iptables match modules =over 8 =item B Account traffic for all hosts in defined network/netmask. This is one of the match modules which behave like a target, i.e. you will mostly have to use the B target. mod account aname mynetwork aaddr 192.168.1.0/24 ashort NOP; =item B Check the address type; either source address or destination address. mod addrtype src-type BROADCAST; mod addrtype dst-type LOCAL; Type "iptables -m addrtype -h" for details. =item B Checks the SPI header in an AH packet. mod ah ahspi 0x101; mod ah ahspi ! 0x200:0x2ff; Additional arguments for IPv6: mod ah ahlen 32 ACCEPT; mod ah ahlen !32 ACCEPT; mod ah ahres ACCEPT; =item B Match using Linux Socket Filter. mod bpf bytecode "4,48 0 0 9,21 0 1 6,6 0 0 1,6 0 0 0"; =item B Match using cgroupsv2 hierarchy or legacy net_cls cgroup. mod cgroup path ! example/path ACCEPT; The path is relative to the root of the cgroupsv2 hierarchy and is compared against the initial portion of a process' path in the hierarchy. mod cgroup cgroup 10:10 DROP; mod cgroup cgroup 1048592 DROP; Matches against the value of C set on the process' legacy net_cls cgroup. The class may be specified as a hexadecimal major:minor pair (see L), or as a decimal, so those two rules are equivalent. =item B Adds a comment of up to 256 characters to a rule, without an effect. Note that unlike ferm comments ('#'), this one will show up in "iptables -L". mod comment comment "This is my comment." ACCEPT; The "mod comment" can be omitted, because ferm inserts it automatically. =item B Matches if a value in /proc/net/ipt_condition/NAME is 1 (path is /proc/net/ip6t_condition/NAME for the ip6 domain). mod condition condition (abc def) ACCEPT; mod condition condition !foo ACCEPT; =item B Match by how many bytes or packets a connection (or one of the two flows constituting the connection) have transferred so far, or by average bytes per packet. mod connbytes connbytes 65536: connbytes-dir both connbytes-mode bytes ACCEPT; mod connbytes connbytes !1024:2048 connbytes-dir reply connbytes-mode packets ACCEPT; Valid values for I: I, I, I; for I: I, I, I. =item B Module matches or adds connlabels to a connection. mod connlabel label "name"; mod connlabel label "name" set; =item B Allows you to restrict the number of parallel TCP connections to a server per client IP address (or address block). mod connlimit connlimit-above 4 REJECT; mod connlimit connlimit-above !4 ACCEPT; mod connlimit connlimit-above 4 connlimit-mask 24 REJECT; mod connlimit connlimit-upto 4 connlimit-saddr REJECT; mod connlimit connlimit-above 4 connlimit-daddr REJECT; =item B Check the mark field associated with the connection, set by the CONNMARK target. mod connmark mark 64; mod connmark mark 6/7; =item B Check connection tracking information. mod conntrack ctstate (ESTABLISHED RELATED); mod conntrack ctproto tcp; mod conntrack ctorigsrc 192.168.0.2; mod conntrack ctorigdst 1.2.3.0/24; mod conntrack ctorigsrcport 67; mod conntrack ctorigdstport 22; mod conntrack ctreplsrc 2.3.4.5; mod conntrack ctrepldst ! 3.4.5.6; mod conntrack ctstatus ASSURED; mod conntrack ctexpire 60; mod conntrack ctexpire 180:240; Type "iptables -m conntrack -h" for details. =item B Match CPU handling this packet. mod cpu cpu 0; =item B Check DCCP (Datagram Congestion Control Protocol) specific attributes. This module is automatically loaded when you use "protocol dccp". proto dccp sport 1234 dport 2345 ACCEPT; proto dccp dccp-types (SYNCACK ACK) ACCEPT; proto dccp dccp-types !REQUEST DROP; proto dccp dccp-option 2 ACCEPT; =item B Match the 6-bit DSCP field within the TOS field. mod dscp dscp 11; mod dscp dscp-class AF41; =item B Match the parameters in Destination Options header (IPv6). mod dst dst-len 10; mod dst dst-opts (type1 type2 ...); =item B Match the ECN bits of an IPv4 TCP header. mod ecn ecn-tcp-cwr; mod ecn ecn-tcp-ece; mod ecn ecn-ip-ect 2; Type "iptables -m ecn -h" for details. =item B Checks the SPI header in an ESP packet. mod esp espspi 0x101; mod esp espspi ! 0x200:0x2ff; =item B "This module matches the EUI-64 part of a stateless autoconfigured IPv6 address. It compares the EUI-64 derived from the source MAC address in Ethernet frame with the lower 64 bits of the IPv6 source address. But "Universal/Local" bit is not compared. This module doesn't match other link layer frame, and is only valid in the PREROUTING, INPUT and FORWARD chains." mod eui64 ACCEPT; =item B "This module matches a rate limit based on a fuzzy logic controller [FLC]." mod fuzzy lower-limit 10 upper-limit 20 ACCEPT; =item B Matches packets based on their geological location. (Needs an installed GeoDB.) mod geoip src-cc "CN,VN,KR,BH,BR,AR,TR,IN,HK" REJECT; mod geoip dst-cc "DE,FR,CH,AT" ACCEPT; =item B Matches the Hop-by-Hop Options header (ip6). mod hbh hbh-len 8 ACCEPT; mod hbh hbh-len !8 ACCEPT; mod hbh hbh-opts (1:4 2:8) ACCEPT; =item B Matches the Hop Limit field (ip6). mod hl hl-eq (8 10) ACCEPT; mod hl hl-eq !5 ACCEPT; mod hl hl-gt 15 ACCEPT; mod hl hl-lt 2 ACCEPT; =item B Checks which conntrack helper module tracks this connection. The port may be specified with "-portnr". mod helper helper irc ACCEPT; mod helper helper ftp-21 ACCEPT; =item B Check ICMP specific attributes. This module is automatically loaded when you use "protocol icmp". proto icmp icmp-type echo-request ACCEPT; This option can also be used in be I domain, although this is called B in F. Use "iptables -p icmp C<-h>" to obtain a list of valid ICMP types. =item B Match a range of IPv4 addresses. mod iprange src-range 192.168.2.0-192.168.3.255; mod iprange dst-range ! 192.168.6.0-192.168.6.255; =item B Match on IPv4 header options like source routing, record route, timestamp and router-alert. mod ipv4options ssrr ACCEPT; mod ipv4options lsrr ACCEPT; mod ipv4options no-srr ACCEPT; mod ipv4options !rr ACCEPT; mod ipv4options !ts ACCEPT; mod ipv4options !ra ACCEPT; mod ipv4options !any-opt ACCEPT; =item B Matches the IPv6 extension header (ip6). mod ipv6header header !(hop frag) ACCEPT; mod ipv6header header (auth dst) ACCEPT; =item B Similar to 'mod limit', but adds the ability to add per-destination or per-port limits managed in a hash table. mod hashlimit hashlimit 10/minute hashlimit-burst 30/minute hashlimit-mode dstip hashlimit-name foobar ACCEPT; Possible values for hashlimit-mode: dstip dstport srcip srcport (or a list with more than one of these). There are more possible settings, type "iptables -m hashlimit -h" for documentation. =item B Match IPVS connection properties. mod ipvs ipvs ACCEPT; # packet belongs to an IPVS connection mod ipvs vproto tcp ACCEPT; # VIP protocol to match; by number or name, e.g. "tcp mod ipvs vaddr 1.2.3.4/24 ACCEPT; # VIP address to match mod ipvs vport http ACCEPT; # VIP port to match mod ipvs vdir ORIGINAL ACCEPT; # flow direction of packet mod ipvs vmethod GATE ACCEPT; # IPVS forwarding method used mod ipvs vportctl 80; # VIP port of the controlling connection to match =item B Check the package length. mod length length 128; # exactly 128 bytes mod length length 512:768; # range mod length length ! 256; # negated =item B Limits the packet rate. mod limit limit 1/second; mod limit limit 15/minute limit-burst 10; Type "iptables -m limit -h" for details. =item B Match the source MAC address. mod mac mac-source 01:23:45:67:89; =item B Matches packets based on their netfilter mark field. This may be a 32 bit integer between 0 and 4294967295. mod mark mark 42; =item B Matches the mobility header (domain I). proto mh mh-type binding-update ACCEPT; =item B Match a set of source or destination ports (UDP and TCP only). mod multiport source-ports (https ftp); mod multiport destination-ports (mysql domain); This rule has a big advantage over "dport" and "sport": it generates only one rule for up to 15 ports instead of one rule for every port. As a shortcut, you can use "sports" and "dports" (without "mod multiport"): sports (https ftp); dports (mysql domain); =item B Add packet accounting (bytes + packets). See also the user space tool "nfacct". mod nfacct nfacct-name my-nfacct-object; =item B Match every 'n'th packet. mod nth every 3; mod nth counter 5 every 2; mod nth start 2 every 3; mod nth start 5 packet 2 every 6; Type "iptables -m nth -h" for details. =item B Match packets depending on the operating system of the sender. mod osf genre Linux; mod osf ! genre FreeBSD ttl 1 log 1; Type "iptables -m osf -h" for details. =item B Check information about the packet creator, namely user id, group id, process id, session id and command name. mod owner uid-owner 0; mod owner gid-owner 1000; mod owner pid-owner 5432; mod owner sid-owner 6543; mod owner cmd-owner "sendmail"; ("cmd-owner", "pid-owner" and "sid-owner" require special kernel patches not included in the vanilla Linux kernel) =item B Matches the physical device on which a packet entered or is about to leave the machine. This is useful for bridged interfaces. mod physdev physdev-in ppp1; mod physdev physdev-out eth2; mod physdev physdev-is-in; mod physdev physdev-is-out; mod physdev physdev-is-bridged; =item B Check the link-layer packet type. mod pkttype pkt-type unicast; mod pkttype pkt-type broadcast; mod pkttype pkt-type multicast; =item B Matches the IPsec policy being applied to this packet. mod policy dir out pol ipsec ACCEPT; mod policy strict reqid 23 spi 0x10 proto ah ACCEPT; mod policy mode tunnel tunnel-src 192.168.1.2 ACCEPT; mod policy mode tunnel tunnel-dst 192.168.2.1 ACCEPT; mod policy strict next reqid 24 spi 0x11 ACCEPT; Note that the keyword I is also used as a shorthand version of I (built-in match module). You can fix this conflict by always using the long keyword I. =item B Detect TCP/UDP port scans. mod psd psd-weight-threshold 21 psd-delay-threshold 300 psd-lo-ports-weight 3 psd-hi-ports-weight 1 DROP; =item B Implements network quotas by decrementing a byte counter with each packet. mod quota quota 65536 ACCEPT; =item B Match a random percentage of all packets. mod random average 70; =item B Match the routing realm. Useful in environments using BGP. mod realm realm 3; =item B Temporarily mark source IP addresses. mod recent set; mod recent rcheck seconds 60; mod recent set rsource name "badguy"; mod recent set rdest; mod recent rcheck rsource name "badguy" seconds 60; mod recent update seconds 120 hitcount 3 rttl; mod recent mask 255.255.255.0 reap; This netfilter module has a design flaw: although it is implemented as a match module, it has target-like behaviour when using the "set" keyword. L =item B Checks a reply to the packet would be sent via the same interface it arrived on. Packets from the loopback interface are always permitted. mod rpfilter proto tcp loose RETURN; mod rpfilter validmark accept-local RETURN; mod rpfilter invert DROP; This netfilter module is the preferred way to perform reverse path filtering for IPv6, and a powerful alternative to checks controlled by sysctl I. =item B Match the IPv6 routing header (ip6 only). mod rt rt-type 2 rt-len 20 ACCEPT; mod rt rt-type !2 rt-len !20 ACCEPT; mod rt rt-segsleft 2:3 ACCEPT; mod rt rt-segsleft !4:5 ACCEPT; mod rt rt-0-res rt-0-addrs (::1 ::2) rt-0-not-strict ACCEPT; =item B Check SCTP (Stream Control Transmission Protocol) specific attributes. This module is automatically loaded when you use "protocol sctp". proto sctp sport 1234 dport 2345 ACCEPT; proto sctp chunk-types only DATA:Be ACCEPT; proto sctp chunk-types any (INIT INIT_ACK) ACCEPT; proto sctp chunk-types !all (HEARTBEAT) ACCEPT; Use "iptables -p sctp C<-h>" to obtain a list of valid chunk types. =item B Checks the source or destination IP/Port/MAC against a set. mod set set badguys src DROP; See L for more information. =item B Checks the connection tracking state. mod state state INVALID DROP; mod state state (ESTABLISHED RELATED) ACCEPT; Type "iptables -m state -h" for details. =item B Successor of B and B, currently undocumented in the iptables(8) man page. mod statistic mode random probability 0.8 ACCEPT; mod statistic mode nth every 5 packet 0 DROP; =item B Matches a string. mod string string "foo bar" ACCEPT; mod string algo kmp from 64 to 128 hex-string "deadbeef" ACCEPT; =item B Checks TCP specific attributes. This module is automatically loaded when you use "protocol tcp". proto tcp sport 1234; proto tcp dport 2345; proto tcp tcp-flags (SYN ACK) SYN; proto tcp tcp-flags ! (SYN ACK) SYN; proto tcp tcp-flags ALL (RST ACK); proto tcp syn; proto tcp tcp-option 2; proto tcp mss 512; Type "iptables -p tcp -h" for details. =item B Check the TCP MSS field of a SYN or SYN/ACK packet. mod tcpmss mss 123 ACCEPT; mod tcpmss mss 234:567 ACCEPT; =item B