]> git.ipfire.org Git - network.git/commitdiff
firewall: Enhance filtering for INVALID packets.
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 5 May 2013 20:45:00 +0000 (22:45 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 5 May 2013 20:45:00 +0000 (22:45 +0200)
functions.constants-firewall
functions.firewall
functions.iptables
man/firewall-config.xml

index 41b1ac20cd3a686e807b4480b575e63e2f86a28c..f1eaf505b5531c10b0c80a9dcc275ffe3597457a 100644 (file)
@@ -85,6 +85,26 @@ FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_PMTU_DISCOVERY"
 FIREWALL_DEFAULT_TTL="64"
 FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_DEFAULT_TTL"
 
+# Log stealth scans
+FIREWALL_LOG_STEALTH_SCANS="true"
+FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_LOG_STEALTH_SCANS"
+
+# Log packets with bad TCP flags
+FIREWALL_LOG_BAD_TCP_FLAGS="true"
+FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_LOG_BAD_TCP_FLAGS"
+
+# Log INVALID TCP packets
+FIREWALL_LOG_INVALID_TCP="true"
+FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_LOG_INVALID_TCP"
+
+# Log INVALID UDP packets
+FIREWALL_LOG_INVALID_UDP="true"
+FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_LOG_INVALID_UDP"
+
+# Log INVALID ICMP packets
+FIREWALL_LOG_INVALID_ICMP="true"
+FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_LOG_INVALID_ICMP"
+
 FIREWALL_SUPPORTED_PROTOCOLS="tcp udp icmp igmp esp ah gre"
 FIREWALL_PROTOCOLS_SUPPORTING_PORTS="tcp udp"
 
index 947367a4bbdd643d8567a824baf9fc2fd4c168b1..494e3bb367edc9be1286293cf7573d4763704a16 100644 (file)
@@ -185,7 +185,7 @@ function firewall_start() {
        # Add default chains.
        firewall_filter_rh0_headers "${protocol}"
        firewall_filter_icmp "${protocol}"
-       firewall_tcp_state_flags "${protocol}"
+       firewall_filter_invalid_packets "${protocol}"
        firewall_custom_chains "${protocol}"
        firewall_connection_tracking "${protocol}"
        firewall_tcp_clamp_mss "${protocol}"
@@ -323,28 +323,145 @@ function firewall_custom_chains() {
        iptables "${protocol}" -t nat -A OUTPUT -j CUSTOMOUTPUT
 }
 
-function firewall_tcp_state_flags() {
+function firewall_filter_invalid_packets() {
        local protocol="${1}"
        assert isset protocol
 
-       log INFO "Creating TCP State Flags chain..."
+       local log_limit="-m limit --limit 5/m --limit-burst 10"
 
-       iptables_chain_create "${protocol}" BADTCP_LOG
-       iptables "${protocol}" -A BADTCP_LOG -p tcp -j "$(iptables_LOG "Illegal TCP state: ")"
-       iptables "${protocol}" -A BADTCP_LOG -j DROP
+       # Create a chain
+       iptables_chain_create "${protocol}" FILTER_INVALID
+       iptables "${protocol}" -A INPUT   -j FILTER_INVALID
+       iptables "${protocol}" -A OUTPUT  -j FILTER_INVALID
+       iptables "${protocol}" -A FORWARD -j FILTER_INVALID
 
-       iptables_chain_create "${protocol}" BADTCP
-       iptables "${protocol}" -A BADTCP -p tcp --tcp-flags ALL NONE        -j BADTCP_LOG
-       iptables "${protocol}" -A BADTCP -p tcp --tcp-flags SYN,FIN SYN,FIN -j BADTCP_LOG
-       iptables "${protocol}" -A BADTCP -p tcp --tcp-flags SYN,RST SYN,RST -j BADTCP_LOG
-       iptables "${protocol}" -A BADTCP -p tcp --tcp-flags FIN,RST FIN,RST -j BADTCP_LOG
-       iptables "${protocol}" -A BADTCP -p tcp --tcp-flags ACK,FIN FIN     -j BADTCP_LOG
-       iptables "${protocol}" -A BADTCP -p tcp --tcp-flags ACK,PSH PSH     -j BADTCP_LOG
-       iptables "${protocol}" -A BADTCP -p tcp --tcp-flags ACK,URG URG     -j BADTCP_LOG
+       # Create a chain where only TCP packets go
+       iptables_chain_create "${protocol}" FILTER_INVALID_TCP
+       iptables "${protocol}" -A FILTER_INVALID -p tcp -j FILTER_INVALID_TCP
 
-       iptables "${protocol}" -A INPUT   -p tcp -j BADTCP
-       iptables "${protocol}" -A OUTPUT  -p tcp -j BADTCP
-       iptables "${protocol}" -A FORWARD -p tcp -j BADTCP
+       # Create a chain where only UDP packets go
+       iptables_chain_create "${protocol}" FILTER_INVALID_UDP
+       iptables "${protocol}" -A FILTER_INVALID -p udp -j FILTER_INVALID_UDP
+
+       # Create a chain where only ICMP packets go
+       iptables_chain_create "${protocol}" FILTER_INVALID_ICMP
+       iptables "${protocol}" -A FILTER_INVALID -p icmp -j FILTER_INVALID_ICMP
+
+
+       # Optionally log all port scans
+
+       if enabled FIREWALL_LOG_STEALTH_SCANS; then
+               log INFO "Logging of stealth scans enabled"
+
+               # NMAP FIN/URG/PSH - XMAS scan
+               iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL FIN,URG,PSH \
+                       "${log_limit}" -j "$(iptables_LOG "Stealth XMAS scan")"
+
+               # SYN/RST/ACK/FIN/URG
+               iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG \
+                       "${log_limit}" -j "$(iptables_LOG "Stealth XMAS-PSH scan")"
+
+               # ALL/ALL
+               iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL ALL \
+                       "${log_limit}" -j "$(iptables_LOG "Stealth XMAS-ALL scan")"
+
+               # NMAP FIN Stealth
+               iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL FIN \
+                       "${log_limit}" -j "$(iptables_LOG "Stealth FIN scan")"
+
+               # SYN/RST
+               iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags SYN,RST SYN,RST \
+                       "${log_limit}" -j "$(iptables_LOG "Stealth SYN/RST scan")"
+
+               # SYN/FIN
+               iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags SYN,FIN SYN,FIN \
+                       "${log_limit}" -j "$(iptables_LOG "Stealth SYN/FIN scan")"
+
+               # Null scan
+               iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL NONE \
+                       "${log_limit}" -j "$(iptables_LOG "Stealth NULL scan")"
+       else
+               log INFO "Logging of stealth scans disabled"
+       fi
+
+
+       # Drop scan packets
+
+       # NMAP FIN/URG/PSH
+       iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
+
+       # SYN/RST/ACK/FIN/URG
+       iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
+
+       # ALL/ALL
+       iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL ALL -j DROP
+
+       # NMAP FIN Stealth
+       iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL FIN -j DROP
+
+       # SYN/RST
+       iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
+
+       # SYN/FIN
+       iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
+
+       # Null scan
+       iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL NONE -j DROP
+
+
+       # Log packets with bad flags
+
+       if enabled FIREWALL_LOG_BAD_TCP_FLAGS; then
+               log INFO "Logging of packets with bad TCP flags enabled"
+
+               # Option 64
+               iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-option 64 \
+                       "${log_limit}" -j "$(iptables_LOG "Bad TCP flag(64)")"
+
+               # Option 128
+               iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-option 128 \
+                       "${log_limit}" -j "$(iptables_LOG "Bad TCP flag(128)")"
+       else
+               log INFO "Logging of packets with bad TCP flags disabled"
+       fi
+
+       # Drop packets with bad flags
+
+       iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-option 64 -j DROP
+       iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-option 128 -j DROP
+
+
+       # Log invalid packets
+
+       if enabled FIREWALL_LOG_INVALID_TCP; then
+               log INFO "Logging of INVALID TCP packets enabled"
+
+               iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp -m conntrack --ctstate INVALID \
+                       "${log_limit}" -j "$(iptables_LOG "INVALID TCP")"
+       else
+               log INFO "Logging of INVALID TCP packets disabled"
+       fi
+
+       if enabled FIREWALL_LOG_INVALID_UDP; then
+               log INFO "Logging of INVALID UDP packets enabled"
+
+               iptables "${protocol}" -A FILTER_INVALID_UDP -p udp -m conntrack --ctstate INVALID \
+                       "${log_limit}" -j "$(iptables_LOG "INVALID UDP")"
+       else
+               log INFO "Logging of INVALID UDP packets disabled"
+       fi
+
+       if enabled FIREWALL_LOG_INVALID_ICMP; then
+               log INFO "Logging of INVALID ICMP packets enabled"
+
+               iptables "${protocol}" -A FILTER_INVALID_ICMP -p icmp -m conntrack --ctstate INVALID \
+                       "${log_limit}" -j "$(iptables_LOG "INVALID ICMP")"
+       else
+               log INFO "Logging of INVALID ICMP packets disabled"
+       fi
+
+       # Drop all INVALID packets
+       iptables "${protocol}" -A FILTER_INVALID -m conntrack --ctstate INVALID -j DROP
 }
 
 function firewall_tcp_clamp_mss() {
index 3e1b929397b895d00dd8d3033a8099507e39c491..e2e2b2ea0245343cfcccf591d52fe020dcf685bd 100644 (file)
@@ -380,9 +380,25 @@ function iptables_dump() {
 }
 
 function iptables_LOG() {
-       local prefix=${1}
+       local prefix="${1}"
        local ret
 
+       # Automatically append a colon and whitespace.
+       case "${prefix}" in
+               # Everything is fine.
+               "*: ") ;;
+
+               # Ends with colon, add whitespace only.
+               "*:")
+                       prefix="${prefix} "
+                       ;;
+
+               # Append both.
+               *)
+                       prefix="${prefix}: "
+                       ;;
+       esac
+
        case "${FIREWALL_LOG_METHOD}" in
                nflog)
                        ret="NFLOG --nflog-threshold ${FIREWALL_NFLOG_THRESHOLD}"
index 6bc8f62f429dd678b1474ad8a433861211b07246..ae011e14114799546361f284c2a46eefe50b865b 100644 (file)
                                </listitem>
                        </varlistentry>
 
+                       <varlistentry>
+                               <term>
+                                       <varname>FIREWALL_LOG_BAD_TCP_FLAGS</varname> = [<emphasis>true</emphasis>|false]
+                               </term>
+
+                               <listitem>
+                                       <para>
+                                               Enable this to log TCP packets with bad flags or options.
+                                       </para>
+                               </listitem>
+                       </varlistentry>
+
+                       <varlistentry>
+                               <term>
+                                       <varname>FIREWALL_LOG_INVALID_ICMP</varname> = [<emphasis>true</emphasis>|false]
+                               </term>
+
+                               <listitem>
+                                       <para>
+                                               Enable this to log INVALID ICMP packets.
+                                       </para>
+                               </listitem>
+                       </varlistentry>
+
+                       <varlistentry>
+                               <term>
+                                       <varname>FIREWALL_LOG_INVALID_TCP</varname> = [<emphasis>true</emphasis>|false]
+                               </term>
+
+                               <listitem>
+                                       <para>
+                                               Enable this to log INVALID TCP packets.
+                                       </para>
+                               </listitem>
+                       </varlistentry>
+
+                       <varlistentry>
+                               <term>
+                                       <varname>FIREWALL_LOG_INVALID_UDP</varname> = [<emphasis>true</emphasis>|false]
+                               </term>
+
+                               <listitem>
+                                       <para>
+                                               Enable this to log INVALID UDP packets.
+                                       </para>
+                               </listitem>
+                       </varlistentry>
+
                        <varlistentry>
                                <term>
                                        <varname>FIREWALL_LOG_MARTIANS</varname> = [true|<emphasis>false</emphasis>]
                                </listitem>
                        </varlistentry>
 
+                       <varlistentry>
+                               <term>
+                                       <varname>FIREWALL_LOG_STEALTH_SCANS</varname> = [<emphasis>true</emphasis>|false]
+                               </term>
+
+                               <listitem>
+                                       <para>
+                                               Enable this to log all stealth scans.
+                                       </para>
+                               </listitem>
+                       </varlistentry>
+
                        <varlistentry>
                                <term>
                                        <varname>FIREWALL_PMTU_DISCOVERY</varname> = [<emphasis>true</emphasis>|false]