Return to UOCC HomeComputing News Home
Header bar

Linux 2.4's Netfilter Dramatically Improves Linux Packet Filtering

Stephen Fromm
stephenf@ns.uoregon.edu

If you've been using Linux's packet-filter ipchains or ipfwadm, you may want to consider upgrading to kernel 2.4 to gain the advantages of its new packet filtering system. While 2.4 does contain backward compatibility support for ipchains and ipfwadm, you can only gain the advantages of the new packet filtering subsystem by using Netfilter (http://netfilter.kernelnotes.org).

How Netfilter's Packet-Filter Works

Briefly, a packet-filter is a program that uses a set of rules to determine how to handle a received (or about-to-be-sent) packet, and each rule describes specific packet characteristics (e.g., one rule might describe a packet from outside the UO network that is headed to port 25 on your machine). Each rule also has a target, specifying what to do with the packet in the event of a match, either allowing or denying further processing. If a packet fails to match a specific rule, the default policy for that set of rules dictates how to handle the packet.

Netfilter's biggest advantage is its ability to maintain "state," or knowledge of connections going in and out of the system. Many older firewall technologies inspect packets individually, without regard to the overall connection they're a part of. In contrast, Netfilter's "stateful" inspection is a much more powerful form of packet filtering because it is aware of the ongoing connection and the state it is in. States that provide connection-tracking analysis include New, Established, Related, and Invalid. You can see open connections in /proc/ip_conntrack, e.g.:

tcp 6 431990 ESTABLISHED src=192.168.10.36 dst=192.168.10.13

sport=32922 dport=80 src=192.168.10.13 dst=192.168.10.36 sport=80
dport=32922 [ASSURED] use=1

udp 17 170 src=192.168.10.36 dst=192.168.10.35 sport=32768 dport=53

src=192.168.10.35 dst=192.168.10.36 sport=53 dport=32768 [ASSURED] use=1

tcp 6 431962 ESTABLISHED src=192.168.10.36 dst=192.168.10.13

sport=935 dport=22 src=192.168.10.13 dst=192.168.10.36 sport=22
dport=935 [ASSURED] use=1

Netfilter can use this list of connections as another way of inspecting packets. Its ability to maintain state makes it much easier to write filtering rules under 2.4. An obvious example is FTP. Before 2.4, clumsy, complicated rules had to be written to allow FTP traffic, whereas Netfilter can recognize a related connection and allow it to pass through. Consider the following example:

# iptables -P INPUT DROP
# iptables -A INPUT -m state Ñstate ESTABLISHED,RELATED \
-i eth0 -s ! 192.168.10.36 -d 192.168.10.36 -j ACCEPT

In this example, we specified a default policy of 'DROP' for anything on the INPUT chain. Next, we accepted anything on the INPUT chain that's part of an existing (or related) connection whose source is anything but the ip address of the destination computer. This takes care of everything: there is no need to write complicated rules to allow DNS, client-based, or other kinds of traffic. To take advantage of this feature, you will want to make sure the appropriate modules are loaded:

# modprobe ip_conntrack
# modprobe ip_conntrack_ftp

Netfilter's modular design allows you to extend its capabilities with other modules as they become available, or you can write your own (see http://netfilter.kernelnotes.org/unreliable-guides/netfilter-hacking-HOWTO/index.html). By default, the maximum number of connections that Netfilter will track depends on the amount of memory available. On my test machine with 256MB, this was 16376. However, this can be changed with the sysctl interface. The timeout for a given connection depends on the protocol (TCP, UDP, or ICMP) and, if it's TCP, the current state of the connection (e.g. SYN_SENT, ESTABLISHED, TIME_WAIT). While the timeouts cannot be configured at runtime, you can modify the source code as appropriate (e.g., see the timeouts for TCP state tracking specified in the file /usr/src/linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c under the variable tcp_timeouts).

Other Notable Features
Aside from its ability to track connections, Netfilter offers some other interesting new features, including the ability to match any TCP flag, specify more LOG options, and limit rules.

Matching TCP flags. You can now match any TCP flag, an operation that could be useful in detecting certain types of scans. Suppose you're trying to detect Nmap's XMAS scan, where the FIN, URG, and PSH flags are set. With Netfilter, you can write a rule to detect it:

# iptables -A INPUT -p tcp -tcp-flags ALL FIN,URG,PSH \
-j LOG Ñlog-level warning -log-prefix "XMAS scan detected"

We specify that ALL flags should be examined, but only FIN, URG, and PSH should be set. This would then yield the following message to syslog:

Feb 23 17:45:50 bizarro kernel: XMAS scan detected IN+eth) OUT-

MAC=00:10:4b:32:14:4f:00:29:lc:de:12:08:00 src=192.168.10.46
DST=192.268.10.36 LEN=40 TOS=)x00 PREC=)x00 TTL=50 ID=59590 PROTO=TCP
SPT=40862 DPT=27 WINDOW=3072 RES=0X00 URG PSH FIN URGP=0

(For those feeling especially adventurous, there currently is a module in CVS that attempts to detect a port scan.)

More LOG options. The above example, which uses the target LOG, also highlights Netfilter's new logging mechanism. Among other options with LOG, you can specify the log-level (debug, info, notice, warning, etc.) and a prefix to the log message so as to distinguish one match from others.

Rate limiting. Lastly, Netfilter gives you the ability to limit the rate at which a packet can match a given rule. Remember, a packet traverses a chain of rules until it finds a match (or, failing that, follows the default policy for the chain). Once a match is found, it performs the targeted action. With the ability to limit the rate that a specific rule can be matched, you can now say "Once a packet matches this rule n times, stop performing the targeted action." You can specify the maximum number of matches allowed per second, minute, hour, or day. You can also specify the maximum burst before the limit is reached. The default is three matches per hour, with a burst limit of five. This feature can be used in conjunction with the LOG target to limit the number of logs generated for a specific match.

This feature may best be highlighted with two examples. Suppose we wanted to block and log NetBIOS traffic, but we don't want to log every NetBIOS packet we receive. We could use a rule such as:

# iptables -A INPUT -1 eth0 - s 128.223.0.0/16 -p udp.tcp --dport 137.139\

-m limit -j LOG --log-level info --log-prefix "Unwanted NetBIOS"

By using the "limit" module, this rule will log the first five NetBIOS packets and then begin enforcing the limit of three matches per hour. If more than three NetBIOS packets are received per hour, they will not be logged. This feature can also be used to limit incoming or outgoing traffic. For example, we could limit the number of pings we accept:

# iptables -A INPUT -p icmp --icmp-type echo-request \
-m limit --limit 1/s -j ACCEPT

This rule will be enforced once the limit-burst of five packets is reached. Afterwards, only one echo-request per second will be accepted. We can change the limit-burst value with the '--limit-burst' option.

These are just a sample of some of the useful features I've discovered when working with Netfilter. I encourage you to investigate Netfilter and the advantages it may have for you over ipchains and ipfwadm.

References
For more information on Netfilter and network security, see:

Modules

Below is a list of the modules you can compile in support of Netfilter when compiling Linux 2.4 (this is from 2.4.2).

CONFIG_IP_NF_MATCH_LIMIT - allows you to control the rate at which a rule can be matched. Mainly useful in combination with the LOG target (see "LOG target support" below) and to avoid some Denial of Service attacks.

CONFIG_IP_NF_MATCH_MAC - allows you to match packets based on the source ethernet address of the packet.

CONFIG_IP_NF_MATCH_MARK - allows you to match packets based on the 'nfmark' value in the packet. This can be set by the MARK target (see below).

CONFIG_IP_NF_MATCH_TOS - allows you to match packets based on the Type Of Service fields of the IP packet.

CONFIG_IP_NF_MATCH_STATE - allows you to match packets based on their relationship to a tracked connection (i.e. previous packets). This is a powerful tool for packet classification.

CONFIG_IP_NF_MATCH_UNCLEAN - matches any strange or invalid packets by looking at a series of fields in the IP, TCP, UDP and ICMP headers.

CONFIG_IP_NF_MATCH_OWNER - allows you to match locally generated packets based on who created them: the user, group, process or session.

CONFIG_IP_NF_FILTER - packet filtering defines a table 'filter', which has a series of rules for simple packet filtering at local input, forwarding and local output. See the man page for iptables(8)

CONFIG_IP_NF_TARGET_REJECT - the REJECT target allows a filtering rule to specify that an ICMP error should be issued in response to an incoming packet, rather than silently being dropped.

CONFIG_IP_NF_TARGET_MIRROR - the MIRROR target allows a filtering rule to specify that an incoming packet should be bounced back to the sender.

CONFIG_IP_NF_TARGET_MASQUERADE - all outgoing connections are changed to look as if they come from a particular interface's address, and if the interface goes down, those connections are lost. This is only useful for dialup accounts with dynamic IP address (i.e. your IP address will be different on next dialup).

CONFIG_IP_NF_TARGET_REDIRECT - all incoming connections are mapped onto the incoming interface's address, causing the packets to come to the local machine instead of passing through. This is useful for transparent proxies.

CONFIG_IP_NF_MANGLE - adds a 'mangle' table to iptables: see the man page for iptables(8). This table is used for various packet alterations which can effect how the packet is routed.

CONFIG_IP_NF_TARGET_TOS - adds a 'TOS' target, which allows you to create rules in the 'mangle' table that alter the Type Of Service field of an IP packet prior to routing.

CONFIG_IP_NF_TARGET_MARK - adds a 'MARK' target, allowing you to create rules in the 'mangle' table that alter the netfilter mark (nfmark) field associated with the packet prior to routing. This can change the routing method (see "IP: use netfilter MARK value as routing key") and can also be used by other subsystems to change their behavior.

CONFIG_IP_NF_TARGET_LOG - adds a 'LOG' target, which allows you to create rules in any iptables table that records the packet header to the syslog.


Spring 2001 Computing News | Computing Center Home Page