|
Chapter 9. How a rule is built
This chapter and the upcoming three chapters will discuss at length how to build
your own rules. A rule could be described as the directions the firewall will adhere
to when blocking or permitting different connections and packets in a specific chain.
Each line you write that's inserted in a chain should be considered a rule. We will
also discuss the basic matches that are available, and how to use them, as well
as the different targets and how we can construct new targets of our own (i.e.,new
sub chains).
This chapter will deal with the raw basics of how a rule is created and how you
write it and enter it so that it will be accepted by the userspace program iptables,
the different tables, as well as the commands that you can issue to iptables. After
that we will in the next chapter look at all the matches that are available to iptables,
and then get more into detail of each type of target and jump.
As we have already explained, each rule is a line that the kernel looks at to find
out what to do with a packet. If all the criteria - or matches - are met, we perform
the target - or jump - instruction. Normally we would write our rules in a syntax
that looks something like this:
iptables [-t table] command [match] [target/jump]
There is nothing that says that the target instruction has to be the last function
in the line. However, you would usually adhere to this syntax to get the best readability.
Anyway, most of the rules you'll see are written in this way. Hence, if you read
someone else's script, you'll most likely recognize the syntax and easily understand
the rule.
If you want to use a table other than the standard table, you could insert the table
specification at the point at which [table] is specified. However, it is not necessary
to state explicitly what table to use, since by default iptables uses the filter
table on which to implement all commands. Neither do you have to specify the table
at just this point in the rule. It could be set pretty much anywhere along the line.
However, it is more or less standard to put the table specification at the beginning.
One thing to think about though: The command should always come first, or alternatively
directly after the table specification. We use 'command' to tell the program what
to do, for example to insert a rule or to add a rule to the end of the chain, or
to delete a rule. We shall take a further look at this below.
The match is the part of the rule that we send to the kernel that details the specific
character of the packet, what makes it different from all other packets. Here we
could specify what IP address the packet comes from, from which network interface,
the intended IP address, port, protocol or whatever. There is a heap of different
matches that we can use that we will look closer at further on in this chapter.
Finally we have the target of the packet. If all the matches are met for a packet,
we tell the kernel what to do with it. We could, for example, tell the kernel to
send the packet to another chain that we've created ourselves, and which is part
of this particular table. We could tell the kernel to drop the packet dead and do
no further processing, or we could tell the kernel to send a specified reply to
the sender. As with the rest of the content in this section, we'll look closer at
it further on in the chapter.
The -t option specifies which table to use. Per default, the filter table is used.
We may specify one of the following tables with the -t option. Do note that this
is an extremely brief summary of some of the contents of the
Traversing of tables and chains chapter.
Table 9-1. Tables
Table |
Explanation |
nat |
The nat table is used mainly for Network Address Translation. "NAT"ed packets get
their IP addresses altered, according to our rules. Packets in a stream only traverse
this table once. We assume that the first packet of a stream is allowed. The rest
of the packets in the same stream are automatically "NAT"ed or Masqueraded etc,
and will be subject to the same actions as the first packet. These will, in other
words, not go through this table again, but will nevertheless be treated like the
first packet in the stream. This is the main reason why you should not do any filtering
in this table, which we will discuss at greater length further on. The PREROUTING
chain is used to alter packets as soon as they get in to the firewall. The OUTPUT
chain is used for altering locally generated packets (i.e., on the firewall) before
they get to the routing decision. Finally we have the POSTROUTING chain which is
used to alter packets just as they are about to leave the firewall.
|
mangle |
This table is used mainly for mangling packets. Among other things, we can change
the contents of different packets and that of their headers. Examples of this would
be to change the TTL, TOS or MARK. Note that the MARK is not really a change to
the packet, but a mark value for the packet is set in kernel space. Other rules
or programs might use this mark further along in the firewall to filter or do advanced
routing on; tc is one example. The table consists of five built in chains, the PREROUTING,
POSTROUTING, OUTPUT, INPUT and FORWARD chains. PREROUTING is used for altering packets
just as they enter the firewall and before they hit the routing decision. POSTROUTING
is used to mangle packets just after all routing decisions have been made. OUTPUT
is used for altering locally generated packets after they enter the routing decision.
INPUT is used to alter packets after they have been routed to the local computer
itself, but before the user space application actually sees the data. FORWARD is
used to mangle packets after they have hit the first routing decision, but before
they actually hit the last routing decision. Note that mangle can't be used for
any kind of Network Address Translation or Masquerading, the nat table was made
for these kinds of operations.
|
filter |
The filter table should be used exclusively for filtering packets. For example,
we could DROP, LOG, ACCEPT or REJECT packets without problems, as we can in the
other tables. There are three chains built in to this table. The first one is named
FORWARD and is used on all non-locally generated packets that are not destined for
our local host (the firewall, in other words). INPUT is used on all packets that
are destined for our local host (the firewall) and OUTPUT is finally used for all
locally generated packets.
|
raw |
The raw table and its chains are used before any other tables in netfilter. It was
introduced to use the NOTRACK target. This table is rather new and is only available,
if compiled, with late 2.6 kernels and later. The raw table contains two chains.
The PREROUTING and OUTPUT chain, where they will handle packets before they hit
any of the other netfilter subsystems. The PREROUTING chain can be used for all
incoming packets to this machine, or that are forwarded, while the OUTPUT chain
can be used to alter the locally generated packets before they hit any of the other
netfilter subsystems.
|
The above details should have explained the basics about the three different tables
that are available. They should be used for totally different purposes, and you
should know what to use each chain for. If you do not understand their usage, you
may well dig a pit for yourself in your firewall, into which you will fall as soon
as someone finds it and pushes you into it. We have already discussed the requisite
tables and chains in more detail within the Traversing
of tables and chains chapter. If you do not understand this fully, I
advise you to go back and read through it again.
In this section we will cover all the different commands and what can be done with
them. The command tells iptables what to do with the rest of the rule that we send
to the parser. Normally we would want either to add or delete something in some
table or another. The following commands are available to iptables:
Table 9-2. Commands
Command |
-A, --append |
Example |
iptables -A INPUT ... |
Explanation |
This command appends the rule to the end of the chain. The rule will in other words
always be put last in the rule-set and hence be checked last, unless you append
more rules later on. |
Command |
-D, --delete |
Example |
iptables -D INPUT --dport 80 -j DROP, iptables -D INPUT 1
|
Explanation |
This command deletes a rule in a chain. This could be done in two ways; either by
entering the whole rule to match (as in the first example), or by specifying the
rule number that you want to match. If you use the first method, your entry must
match the entry in the chain exactly. If you use the second method, you must match
the number of the rule you want to delete. The rules are numbered from the top of
each chain, starting with number 1. |
Command |
-R, --replace |
Example |
iptables -R INPUT 1 -s 192.168.0.1 -j DROP |
Explanation |
This command replaces the old entry at the specified line. It works in the same
way as the --delete command, but instead of totally deleting the entry, it will
replace it with a new entry. The main use for this might be while you're experimenting
with iptables. |
Command |
-I, --insert |
Example |
iptables -I INPUT 1 --dport 80 -j ACCEPT |
Explanation |
Insert a rule somewhere in a chain. The rule is inserted as the actual number that
we specify. In other words, the above example would be inserted as rule 1 in the
INPUT chain, and hence from now on it would be the very first rule in the chain. |
Command |
-L, --list |
Example |
iptables -L INPUT |
Explanation |
This command lists all the entries in the specified chain. In the above case, we
would list all the entries in the INPUT chain. It's also legal to not specify any
chain at all. In the last case, the command would list all the chains in the specified
table (To specify a table, see the Tables section).
The exact output is affected by other options sent to the parser, for example the
-n and -v options, etc. |
Command |
-F, --flush |
Example |
iptables -F INPUT |
Explanation |
This command flushes all rules from the specified chain and is equivalent to deleting
each rule one by one, but is quite a bit faster. The command can be used without
options, and will then delete all rules in all chains within the specified table.
|
Command |
-Z, --zero |
Example |
iptables -Z INPUT |
Explanation |
This command tells the program to zero all counters in a specific chain, or in all
chains. If you have used the -v option with the -L command, you have probably seen
the packet counter at the beginning of each field. To zero this packet counter,
use the -Z option. This option works the same as -L, except that -Z won't list the
rules. If -L and -Z is used together (which is legal), the chains will first be
listed, and then the packet counters are zeroed. |
Command |
-N, --new-chain |
Example |
iptables -N allowed |
Explanation |
This command tells the kernel to create a new chain of the specified name in the
specified table. In the above example we create a chain called allowed. Note that
there must not already be a chain or target of the same name. |
Command |
-X, --delete-chain |
Example |
iptables -X allowed |
Explanation |
This command deletes the specified chain from the table. For this command to work,
there must be no rules that refer to the chain that is to be deleted. In other words,
you would have to replace or delete all rules referring to the chain before actually
deleting the chain. If this command is used without any options, all chains but
those built in to the specified table will be deleted. |
Command |
-P, --policy |
Example |
iptables -P INPUT DROP |
Explanation |
This command tells the kernel to set a specified default target, or policy, on a
chain. All packets that don't match any rule will then be forced to use the policy
of the chain. Legal targets are DROP and ACCEPT (There might be more, mail me if
so). |
Command |
-E, --rename-chain |
Example |
iptables -E allowed disallowed |
Explanation |
The -E command tells iptables to change the first name of a chain, to the second
name. In the example above we would, in other words, change the name of the chain
from allowed to disallowed .
Note that this will not affect the actual way the table will work. It is, in other
words, just a cosmetic change to the table. |
You should always enter a complete command line, unless you just want to list the
built-in help for iptables or get the version of the command. To get the version,
use the -v option and to get the help message, use the -h option. As usual, in other
words. Next comes a few options that can be used with various different commands.
Note that we tell you with which commands the options can be used and what effect
they will have. Also note that we do not include any options here that affect rules
or matches. Instead, we'll take a look at matches and targets in a later section
of this chapter.
Table 9-3. Options
Option |
-v, --verbose |
Commands used with |
--list, --append, --insert, --delete, --replace |
Explanation |
This command gives verbose output and is mainly used together with the --list command.
If used together with the --list command, it outputs the interface address, rule
options and TOS masks. The --list command will also include a bytes and packet counter
for each rule, if the --verbose option is set. These counters uses the K (x1000),
M (x1,000,000) and G (x1,000,000,000) multipliers. To overrule this and get exact
output, you can use the -x option, described later. If this option is used with
the --append, --insert, --delete or --replace commands, the program will output
detailed information on how the rule was interpreted and whether it was inserted
correctly, etc. |
Option |
-x, --exact |
Commands used with |
--list |
Explanation |
This option expands the numerics. The output from --list will in other words not
contain the K, M or G multipliers. Instead we will get an exact output from the
packet and byte counters of how many packets and bytes that have matched the rule
in question. Note that this option is only usable in the --list command and isn't
really relevant for any of the other commands. |
Option |
-n, --numeric |
Commands used with |
--list |
Explanation |
This option tells iptables to output numerical values. IP addresses and port numbers
will be printed by using their numerical values and not host-names, network names
or application names. This option is only applicable to the --list command. This
option overrides the default of resolving all numerics to hosts and names, where
this is possible. |
Option |
--line-numbers |
Commands used with |
--list |
Explanation |
The --line-numbers command, together with the --list command, is used to output
line numbers. Using this option, each rule is output with its number. It could be
convenient to know which rule has which number when inserting rules. This option
only works with the --list command. |
Option |
-c, --set-counters |
Commands used with |
--insert, --append, --replace |
Explanation |
This option is used when creating a rule or modifying it in some way. We can then
use the option to initialize the packet and byte counters for the rule. The syntax
would be something like --set-counters 20 4000, which would tell the kernel to set
the packet counter to 20 and byte counter to 4000. |
Option |
--modprobe |
Commands used with |
All |
Explanation |
The --modprobe option is used to tell iptables which module to use when probing
for modules or adding them to the kernel. It could be used if your modprobe command
is not somewhere in the search path etc. In such cases, it might be necessary to
specify this option so the program knows what to do in case a needed module is not
loaded. This option can be used with all commands. |
This chapter has discussed some of the basic commands for iptables and the tables
very briefly that can be used in netfilter. The commands makes it possible to do
quite a lot of different operations on the netfilter package loaded inside kernel
as you have seen.
The next chapter will discuss all the available matches in iptables and netfilter.
This is a very heavy and long chapter, and I humbly suggest that you don't need
to actually learn every single match available in any detail, except the ones that
you are going to use. A good idea might be to get a brief understanding of what
each match does, and then get a better grasp on them as you need them.
|
|
|