iptables has a fairly detailed manual page (man iptables),
and if you need more detail on particulars. Those of you familiar
with ipchains may simply want to look at
Differences Between iptables and ipchains; they are very
similar.
There are several different things you can do with iptables.
You start with three built-in chains INPUT, OUTPUT
and FORWARD which you can't delete. Let's look at the
operations to manage whole chains:
There are several ways to manipulate rules inside a chain:
iptables may be a module, called (`iptable_filter.o'), which should be
automatically loaded when you first run iptables. It can
also be built into the kernel permenantly.
Before any iptables commands have been run (be careful: some distributions will run iptables in their initialization scripts), there will be no rules in any of the built-in chains (`INPUT', `FORWARD' and `OUTPUT'), all the chains will have a policy of ACCEPT. You can alter the default policy of the FORWARD chain by providing the `forward=0' option to the iptable_filter module.
This is the bread-and-butter of packet filtering; manipulating rules. Most commonly, you will probably use the append (-A) and delete (-D) commands. The others (-I for insert and -R for replace) are simple extensions of these concepts.
Each rule specifies a set of conditions the packet must meet, and what to do if it meets them (a `target'). For example, you might want to drop all ICMP packets coming from the IP address 127.0.0.1. So in this case our conditions are that the protocol must be ICMP and that the source address must be 127.0.0.1. Our target is `DROP'.
127.0.0.1 is the `loopback' interface, which you will have even if you have no real network connection. You can use the `ping' program to generate such packets (it simply sends an ICMP type 8 (echo request) which all cooperative hosts should obligingly respond to with an ICMP type 0 (echo reply) packet). This makes it useful for testing.
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.2/0.2/0.2 ms
# iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
#
You can see here that the first ping succeeds (the `-c 1' tells ping to only send a single packet).
Then we append (-A) to the `INPUT' chain, a rule specifying that for packets from 127.0.0.1 (`-s 127.0.0.1') with protocol ICMP (`-p icmp') we should jump to DROP (`-j DROP').
Then we test our rule, using the second ping. There will be a pause before the program gives up waiting for a response that will never come.
We can delete the rule in one of two ways. Firstly, since we know that it is the only rule in the input chain, we can use a numbered delete, as in:
# iptables -D INPUT 1
#
To delete rule number 1 in the INPUT chain.
The second way is to mirror the -A command, but replacing the -A with -D. This is useful when you have a complex chain of rules and you don't want to have to count them to figure out that it's rule 37 that you want to get rid of. In this case, we would use:
# iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP
#
The syntax of -D must have exactly the same options as the -A (or -I
or -R) command. If there are multiple identical rules in the same
chain, only the first will be deleted.
We have seen the use of `-p' to specify protocol, and `-s' to specify source address, but there are other options we can use to specify packet characteristics. What follows is an exhaustive compendium.
Source (`-s', `--source' or `--src') and destination (`-d', `--destination' or `--dst') IP addresses can be specified in four ways. The most common way is to use the full name, such as `localhost' or `www.linuxhq.com'. The second way is to specify the IP address such as `127.0.0.1'.
The third and fourth ways allow specification of a group of IP addresses, such as `199.95.207.0/24' or `199.95.207.0/255.255.255.0'. These both specify any IP address from 199.95.207.0 to 199.95.207.255 inclusive; the digits after the `/' tell which parts of the IP address are significant. `/32' or `/255.255.255.255' is the default (match all of the IP address). To specify any IP address at all `/0' can be used, like so:
[ NOTE: `-s 0/0' is redundant here. ]
# iptables -A INPUT -s 0/0 -j DROP
#
This is rarely used, as the effect above is the same as not specifying the `-s' option at all.
Many flags, including the `-s' (or `--source') and `-d' (`--destination') flags can have their arguments preceded by `!' (pronounced `not') to match addresses NOT equal to the ones given. For example. `-s ! localhost' matches any packet not coming from localhost.
The protocol can be specified with the `-p' (or `--protocol') flag. Protocol can be a number (if you know the numeric protocol values for IP) or a name for the special cases of `TCP', `UDP' or `ICMP'. Case doesn't matter, so `tcp' works as well as `TCP'.
The protocol name can be prefixed by a `!', to invert it, such as `-p ! TCP' to specify packets which are not TCP.
The `-i' (or `--in-interface') and `-o' (or `--out-interface') options
specify the name of an interface to match. An interface is
the physical device the packet came in on (`-i') or is going out on
(`-o'). You can use the ifconfig command to list the
interfaces which are `up' (i.e., working at the moment).
Packets traversing the INPUT chain don't have an output
interface, so any rule using `-o' in this chain will never match.
Similarly, packets traversing the OUTPUT chain don't have an
input interface, so any rule using `-i' in this chain will never match.
Only packets traversing the FORWARD chain have both an
input and output interface.
It is perfectly legal to specify an interface that currently does not
exist; the rule will not match anything until the interface comes up.
This is extremely useful for dial-up PPP links (usually interface
ppp0) and the like.
As a special case, an interface name ending with a `+' will match all
interfaces (whether they currently exist or not) which begin with that
string. For example, to specify a rule which matches all PPP
interfaces, the -i ppp+ option would be used.
The interface name can be preceded by a `!' with spaces around it, to
match a packet which does not match the specified
interface(s), eg -i ! ppp+.
Sometimes a packet is too large to fit down a wire all at once. When this happens, the packet is divided into fragments, and sent as multiple packets. The other end reassembles these fragments to reconstruct the whole packet.
The problem with fragments is that the initial fragment has the complete header fields (IP + TCP, UDP and ICMP) to examine, but subsequent packets only have a subset of the headers (IP without the additional protocol fields). Thus looking inside subsequent fragments for protocol headers (such as is done by the TCP, UDP and ICMP extensions) is not possible.
If you are doing connection tracking or NAT, then all fragments will get merged back together before they reach the packet filtering code, so you need never worry about fragments.
Please also note that in the INPUT chain of the filter table (or any other table hooking into the NF_IP_LOCAL_IN hook) is traversed after defragmentation of the core IP stack.
Otherwise, it is important to understand how fragments get treated by
the filtering rules. Any filtering rule that asks for information we
don't have will not match. This means that the first fragment is
treated like any other packet. Second and further fragments won't be.
Thus a rule -p TCP --sport www (specifying a source port of
`www') will never match a fragment (other than the first fragment).
Neither will the opposite rule -p TCP --sport ! www.
However, you can specify a rule specifically for second and further fragments, using the `-f' (or `--fragment') flag. It is also legal to specify that a rule does not apply to second and further fragments, by preceding the `-f' with ` ! '.
Usually it is regarded as safe to let second and further fragments through, since filtering will effect the first fragment, and thus prevent reassembly on the target host; however, bugs have been known to allow crashing of machines simply by sending fragments. Your call.
Note for network-heads: malformed packets (TCP, UDP and ICMP packets too short for the firewalling code to read the ports or ICMP code and type) are dropped when such examinations are attempted. So are TCP fragments starting at position 8.
As an example, the following rule will drop any fragments going to 192.168.1.1:
# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP
#
iptables is extensible, meaning that both the
kernel and the iptables tool can be extended to provide new features.
Some of these extensions are standard, and other are more exotic. Extensions can be made by other people and distributed separately for niche users.
Kernel extensions normally live in the kernel module subdirectory, such as /lib/modules/2.4.0-test10/kernel/net/ipv4/netfilter. They are demand loaded if your kernel was compiled with CONFIG_KMOD set, so you should not need to manually insert them.
Extensions to the iptables program are shared libraries which usually live in /usr/local/lib/iptables/, although a distribution would put them in /lib/iptables or /usr/lib/iptables.
Extensions come in two types: new targets, and new matches (we'll talk about new targets a little later). Some protocols automatically offer new tests: currently these are TCP, UDP and ICMP as shown below.
For these you will be able to specify the new tests on the command line after the `-p' option, which will load the extension. For explicit new tests, use the `-m' option to load the extension, after which the extended options will be available.
To get help on an extension, use the option to load it (`-p', `-j' or `-m') followed by `-h' or `--help', eg:
# iptables -p tcp --help
#
The TCP extensions are automatically loaded if `-p tcp' is specified. It provides the following options (none of which match fragments).
Followed by an optional `!', then two strings of flags, allows you to filter on specific TCP flags. The first string of flags is the mask: a list of flags you want to examine. The second string of flags tells which one(s) should be set. For example,
# iptables -A INPUT --protocol tcp --tcp-flags ALL SYN,ACK -j DROP
This indicates that all flags should be examined (`ALL' is synonymous with `SYN,ACK,FIN,RST,URG,PSH'), but only SYN and ACK should be set. There is also an argument `NONE' meaning no flags.
Optionally preceded by a `!', this is shorthand for `--tcp-flags SYN,RST,ACK SYN'.
followed by an optional `!', then either a single TCP port, or a range of ports. Ports can be port names, as listed in /etc/services, /netource' or `--src') and destination (`-d', `--destination' or `--dst') IP addresses can be specified in four ways. The most common way is to use the full name, such as `localhost' or `www.linuxhq.com'. The second way is to specify the IP address such as `127.0.0.1'.
The third and fourth ways allow specification of a group of IP addresses, such as `199.95.207.0/24' or `199.95.207.0/255.255.255.0'. These both specify any IP address from 199.95.207.0 to 199.95.207.255 inclusive; the digits after the `/' tell which parts of the IP address are significant. `/32' or `/255.255.255.255' is the default (match all of the IP address). To specify any IP address at all `/0' can be used, like so:
[ NOTE: `-s 0/0' is redundant here. ]
# iptables -A INPUT -s 0/0 -j DROP
#
This is rarely used, as the effect above is the same as not specifying the `-s' option at all.
Many flags, including the `-s' (or `--source') and `-d' (`--destination') flags can have their arguments preceded by `!' (pronounced `not') to match addresses NOT equal to the ones given. For example. `-s ! localhost' matches any packet not coming from localhost.
The protocol can be specified with the `-p' (or `--protocol') flag. Protocol can be a number (if you know the numeric protocol values for IP) or a name for the special cases of `TCP', `UDP' or `ICMP'. Case doesn't matter, so `tcp' works as well as `TCP'.
The protocol name can be prefixed by a `!', to invert it, such as `-p ! TCP' to specify packets which are not TCP.
The `-i' (or `--in-interface') and `-o' (or `--out-interface') options
specify the name of an interface to match. An interface is
the physical device the packet came in on (`-i') or is going out on
(`-o'). You can use the ifconfig command to list the
interfaces which are `up' (i.e., working at the moment).
Packets traversing the INPUT chain don't have an output
interface, so any rule using `-o' in this chain will never match.
Similarly, packets traversing the OUTPUT chain don't have an
input interface, so any rule using `-i' in this chain will never match.
Only packets traversing the FORWARD chain have both an
input and output interface.
It is perfectly legal to specify an interface that currently does not
exist; the rule will not match anything until the interface comes up.
This is extremely useful for dial-up PPP links (usually interface
ppp0) and the like.
As a special case, an interface name ending with a `+' will match all
interfaces (whether they currently exist or not) which begin with that
string. For example, to specify a rule which matches all PPP
interfaces, the -i ppp+ option would be used.
The interface name can be preceded by a `!' with spaces around it, to
match a packet which does not match the specified
interface(s), eg -i ! ppp+.
Sometimes a packet is too large to fit down a wire all at once. When this happens, the packet is divided into fragments, and sent as multiple packets. The other end reassembles these fragments to reconstruct the whole packet.
The problem with fragments is that the initial fragment has the complete header fields (IP + TCP, UDP and ICMP) to examine, but subsequent packets only have a subset of the headers (IP without the additional protocol fields). Thus looking inside subsequent fragments for protocol headers (such as is done by the TCP, UDP and ICMP extensions) is not possible.
If you are doing connection tracking or NAT, then all fragments will get merged back together before they reach the packet filtering code, so you need never worry about fragments.
Please also note that in the INPUT chain of the filter table (or any other table hooking into the NF_IP_LOCAL_IN hook) is traversed after defragmentation of the core IP stack.
Otherwise, it is important to understand how fragments get treated by
the filtering rules. Any filtering rule that asks for information we
don't have will not match. This means that the first fragment is
treated like any other packet. Second and further fragments won't be.
Thus a rule -p TCP --sport www (specifying a source port of
`www') will never match a fragment (other than the first fragment).
Neither will the opposite rule -p TCP --sport ! www.
However, you can specify a rule specifically for second and further fragments, using the `-f' (or `--fragment') flag. It is also legal to specify that a rule does not apply to second and further fragments, by preceding the `-f' with ` ! '.
Usually it is regarded as safe to let second and further fragments through, since filtering will effect the first fragment, and thus prevent reassembly on the target host; however, bugs have been known to allow crashing of machines simply by sending fragments. Your call.
Note for network-heads: malformed packets (TCP, UDP and ICMP packets too short for the firewalling code to read the ports or ICMP code and type) are dropped when such examinations are attempted. So are TCP fragments starting at position 8.
As an example, the following rule will drop any fragments going to 192.168.1.1:
# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP
#
iptables is extensible, meaning that both the
kernel and the iptables tool can be extended to provide new features.
Some of these extensions are standard, and other are more exotic. Extensions can be made by other people and distributed separately for niche users.
Kernel extensions normally live in the kernel module subdirectory, such as /lib/modules/2.4.0-test10/kernel/net/ipv4/netfilter. They are demand loaded if your kernel was compiled with CONFIG_KMOD set, so you should not need to manually insert them.
Extensions to the iptables program are shared libraries which usually live in /usr/local/lib/iptables/, although a distribution would put them in /lib/iptables or /usr/lib/iptables.
Extensions come in two types: new targets, and new matches (we'll talk about new targets a little later). Some protocols automatically offer new tests: currently these are TCP, UDP and ICMP as shown below.
For these you will be able to specify the new tests on the command line after the `-p' option, which will load the extension. For explicit new tests, use the `-m' option to load the extension, after which the extended options will be available.
To get help on an extension, use the option to load it (`-p', `-j' or `-m') followed by `-h' or `--help', eg:
# iptables -p tcp --help
#
The TCP extensions are automatically loaded if `-p tcp' is specified. It provides the following options (none of which match fragments).
Followed by an optional `!', then two strings of flags, allows you to filter on specific TCP flags. The first string of flags is the mask: a list of flags you want to examine. The second string of flags tells which one(s) should be set. For example,
# iptables -A INPUT --protocol tcp --tcp-flags ALL SYN,ACK -j DROP
This indicates that all flags should be examined (`ALL' is synonymous with `SYN,ACK,FIN,RST,URG,PSH'), but only SYN and ACK should be set. There is also an argument `NONE' meaning no flags.
Optionally preceded by a `!', this is shorthand for `--tcp-flags SYN,RST,ACK SYN'.
followed by an optional `!', then either a single TCP port, or a range of ports. Ports can be port names, as listed in /etc/services, /netource' or `--src') and destination (`-d', `--destination' or `--dst') IP addresses can be specified in four ways. The most common way is to use the full name, such as `localhost' or `www.linuxhq.com'. The second way is to specify the IP address such as `127.0.0.1'.
The third and fourth ways allow specification of a group of IP addresses, such as `199.95.207.0/24' or `199.95.207.0/255.255.255.0'. These both specify any IP address from 199.95.207.0 to 199.95.207.255 inclusive; the digits after the `/' tell which parts of the IP address are significant. `/32' or `/255.255.255.255' is the default (match all of the IP address). To specify any IP address at all `/0' can be used, like so:
[ NOTE: `-s 0/0' is redundant here. ]
# iptables -A INPUT -s 0/0 -j DROP
#
This is rarely used, as the effect above is the same as not specifying the `-s' option at all.
Many flags, including the `-s' (or `--source') and `-d' (`--destination') flags can have their arguments preceded by `!' (pronounced `not') to match addresses NOT equal to the ones given. For example. `-s ! localhost' matches any packet not coming from localhost.
The protocol can be specified with the `-p' (or `--protocol') flag. Protocol can be a number (if you know the numeric protocol values for IP) or a name for the special cases of `TCP', `UDP' or `ICMP'. Case doesn't matter, so `tcp' works as well as `TCP'.
The protocol name can be prefixed by a `!', to invert it, such as `-p ! TCP' to specify packets which are not TCP.
The `-i' (or `--in-interface') and `-o' (or `--out-interface') options
specify the name of an interface to match. An interface is
the physical device the packet came in on (`-i') or is going out on
(`-o'). You can use the ifconfig command to list the
interfaces which are `up' (i.e., working at the moment).
Packets traversing the INPUT chain don't have an output
interface, so any rule using `-o' in this chain will never match.
Similarly, packets traversing the OUTPUT chain don't have an
input interface, so any rule using `-i' in this chain will never match.
Only packets traversing the FORWARD chain have both an
input and output interface.
It is perfectly legal to specify an interface that currently does not
exist; the rule will not match anything until the interface comes up.
This is extremely useful for dial-up PPP links (usually interface
ppp0) and the like.
As a special case, an interface name ending with a `+' will match all
interfaces (whether they currently exist or not) which begin with that
string. For example, to specify a rule which matches all PPP
interfaces, the -i ppp+ option would be used.
The interface name can be preceded by a `!' with spaces around it, to
match a packet which does not match the specified
interface(s), eg -i ! ppp+.
Sometimes a packet is too large to fit down a wire all at once. When this happens, the packet is divided into fragments, and sent as multiple packets. The other end reassembles these fragments to reconstruct the whole packet.
The problem with fragments is that the initial fragment has the complete header fields (IP + TCP, UDP and ICMP) to examine, but subsequent packets only have a subset of the headers (IP without the additional protocol fields). Thus looking inside subsequent fragments for protocol headers (such as is done by the TCP, UDP and ICMP extensions) is not possible.
If you are doing connection tracking or NAT, then all fragments will get merged back together before they reach the packet filtering code, so you need never worry about fragments.
Please also note that in the INPUT chain of the filter table (or any other table hooking into the NF_IP_LOCAL_IN hook) is traversed after defragmentation of the core IP stack.
Otherwise, it is important to understand how fragments get treated by
the filtering rules. Any filtering rule that asks for information we
don't have will not match. This means that the first fragment is
treated like any other packet. Second and further fragments won't be.
Thus a rule -p TCP --sport www (specifying a source port of
`www') will never match a fragment (other than the first fragment).
Neither will the opposite rule -p TCP --sport ! www.
However, you can specify a rule specifically for second and further fragments, using the `-f' (or `--fragment') flag. It is also legal to specify that a rule does not apply to second and further fragments, by preceding the `-f' with ` ! '.
Usually it is regarded as safe to let second and further fragments through, since filtering will effect the first fragment, and thus prevent reassembly on the target host; however, bugs have been known to allow crashing of machines simply by sending fragments. Your call.
Note for network-heads: malformed packets (TCP, UDP and ICMP packets too short for the firewalling code to read the ports or ICMP code and type) are dropped when such examinations are attempted. So are TCP fragments starting at position 8.
As an example, the following rule will drop any fragments going to 192.168.1.1:
# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP
#
iptables is extensible, meaning that both the
kernel and the iptables tool can be extended to provide new features.
Some of these extensions are standard, and other are more exotic. Extensions can be made by other people and distributed separately for niche users.
Kernel extensions normally live in the kernel module subdirectory, such as /lib/modules/2.4.0-test10/kernel/net/ipv4/netfilter. They are demand loaded if your kernel was compiled with CONFIG_KMOD set, so you should not need to manually insert them.
Extensions to the iptables program are shared libraries which usually live in /usr/local/lib/iptables/, although a distribution would put them in /lib/iptables or /usr/lib/iptables.
Extensions come in two types: new targets, and new matches (we'll talk about new targets a little later). Some protocols automatically offer new tests: currently these are TCP, UDP and ICMP as shown below.
For these you will be able to specify the new tests on the command line after the `-p' option, which will load the extension. For explicit new tests, use the `-m' option to load the extension, after which the extended options will be available.
To get help on an extension, use the option to load it (`-p', `-j' or `-m') followed by `-h' or `--help', eg:
# iptables -p tcp --help
#
The TCP extensions are automatically loaded if `-p tcp' is specified. It provides the following options (none of which match fragments).
Followed by an optional `!', then two strings of flags, allows you to filter on specific TCP flags. The first string of flags is the mask: a list of flags you want to examine. The second string of flags tells which one(s) should be set. For example,
# iptables -A INPUT --protocol tcp --tcp-flags ALL SYN,ACK -j DROP
This indicates that all flags should be examined (`ALL' is synonymous with `SYN,ACK,FIN,RST,URG,PSH'), but only SYN and ACK should be set. There is also an argument `NONE' meaning no flags.
Optionally preceded by a `!', this is shorthand for `--tcp-flags SYN,RST,ACK SYN'.
followed by an optional `!', then either a single TCP port, or a range of ports. Ports can be port names, as listed in /etc/services, /netource' or `--src') and destination (`-d', `--destination' or `--dst') IP addresses can be specified in four ways. The most common way is to use the full name, such as `localhost' or `www.linuxhq.com'. The second way is to specify the IP address such as `127.0.0.1'.
The third and fourth ways allow specification of a group of IP addresses, such as `199.95.207.0/24' or `199.95.207.0/255.255.255.0'. These both specify any IP address from 199.95.207.0 to 199.95.207.255 inclusive; the digits after the `/' tell which parts of the IP address are significant. `/32' or `/255.255.255.255' is the default (match all of the IP address). To specify any IP address at all `/0' can be used, like so:
[ NOTE: `-s 0/0' is redundant here. ]
# iptables -A INPUT -s 0/0 -j DROP
#
This is rarely used, as the effect above is the same as not specifying the `-s' option at all.
Many flags, including the `-s' (or `--source') and `-d' (`--destination') flags can have their arguments preceded by `!' (pronounced `not') to match addresses NOT equal to the ones given. For example. `-s ! localhost' matches any packet not coming from localhost.
The protocol can be specified with the `-p' (or `--protocol') flag. Protocol can be a number (if you know the numeric protocol values for IP) or a name for the special cases of `TCP', `UDP' or `ICMP'. Case doesn't matter, so `tcp' works as well as `TCP'.
The protocol name can be prefixed by a `!', to invert it, such as `-p ! TCP' to specify packets which are not TCP.
The `-i' (or `--in-interface') and `-o' (or `--out-interface') options
specify the name of an interface to match. An interface is
the physical device the packet came in on (`-i') or is going out on
(`-o'). You can use the ifconfig command to list the
interfaces which are `up' (i.e., working at the moment).
Packets traversing the INPUT chain don't have an output
interface, so any rule using `-o' in this chain will never match.
Similarly, packets traversing the OUTPUT chain don't have an
input interface, so any rule using `-i' in this chain will never match.
Only packets traversing the FORWARD chain have both an
input and output interface.
It is perfectly legal to specify an interface that currently does not
exist; the rule will not match anything until the interface comes up.
This is extremely useful for dial-up PPP links (usually interface
ppp0) and the like.
As a special case, an interface name ending with a `+' will match all
interfaces (whether they currently exist or not) which begin with that
string. For example, to specify a rule which matches all PPP
interfaces, the -i ppp+ option would be used.
The interface name can be preceded by a `!' with spaces around it, to
match a packet which does not match the specified
interface(s), eg -i ! ppp+.
Sometimes a packet is too large to fit down a wire all at once. When this happens, the packet is divided into fragments, and sent as multiple packets. The other end reassembles these fragments to reconstruct the whole packet.
The problem with fragments is that the initial fragment has the complete header fields (IP + TCP, UDP and ICMP) to examine, but subsequent packets only have a subset of the headers (IP without the additional protocol fields). Thus looking inside subsequent fragments for protocol headers (such as is done by the TCP, UDP and ICMP extensions) is not possible.
If you are doing connection tracking or NAT, then all fragments will get merged back together before they reach the packet filtering code, so you need never worry about fragments.
Please also note that in the INPUT chain of the filter table (or any other table hooking into the NF_IP_LOCAL_IN hook) is traversed after defragmentation of the core IP stack.
Otherwise, it is important to understand how fragments get treated by
the filtering rules. Any filtering rule that asks for information we
don't have will not match. This means that the first fragment is
treated like any other packet. Second and further fragments won't be.
Thus a rule -p TCP --sport www (specifying a source port of
`www') will never match a fragment (other than the first fragment).
Neither will the opposite rule -p TCP --sport ! www.
However, you can specify a rule specifically for second and further fragments, using the `-f' (or `--fragment') flag. It is also legal to specify that a rule does not apply to second and further fragments, by preceding the `-f' with ` ! '.
Usually it is regarded as safe to let second and further fragments through, since filtering will effect the first fragment, and thus prevent reassembly on the target host; however, bugs have been kn