Package: firehol
Version: 3.1.1+ds-1
Severity: important
Tags: patch upstream

Dear Maintainer,

In recent Firehol (3.x), a family of options like FIREHOL_DROP_ORPHAN_TCP_ACK
were added, intended to avoid log noise for end-of-session packets where the
connection tracker has already closed them (on the assumption that they would
hit a log/reject or log/invalid).

These rules are inserted at the top of the INPUT/OUTPUT/FORWARD chains, and thus
apply before any user-specified action.

In particular, this means that even a 'policy accept' does not override these
rules, since the jump to a policy chain is later in I/O/F than the fixed rules.

On a current Stretch system (kernel 4.9.2-2) the NFSv3 client is not able to
function, and packets are counted against the DROP ACK/ACK INVALID/NEW rule.

These rules should be handled after user policy, both addressing the above issue
and also the more systematic situation that 'policy accept' should be equivalent
to not running the firewall at all [but possibly restricted to a single 
interface]

Disabling the option does allow NFS to work, however this is a global change
affecting other interfaces and traffic flows, should not be a requirement, is
clearly not an intended piece of behaviour, and is not at all an obvious place
to look.

A pull request to correct this behaviour has been raised at:
https://github.com/firehol/firehol/pull/197

Thanks,

Dominic

-- System Information:
Debian Release: 9.0
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)

Kernel: Linux 4.9.0-1-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages firehol depends on:
ii  firehol-common  3.1.1+ds-1
ii  lsb-base        9.20161125

Versions of packages firehol recommends:
ii  fireqos  3.1.1+ds-1

Versions of packages firehol suggests:
pn  firehol-doc    <none>
pn  firehol-tools  <none>
pn  ulogd2         <none>

-- Configuration Files:
/etc/default/firehol changed [not included]
/etc/firehol/firehol.conf changed [not included]

-- no debconf information
diff -rupN firehol-3.1.1+ds/.idea/encodings.xml 
firehol-3.1.1+ds-patched/.idea/encodings.xml
--- firehol-3.1.1+ds/.idea/encodings.xml        1970-01-01 01:00:00.000000000 
+0100
+++ firehol-3.1.1+ds-patched/.idea/encodings.xml        2017-02-02 
09:19:47.090975787 +0000
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding">
+    <file url="PROJECT" charset="UTF-8" />
+  </component>
+</project>
\ No newline at end of file
diff -rupN firehol-3.1.1+ds/.idea/firehol-3.1.1+ds.iml 
firehol-3.1.1+ds-patched/.idea/firehol-3.1.1+ds.iml
--- firehol-3.1.1+ds/.idea/firehol-3.1.1+ds.iml 1970-01-01 01:00:00.000000000 
+0100
+++ firehol-3.1.1+ds-patched/.idea/firehol-3.1.1+ds.iml 2017-02-02 
09:24:08.859903795 +0000
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module-library">
+      <library name="PHP Runtime" type="php">
+        <CLASSES>
+          <root 
url="jar://$APPLICATION_HOME_DIR$/plugins/php/lib/php.jar!/stubs/standard" />
+        </CLASSES>
+        <SOURCES>
+          <root 
url="jar://$APPLICATION_HOME_DIR$/plugins/php/lib/php.jar!/stubs/standard" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+  </component>
+</module>
\ No newline at end of file
diff -rupN firehol-3.1.1+ds/.idea/modules.xml 
firehol-3.1.1+ds-patched/.idea/modules.xml
--- firehol-3.1.1+ds/.idea/modules.xml  1970-01-01 01:00:00.000000000 +0100
+++ firehol-3.1.1+ds-patched/.idea/modules.xml  2017-02-02 09:19:47.102975651 
+0000
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/firehol-3.1.1+ds.iml" 
filepath="$PROJECT_DIR$/.idea/firehol-3.1.1+ds.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff -rupN firehol-3.1.1+ds/.idea/workspace.xml 
firehol-3.1.1+ds-patched/.idea/workspace.xml
--- firehol-3.1.1+ds/.idea/workspace.xml        2017-02-02 10:39:29.142322306 
+0000
+++ firehol-3.1.1+ds-patched/.idea/workspace.xml        2017-02-02 
10:13:07.988728744 +0000
@@ -18,8 +18,8 @@
       <file leaf-file-name="firehol" pinned="false" current-in-tab="true">
         <entry file="file://$PROJECT_DIR$/sbin/firehol">
           <provider selected="true" editor-type-id="text-editor">
-            <state relative-caret-position="-12462">
-              <caret line="11935" column="4" lean-forward="false" 
selection-start-line="11935" selection-start-column="4" 
selection-end-line="11935" selection-end-column="4" />
+            <state relative-caret-position="-12752">
+              <caret line="11984" column="4" lean-forward="false" 
selection-start-line="11984" selection-start-column="4" 
selection-end-line="11984" selection-end-column="4" />
               <folding />
             </state>
           </provider>
@@ -263,12 +263,12 @@
       <option name="number" value="Default" />
       <option name="presentableId" value="Default" />
       <updated>1486027187049</updated>
-      <workItem from="1486027188312" duration="3676000" />
+      <workItem from="1486027188312" duration="3116000" />
     </task>
     <servers />
   </component>
   <component name="TimeTrackingManager">
-    <option name="totallyTimeSpent" value="3676000" />
+    <option name="totallyTimeSpent" value="3116000" />
   </component>
   <component name="ToolWindowManager">
     <frame x="3954" y="42" width="3726" height="2118" extended-state="6" />
@@ -306,8 +306,8 @@
   <component name="editorHistoryManager">
     <entry file="file://$PROJECT_DIR$/sbin/firehol">
       <provider selected="true" editor-type-id="text-editor">
-        <state relative-caret-position="-12462">
-          <caret line="11935" column="4" lean-forward="false" 
selection-start-line="11935" selection-start-column="4" 
selection-end-line="11935" selection-end-column="4" />
+        <state relative-caret-position="-12752">
+          <caret line="11984" column="4" lean-forward="false" 
selection-start-line="11984" selection-start-column="4" 
selection-end-line="11984" selection-end-column="4" />
           <folding />
         </state>
       </provider>
diff -rupN firehol-3.1.1+ds/sbin/firehol firehol-3.1.1+ds-patched/sbin/firehol
--- firehol-3.1.1+ds/sbin/firehol       2017-02-02 10:30:35.100620537 +0000
+++ firehol-3.1.1+ds-patched/sbin/firehol       2017-02-02 12:02:26.057692425 
+0000
@@ -6346,6 +6346,7 @@ close_interface() {
        # make sure we have a policy
        test -z "${work_policy}" && work_policy="${DEFAULT_INTERFACE_POLICY}"
        local inlog=() outlog=()
+       local drop_noise=1
        case "${work_policy}" in
                return|RETURN)
                        set_work_function "Nothing to be done for policy RETURN 
of interface '${work_name}'"
@@ -6354,6 +6355,7 @@ close_interface() {
                        ;;
                        
                accept|ACCEPT)
+                   drop_noise=0
                        ;;
                
                *)      
@@ -6361,6 +6363,17 @@ close_interface() {
                        outlog=(loglimit "OUT-${work_name}")
                        ;;
        esac
+
+       if [ $drop_noise -eq 1 ]; then
+           if running_ipv4; then
+               firewall_filtering_policy_common_late iptables "in_${work_name}"
+               firewall_filtering_policy_common_late iptables 
"out_${work_name}"
+        fi
+           if running_ipv6; then
+               firewall_filtering_policy_common_late ip6tables 
"in_${work_name}"
+               firewall_filtering_policy_common_late ip6tables 
"out_${work_name}"
+        fi
+       fi
        
        set_work_function "Applying default policy of ${work_policy} on 
interface '${work_name}'"
 
@@ -6471,6 +6484,21 @@ close_master() {
                ip6tables -A FORWARD -m conntrack --ctstate RELATED -p icmpv6 
-j ACCEPT
        fi
 
+
+       # Insert session cleanup rules here, after user rules are processed
+    if [ ${ENABLE_IPV4} -eq 1 ]
+       then
+               firewall_filtering_policy_common_late iptables INPUT
+               firewall_filtering_policy_common_late iptables OUTPUT
+               firewall_filtering_policy_common_late iptables FORWARD
+       fi
+       if [ ${ENABLE_IPV6} -eq 1 ]
+       then
+       firewall_filtering_policy_common_late ip6tables INPUT
+       firewall_filtering_policy_common_late ip6tables OUTPUT
+       firewall_filtering_policy_common_late ip6tables FORWARD
+       fi
+
        set_work_function "Accepting TCP-RESET at the end of the firewall."
        rule chain "OUTPUT" state RELATED proto tcp custom '--tcp-flags ALL 
ACK,RST' action ACCEPT || return 1
        rule chain "FORWARD" state RELATED proto tcp custom '--tcp-flags ALL 
ACK,RST' action ACCEPT || return 1
@@ -11933,15 +11961,36 @@ firewall_filtering_policy_common() {
        # ${iptables_cmd} -t filter -A OUTPUT -m conntrack --ctstate RELATED -j 
ACCEPT
        # ${iptables_cmd} -t filter -A FORWARD -m conntrack --ctstate RELATED 
-j ACCEPT
 
+       if [ ! -z ${FIREHOL_GLOBAL_RPFILTER} ]
+       then
+               ${iptables_cmd} -t raw -A PREROUTING -m rpfilter 
${FIREHOL_GLOBAL_RPFILTER} -j DROP
+       fi
+}
+
+
+# this will be run when the first iptables command get executed in pre-process 
mode.
+# so that its commands are prepended to the other iptables commands of the 
firewall
+
+firewall_filtering_policy_common_late() {
+       local iptables_cmd="${1}"
+       local iptables_chain="${2}"
+
+       local oldns="${FIREHOL_NS_CURR}"
+
+       if [ "${iptables_cmd}" == "iptables" ]
+    then
+               FIREHOL_NS_CURR="ipv4"
+       else
+               FIREHOL_NS_CURR="ipv6"
+       fi
+
        if [ "${FIREHOL_DROP_ORPHAN_TCP_ACK_FIN}" = "1" ]
        then
                set_work_function "Silently droping TCP ACK+FIN packets 
(option: FIREHOL_DROP_ORPHAN_TCP_ACK_FIN)"
 
                # Silently drop orphan TCP/ACK FIN packets
                # before droping INVALID below, otherwise these will be logged 
as INVALID too
-               ${iptables_cmd} -t filter -A INPUT -p tcp --tcp-flags ACK,FIN 
ACK,FIN -m conntrack --ctstate NEW,INVALID -j DROP
-               ${iptables_cmd} -t filter -A OUTPUT -p tcp --tcp-flags ACK,FIN 
ACK,FIN -m conntrack --ctstate NEW,INVALID -j DROP
-               ${iptables_cmd} -t filter -A FORWARD -p tcp --tcp-flags ACK,FIN 
ACK,FIN -m conntrack --ctstate NEW,INVALID -j DROP
+               ${iptables_cmd} -t filter -A ${iptables_chain} -p tcp 
--tcp-flags ACK,FIN ACK,FIN -m conntrack --ctstate NEW,INVALID -j DROP
        fi
 
        if [ "${FIREHOL_DROP_ORPHAN_TCP_ACK_RST}" = "1" ]
@@ -11950,9 +11999,8 @@ firewall_filtering_policy_common() {
 
                # Silently drop orphan TCP/ACK RST packets
                # before droping INVALID below, otherwise these will be logged 
as INVALID too
-               ${iptables_cmd} -t filter -A INPUT -p tcp --tcp-flags ACK,RST 
ACK,RST -m conntrack --ctstate NEW,INVALID -j DROP
-               ${iptables_cmd} -t filter -A OUTPUT -p tcp --tcp-flags ACK,RST 
ACK,RST -m conntrack --ctstate NEW,INVALID -j DROP
-               ${iptables_cmd} -t filter -A FORWARD -p tcp --tcp-flags ACK,RST 
ACK,RST -m conntrack --ctstate NEW,INVALID -j DROP
+               ${iptables_cmd} -t filter -A ${iptables_chain} -p tcp 
--tcp-flags ACK,RST ACK,RST -m conntrack --ctstate NEW,INVALID -j DROP
+
        fi
 
        if [ "${FIREHOL_DROP_ORPHAN_TCP_ACK}" = "1" ]
@@ -11961,9 +12009,7 @@ firewall_filtering_policy_common() {
 
                # Silently drop orphan TCP/ACK packets
                # before droping INVALID below, otherwise these will be logged 
as INVALID too
-               ${iptables_cmd} -t filter -A INPUT -p tcp --tcp-flags ACK ACK 
-m conntrack --ctstate NEW,INVALID -j DROP
-               ${iptables_cmd} -t filter -A OUTPUT -p tcp --tcp-flags ACK ACK 
-m conntrack --ctstate NEW,INVALID -j DROP
-               ${iptables_cmd} -t filter -A FORWARD -p tcp --tcp-flags ACK ACK 
-m conntrack --ctstate NEW,INVALID -j DROP
+               ${iptables_cmd} -t filter -A ${iptables_chain} -p tcp 
--tcp-flags ACK ACK -m conntrack --ctstate NEW,INVALID -j DROP
        fi
 
        if [ "${FIREHOL_DROP_ORPHAN_TCP_RST}" = "1" ]
@@ -11972,9 +12018,7 @@ firewall_filtering_policy_common() {
 
                # Silently drop orphan TCP/RST packets
                # before droping INVALID below, otherwise these will be logged 
as INVALID too
-               ${iptables_cmd} -t filter -A INPUT -p tcp --tcp-flags RST RST 
-m conntrack --ctstate NEW,INVALID -j DROP
-               ${iptables_cmd} -t filter -A OUTPUT -p tcp --tcp-flags RST RST 
-m conntrack --ctstate NEW,INVALID -j DROP
-               ${iptables_cmd} -t filter -A FORWARD -p tcp --tcp-flags RST RST 
-m conntrack --ctstate NEW,INVALID -j DROP
+               ${iptables_cmd} -t filter -A ${iptables_chain} -p tcp 
--tcp-flags RST RST -m conntrack --ctstate NEW,INVALID -j DROP
        fi
 
        if [ "${iptables_cmd}" = "iptables" -a 
"${FIREHOL_DROP_ORPHAN_IPV4_ICMP_TYPE3}" = "1" ]
@@ -11983,9 +12027,7 @@ firewall_filtering_policy_common() {
 
                # Silently drop orphan ICMP/TYPE3 packets
                # before droping INVALID below, otherwise these will be logged 
as INVALID too
-               ${iptables_cmd} -t filter -A INPUT -p icmp --icmp-type 
destination-unreachable -m conntrack --ctstate NEW,INVALID -j DROP
-               ${iptables_cmd} -t filter -A OUTPUT -p icmp --icmp-type 
destination-unreachable -m conntrack --ctstate NEW,INVALID -j DROP
-               ${iptables_cmd} -t filter -A FORWARD -p icmp --icmp-type 
destination-unreachable -m conntrack --ctstate NEW,INVALID -j DROP
+               ${iptables_cmd} -t filter -A ${iptables_chain} -p icmp 
--icmp-type destination-unreachable -m conntrack --ctstate NEW,INVALID -j DROP
        fi
 
        # Drop all invalid packets.
@@ -11996,20 +12038,13 @@ firewall_filtering_policy_common() {
 
                if [ ${FIREHOL_LOG_DROP_INVALID} -eq 1 ]
                then
-                       rule table filter chain INPUT state INVALID action DROP 
loglimit "BLOCKED INVALID IN"
-                       rule table filter chain OUTPUT state INVALID action 
DROP loglimit "BLOCKED INVALID OUT"
-                       rule table filter chain FORWARD state INVALID action 
DROP loglimit "BLOCKED INVALID PASS"
+               rule table filter chain ${iptables_chain} state INVALID action 
DROP loglimit "BLOCKED INVALID"
                else
-                       ${iptables_cmd} -t filter -A INPUT -m conntrack 
--ctstate INVALID -j DROP
-                       ${iptables_cmd} -t filter -A OUTPUT -m conntrack 
--ctstate INVALID -j DROP
-                       ${iptables_cmd} -t filter -A FORWARD -m conntrack 
--ctstate INVALID -j DROP
+                       ${iptables_cmd} -t filter -A ${iptables_chain} -m 
conntrack --ctstate INVALID -j DROP
                fi
        fi
 
-       if [ ! -z ${FIREHOL_GLOBAL_RPFILTER} ]
-       then
-               ${iptables_cmd} -t raw -A PREROUTING -m rpfilter 
${FIREHOL_GLOBAL_RPFILTER} -j DROP
-       fi
+       FIREHOL_NS_CURR="${oldns}"
 }
 
 firewall_filtering_policy() {

Reply via email to