|
Chapter 11. Iptables targets and jumps
The target/jumps tells the rule what to do with a packet that is a perfect match
with the match section of the rule. There are a couple of basic targets, the ACCEPT
and DROP targets, which we will deal with first. However, before we do that, let
us have a brief look at how a jump is done.
The jump specification is done in exactly the same way as in the target definition,
except that it requires a chain within the same table to jump to. To jump to a specific
chain, it is of course a prerequisite that that chain exists. As we have already
explained, a user-defined chain is created with the -N command. For example, let's
say we create a chain in the filter table called tcp_packets, like this:
iptables -N tcp_packets
We could then add a jump target to it like this:
iptables -A INPUT -p tcp -j tcp_packets
We would then jump from the INPUT chain to the tcp_packets chain and start traversing
that chain. When/If we reach the end of that chain, we get dropped back to the INPUT
chain and the packet starts traversing from the rule one step below where it jumped
to the other chain (tcp_packets in this case). If a packet is ACCEPTed within one
of the sub chains, it will be ACCEPT'ed in the superset chain also and it will not
traverse any of the superset chains any further. However, do note that the packet
will traverse all other chains in the other tables in a normal fashion. For more
information on table and chain traversing, see the
Traversing of tables and chains chapter.
Targets on the other hand specify an action to take on the packet in question. We
could for example, DROP or ACCEPT the packet depending on what we want to do. There
are also a number of other actions we may want to take, which we will describe further
on in this section. Jumping to targets may incur different results, as it were.
Some targets will cause the packet to stop traversing that specific chain and superior
chains as described above. Good examples of such rules are DROP and ACCEPT. Rules
that are stopped, will not pass through any of the rules further on in the chain
or in superior chains. Other targets, may take an action on the packet, after which
the packet will continue passing through the rest of the rules. A good example of
this would be the LOG, ULOG and TOS targets. These targets can log the packets,
mangle them and then pass them on to the other rules in the same set of chains.
We might, for example, want this so that we in addition can mangle both the TTL
and the TOS values of a specific packet/stream. Some targets will accept extra options
(What TOS value to use etc), while others don't necessarily need any options - but
we can include them if we want to (log prefixes, masquerade-to ports and so on).
We will try to cover all of these points as we go through the target descriptions.
Let us have a look at what kinds of targets there are.
This target needs no further options. As soon as the match specification for a packet
has been fully satisfied, and we specify ACCEPT as the target, the rule is accepted
and will not continue traversing the current chain or any other ones in the same
table. Note however, that a packet that was accepted in one chain might still travel
through chains within other tables, and could still be dropped there. There is nothing
special about this target whatsoever, and it does not require, nor have the possibility
of, adding options to the target. To use this target, we simply specify -j ACCEPT.
|
Works under Linux kernel 2.3, 2.4, 2.5 and 2.6.
|
The CLASSIFY target can be used to classify packets in such a way that can be used
by a couple of different qdiscs (Queue Disciplines). For example, atm, cbq, dsmark,
pfifo_fast, htb and the prio qdiscs. For more information about qdiscs and traffic
controlling, visit the Linux Advanced Routing and Traffic Control
HOW-TO webpage.
The CLASSIFY target is only valid in the POSTROUTING chain of the mangle table.
Table 11-1. CLASSIFY target options
Option |
--set-class |
Example |
iptables -t mangle -A POSTROUTING -p tcp --dport 80 -j CLASSIFY --set-class 20:10
|
Explanation |
The CLASSIFY target only takes one argument, the --set-class. This tells the target
how to class the packet. The class takes 2 values separated by a coma sign, like
this MAJOR:MINOR. Once again, if you want more information on this, check the Linux Advanced Routing and Traffic Control HOW-TO webpage.
|
|
Works under Linux kernel 2.5 and 2.6.
|
The CLUSTERIP target is used to create simple clusters of nodes answering to the
same IP and MAC address in a round robin fashion. This is a simple form of clustering
where you set up a Virtual IP (VIP) on all hosts participating in the cluster, and
then use the CLUSTERIP on each host that is supposed to answer the requests. The
CLUSTERIP match requires no special load balancing hardware or machines, it simply
does its work on each host part of the cluster of machines. It is a very simple
clustering solution and not suited for large and complex clusters, neither does
it have built in heartbeat handling, but it should be easily implemented as a simple
script.
All servers in the cluster uses a common Multicast MAC for a VIP, and then a special
hash algorithm is used within the CLUSTERIP target to figure out who of the cluster
participants should respond to each connection. A Multicast MAC is a MAC address
starting with 01:00:5e as the first 24 bits. an example of a Multicast MAC would
be 01:00:5e:00:00:20. The VIP can be any IP address, but must be the same on all
hosts as well.
|
Remember that the CLUSTERIP might break protocols such as SSH et cetera. The connection
will go through properly, but if you try the same time again to the same host, you
might be connected to another machine in the cluster, with a different keyset, and
hence your ssh client might refuse to connect or give you errors. For this reason,
this will not work very well with some protocols, and it might be a good idea to
add separate addresses that can be used for maintenance and administration. Another
solution is to use the same SSH keys on all hosts participating in the cluster.
|
The cluster can be loadbalanced with three kinds of hashmodes. The first one is
only source IP (sourceip), the second is source IP and source port (sourceip-sourceport)
and the third one is source IP, source port and destination port (sourceip-sourceport-destport).
The first one might be a good idea where you need to remember states between connections,
for example a webserver with a shopping cart that keeps state between connections,
this load-balancing might become a little bit uneven -- different machines might
get a higher loads than others, et cetera -- since connections from the same source
IP will go to the same server. The sourceip-sourceport hash might be a good idea
where you want to get the load-balancing a little bit more even, and where state
does not have to be kept between connections on each server. For example, a large
informational webpage with perhaps a simple search engine might be a good idea here.
The third and last hashmode, sourceip-sourceport-destport, might be a good idea
where you have a host with several services running that does not require any state
to be preserved between connections. This might for example be a simple ntp, dns
and www server on the same host. Each connection to each new destination would hence
be "renegotiated" -- actually no negotiation goes on, it is basically just a round
robin system and each host receives one connection each.
Each CLUSTERIP cluster gets a separate file in the /proc/net/ipt_CLUSTERIP
directory, based on the VIP of the cluster. If the VIP is 192.168.0.5 for example,
you could cat /proc/net/ipt_CLUSTERIP/192.168.0.5 to see which nodes this machine
is answering for. To make the machine answer for another machine, lets say node
2, add it using echo "+2" >> /proc/net/ipt_CLUSTERIP/192.168.0.5. To remove
it, run echo "-2" >> /proc/net/ipt_CLUSTERIP/192.168.0.5.
Table 11-2. CLUSTERIP target options
Option |
--new |
Example |
iptables -A INPUT -p tcp -d 192.168.0.5 --dport 80 -j CLUSTERIP --new ...
|
Explanation |
This creates a new CLUSTERIP entry. It must be set on the first rule for a VIP,
and is used to create a new cluster. If you have several rules connecting to the
same CLUSTERIP you can omit the --new keyword in any secondary references to the
same VIP.
|
Option |
--hashmode |
Example |
iptables -A INPUT -p tcp -d 192.168.0.5 --dport 443 -j CLUSTERIP --new --hashmode
sourceip ...
|
Explanation |
The --hashmode keyword specifies the kind of hash that should be created. The hashmode
can be any of the following three.
The hashmodes has been extensively explained above. Basically, sourceip will give
better performance and simpler states between connections, but not as good load-balancing
between the machines. sourceip-sourceport will give a slightly slower hashing and
not as good to maintain states between connections, but will give better load-balancing
properties. The last one may create very slow hashing that consumes a lot of memory,
but will on the other hand also create very good load-balancing properties.
|
Option |
--clustermac |
Example |
iptables -A INPUT -p tcp -d 192.168.0.5 --dport 80 -j CLUSTERIP --new --hashmode
sourceip --clustermac 01:00:5e:00:00:20 ...
|
Explanation |
The MAC address that the cluster is listening to for new connections. This is a
shared Multicast MAC address that all the hosts are listening to. See above for
a deeper explanation of this.
|
Option |
--total-nodes |
Example |
iptables -A INPUT -p tcp -d 192.168.0.5 --dport 80 -j CLUSTERIP --new --hashmode
sourceip --clustermac 01:00:5e:00:00:20 --total-nodes 2 ...
|
Explanation |
The --total-nodes keyword specifies how many hosts are participating in the cluster
and that will answer to requests. See above for a deeper explanation.
|
Option |
--local-node |
Example |
iptables -A INPUT -p tcp -d 192.168.0.5 --dport 80 -j CLUSTERIP --new --hashmode
sourceip --clustermac 01:00:5e:00:00:20 --total-nodes 2 --local-node 1
|
Explanation |
This is the number that this machine has in the cluster. The cluster answers in
a round-robin fashion, so once a new connection is made to the cluster, the next
machine answers, and then the next after that, and so on.
|
Option |
--hash-init |
Example |
iptables -A INPUT -p tcp -d 192.168.0.5 --dport 80 -j CLUSTERIP --new --hashmode
sourceip --clustermac 01:00:5e:00:00:20 --hash-init 1234
|
Explanation |
Specifies a random seed for hash initialization.
|
|
This target is in violation of the RFC 1812 - Requirements for
IP Version 4 Routers RFC, so be wary of any problems that may arise.
Specifically, section 3.3.2 which specifies that a router must never trust another
host or router that says that it is using a multicast mac.
|
|
Works under late Linux 2.6 kernels, marked experimental.
|
The CONNMARK target is used to set a mark on a whole connection, much the same way
as the MARK target does. It can then be used together with the connmark match to
match the connection in the future. For example, say we see a specific pattern in
a header, and we don't want to mark just that packet, but the whole connection.
The CONNMARK target is a perfect solution in that case.
The CONNMARK target is available in all chains and all tables, but remember that
the nat table is only traversed by the first packet in a connection, so the CONNMARK
target will have no effect if you try to use it for subsequent packets after the
first one in here. It can take one of four different options as seen below.
Table 11-3. CONNMARK target options
Option |
--set-mark |
Example |
iptables -t nat -A PREROUTING -p tcp --dport 80 -j CONNMARK --set-mark 4 |
Explanation |
This option sets a mark on the connection. The mark can be an unsigned long int,
which means values between 0 and 4294967295l is valid. Each bit can also be masked
by doing --set-mark 12/8. This will only allow the bits in the mask to be set out
of all the bits in the mark. In this example, only the 4th bit will be set, not
the 3rd. 12 translates to 1100 in binary, and 8 to 1000, and only the bits set in
the mask are allowed to be set. Hence, only the 4th bit, or 8, is set in the actual
mark.
|
Option |
--save-mark |
Example |
iptables -t mangle -A PREROUTING --dport 80 -j CONNMARK --save-mark |
Explanation |
The --save-mark target option is used to save the packet mark into the connection
mark. For example, if you have set a packet mark with the MARK target, you can then
move this mark to mark the whole connection with the --save-mark match. The mark
can also be masked by using the --mask option described further down.
|
Option |
--restore-mark |
Example |
iptables -t mangle -A PREROUTING --dport 80 -j CONNMARK --restore-mark |
Explanation |
This target option restores the packet mark from the connection mark as defined
by the CONNMARK. A mask can also be defined using the --mask option as seen below.
If a mask is set, only the masked options will be set. Note that this target option
is only valid for use in the mangle table.
|
Option |
--mask |
Example |
iptables -t mangle -A PREROUTING --dport 80 -j CONNMARK --restore-mark --mask 12 |
Explanation |
The --mask option must be used in unison with the --save-mark and --restore-mark
options. The --mask option specifies an and-mask that should be applied to the mark
values that the other two options will give. For example, if the restored mark from
the above example would be 15, it would mean that the mark was 1111 in binary, while
the mask is 1100. 1111 and 1100 equals 1100.
|
|
Works under Linux kernel 2.6.
|
The CONNSECMARK target sets a SELinux security context mark to or from a packet
mark. For further information on SELinux, read more at the Security-Enhanced
Linux homepage. The target is only valid in the mangle table and is
used together with the SECMARK target, where the SECMARK target is used to set the
original mark, and then the CONNSECMARK is used to set the mark on the whole connection.
SELinux is beyond the scope of this document, but basically it is an addition of
Mandatory Access Control to Linux. This is more finegrained than the original security
systems of most Linux and Unix security controls. Each object can have security
attributes, or security context, connected to it, and these attributes are then
matched to eachother before allowing or denying a specific task to be performed.
This target will allow a security context to be set on a connection.
Table 11-4. CONNSECMARK target options
Option |
--save |
Example |
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j CONNSECMARK --save |
Explanation |
Save the security context mark from the packet to the connection if the connection
is not marked since before.
|
Option |
--restore |
Example |
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j CONNSECMARK --restore |
Explanation |
If the packet has no security context mark set on it, the --restore option will
set the security context mark associated with the connection on the packet.
|
The DNAT target is used to do Destination Network Address Translation, which means
that it is used to rewrite the Destination IP address
of a packet. If a packet is matched, and this is the target of the rule, the packet,
and all subsequent packets in the same stream will be translated, and then routed
on to the correct device, host or network. This target can be extremely useful,
for example,when you have a host running your web server inside a
LAN, but no real IP to give it that will work
on the Internet. You could then tell the firewall to forward all packets going to
its own HTTP port, on to the real web server within the LAN. We may also specify a whole range of destination
IP addresses, and the DNAT mechanism will choose the destination IP address at random
for each stream. Hence, we will be able to deal with a kind of load balancing by
doing this.
Note that the DNAT target is only available within the PREROUTING and OUTPUT chains
in the nat table, and any of the chains called upon from any of those listed chains.
Note that chains containing DNAT targets may not be used from any other chains,
such as the POSTROUTING chain.
Table 11-5. DNAT target options
Option |
--to-destination |
Example |
iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination
192.168.1.1-192.168.1.10
|
Explanation |
The --to-destination option tells the DNAT mechanism which Destination IP to set
in the IP header, and where to send packets that are matched. The above example
would send on all packets destined for IP address 15.45.23.67 to a range of LAN IP's, namely 192.168.1.1
through 10. Note, as described previously, that a single stream will always use
the same host, and that each stream will randomly be given an IP address that it
will always be Destined for, within that stream. We could also have specified only
one IP address, in which case we would always be connected to the same host. Also
note that we may add a port or port range to which the traffic would be redirected
to. This is done by adding, for example, an :80 statement to the IP addresses to
which we want to DNAT the packets. A rule could then look like --to-destination
192.168.1.1:80 for example, or like --to-destination 192.168.1.1:80-100 if we wanted
to specify a port range. As you can see, the syntax is pretty much the same for
the DNAT target, as for the SNAT target even though they do two totally different
things. Do note that port specifications are only valid for rules that specify the
TCP or UDP protocols with the --protocol option.
|
Since DNAT requires quite a lot of work to work properly, I have decided to add
a larger explanation on how to work with it. Let's take a brief example on how things
would be done normally. We want to publish our website via our Internet connection.
We only have one IP address, and the HTTP server is located on our internal network.
Our firewall has the external IP address $INET_IP, and our HTTP server has the internal
IP address $HTTP_IP and finally the firewall has the internal IP address $LAN_IP.
The first thing to do is to add the following simple rule to the PREROUTING chain
in the nat table:
iptables -t nat -A PREROUTING --dst $INET_IP -p tcp --dport 80 -j DNAT \ --to-destination $HTTP_IP
Now, all packets from the Internet going to port 80 on our firewall are redirected
(or DNAT'ed) to our internal HTTP server. If you test this from the Internet, everything
should work just perfect. So, what happens if you try connecting from a host on
the same local network as the HTTP server? It will simply not work. This is a problem
with routing really. We start out by dissecting what happens in a normal case. The
external box has IP address $EXT_BOX, to maintain readability.
-
Packet leaves the connecting host going to $INET_IP and source $EXT_BOX.
-
Packet reaches the firewall.
-
Firewall DNAT's the packet and runs the packet through all different chains etcetera.
-
Packet leaves the firewall and travels to the $HTTP_IP.
-
Packet reaches the HTTP server, and the HTTP box replies back through the firewall,
if that is the box that the routing database has entered as the gateway for $EXT_BOX.
Normally, this would be the default gateway of the HTTP server.
-
Firewall Un-DNAT's the packet again, so the packet looks as if it was replied to
from the firewall itself.
-
Reply packet travels as usual back to the client $EXT_BOX.
Now, we will consider what happens if the packet was instead generated by a client
on the same network as the HTTP server itself. The client has the IP address $LAN_BOX,
while the rest of the machines maintain the same settings.
-
Packet leaves $LAN_BOX to $INET_IP.
-
The packet reaches the firewall.
-
The packet gets DNAT'ed, and all other required actions are taken, however, the
packet is not SNAT'ed, so the same source IP address is used on the packet.
-
The packet leaves the firewall and reaches the HTTP server.
-
The HTTP server tries to respond to the packet, and sees in the routing databases
that the packet came from a local box on the same network, and hence tries to send
the packet directly to the original source IP address (which now becomes the destination
IP address).
-
The packet reaches the client, and the client gets confused since the return packet
does not come from the host that it sent the original request to. Hence, the client
drops the reply packet, and waits for the "real" reply.
The simple solution to this problem is to SNAT all packets entering the firewall
and leaving for a host or IP that we know we do DNAT to. For example, consider the
above rule. We SNAT the packets entering our firewall that are destined for $HTTP_IP
port 80 so that they look as if they came from $LAN_IP. This will force the HTTP
server to send the packets back to our firewall, which Un-DNAT's the packets and
sends them on to the client. The rule would look something like this:
iptables -t nat -A POSTROUTING -p tcp --dst $HTTP_IP --dport 80 -j SNAT \ --to-source $LAN_IP
Remember that the POSTROUTING chain is processed last of the chains, and hence the
packet will already be DNAT'ed once it reaches that specific chain. This is the
reason that we match the packets based on the internal address.
|
This last rule will seriously harm your logging, so it is really advisable not to
use this method, but the whole example is still a valid one. What will happen is
this, packet comes from the Internet, gets SNAT'ed and DNAT'ed, and finally hits
the HTTP server (for example). The HTTP server now only sees the request as if it
was coming from the firewall, and hence logs
all requests from the internet as if they came from the firewall.
This can also have even more severe implications. Take an SMTP server on the LAN,
that allows requests from the internal network, and you have your firewall set up
to forward SMTP traffic to it. You have now effectively created an open relay SMTP
server, with horrenduously bad logging!
One solution to this problem is to simply make the SNAT rule even more specific
in the match part, and to only work on packets that come in from our LAN interface.
In other words, add a --src $LAN_IP_RANGE to the whole command as well. This will
make the rule only work on streams that come in from the LAN, and hence will not
affect the Source IP, so the logs will look correct, except for streams coming from
our LAN.
You will, in other words, be better off solving these problems by either setting
up a separate DNS server for your LAN, or to actually set up a separate DMZ, the
latter being preferred if you have the money.
|
You think this should be enough by now, and it really is, unless considering one
final aspect to this whole scenario. What if the firewall itself tries to access
the HTTP server, where will it go? As it looks now, it will unfortunately try to
get to its own HTTP server, and not the server residing on $HTTP_IP. To get around
this, we need to add a DNAT rule in the OUTPUT chain as well. Following the above
example, this should look something like the following:
iptables -t nat -A OUTPUT --dst $INET_IP -p tcp --dport 80 -j DNAT \ --to-destination $HTTP_IP
Adding this final rule should get everything up and running. All separate networks
that do not sit on the same net as the HTTP server will run smoothly, all hosts
on the same network as the HTTP server will be able to connect and finally, the
firewall will be able to do proper connections as well. Now everything works and
no problems should arise.
|
Everyone should realize that these rules only affect how the packet is DNAT'ed and
SNAT'ed properly. In addition to these rules, you may also need extra rules in the
filter table (FORWARD chain) to allow the packets to traverse through those chains
as well. Don't forget that all packets have already gone through the PREROUTING
chain, and should hence have their destination addresses rewritten already by DNAT.
|
|
Works under Linux kernel 2.3, 2.4, 2.5 and 2.6.
|
The DROP target does just what it says, it drops packets dead and will not carry
out any further processing. A packet that matches a rule perfectly and is then Dropped
will be blocked. Note that this action might in certain cases have an unwanted effect,
since it could leave dead sockets around on either host. A better solution in cases
where this is likely would be to use the REJECT target, especially when you want
to block port scanners from getting too much information, such as on filtered ports
and so on. Also note that if a packet has the DROP action taken on it in a subchain,
the packet will not be processed in any of the main chains either in the present
or in any other table. The packet is in other words totally dead. As we've seen
previously, the target will not send any kind of information in either direction,
nor to intermediaries such as routers.
|
Works under Linux kernel 2.3, 2.4, 2.5 and 2.6.
|
This is a target that changes the DSCP(Differentiated Services Field) marks inside
a packet. The DSCP target is able to set any DSCP value inside a TCP packet, which
is a way of telling routers the priority of the packet in question. For more information
about DSCP, look at the RFC 2474 - Definition of the Differentiated
Services Field (DS Field) in the IPv4 and IPv6 Headers RFC document.
Basically, DSCP is a way of differentiating different services into separate categories,
and based on this, give them different priority through the routers. This way, you
can give interactive TCP sessions (such as telnet, SSH, POP3) a very high fast connection,
that may not be very suitable for large bulk transfers. If on the other hand the
connection is one of low importance (SMTP, or whatever you classify as low priority),
you could send it over a large bulky network with worse latency than the other network,
that is cheaper to utilize than the faster and lower latency connections.
Table 11-6. DSCP target options
Option |
--set-dscp |
Example |
iptables -t mangle -A FORWARD -p tcp --dport 80 -j DSCP --set-dscp 1
|
Explanation |
This sets the DSCP value to the specified value. The values can be set either via
class, see below, or with the --set-dscp, which takes either an integer value, or
a hex value.
|
Option |
--set-dscp-class |
Example |
iptables -t mangle -A FORWARD -p tcp --dport 80 -j DSCP --set-dscp-class EF
|
Explanation |
This sets the DSCP field according to a predefined DiffServ class. Some of the possible
values are EF, BE and the CSxx and AFxx values available. You can find more information
at Implementing Quality of Service Policies with DSCP
site. Do note that the --set-dscp-class and --set-dscp commands are mutually exclusive,
which means you can not use both of them in the same command!
|
|
Works under Linux kernel 2.3, 2.4, 2.5 and 2.6.
|
This target can be great, used in the correct way. Simply put, the ECN target can
be used to reset the ECN bits from the IPv4 header, or to put it correctly, reset
them to 0 at least. Since ECN is a relatively new thing on the net, there are problems
with it. For example, it uses 2 bits that are defined in the original RFC for the
TCP protocol to be 0. Some routers and other internet appliances will not forward
packets that have these bits set to 1. If you want to make use of at least parts
of the ECN functionality from your hosts, you could for example reset the ECN bits
to 0 for specific networks that you know you are having troubles reaching because
of ECN.
|
Please do note that it isn't possible to turn ECN on in the middle of a stream.
It isn't allowed according to the RFC's, and it isn't possible anyways. Both endpoints
of the stream must negotiate ECN. If we turn it on, then one of the hosts is not
aware of it, and can't respond properly to the ECN notifications.
|
Table 11-7. ECN target options
Option |
--ecn-tcp-remove |
Example |
iptables -t mangle -A FORWARD -p tcp --dport 80 -j ECN --ecn-tcp-remove
|
Explanation |
The ECN target only takes one argument, the --ecn-tcp-remove argument. This tells
the target to remove the ECN bits inside the TCP headers. Read above for more information.
|
|
Works under Linux kernel 2.5 and 2.6.
|
The LOG target is specially designed for logging detailed information about packets.
These could, for example, be considered as illegal. Or, logging can be used purely
for bug hunting and error finding. The LOG target will return specific information
on packets, such as most of the IP headers and other information considered interesting.
It does this via the kernel logging facility, normally syslogd. This information
may then be read directly with dmesg, or from the syslogd logs, or with other programs
or applications. This is an excellent target to use to debug your rule-sets, so
that you can see what packets go where and what rules are applied on what packets.
Note as well that it could be a really great idea to use the LOG target instead
of the DROP target while you are testing a rule you are not 100% sure about on a
production firewall, since a syntax error in the rule-sets could otherwise cause
severe connectivity problems for your users. Also note that the ULOG target may
be interesting if you are using really extensive logging, since the ULOG target
has support for direct logging to MySQL databases and suchlike.
|
Note that if you get undesired logging direct to consoles, this is not an iptables
or Netfilter problem, but rather a problem caused by your syslogd configuration
- most probably /etc/syslog.conf. Read more in man syslog.conf
for information about this kind of problem.
You may also need to tweak your dmesg settings. dmesg is the command that changes
which errors from the kernel that should be shown on the console. dmesg -n 1 should
prevent all messages from showing up on the console, except panic messages. The
dmesg message levels matches exactly the syslogd levels, and it only works on log
messages from the kernel facility. For more information, see man dmesg.
|
The LOG target currently takes five options that could be of interest if you have
specific information needs, or want to set different options to specific values.
They are all listed below.
Table 11-8. LOG target options
Option |
--log-level |
Example |
iptables -A FORWARD -p tcp -j LOG --log-level debug
|
Explanation |
This is the option to tell iptables and syslog which log level to use. For a complete
list of log levels read the syslog.conf manual. Normally
there are the following log levels, or priorities as they are normally referred
to: debug, info, notice, warning, warn, err, error, crit, alert, emerg and panic.
The keyword error is the same as err, warn is the same as warning and panic is the
same as emerg. Note that all three of these are deprecated, in other words do not
use error, warn and panic. The priority defines the severity of the message being
logged. All messages are logged through the kernel facility. In other words, setting
kern.=info /var/log/iptables in your syslog.conf file
and then letting all your LOG messages in iptables use log level info, would make
all messages appear in the /var/log/iptables file. Note
that there may be other messages here as well from other parts of the kernel that
uses the info priority. For more information on logging I recommend you to read
the syslog and syslog.conf man-pages as well as other
HOWTOs etc.
|
Option |
--log-prefix |
Example |
iptables -A INPUT -p tcp -j LOG --log-prefix "INPUT packets" |
Explanation |
This option tells iptables to prefix all log messages with a specific prefix, which
can then easily be combined with grep or other tools to track specific problems
and output from different rules. The prefix may be up to 29 letters long, including
white-spaces and other special symbols.
|
Option |
--log-tcp-sequence |
Example |
iptables -A INPUT -p tcp -j LOG --log-tcp-sequence |
Explanation |
This option will log the TCP Sequence numbers, together with the log message. The
TCP Sequence numbers are special numbers that identify each packet and where it
fits into a TCP sequence, as well as how the stream should be reassembled. Note
that this option constitutes a security risk if the logs are readable by unauthorized
users, or by the world for that matter. As does any log that contains output from
iptables.
|
Option |
--log-tcp-options |
Example |
iptables -A FORWARD -p tcp -j LOG --log-tcp-options |
Explanation |
The --log-tcp-options option logs the different options from the TCP packet headers
and can be valuable when trying to debug what could go wrong, or what has actually
gone wrong. This option does not take any variable fields or anything like that,
just as most of the LOG options don't.
|
Option |
--log-ip-options |
Example |
iptables -A FORWARD -p tcp -j LOG --log-ip-options |
Explanation |
The --log-ip-options option will log most of the IP packet header options. This
works exactly the same as the --log-tcp-options option, but instead works on the
IP options. These logging messages may be valuable when trying to debug or track
specific culprits, as well as for debugging - in just the same way as the previous
option.
|
|
Works under Linux kernel 2.3, 2.4, 2.5 and 2.6.
|
The MARK target is used to set Netfilter mark values that are associated with specific
packets. This target is only valid in the mangle table, and will not work outside
there. The MARK values may be used in conjunction with the advanced routing capabilities
in Linux to send different packets through different routes and to tell them to
use different queue disciplines (qdisc), etc. For more information on advanced routing,
check out the Linux Advanced Routing and Traffic Control HOW-TO.
Note that the mark value is not set within the actual packet, but is a value that
is associated within the kernel with the packet. In other words, you can not set
a MARK for a packet and then expect the MARK still to be there on another host.
If this is what you want, you will be better off with the TOS target which will
mangle the TOS value in the IP header.
Table 11-9. MARK target options
Option |
--set-mark |
Example |
iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 2 |
Explanation |
The --set-mark option is required to set a mark. The --set-mark match takes an integer
value. For example, we may set mark 2 on a specific stream of packets, or on all
packets from a specific host and then do advanced routing on that host, to decrease
or increase the network bandwidth, etc.
|
|
Works under Linux kernel 2.3, 2.4, 2.5 and 2.6.
|
The MASQUERADE target is used basically the same as the SNAT target, but it does
not require any --to-source option. The reason for this is that the MASQUERADE target
was made to work with, for example, dial-up connections, or DHCP connections, which
gets dynamic IP addresses when connecting to the network in question. This means
that you should only use the MASQUERADE target with dynamically assigned IP connections,
which we don't know the actual address of at all times. If you have a static IP
connection, you should instead use the SNAT target.
When you masquerade a connection, it means that we set the IP address used on a
specific network interface instead of the --to-source option, and the IP address
is automatically grabbed from the information about the specific interface. The
MASQUERADE target also has the effect that connections are forgotten when an interface
goes down, which is extremely good if we, for example, kill a specific interface.
If we would have used the SNAT target, we may have been left with a lot of old connection
tracking data, which would be lying around for days, swallowing up useful connection
tracking memory. This is, in general, the correct behavior when dealing with dial-up
lines that are probably assigned a different IP every time they are brought up.
In case we are assigned a different IP, the connection is lost anyways, and it is
more or less idiotic to keep the entry around.
It is still possible to use the MASQUERADE target instead of SNAT even though you
do have a static IP, however, it is not favorable since it will add extra overhead,
and there may be inconsistencies in the future which will thwart your existing scripts
and render them "unusable".
Note that the MASQUERADE target is only valid within the POSTROUTING chain in the
nat table, just as the SNAT target. The MASQUERADE target takes one option specified
below, which is optional.
Table 11-10. MASQUERADE target options
Option |
--to-ports |
Example |
iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 1024-31000 |
Explanation |
The --to-ports option is used to set the source port or ports to use on outgoing
packets. Either you can specify a single port like --to-ports 1025 or you may specify
a port range as --to-ports 1024-3000. In other words, the lower port range delimiter
and the upper port range delimiter separated with a hyphen. This alters the default
SNAT port-selection as described in the SNAT target
section. The --to-ports option is only valid if the rule match section specifies
the TCP or UDP protocols with the --protocol match.
|
|
Works under Linux kernel 2.3, 2.4, 2.5 and 2.6.
|
|
Be warned, the MIRROR is dangerous and was only developed as an example code of
the new conntrack and NAT code. It can cause dangerous things to happen, and very
serious DDoS/DoS will be possible if used improperly. Avoif using it at all costs!
It was removed from 2.5 and 2.6 kernels due to it's bad security implications!
|
The MIRROR target is an experimental and demonstration target only, and you are
warned against using it, since it may result in really bad loops hence, among other
things, resulting in serious Denial of Service. The MIRROR target is used to invert
the source and destination fields in the IP header, and then to retransmit the packet.
This can cause some really funny effects, and I'll bet that, thanks to this target,
not just one red faced cracker has cracked his own box by now. The effect of using
this target is stark, to say the least. Let's say we set up a MIRROR target for
port 80 at computer A. If host B were to come from yahoo.com, and try to access
the HTTP server at host A, the MIRROR target would return the yahoo host's own web
page (since this is where the request came from).
Note that the MIRROR target is only valid within the INPUT, FORWARD and PREROUTING
chains, and any user-defined chains which are called from those chains. Also note
that outgoing packets resulting from the MIRROR target are not seen by any of the
normal chains in the filter, nat or mangle tables, which could give rise to loops
and other problems. This could make the target the cause of unforeseen headaches.
For example, a host might send a spoofed packet to another host that uses the MIRROR
command with a TTL of 255, at the same time spoofing its own packet, so as to seem
as if it comes from a third host that uses the MIRROR command. The packet will then
bounce back and forth incessantly, for the number of hops there are to be completed.
If there is only 1 hop, the packet will jump back and forth 240-255 times. Not bad
for a cracker, in other words, to send 1500 bytes of data and eat up 380 kbyte of
your connection. Note that this is a best case scenario for the cracker or script
kiddie, whatever we want to call them.
|
Works under Linux kernel 2.3 and 2.4. It was removed from 2.5 and 2.6 kernels due
to it's inherent insecurity. Do not use this target!
|
NETMAP is a new implementation of the SNAT and DNAT targets where the host part
of the IP address isn't changed. It provides a 1:1 NAT function for whole networks
which isn't available in the standard SNAT and DNAT functions. For example, lets
say we have a network containing 254 hosts using private IP addresses (a /24 network),
and we just got a new /24 network of public IP's. Instead of walking around and
changing the IP of each and every one of the hosts, we would be able to simply use
the NETMAP target like -j NETMAP -to 10.5.6.0/24 and voila, all the hosts are seen
as 10.5.6.x when they leave the firewall. For example, 192.168.0.26 would become
10.5.6.26.
Table 11-11. NETMAP target options
Option |
--to |
Example |
iptables -t mangle -A PREROUTING -s 192.168.1.0/24 -j NETMAP --to 10.5.6.0/24 |
Explanation |
This is the only option of the NETMAP target. In the above example, the 192.168.1.x
hosts will be directly translated into 10.5.6.x.
|
|
Works under Linux kernel 2.5 and 2.6.
|
The NFQUEUE target is used much the same way as the QUEUE target, and is basically
an extension of it. The NFQUEUE target allows for sending packets for separate and
specific queues. The queue is identified by a 16-bit id.
This target requires the nfnetlink_queue kernel support to run. For more information
on what you can do with the NFQUEUE target, see the QUEUE
target.
Table 11-12. NFQUEUE target options
Option |
--queue-num |
Example |
iptables -t nat -A PREROUTING -p tcp --dport 80 -j NFQUEUE --queue-num 30 |
Explanation |
The --queue-num option specifies which queue to use and to send the queue'd data
to. If this option is skipped, the default queue 0 is used. The queue number is
a 16 bit unsigned integer, which means it can take any value between 0 and 65535.
The default 0 queue is also used by the QUEUE target.
|
|
Works under Linux kernel 2.6.14 and later.
|
This target is used to turn off connection tracking for all packets matching this
rule. The target has been discussed at some length in the
Untracked connections and the raw table section of the
The state machine chapter.
The target takes no options and is very easy to use. Match the packets you wish
to not track, and then set the NOTRACK target on the rules matching the packets
you don't wish to track.
|
The target is only valid inside the raw table.
|
|
Works under late Linux 2.6 kernels.
|
The QUEUE target is used to queue packets to User-land programs and applications.
It is used in conjunction with programs or utilities that are extraneous to iptables
and may be used, for example, with network accounting, or for specific and advanced
applications which proxy or filter packets. We will not discuss this target in depth,
since the coding of such applications is out of the scope of this tutorial. First
of all it would simply take too much time, and secondly such documentation does
not have anything to do with the programming side of Netfilter and iptables. All
of this should be fairly well covered in the Netfilter
Hacking HOW-TO.
|
As of kernel 2.6.14 the behavior of netfilter has changed. A new system for talking
to the QUEUE has been deviced, called the nfnetlink_queue. The QUEUE target is basically
a pointer to the NFQUEUE 0 nowadays. For programming questions, still see the above
link. This requires the nfnetlink_queue.ko module.
|
|
Works under Linux kernel 2.3, 2.4, 2.5 and 2.6.
|
The REDIRECT target is used to redirect packets and streams to the machine itself.
This means that we could for example REDIRECT all packets destined for the HTTP
ports to an HTTP proxy like squid, on our own host. Locally generated packets are
mapped to the 127.0.0.1 address. In other words, this rewrites the destination address
to our own host for packets that are forwarded, or something alike. The REDIRECT
target is extremely good to use when we want, for example, transparent proxying,
where the LAN hosts do not
know about the proxy at all.
Note that the REDIRECT target is only valid within the PREROUTING and OUTPUT chains
of the nat table. It is also valid within user-defined chains that are only called
from those chains, and nowhere else. The REDIRECT target takes only one option,
as described below.
Table 11-13. REDIRECT target options
Option |
--to-ports |
Example |
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080 |
Explanation |
The --to-ports option specifies the destination port, or port range, to use. Without
the --to-ports option, the destination port is never altered. This is specified,
as above, --to-ports 8080 in case we only want to specify one port. If we would
want to specify a port range, we would do it like --to-ports 8080-8090, which tells
the REDIRECT target to redirect the packets to the ports 8080 through 8090. Note
that this option is only available in rules specifying the TCP or UDP protocol with
the --protocol matcher, since it wouldn't make any sense anywhere else.
|
|
Works under Linux kernel 2.3, 2.4, 2.5 and 2.6.
|
The REJECT target works basically the same as the DROP target, but it also sends
back an error message to the host sending the packet that was blocked. The REJECT
target is as of today only valid in the INPUT, FORWARD and OUTPUT chains or their
sub chains. After all, these would be the only chains in which it would make any
sense to put this target. Note that all chains that use the REJECT target may only
be called by the INPUT, FORWARD, and OUTPUT chains, else they won't work. There
is currently only one option which controls the nature of how this target works,
though this may in turn take a huge set of variables. Most of them are fairly easy
to understand, if you have a basic knowledge of TCP/IP.
Table 11-14. REJECT target options
Option |
--reject-with |
Example |
iptables -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset |
Explanation |
This option tells the REJECT target what response to send to the host that sent
the packet that we are rejecting. Once we get a packet that matches a rule in which
we have specified this target, our host will first of all send the associated reply,
and the packet will then be dropped dead, just as the DROP target would drop it.
The following reject types are currently valid: icmp-net-unreachable, icmp-host-unreachable,
icmp-port-unreachable, icmp-proto-unreachable, icmp-net-prohibited and icmp-host-prohibited.
The default error message is to send a port-unreachable to the host. All of the
above are ICMP error messages and may be set as you wish. You can find further information
on their various purposes in the appendix ICMP types.
Finally, there is one more option called tcp-reset, which may only be used together
with the TCP protocol. The tcp-reset option will tell REJECT to send a TCP RST packet
in reply to the sending host. TCP RST packets are used to close open TCP connections
gracefully. For more information about the TCP RST read RFC 793
- Transmission Control Protocol. As stated in the iptables man page,
this is mainly useful for blocking ident probes which frequently occur when sending
mail to broken mail hosts, that won't otherwise accept your mail.
|
|
Works under Linux kernel 2.3, 2.4, 2.5 and 2.6.
|
The RETURN target will cause the current packet to stop traveling through the chain
where it hit the rule. If it is the subchain of another chain, the packet will continue
to travel through the superior chains as if nothing had happened. If the chain is
the main chain, for example the INPUT chain, the packet will have the default policy
taken on it. The default policy is normally set to ACCEPT, DROP or similar.
For example, let's say a packet enters the INPUT chain and then hits a rule that
it matches and that tells it to --jump EXAMPLE_CHAIN. The packet will then start
traversing the EXAMPLE_CHAIN, and all of a sudden it matches a specific rule which
has the --jump RETURN target set. It will then jump back to the INPUT chain. Another
example would be if the packet hit a --jump RETURN rule in the INPUT chain. It would
then be dropped to the default policy as previously described, and no more actions
would be taken in this chain.
|
Works under Linux kernel 2.3, 2.4, 2.5 and 2.6.
|
The SAME target works almost in the same fashion as the SNAT target, but it still
differs. Basically, the SAME target will try to always use the same outgoing IP
address for all connections initiated by a single host on your network. For example,
say you have one /24 network (192.168.1.0) and 3 IP addresses (10.5.6.7-9). Now,
if 192.168.1.20 went out through the .7 address the first time, the firewall will
try to keep that machine always going out through that IP address.
Table 11-15. SAME target options
Option |
--to |
Example |
iptables -t mangle -A PREROUTING -s 192.168.1.0/24 -j SAME --to 10.5.6.7-10.5.6.9 |
Explanation |
As you can see, the --to argument takes 2 IP addresses bound together by a - sign.
These IP addresses, and all in between, are the IP addresses that we NAT to using
the SAME algorithm.
|
Option |
--nodst |
Example |
iptables -t mangle -A PREROUTING -s 192.168.1.0/24 -j SAME --to 10.5.6.7-10.5.6.9
--nodst |
Explanation |
Under normal action, the SAME target is calculating the followup connections based
on both destination and source IP addresses. Using the --nodst option, it uses only
the source IP address to find out which outgoing IP the NAT function should use
for the specific connection. Without this argument, it uses a combination of the
destination and source IP address.
|
|
Works under Linux kernel 2.5 and 2.6.
|
The SECMARK target is used to set a security context mark on a single packet, as
defined by SELinux and security systems. This is still somewhat in it's infancy
in Linux, but should pick up more and more in the future. Since SELinux is out of
the scope of this document, I suggest going to the Security-Enhanced
Linux webpage for more information.
In brief, SELinux is a new and improved security system to add Mandatory Access
Control (MAC) to Linux, implemented by NSA as a proof of concept. SELinux basically
sets security attributes for different objects and then matches them into security
contexts. The SECMARK target is used to set a security context on a packet which
can then be used within the security subsystems to match on.
|
The SECMARK target is only valid in the mangle table.
|
Table 11-16. SECMARK target options
Option |
--selctx |
Example |
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j SECMARK --selctx httpcontext |
Explanation |
The --selctx option is used to specify which security context to set on a packet.
The context can then be used for matching inside the security systems of linux.
|
The SNAT target is used to do Source Network Address Translation, which means that
this target will rewrite the Source IP address in the IP header of the packet. This
is what we want, for example, when several hosts have to share an Internet connection.
We can then turn on ip forwarding in the kernel, and write an SNAT rule which will
translate all packets going out from our local network to the source IP of our own
Internet connection. Without doing this, the outside world would not know where
to send reply packets, since our local networks mostly use the IANA specified IP
addresses which are allocated for LAN networks. If we forwarded these packets as
is, no one on the Internet would know that they were actually from us. The SNAT
target does all the translation needed to do this kind of work, letting all packets
leaving our LAN look as if they came from a single host, which would be our firewall.
The SNAT target is only valid within the nat table, within the POSTROUTING chain.
This is in other words the only chain in which you may use SNAT. Only the first
packet in a connection is mangled by SNAT, and after that all future packets using
the same connection will also be SNATted. Furthermore, the initial rules in the
POSTROUTING chain will be applied to all the packets in the same stream.
Table 11-17. SNAT target options
Option |
--to-source |
Example |
iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to-source 194.236.50.155-194.236.50.160:1024-32000
|
Explanation |
The --to-source option is used to specify which source the packet should use. This
option, at its simplest, takes one IP address which we want to use for the source
IP address in the IP header. If we want to balance between several IP addresses,
we can use a range of IP addresses, separated by a hyphen. The --to--source IP numbers
could then, for instance, be something like in the above example: 194.236.50.155-194.236.50.160.
The source IP for each stream that we open would then be allocated randomly from
these, and a single stream would always use the same IP address for all packets
within that stream. We can also specify a range of ports to be used by SNAT. All
the source ports would then be confined to the ports specified. The port bit of
the rule would then look like in the example above, :1024-32000. This is only valid
if -p tcp or -p udp was specified somewhere in the match of the rule in question.
iptables will always try to avoid making any port alterations if possible, but if
two hosts try to use the same ports, iptables will map one of them to another port.
If no port range is specified, then if they're needed, all source ports below 512
will be mapped to other ports below 512. Those between source ports 512 and 1023
will be mapped to ports below 1024. All other ports will be mapped to 1024 or above.
As previously stated, iptables will always try to maintain the source ports used
by the actual workstation making the connection. Note that this has nothing to do
with destination ports, so if a client tries to make contact with an HTTP server
outside the firewall, it will not be mapped to the FTP control port.
|
|
Works under Linux kernel 2.3, 2.4, 2.5 and 2.6.
|
The TCPMSS target can be used to alter the MSS (Maximum Segment Size) value of TCP
SYN packets that the firewall sees. The MSS value is used to control the maximum
size of packets for specific connections. Under normal circumstances, this means
the size of the MTU (Maximum Transfer Unit) value, minus 40 bytes. This is used
to overcome some ISP's and servers that block ICMP fragmentation needed packets,
which can result in really weird problems which can mainly be described such that
everything works perfectly from your firewall/router, but your local hosts behind
the firewall can't exchange large packets. This could mean such things as mail servers
being able to send small mails, but not large ones, web browsers that connect but
then hang with no data received, and ssh connecting properly, but scp hangs after
the initial handshake. In other words, everything that uses any large packets will
be unable to work.
The TCPMSS target is able to solve these problems, by changing the size of the packets
going out through a connection. Please note that we only need to set the MSS on
the SYN packet since the hosts take care of the MSS after that. The target takes
two arguments.
Table 11-18. TCPMSS target options
Option |
--set-mss |
Example |
iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o eth0 -j TCPMSS
--set-mss 1460
|
Explanation |
The --set-mss argument explicitly sets a specific MSS value of all outgoing packets.
In the example above, we set the MSS of all SYN packets going out over the eth0
interface to 1460 bytes -- normal MTU for ethernet is 1500 bytes, minus 40 bytes
is 1460 bytes. MSS only has to be set properly in the SYN packet, and then the peer
hosts take care of the MSS automatically.
|
Option |
--clamp-mss-to-pmtu |
Example |
iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o eth0 -j TCPMSS
--clamp-mss-to-pmtu
|
Explanation |
The --clamp-mss-to-pmtu automatically sets the MSS to the proper value, hence you
don't need to explicitly set it. It is automatically set to PMTU (Path Maximum Transfer
Unit) minus 40 bytes, which should be a reasonable value for most applications.
|
|
Works under Linux kernel 2.5 and 2.6.
|
The TOS target is used to set the Type of Service field within the IP header. The
TOS field consists of 8 bits which are used to help in routing packets. This is
one of the fields that can be used directly within iproute2 and its subsystem for
routing policies. Worth noting, is that if you handle several separate firewalls
and routers, this is the only way to propagate routing information within the actual
packet between these routers and firewalls. As previously noted, the MARK target
- which sets a MARK associated with a specific packet - is only available within
the kernel, and can't be propagated with the packet. If you feel a need to propagate
routing information for a specific packet or stream, you should therefore set the
TOS field, which was developed for this.
There are currently a lot of routers on the Internet which do a pretty bad job at
this, so as of now it may prove to be a bit useless to attempt TOS mangling before
sending the packets on to the Internet. At best the routers will not pay any attention
to the TOS field. At worst, they will look at the TOS field and do the wrong thing.
However, as stated above, the TOS field can most definitely be put to good use if
you have a large WAN or LAN with multiple routers. You then in fact have the possibility
of giving packets different routes and preferences, based on their TOS value - even
though this might be confined to your own network.
|
The TOS target is only capable of setting specific values, or named values on packets.
These predefined TOS values can be found in the kernel include files, or more precisely,
the Linux/ip.h file. The reasons are many, and you should
actually never need to set any other values; however, there are ways around this
limitation. To get around the limitation of only being able to set the named values
on packets, you can use the FTOS patch available at the Paksecured
Linux Kernel patches site maintained by Matthew G. Marsh. However, be
cautious with this patch! You should not need to use any other than the default
values, except in extreme cases.
|
|
Note that this target is only valid within the mangle table and can't be used outside
it.
|
|
Also note that some old versions (1.2.2 or below) of iptables provided a broken
implementation of this target which did not fix the packet checksum upon mangling,
hence rendering the packets bad and in need of retransmission. That in turn would
most probably lead to further mangling and the connection never working.
|
The TOS target only takes one option as described below.
Table 11-19. TOS target options
Option |
--set-tos |
Example |
iptables -t mangle -A PREROUTING -p TCP --dport 22 -j TOS --set-tos 0x10 |
Explanation |
The --set-tos option tells the TOS mangler what TOS value to set onpackets that
are matched. The option takes a numeric value, either in hex or in decimal value.
As the TOS value consists of 8 bits, the value may be 0-255, or in hex 0x00-0xFF.
Note that in the standard TOS target you are limited to using the named values available
(which should be more or less standardized), as mentioned in the previous warning.
These values are Minimize-Delay (decimal value 16, hex value 0x10), Maximize-Throughput
(decimal value 8, hex value 0x08), Maximize-Reliability (decimal value 4, hex value
0x04), Minimize-Cost (decimal value 2, hex 0x02) or Normal-Service (decimal value
0, hex value 0x00). The default value on most packets is Normal-Service, or 0. Note
that you can, of course, use the actual names instead of the actual hex values to
set the TOS value; in fact this is generally to be recommended, since the values
associated with the names may be changed in future. For a complete listing of the
"descriptive values", do an iptables -j TOS -h.
|
|
Works under Linux kernel 2.3, 2.4, 2.5 and 2.6.
|
The TTL target is used to modify the Time To Live field in the IP header. One useful
application of this is to change all Time To Live values to the same value on all
outgoing packets. One reason for doing this is if you have a bully
ISP which don't allow you to have more than one
machine connected to the same Internet connection, and who actively pursues this.
Setting all TTL values to the same value, will effectively make it a little bit
harder for them to notice that you are doing this. We may then reset the TTL value
for all outgoing packets to a standardized value, such as 64 as specified in the
Linux kernel.
For more information on how to set the default value used in Linux, read the
ip-sysctl.txt, which you may find within the
Other resources and links appendix.
The TTL target is only valid within the mangle table, and nowhere else. It takes
3 options as of writing this, all of them described below in the table.
Table 11-20. TTL target options
Option |
--ttl-set |
Example |
iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-set 64 |
Explanation |
The --ttl-set option tells the TTL target which TTL value to set on the packet in
question. A good value would be around 64 somewhere. It's not too long, and it is
not too short. Do not set this value too high, since it may affect your network
and it is a bit immoral to set this value to high, since the packet may start bouncing
back and forth between two mis-configured routers, and the higher the TTL, the more
bandwidth will be eaten unnecessarily in such a case. This target could be used
to limit how far away our clients are. A good case of this could be DNS servers,
where we don't want the clients to be too far away.
|
Option |
--ttl-dec |
Example |
iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-dec 1 |
Explanation |
The --ttl-dec option tells the TTL target to decrement the Time To Live value by
the amount specified after the --ttl-dec option. In other words, if the TTL for
an incoming packet was 53 and we had set --ttl-dec 3, the packet would leave our
host with a TTL value of 49. The reason for this is that the networking code will
automatically decrement the TTL value by 1, hence the packet will be decremented
by 4 steps, from 53 to 49. This could for example be used when we want to limit
how far away the people using our services are. For example, users should always
use a close-by DNS, and hence we could match all packets leaving our DNS server
and then decrease it by several steps. Of course, the --set-ttl may be a better
idea for this usage.
|
Option |
--ttl-inc |
Example |
iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-inc 1 |
Explanation |
The --ttl-inc option tells the TTL target to increment the Time To Live value with
the value specified to the --ttl-inc option. This means that we should raise the
TTL value with the value specified in the --ttl-inc option, and if we specified
--ttl-inc 4, a packet entering with a TTL of 53 would leave the host with TTL 56.
Note that the same thing goes here, as for the previous example of the --ttl-dec
option, where the network code will automatically decrement the TTL value by 1,
which it always does. This may be used to make our firewall a bit more stealthy
to trace-routes among other things. By setting the TTL one value higher for all
incoming packets, we effectively make the firewall hidden from trace-routes. Trace-routes
are a loved and hated thing, since they provide excellent information on problems
with connections and where it happens, but at the same time, it gives the hacker/cracker
some good information about your upstreams if they have targeted you. For a good
example on how this could be used, see the Ttl-inc.txt
script.
|
|
Works under Linux kernel 2.3, 2.4, 2.5 and 2.6.
|
The ULOG target is used to provide user-space logging of matching packets. If a
packet is matched and the ULOG target is set, the packet information is multicasted
together with the whole packet through a netlink socket. One or more user-space
processes may then subscribe to various multicast groups and receive the packet.
This is in other words a more complete and more sophisticated logging facility that
is only used by iptables and Netfilter so far, and it contains much better facilities
for logging packets. This target enables us to log information to MySQL databases,
and other databases, making it much simpler to search for specific packets, and
to group log entries. You can find the ULOGD user-land applications at the
ULOGD project page.
Table 11-21. ULOG target options
Option |
--ulog-nlgroup |
Example |
iptables -A INPUT -p TCP --dport 22 -j ULOG --ulog-nlgroup 2 |
Explanation |
The --ulog-nlgroup option tells the ULOG target which netlink group to send the
packet to. There are 32 netlink groups, which are simply specified as 1-32. If we
would like to reach netlink group 5, we would simply write --ulog-nlgroup 5. The
default netlink group used is 1.
|
Option |
--ulog-prefix |
Example |
iptables -A INPUT -p TCP --dport 22 -j ULOG --ulog-prefix "SSH connection attempt:
" |
Explanation |
The --ulog-prefix option works just the same as the prefix value for the standard
LOG target. This option prefixes all log entries with a user-specified log prefix.
It can be 32 characters long, and is definitely most useful to distinguish different
log-messages and where they came from.
|
Option |
--ulog-cprange |
Example |
iptables -A INPUT -p TCP --dport 22 -j ULOG --ulog-cprange 100 |
Explanation |
The --ulog-cprange option tells the ULOG target how many bytes of the packet to
send to the user-space daemon of ULOG. If we specify 100 as above, we would copy
100 bytes of the whole packet to user-space, which would include the whole header
hopefully, plus some leading data within the actual packet. If we specify 0, the
whole packet will be copied to user-space, regardless of the packets size. The default
value is 0, so the whole packet will be copied to user-space.
|
Option |
--ulog-qthreshold |
Example |
iptables -A INPUT -p TCP --dport 22 -j ULOG --ulog-qthreshold 10 |
Explanation |
The --ulog-qthreshold option tells the ULOG target how many packets to queue inside
the kernel before actually sending the data to user-space. For example, if we set
the threshold to 10 as above, the kernel would first accumulate 10 packets inside
the kernel, and then transmit it outside to the user-space as one single netlink
multi part message. The default value here is 1 because of backward compatibility,
the user-space daemon did not know how to handle multi-part messages previously.
|
|
Works under Linux kernel 2.3, 2.4, 2.5 and 2.6.
|
This chapter has discussed in detail each and every target that is available in
Linux. This list is still growing as people write more and more target extensions
for iptables and netfilter, and it is already quite extensive as you have seen.
The chapter has also discussed the different target options available for each target.
The next chapter will delve into debugging your firewall scripts and what techniques
are available for doing this. It will both show you moderate debugging techniques
such as using bash and echo, to some more advanced tools such as nmap and nessus.
|
|
|