diff -Nru ferm-2.3/AUTHORS ferm-2.4/AUTHORS --- ferm-2.3/AUTHORS 2016-03-30 12:16:02.000000000 +0000 +++ ferm-2.4/AUTHORS 2017-04-02 19:05:10.000000000 +0000 @@ -1,5 +1,5 @@ Authors of this package - * Max Kellermann + * Max Kellermann * Auke Kok People who contributed to this package diff -Nru ferm-2.3/COPYING ferm-2.4/COPYING --- ferm-2.3/COPYING 2016-03-30 12:16:02.000000000 +0000 +++ ferm-2.4/COPYING 2017-04-02 19:05:10.000000000 +0000 @@ -1,12 +1,12 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + 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 + Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -15,7 +15,7 @@ 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 +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 @@ -55,8 +55,8 @@ The precise terms and conditions for copying, distribution and modification follow. - - GNU GENERAL PUBLIC LICENSE + + GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains @@ -110,7 +110,7 @@ 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 @@ -168,7 +168,7 @@ 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 @@ -225,7 +225,7 @@ 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 @@ -255,7 +255,7 @@ of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY + 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 @@ -277,9 +277,9 @@ 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 + 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 @@ -291,7 +291,7 @@ the "copyright" line and a pointer to where the full notice is found. - Copyright (C) 19yy + 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 @@ -303,17 +303,16 @@ 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 - + 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) 19yy name of author + 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. @@ -336,5 +335,5 @@ 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 +library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. diff -Nru ferm-2.3/debian/changelog ferm-2.4/debian/changelog --- ferm-2.3/debian/changelog 2017-07-11 23:58:15.000000000 +0000 +++ ferm-2.4/debian/changelog 2017-07-11 23:58:16.000000000 +0000 @@ -1,3 +1,11 @@ +ferm (2.4-1) unstable; urgency=medium + + * [2bd37ee] New upstream version 2.4 + * [f280aca] Rework example firewall (Closes: #701200, #770946) + * [9736ebd] Disable cache by default (Closes: #849760) + + -- Alexander Wirt Tue, 11 Jul 2017 14:52:19 +0200 + ferm (2.3-2) unstable; urgency=medium * [3e49919] Start ferm as before network and stop as late as possible diff -Nru ferm-2.3/debian/ferm.conf ferm-2.4/debian/ferm.conf --- ferm-2.3/debian/ferm.conf 2017-07-11 23:58:15.000000000 +0000 +++ ferm-2.4/debian/ferm.conf 2017-07-11 23:58:16.000000000 +0000 @@ -2,51 +2,47 @@ # # Configuration file for ferm(1). # - -table filter { - chain INPUT { - policy DROP; - - # connection tracking - mod state state INVALID DROP; - mod state state (ESTABLISHED RELATED) ACCEPT; - - # allow local packet - interface lo ACCEPT; - - # respond to ping - proto icmp ACCEPT; - - # allow IPsec - proto udp dport 500 ACCEPT; - proto (esp ah) ACCEPT; - - # allow SSH connections - proto tcp dport ssh ACCEPT; - } - chain OUTPUT { - policy ACCEPT; - - # connection tracking - #mod state state INVALID DROP; - mod state state (ESTABLISHED RELATED) ACCEPT; - } - chain FORWARD { - policy DROP; - - # connection tracking - mod state state INVALID DROP; - mod state state (ESTABLISHED RELATED) ACCEPT; +domain (ip ip6) { + table filter { + chain INPUT { + policy DROP; + + # connection tracking + mod state state INVALID DROP; + mod state state (ESTABLISHED RELATED) ACCEPT; + + # allow local packet + interface lo ACCEPT; + + # respond to ping + proto icmp ACCEPT; + + # allow IPsec + proto udp dport 500 ACCEPT; + @if @eq($DOMAIN, ip) { + proto (esp ah) ACCEPT; + } @else { + proto (esp) ACCEPT; + } + + # allow SSH connections + proto tcp dport ssh ACCEPT; + } + chain OUTPUT { + policy ACCEPT; + + # connection tracking + #mod state state INVALID DROP; + mod state state (ESTABLISHED RELATED) ACCEPT; + } + chain FORWARD { + policy DROP; + + # connection tracking + mod state state INVALID DROP; + mod state state (ESTABLISHED RELATED) ACCEPT; + } } } -# IPv6: -#domain ip6 { -# table filter { -# chain INPUT { -# policy ACCEPT; -# # ... -# } -# # ... -# } -#} +@include ferm.d/; diff -Nru ferm-2.3/debian/ferm.dirs ferm-2.4/debian/ferm.dirs --- ferm-2.3/debian/ferm.dirs 2017-07-11 23:58:15.000000000 +0000 +++ ferm-2.4/debian/ferm.dirs 2017-07-11 23:58:16.000000000 +0000 @@ -1 +1,2 @@ var/cache/ferm +etc/ferm/ferm.d diff -Nru ferm-2.3/debian/ferm.postinst ferm-2.4/debian/ferm.postinst --- ferm-2.3/debian/ferm.postinst 2017-07-11 23:58:15.000000000 +0000 +++ ferm-2.4/debian/ferm.postinst 2017-07-11 23:58:16.000000000 +0000 @@ -13,7 +13,7 @@ FAST=yes # cache the output of ferm --lines in /var/cache/ferm? - CACHE=yes + CACHE=no # additional paramaters for ferm (like --def '$foo=bar') OPTIONS= diff -Nru ferm-2.3/debian/README.Debian ferm-2.4/debian/README.Debian --- ferm-2.3/debian/README.Debian 2017-07-11 23:58:15.000000000 +0000 +++ ferm-2.4/debian/README.Debian 2017-07-11 23:58:16.000000000 +0000 @@ -16,7 +16,7 @@ dependency and set FAST=no in /etc/default/ferm (the latter is done for the packages on backports.org). -The cache ("CACHE=yes", enabled by default) speeds things up, too, +The cache ("CACHE=yes", disabled by default) speeds things up, too, because ferm will only be run when you modify its configuration, but this also means that ferm's rollback-on-error isn't assisting you. Also note that the init script doesn't notice when you change an diff -Nru ferm-2.3/doc/ferm.1 ferm-2.4/doc/ferm.1 --- ferm-2.3/doc/ferm.1 2016-03-30 12:16:02.000000000 +0000 +++ ferm-2.4/doc/ferm.1 2017-04-02 19:05:10.000000000 +0000 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29) +.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== @@ -46,7 +46,7 @@ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" -.\" If the F register is turned on, we'll generate index entries on stderr for +.\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. @@ -54,20 +54,16 @@ .\" Avoid warning from groff about undefined register 'F'. .de IX .. -.nr rF 0 -.if \n(.g .if rF .nr rF 1 -.if (\n(rF:(\n(.g==0)) \{ -. if \nF \{ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" +.if !\nF .nr F 0 +.if \nF>0 \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" .. -. if !\nF==2 \{ -. nr % 0 -. nr F 2 -. \} +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 . \} .\} -.rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. @@ -133,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "FERM 1" -.TH FERM 1 "2016-03-30" "ferm 2.3" "FIREWALL RULES MADE EASY" +.TH FERM 1 "2017-03-22" "ferm 2.4" "FIREWALL RULES MADE EASY" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -532,7 +528,7 @@ .Sp To avoid ambiguity, always specify the policies of all predefined chains explicitly. -.ie n .IP "\fB\fB@subchain\fB [""\s-1CHAIN\-NAME""\s0] { ... }\fR" 8 +.ie n .IP "\fB\f(CB@subchain\fB [""\s-1CHAIN\-NAME""\s0] { ... }\fR" 8 .el .IP "\fB\f(CB@subchain\fB [``\s-1CHAIN\-NAME''\s0] { ... }\fR" 8 .IX Item "@subchain [CHAIN-NAME] { ... }" Works like the normal block operators (i.e. without the \fI\f(CI@subchain\fI\fR @@ -581,12 +577,26 @@ .Sp You can achieve the same by explicitly declaring a custom chain, but you may feel that using \fB\f(CB@subchain\fB\fR requires less typing. -.ie n .IP "\fB\fB@gotosubchain\fB [""\s-1CHAIN\-NAME""\s0] { ... }\fR" 8 +.ie n .IP "\fB\f(CB@gotosubchain\fB [""\s-1CHAIN\-NAME""\s0] { ... }\fR" 8 .el .IP "\fB\f(CB@gotosubchain\fB [``\s-1CHAIN\-NAME''\s0] { ... }\fR" 8 .IX Item "@gotosubchain [CHAIN-NAME] { ... }" Works like \fB\f(CB@subchain\fB\fR except that instead of using \fBjump\fR target it uses \fBgoto\fR target. See discussion below for the difference between these two targets. +.IP "\fB\f(CB@preserve\fB\fR" 8 +.IX Item "@preserve" +Preserve existing rules of the current chain: +.Sp +.Vb 1 +\& chain (foo bar) @preserve; +.Ve +.Sp +With this option, \fBferm\fR loads the previous rule set using +\&\fBiptables-save\fR, extracts all \*(L"preserved\*(R" chains and inserts their +data into the output. +.Sp +\&\*(L"Preserved\*(R" chains must not be modified with \fBferm\fR: no rules and no +policies. .SS "Basic iptables match keywords" .IX Subsection "Basic iptables match keywords" .IP "\fBinterface [interface\-name]\fR" 8 @@ -611,7 +621,7 @@ Examples: .Sp .Vb 3 -\& saddr 192.168/8 ACCEPT; # (identical to the next one:) +\& 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; .Ve @@ -647,7 +657,7 @@ .IX Item "syn" Specify that the \s-1SYN\s0 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 wether you want +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. @@ -741,6 +751,25 @@ .Vb 1 \& mod bpf bytecode "4,48 0 0 9,21 0 1 6,6 0 0 1,6 0 0 0"; .Ve +.IP "\fBcgroup\fR" 8 +.IX Item "cgroup" +Match using cgroupsv2 hierarchy or legacy net_cls cgroup. +.Sp +.Vb 1 +\& mod cgroup path ! example/path ACCEPT; +.Ve +.Sp +The path is relative to the root of the cgroupsv2 hiearchy, and is compared +against the initial portion of a process' path in the hierarchy. +.Sp +.Vb 2 +\& mod cgroup cgroup 10:10 DROP; +\& mod cgroup cgroup 1048592 DROP; +.Ve +.Sp +Matches against the value of \f(CW\*(C`net_cls.classid\*(C'\fR set on the process' legacy +net_cls cgroup. The class may be specified as a hexadecimal major:minor pair +(see \fItc\fR\|(8)), or as a decimal, so those two rules are equivalent. .IP "\fBcomment\fR" 8 .IX Item "comment" Adds a comment of up to 256 characters to a rule, without an effect. @@ -785,10 +814,12 @@ Allows you to restrict the number of parallel \s-1TCP\s0 connections to a server per client \s-1IP\s0 address (or address block). .Sp -.Vb 3 +.Vb 5 \& 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; .Ve .IP "\fBconnmark\fR" 8 .IX Item "connmark" @@ -890,6 +921,15 @@ .Vb 1 \& mod fuzzy lower\-limit 10 upper\-limit 20 ACCEPT; .Ve +.IP "\fBgeoip\fR" 8 +.IX Item "geoip" +Matches packets based on their geological location. (Needs an installed +GeoDB.) +.Sp +.Vb 2 +\& mod geoip src\-cc "CN,VN,KR,BH,BR,AR,TR,IN,HK" REJECT; +\& mod geoip dst\-cc "DE,FR,CH,AT" ACCEPT; +.Ve .IP "\fBhbh\fR" 8 .IX Item "hbh" Matches the Hop-by-Hop Options header (ip6). @@ -1147,13 +1187,14 @@ .IX Item "recent" Temporarily mark source \s-1IP\s0 addresses. .Sp -.Vb 6 +.Vb 7 \& 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; .Ve .Sp This netfilter module has a design flaw: although it is implemented as @@ -1775,33 +1816,26 @@ .IX Subsection "Automatic variables" Some variables are set internally by ferm. Ferm scripts can use them just like any other variable. -.ie n .IP "\fB\fB$FILENAME\fB\fR" 8 -.el .IP "\fB\f(CB$FILENAME\fB\fR" 8 +.IP "\fB\f(CB$FILENAME\fB\fR" 8 .IX Item "$FILENAME" The name of the configuration file relative to the directory ferm was started in. -.ie n .IP "\fB\fB$FILEBNAME\fB\fR" 8 -.el .IP "\fB\f(CB$FILEBNAME\fB\fR" 8 +.IP "\fB\f(CB$FILEBNAME\fB\fR" 8 .IX Item "$FILEBNAME" The base name of the configuration file. -.ie n .IP "\fB\fB$DIRNAME\fB\fR" 8 -.el .IP "\fB\f(CB$DIRNAME\fB\fR" 8 +.IP "\fB\f(CB$DIRNAME\fB\fR" 8 .IX Item "$DIRNAME" The directory of the configuration file. -.ie n .IP "\fB\fB$DOMAIN\fB\fR" 8 -.el .IP "\fB\f(CB$DOMAIN\fB\fR" 8 +.IP "\fB\f(CB$DOMAIN\fB\fR" 8 .IX Item "$DOMAIN" The current domain. One of \fIip\fR, \fIip6\fR, \fIarp\fR, \fIeb\fR. -.ie n .IP "\fB\fB$TABLE\fB\fR" 8 -.el .IP "\fB\f(CB$TABLE\fB\fR" 8 +.IP "\fB\f(CB$TABLE\fB\fR" 8 .IX Item "$TABLE" The current netfilter table. -.ie n .IP "\fB\fB$CHAIN\fB\fR" 8 -.el .IP "\fB\f(CB$CHAIN\fB\fR" 8 +.IP "\fB\f(CB$CHAIN\fB\fR" 8 .IX Item "$CHAIN" The current netfilter chain. -.ie n .IP "\fB\fB$LINE\fB\fR" 8 -.el .IP "\fB\f(CB$LINE\fB\fR" 8 +.IP "\fB\f(CB$LINE\fB\fR" 8 .IX Item "$LINE" The line of the current script. It can be used like this: .Sp @@ -2176,11 +2210,12 @@ .IX Header "BUGS" Bugs? What bugs? .PP -If you find a bug, please tell us: ferm@foo\-projects.org +If you find a bug, please report it on GitHub: + .SH "COPYRIGHT" .IX Header "COPYRIGHT" -Copyright (C) 2001\-2012 Max Kellermann , Auke -Kok +Copyright 2001\-2017 Max Kellermann , +Auke Kok and various other contributors. .PP This program is free software; you can redistribute it and/or modify it under the terms of the \s-1GNU\s0 General Public License as published by @@ -2194,9 +2229,9 @@ .PP You should have received a copy of the \s-1GNU\s0 General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, \s-1MA 02111\-1307 -USA\s0 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +\&\s-1MA 02110\-1301 USA.\s0 .SH "AUTHOR" .IX Header "AUTHOR" -Max Kellermann , Auke Kok +Max Kellermann , Auke Kok diff -Nru ferm-2.3/doc/ferm.html ferm-2.4/doc/ferm.html --- ferm-2.3/doc/ferm.html 2016-03-30 12:16:02.000000000 +0000 +++ ferm-2.4/doc/ferm.html 2017-04-02 19:05:10.000000000 +0000 @@ -457,6 +457,18 @@

Works like @subchain except that instead of using jump target it uses goto target. See discussion below for the difference between these two targets.

+
@preserve
+
+ +

Preserve existing rules of the current chain:

+ +
 chain (foo bar) @preserve;
+ +

With this option, ferm loads the previous rule set using iptables-save, extracts all "preserved" chains and inserts their data into the output.

+ +

"Preserved" chains must not be modified with ferm: no rules and no policies.

+ +

Basic iptables match keywords

@@ -488,7 +500,7 @@

Examples:

-
    saddr 192.168/8 ACCEPT; # (identical to the next one:)
+
    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;
@@ -520,7 +532,7 @@
syn
-

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 wether 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.

+

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.

module [module-name]
@@ -634,6 +646,21 @@
    mod bpf bytecode "4,48 0 0 9,21 0 1 6,6 0 0 1,6 0 0 0";
+
cgroup
+
+ +

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 hiearchy, 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 net_cls.classid set on the process' legacy net_cls cgroup. The class may be specified as a hexadecimal major:minor pair (see tc(8)), or as a decimal, so those two rules are equivalent.

+ +
comment
@@ -678,7 +705,9 @@
    mod connlimit connlimit-above 4 REJECT;
     mod connlimit connlimit-above !4 ACCEPT;
-    mod connlimit connlimit-above 4 connlimit-mask 24 REJECT;
+ 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;
connmark
@@ -784,6 +813,15 @@
    mod fuzzy lower-limit 10 upper-limit 20 ACCEPT;
+
geoip
+
+ +

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;
+ +
hbh
@@ -1058,7 +1096,8 @@ 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 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.

@@ -2089,21 +2128,21 @@

Bugs? What bugs?

-

If you find a bug, please tell us: ferm@foo-projects.org

+

If you find a bug, please report it on GitHub: https://github.com/MaxKellermann/ferm/issues

COPYRIGHT

-

Copyright (C) 2001-2012 Max Kellermann <max@foo-projects.org>, Auke Kok <sofar@foo-projects.org>

+

Copyright 2001-2017 Max Kellermann <max.kellermann@gmail.com>, Auke Kok <sofar@foo-projects.org> and various other contributors.

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

+

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.

AUTHOR

-

Max Kellermann <max@foo-projects.org>, Auke Kok <sofar@foo-projects.org>

+

Max Kellermann <max.kellermann@gmail.com>, Auke Kok <sofar@foo-projects.org>

diff -Nru ferm-2.3/doc/ferm.pod ferm-2.4/doc/ferm.pod --- ferm-2.3/doc/ferm.pod 2016-03-30 12:16:02.000000000 +0000 +++ ferm-2.4/doc/ferm.pod 2017-04-02 19:05:10.000000000 +0000 @@ -5,10 +5,10 @@ # # ferm, a firewall setup program that makes firewall rules easy! # -# Copyright (C) 2001-2012 Max Kellermann, Auke Kok +# Copyright 2001-2017 Max Kellermann, Auke Kok # -# Comments, questions, greetings and additions to this program -# may be sent to +# Bug reports and patches for this program may be sent to the GitHub +# repository: L # # @@ -24,7 +24,8 @@ # # 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 +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA. # =head1 NAME @@ -454,6 +455,19 @@ 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. + =back @@ -485,7 +499,7 @@ Examples: - saddr 192.168/8 ACCEPT; # (identical to the next one:) + 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; @@ -521,7 +535,7 @@ 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 wether you want +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. @@ -628,6 +642,22 @@ 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 hiearchy, 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. @@ -671,6 +701,8 @@ 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 @@ -762,6 +794,14 @@ 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). @@ -1000,6 +1040,7 @@ 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" @@ -1981,12 +2022,13 @@ Bugs? What bugs? -If you find a bug, please tell us: ferm@foo-projects.org +If you find a bug, please report it on GitHub: +L =head1 COPYRIGHT -Copyright (C) 2001-2012 Max Kellermann , Auke -Kok +Copyright 2001-2017 Max Kellermann , +Auke Kok and various other contributors. 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 @@ -2000,12 +2042,12 @@ 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 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +MA 02110-1301 USA. =head1 AUTHOR -Max Kellermann , Auke Kok +Max Kellermann , Auke Kok =cut diff -Nru ferm-2.3/doc/ferm.txt ferm-2.4/doc/ferm.txt --- ferm-2.3/doc/ferm.txt 2016-03-30 12:16:02.000000000 +0000 +++ ferm-2.4/doc/ferm.txt 2017-04-02 19:05:10.000000000 +0000 @@ -372,6 +372,18 @@ uses goto target. See discussion below for the difference between these two targets. + @preserve + Preserve existing rules of the current chain: + + chain (foo bar) @preserve; + + With this option, ferm loads the previous rule set using + iptables-save, extracts all "preserved" chains and inserts their + data into the output. + + "Preserved" chains must not be modified with ferm: no rules and + no policies. + Basic iptables match keywords interface [interface-name] Define the interface name, your outside network card, like eth0, @@ -393,7 +405,7 @@ Examples: - saddr 192.168/8 ACCEPT; # (identical to the next one:) + 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; @@ -426,7 +438,7 @@ syn 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 wether you want to + 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. @@ -500,6 +512,22 @@ mod bpf bytecode "4,48 0 0 9,21 0 1 6,6 0 0 1,6 0 0 0"; + cgroup 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 hiearchy, 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 "net_cls.classid" set on the + process' legacy net_cls cgroup. The class may be specified as a + hexadecimal major:minor pair (see tc(8)), or as a decimal, so + those two rules are equivalent. + comment 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". @@ -537,6 +565,8 @@ 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; connmark Check the mark field associated with the connection, set by the @@ -612,6 +642,12 @@ mod fuzzy lower-limit 10 upper-limit 20 ACCEPT; + geoip 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; + hbh Matches the Hop-by-Hop Options header (ip6). mod hbh hbh-len 8 ACCEPT; @@ -806,6 +842,7 @@ 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 @@ -1606,11 +1643,12 @@ BUGS Bugs? What bugs? - If you find a bug, please tell us: ferm@foo-projects.org + If you find a bug, please report it on GitHub: + COPYRIGHT - Copyright (C) 2001-2012 Max Kellermann , Auke Kok - + Copyright 2001-2017 Max Kellermann , Auke Kok + and various other contributors. 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 @@ -1624,8 +1662,9 @@ 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 + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. AUTHOR - Max Kellermann , Auke Kok + Max Kellermann , Auke Kok + diff -Nru ferm-2.3/doc/import-ferm.1 ferm-2.4/doc/import-ferm.1 --- ferm-2.3/doc/import-ferm.1 2016-03-30 12:16:02.000000000 +0000 +++ ferm-2.4/doc/import-ferm.1 2017-04-02 19:05:10.000000000 +0000 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29) +.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== @@ -46,7 +46,7 @@ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" -.\" If the F register is turned on, we'll generate index entries on stderr for +.\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. @@ -54,20 +54,16 @@ .\" Avoid warning from groff about undefined register 'F'. .de IX .. -.nr rF 0 -.if \n(.g .if rF .nr rF 1 -.if (\n(rF:(\n(.g==0)) \{ -. if \nF \{ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" +.if !\nF .nr F 0 +.if \nF>0 \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" .. -. if !\nF==2 \{ -. nr % 0 -. nr F 2 -. \} +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 . \} .\} -.rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. @@ -133,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "IMPORT-FERM 1" -.TH IMPORT-FERM 1 "2016-03-30" "ferm 2.3" "FIREWALL RULES MADE EASY" +.TH IMPORT-FERM 1 "2017-03-29" "ferm 2.4" "FIREWALL RULES MADE EASY" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff -Nru ferm-2.3/Makefile ferm-2.4/Makefile --- ferm-2.3/Makefile 2016-03-30 12:16:02.000000000 +0000 +++ ferm-2.4/Makefile 2017-04-02 19:05:10.000000000 +0000 @@ -161,5 +161,5 @@ .PHONY: upload upload: doc/ferm.html - scp NEWS doc/ferm.html foo-projects.org:/var/www/ferm.foo-projects.org/download/2.3/ + scp NEWS doc/ferm.html foo-projects.org:/var/www/ferm.foo-projects.org/download/2.4/ scp examples/*.ferm foo-projects.org:/var/www/ferm.foo-projects.org/download/examples/ diff -Nru ferm-2.3/NEWS ferm-2.4/NEWS --- ferm-2.3/NEWS 2016-03-30 12:16:02.000000000 +0000 +++ ferm-2.4/NEWS 2017-04-02 19:05:10.000000000 +0000 @@ -3,10 +3,35 @@ version history for ferm - Max Kellermann + Max Kellermann Auke Kok +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 diff -Nru ferm-2.3/src/ferm ferm-2.4/src/ferm --- ferm-2.3/src/ferm 2016-03-30 12:16:02.000000000 +0000 +++ ferm-2.4/src/ferm 2017-04-02 19:05:10.000000000 +0000 @@ -3,10 +3,10 @@ # # ferm, a firewall setup program that makes firewall rules easy! # -# Copyright (C) 2001-2012 Max Kellermann, Auke Kok +# Copyright 2001-2017 Max Kellermann, Auke Kok # -# Comments, questions, greetings and additions to this program -# may be sent to +# Bug reports and patches for this program may be sent to the GitHub +# repository: L # # @@ -22,7 +22,8 @@ # # 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 +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA. # # $Id$ @@ -48,7 +49,7 @@ use vars qw($VERSION); -$VERSION = '2.3'; +$VERSION = '2.4'; #$VERSION .= '~git'; ## interface variables @@ -241,21 +242,24 @@ qw(limit-iface-in*0 limit-iface-out*0); add_match_def 'ah', qw(ahspi! ahlen! ahres*0); add_match_def 'bpf', qw(bytecode); +add_match_def 'cgroup', qw(path! cgroup&cgroup_classid); add_match_def 'comment', qw(comment=s); add_match_def 'condition', qw(condition!); add_match_def 'connbytes', qw(!connbytes connbytes-dir connbytes-mode); add_match_def 'connlabel', qw(!label set*0); -add_match_def 'connlimit', qw(!connlimit-above connlimit-mask); +add_match_def 'connlimit', qw(!connlimit-upto !connlimit-above connlimit-mask connlimit-saddr*0 connlimit-daddr*0); add_match_def 'connmark', qw(!mark); add_match_def 'conntrack', qw(!ctstate=c !ctproto ctorigsrc! ctorigdst! ctorigsrcport! ctorigdstport!), qw(ctreplsrc! ctrepldst! !ctstatus !ctexpire=s ctdir=s); add_match_def 'cpu', qw(!cpu); +add_match_def 'devgroup', qw(!src-group !dst-group); add_match_def 'dscp', qw(dscp dscp-class); add_match_def 'dst', qw(!dst-len=s dst-opts=c); add_match_def 'ecn', qw(ecn-tcp-cwr*0 ecn-tcp-ece*0 ecn-ip-ect); add_match_def 'esp', qw(espspi!); add_match_def 'eui64'; add_match_def 'fuzzy', qw(lower-limit=s upper-limit=s); +add_match_def 'geoip', qw(!src-cc=s !dst-cc=s); add_match_def 'hbh', qw(hbh-len! hbh-opts=c); add_match_def 'helper', qw(helper); add_match_def 'hl', qw(hl-eq! hl-lt=s hl-gt=s); @@ -288,10 +292,11 @@ add_match_def 'quota', qw(quota=s); add_match_def 'random', qw(average); add_match_def 'realm', qw(realm!); -add_match_def 'recent', qw(name=s !set*0 !remove*0 !rcheck*0 !update*0 !seconds !hitcount rttl*0 rsource*0 rdest*0); +add_match_def 'recent', qw(name=s !set*0 !remove*0 !rcheck*0 !update*0 !seconds !hitcount rttl*0 rsource*0 rdest*0 mask*0 reap*0); add_match_def 'rpfilter', qw(loose*0 validmark*0 accept-local*0 invert*0); add_match_def 'rt', qw(rt-type! rt-segsleft! rt-len! rt-0-res*0 rt-0-addrs=c rt-0-not-strict*0); -add_match_def 'set', qw(!match-set=sc set:=match-set); +add_match_def 'set', qw(!match-set=sc set:=match-set return-nomatch*0 !update-counters*0 !update-subcounters*0 !packets-eq=s packets-lt=s packets-gt=s !bytes-eq=s bytes-lt=s bytes-gt=s); +add_match_def 'socket', qw(transparent*0 nowildcard*0 restore-skmark*0); add_match_def 'state', qw(!state=c); add_match_def 'statistic', qw(mode=s probability=s every=s packet=s); add_match_def 'string', qw(algo=s from=s to=s string hex-string); @@ -340,13 +345,13 @@ add_target_def 'SET', qw(add-set=sc del-set=sc timeout exist*0); add_target_def 'SNAT', qw(to-source=m to:=to-source persistent*0 random*0); add_target_def 'SNPT', qw(src-pfx dst-pfx); -add_target_def 'SYNPROXY', qw(sack-perm*0 timestamp*0 ecn*0 wscale=s mss=s); +add_target_def 'SYNPROXY', qw(sack-perm*0 timestamps*0 ecn*0 wscale=s mss=s); add_target_def 'TARPIT'; add_target_def 'TCPMSS', qw(set-mss clamp-mss-to-pmtu*0); add_target_def 'TCPOPTSTRIP', qw(strip-options=c); add_target_def 'TEE', qw(gateway); add_target_def 'TOS', qw(set-tos and-tos or-tos xor-tos); -add_target_def 'TPROXY', qw(tproxy-mark on-port); +add_target_def 'TPROXY', qw(tproxy-mark on-ip on-port); add_target_def 'TRACE'; add_target_def 'TTL', qw(ttl-set ttl-dec ttl-inc); add_target_def 'ULOG', qw(ulog-nlgroup ulog-prefix ulog-cprange ulog-qthreshold); @@ -498,6 +503,40 @@ } } +sub cgroup_classid { + my $rule = shift; + my $value = getvalues(undef, allow_negation => 1); + + my @classids; + my $negated = 0; + if (ref $value and ref $value eq 'ARRAY') { + @classids = @$value; + } elsif (ref $value and ref $value eq 'negated') { + @classids = @$value; + $negated = 1; + } elsif (ref $value) { + die; + } else { + @classids = ($value); + } + + foreach (@classids) { + if ($_ =~ /^([0-9A-Fa-f]{1,4}):([0-9A-Fa-f]{1,4})$/) { + $_ = (hex($1) << 16) + hex($2); + } elsif ($_ !~ /^-?\d+$/) { + error('classid must be hex:hex or decimal'); + } + error('classid must be non-negative') if $_ < 0; + error('classid is too large') if $_ > 0xffffffff; + } + + if ($negated && scalar @classids) { + return bless \@classids, 'negated'; + } else { + return \@classids; + } +} + # initialize stack: command line definitions unshift @stack, {}; @@ -647,7 +686,8 @@ system($cmd) unless $option{noexec}; } -while (my ($domain, $domain_info) = each %domains) { +foreach my $domain (sort keys %domains) { + my $domain_info = $domains{$domain}; next unless $domain_info->{enabled}; my $s = $option{fast} && defined $domain_info->{tools}{'tables-restore'} @@ -672,7 +712,8 @@ print LINES "echo 'ferm has applied the new firewall rules.'\n"; print LINES "echo 'Please press Ctrl-C to confirm.'\n"; print LINES "sleep $option{timeout}\n"; - while (my ($domain, $domain_info) = each %domains) { + foreach my $domain (sort keys %domains) { + my $domain_info = $domains{$domain}; my $restore = $domain_info->{tools}{'tables-restore'}; next unless defined $restore; print LINES "$restore <\$${domain}_tmp\n"; @@ -691,7 +732,7 @@ sub printversion { print "ferm $VERSION\n"; - print "Copyright (C) 2001-2012 Max Kellermann, Auke Kok\n"; + print "Copyright 2001-2017 Max Kellermann, Auke Kok\n"; print "This program is free software released under GPLv2.\n"; print "See the included COPYING file for license details.\n"; } @@ -1114,6 +1155,13 @@ my @result; foreach my $hostname (@$names) { + if (($type eq 'A' and $hostname =~ /^\d+\.\d+\.\d+\.\d+$/) or + (($type eq 'AAAA' and + $hostname =~ /^[0-9a-fA-F:]*:[0-9a-fA-F:]*$/))) { + push @result, $hostname; + next; + } + my $query = $resolver->search($hostname, $type); error("DNS query for '$hostname' failed: " . $resolver->errorstring) unless $query; @@ -2097,6 +2145,37 @@ next; } + if ($keyword eq '@preserve') { + error('@preserve not implemented for --slow mode') + unless $option{fast}; + error('@preserve without chain') + unless exists $rule{chain}; + error('Cannot specify matches for @preserve') + if $rule{has_rule}; + expect_token(';'); + + my $domain = $rule{domain}; + my $domain_info = $domains{$domain}; + + error("\@preserve not supported on domain $domain") + unless $option{test} or exists $domain_info->{previous}; + + my $chains = $rule{chain}; + foreach my $table (to_array $rule{table}) { + my $table_info = $domain_info->{tables}{$table}; + foreach my $chain (to_array $chains) { + my $chain_info = $table_info->{chains}{$chain}; + error("Cannot \@preserve chain $chain because it is not empty") + if exists $chain_info->{rules} and @{$chain_info->{rules}}; + + $chain_info->{preserve} = 1; + } + } + + new_level(%rule, $prev); + next; + } + # this rule has something which isn't inherited by its # parent closure. This variable is used in a lot of # syntax checks. @@ -2548,25 +2627,60 @@ foreach my $chain (sort keys %{$table_info->{chains}}) { my $chain_info = $table_info->{chains}{$chain}; + + $$result_r .= $chain_info->{preserve} + if exists $chain_info->{preserve}; + + next if $option{flush}; + foreach my $rule (@{$chain_info->{rules}}) { $$result_r .= "-A $chain$rule->{rule}\n"; } } } +sub extract_table_from_save($$) { + my ($save, $table) = @_; + return $save =~ /^\*${table}\s*$\s*(.*?)^COMMIT\s*$/ms + ? $1 + : ''; +} + +sub extract_chain_from_table_save($$) { + my ($table_save, $chain) = @_; + my $result = ''; + $result .= $& while $table_save =~ /^-A \Q${chain}\E .*\n/gm; + return $result; +} + sub rules_to_save($) { my ($domain_info) = @_; # convert this into an iptables-save text my $result = "# Generated by ferm $VERSION on " . localtime() . "\n"; - while (my ($table, $table_info) = each %{$domain_info->{tables}}) { + foreach my $table (sort keys %{$domain_info->{tables}}) { + my $table_info = $domain_info->{tables}{$table}; + # select table $result .= '*' . $table . "\n"; # create chains / set policy foreach my $chain (sort keys %{$table_info->{chains}}) { my $chain_info = $table_info->{chains}{$chain}; + + if (exists $chain_info->{preserve}) { + my $table_save = + extract_table_from_save($domain_info->{previous}, $table); + my $chain_save = extract_chain_from_table_save($table_save, $chain); + $chain_info->{preserve} = $chain_save; + + if ($table_save =~ /^:\Q${chain}\E .*\n/m) { + $result .= $&; + next; + } + } + my $policy = $option{flush} ? undef : $chain_info->{policy}; unless (defined $policy) { if (is_netfilter_builtin_chain($table, $chain)) { @@ -2576,11 +2690,11 @@ $policy = '-'; } } + $result .= ":$chain $policy\ [0:0]\n"; } - table_to_save(\$result, $table_info) - unless $option{flush}; + table_to_save(\$result, $table_info); # do it $result .= "COMMIT\n"; diff -Nru ferm-2.3/src/import-ferm ferm-2.4/src/import-ferm --- ferm-2.3/src/import-ferm 2016-03-30 12:16:02.000000000 +0000 +++ ferm-2.4/src/import-ferm 2017-04-02 19:05:10.000000000 +0000 @@ -3,10 +3,10 @@ # # ferm, a firewall setup program that makes firewall rules easy! # -# Copyright (C) 2001-2012 Max Kellermann, Auke Kok +# Copyright 2001-2017 Max Kellermann, Auke Kok # -# Comments, questions, greetings and additions to this program -# may be sent to +# Bug reports and patches for this program may be sent to the GitHub +# repository: L # # This tool allows you to import an existing firewall configuration @@ -25,7 +25,8 @@ # # 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 +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA. # # $Id$ @@ -43,6 +44,9 @@ $ferm = 'ferm'; } + # Perl 5.24 requires this prefix or else it will only look in @INC + $ferm = "./$ferm" unless $ferm =~ /^\//; + # import its module tables require $ferm; @@ -54,6 +58,7 @@ %aliases = ( i => 'interface', o => 'outerface', + f => 'fragment', p => 'protocol', d => 'daddr', s => 'saddr',