Chapter 28
Packet Filtering with IP-Chains
|
|
|
|
| ![](gif/black.gif) |
In this chapter: |
|
| |
![*](gif/bullet.gif) ![](gif/clear.gif) |
IP chains as a Linux packet filtering mechanism
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
How IP traffic passes through the filter chains in the kernel
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
Examining filter rules-their conditions and targets
|
|
|
|
![](gif/black.gif) |
|
In chapter 23 we covered general security issues. It
should be quite clear by now that the need to protect yourself from
intruders within your systems demands high priority. In chapter
26 we saw how the TCP wrapper (tcpd) can
be used to protect a single machine . We also learned that this
technique cannot be used to protect other machines, only the host
tcpd is running on. To protect your network from the
outside, a firewall is the most appropriate method. The Linux kernel
supports packet filtering which can be used to implement a simple form
of a firewall.
This chapter is an introduction to the Linux packet filter
mechanisms, which can be used to masquerade packets and construct a
firewall, as we will see in chapter 1
and
29
. First let's look at the principles of packet filtering
and see how IP chains work.
Linux has supported packet filtering for quite a while. With version
2.2 of the kernel, there is a in the structure of this service. The
basic principles remain the same.
All network traffic is sent in packets. The beginning of each packet
states its destination, source, protocol, and administrative
details. The beginning of the packet is called the header. The rest of
the packet which contains the actual data being transmitted, is often
called the body.
Some protocols, such as TCP, (used for web traffic, mail, and remote
logins), use the connection process to send and receive
information. Before any packets with actual data are sent, various
setup packets are sent out that initiate the connection, gain
permission to transmit, then proceed with the data transfer and/or
exchange.
A packet filter is a piece of software that examines the packet's
header as it passes through and decides the fate of the entire
packet. It might decide to deny the packet (i.e., it will discard the
packet as if it had never received it), accept the packet (allow the
packet to pass), or reject the packet (much like deny, but the filter
will tell the source of the packet that it has rejected it).
Packet filtering is built into the Linux kernel. There are some more
complex things we can do with packets, but the general principle
remains.
The kernel employs chains of rules to match against packets that it
reviews. If a packet matches a rule, the rule will determine what
should be done with the packet. The packet can be accepted, denied,
rejected, masqueraded, or fed into another chain.
With this mechanism it's quite easy to build a stateless packet
filtering firewall. 'Stateless' means that every packet is reviewed
independently of the TCP or UDP connection it belongs to. A 'state
full' firewall would keep track of connections rather than examine
single packets.
Linux also supports several log and accounting features with its
firewall rules and packet masquerading.
A firewall chain is nothing more than a set of rules which are used to
determine the course of action for a packet as it is matched against
each rule. The rules fall in a certain order. When a rule matches a
packet, the target of the rule determines what happens next. If the
packet doesn't match a rule, the next rule in the chain will be
followed. If the end of the chain is reached, the default policy or
the default target is taken in order to process the packet.
By default there are three types of predefined chains:
| |
![*](gif/bullet.gif) ![](gif/clear.gif) |
Input
Rules in this chain regulate the acceptance of incoming IP packets.
All packets entering via one of the local network interfaces is
checked against the input rules. When no matching rule is found, the
default policy for the input chain is used.
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
Output
These rules define the permissions for sending IP packets. All
packets that are ready to be sent via one of the local network
interfaces are checked against the rules of the output chain. When no
matching rule is found, the default policy for the output firewall is
used.
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
Forward
These rules define the permissions for forwarding IP packets. All
packets sent by a remote host with another remote host as the
destination are checked against the forwarding chain. Again the filter
defers to a default policy when no matching rule is found.
|
|
|
Figure 28-1
illustrates a setup with five machines split across two
networks. System R acts as router between the two networks.
|
Figure 28-1 |
![ipchains](figures/IPchains.gif) |
| Network Traffic Through the Standard Chains |
|
Three connections are displayed. The small dotted line shows a
connection from A to R. You see this connection only has to pass
through the Input Chain of device eth0 of machine R. The
solid line shows the flow of datagrams from B to Y. They first go
through the Input Chain of device eth0, then pass the
Forward Chain, and finally go through the Output Chain of device
eth1. The large dotted line displays a connection from R
to X, which only goes through the Output Chain of device
eth1.
Only packets that come from an outside host en route to another host
have to pass through all three chains, while packets whose destination
is the local machine only go through the input chain, and packets
originated by the local machine only go through the output chain. This
scheme allows a great deal of flexibility to implement rules for
different kinds of traffic.
Along with the predefined chains, you can create new, user-defined
chains. Rules in the standard chains can be instructed to forward
packets to a user-defined chain. This minimizes the number of rules a
packet has to go through before a decision is made about how the
packet will be treated. The user-defined chains don't really add new
functionality to the filter, but they do make things easier.
A set of accounting rules was included in kernel versions prior to
2.2. These have been integrated into the input and output chains with
2.2, and are no longer needed as separate rule set.
Firewall rules are like all other rules. They have a condition that
determines when to apply them, and a so-called target which determines
where to send the packet when the criteria defined by the rule match
it. The target can be the name of a user defined chain, in which case
the packet will be fed into the beginning of the chain, or to one of
these special values:
| |
![*](gif/bullet.gif) ![](gif/clear.gif) |
ACCEPT
This means accept the packet. As soon as a packet matches a
rule with this target, processing will stop and the packet can
pass.
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
DENY
This means to drop the packet on the floor. This packet is "dead",
and it will never be heard from again.
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
REJECT
Rejecting a packet is nearly the same as dropping it, but is more
polite way of processing it and easier to debug. An ICMP message is
forwarded to the sender indicating that the packet was dropped.
(Note that DENY and
REJECT are the same for ICMP packets.)
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
MASQ
This target is only legal for the forward and user defined
chains, and can only be used when the kernel is compiled
with support for masquerading. With this, reverse packets
will be masqueraded as if they originated from the local
host. Furthermore, reverse packets will be recognized as
such and will be de-masqueraded automatically, bypassing the
forwarding chain.
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
REDIRECT
Packets can only be redirected from the input and user-defined
chains and can only be used when the Linux kernel is compiled with
transparent proxy support. With this, packets will be redirected to a
local socket even if they were sent to a remote host.
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
RETURN
In user defined queues, this means that the processing of the packet
will continue at the next rule in the previous (calling) chain. In the
standard chains, this means that the default policy of this chain
should be used for the packet.
|
|
|
The condition statement is more complex than the target statement. IP
packets on the stack have a range of parameters which can be used to
determine if the packet matches a given rule or not. The rules
contain a set of ranges or single values for these
parameters. Parameters not specified by the rule match any value of
this parameter in the packet structure. These are the parameters
which can be specified in a filter rule:
| |
![*](gif/bullet.gif) ![](gif/clear.gif) |
Protocol
Confirms the packet's protocol. The specified protocol can be either
TCP, UPD, ICMP, all, or a numeric value representing one of
these protocols. A protocol name from the list in
/etc/protocols is acceptable.
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
Source
The packet's origin. The source information contains an IP
address or an address range which is created by giving an address and
a netmask. It may include a port specification or ICMP type. This can
either be a service name, a port number, a numeric ICMP type, or an
ICMP-type name.
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
Destination
Provides the same values as seen in the source specification, but this
time they specify where the packet is headed.
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
Interface
Name of the interface through which a packet is received, or the
interface through which it will be sent.
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
Fragment
This means that the rule only refers to second and further fragments
of fragmented packets. Since there is no way to tell the source or
destination ports of such a packet (or ICMP type), rules which specify
source and/or destination port will not match fragmented packets.
Therefore it's not allowed to specify them for this kind of rules.
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
SYN bit set
Only matches TCP packets with the SYN bit set and the ACK and FIN bits
cleared. Such packets are used to request TCP connection initiation.
When implemented, they could, for example, block packets coming in an
interface will prevent incoming TCP connections, but outgoing TCP
connections will be unaffected. This option is only meaningful when
the protocol type is set to TCP. A meaningful option for packets
with the TCP protocol type and with the SYN bit set and the ACK and
FIN bits cleared.
|
|
|
A more detailed introduction on IP chains can be found in the Linux
IPCHAINS-HOWTO at http://www.rustcorp.com/linux/ipchains/HOWTO.html.
The next question for us is: how do we set up these rules, and how do we
monitor them? The answer is /sbin/ipchains, which inserts,
deletes, lists, and modifies the kernel firewall rules.
The exact syntax of this command can be found in the man page
ipchains(8). We'll see it in action when the
masquerading script is discussed in the next chapter.
|
![](gif/black.gif) |
Summary: |
|
IP traffic is broken down into packets. These packets can be
filtered using their header entries to match against sets of filter
rules, or so-called chains. The Linux kernel has three standard chains
for incoming, outgoing and forwarded packets. Additional user defined
chains can be set up to increase performance and ease packet filter
maintenance.
|
![](gif/black.gif) |
|
| ![](gif/clear.gif) |