IPTABLES quick HOWTO

Contents

  1. Introduction
  2. Sample Rules
  3. Rules insertion/removal
  4. Main Steps
  5. Starting/Stopping iptables
  6. Basic masquerading
  7. Resources

Introduction

The information that a computer exchanges with other computers on the internet travels in units called packets. The packets contain the data intended to be communicated between two computers, as well as a header. The header contains information about the packet (e.g. the size of the packet, various flags, etc.), and routing information (such as the source and the destination). The usual analogy is with a postal letter: if the letter itself is the data, the envelope (containing the "TO:" and the "FROM:" fields) is the header. Again, the packet header contains other information as well, and the exact fields in the header depend on the protocol (such as tcp, udp or icmp). We will be interested mainly in the source address/port and the destination address/port fields, the protocol of the packet, as well as some packet flags.

A firewall is a list of rules used to decide the fate of the packets that come into or leave a computer, according to certain criteria, or parameters. For example, we may want to allow all outgoing traffic, but we may want to drop all incoming packets, except perhaps the secure shell packets, email packets and http packets. At this point in Linux history, there are two mechanisms to implement a firewall: ipchains and iptables. Ipchains was the sole method until relatively recently, and for the average needs of the average home user, it may do just fine. It is aging slowly, passing on the responsibility to the newer, preferred method - iptables. Iptables is not just an improvement over ipchains. It was re-designed from scratch, to allow for far more flexible firewalls, while trying to preserve the ipchains syntax for user level command tools. So for the user familiar with ipchains, the transition to iptables should be fairly smooth. Familiarity with ipchains will not be required in this tutorial though.

Ipchains has three chains (INPUT, OUTPUT and FORWARD), each with its own set of rules. A packet travels along one of these chains and it is being matched against each of the rules, from top to bottom. If the packet matches one of the rules, then the action specified by that rule is applied (e.g. in ipchains, ACCEPT the packet, or DENY it, etc.). Certainly, there must be a default rule (the policy) in each chain, in case the packet does not match any of the explicit rules. In ipchains, there are 6 built-in actions (targets): ACCEPT, DENY, REJECT, MASQ, REDIRECT, RETURN).

By contrast, iptables has 3 tables now, each with its own chains. Specifically, in iptables the tables are

The default table is FILTER. That is, if some maintenance is done on the firewall without explicitly specifying the table, the work is done on the FILTER table. The built-in iptables targets are only ACCEPT, DROP, QUEUE and RETURN. In addition to these targets, there are target extensions (LOG, MARK, REJECT, TOS, MIRROR, SNAT, DNAT, MASQUERADE and REDIRECT), and even extra extensions (man iptables). We will only use in this tutorial the ACCEPT and DROP builtins, and LOG. Loosely speaking (in fact very loosely), ipchains can be thought of as a subset of iptables: it fulfills the role of the FILTER table (and more). I'm sure this statement will trigger vehement protests from the experts, but so be it. I'm open to comments.

Note 1: This tutorial only covers how to write FILTER rules for the INPUT chain. Writing rules for the OUTPUT chain is similar, and unless you want to restrict your own users access to certain sites, for starters you can just set the OUTPUT policy to ACCEPT. The intention is only to provide a starting point in creating a firewall. Subsequently, you can make your firewall arbitrarily tight.

Note 2: This tutorial now covers very briefly the essentials of MASQUERADING, useful in the simplest of cases, i.e. when a home user has a single IP address from the provider, and wants his home lan computers to be able to connect transparently to the internet. We do not explain other NAT uses, such as destination nat, or transparent proxies. We do provide pointers to references to these topics though.

Sample Rules

On to examples. You probably do not have an iptables firewall running. You will have to build the rules first. So you will probably not be able to run the first examples right now. Nevertheless, I do have a firewall up and running, so we shall take a look at some rules that I have in it. In what follows,

1) root:~>

is my prompt, configured to my liking. It is not part of the command. It shows the number of the command, who I am (root) and the directory I'm in.

Root creates and manages the rules. The command for this is /sbin/iptables. Various flags will do various things. To see (list) the rules we already have in the firewall, run /sbin/iptables -L:

4) root:~> /sbin/iptables -L    # list rules
5) root:~> /sbin/iptables -L -n  # list in numeric format
6) root:~> /sbin/iptables -L --line-numbers # show also the rule number

Here's what an empty firewall looks like:

7) root:~> /sbin/iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

All 3 chains in the default table (FILTER) are listed, but contain no rules. For each channel, the default rule (policy) is set to ACCEPT. Let us now see a firewall with some contents.


10) root:~> /sbin/iptables -L -n --line-numbers
Chain INPUT (policy DROP)
num  target     prot opt source               destination         
1    LOG        tcp  --  0.0.0.0/0            0.0.0.0/0          tcp flags:!0x16/0x02 state NEW LOG flags 0 level 4 prefix `NEW NOT SYN: ' 
2    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0          tcp flags:!0x16/0x02 state NEW 
3    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0          tcp dpt:1214 
4    DROP       udp  --  0.0.0.0/0            0.0.0.0/0          udp dpt:1214 
5    ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0          udp spt:67 dpt:68 
6    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0          state RELATED,ESTABLISHED 
These are only the very first few rules listed in numeric format, in the INPUT chain (of the default table - FILTER). There are more rules for the INPUT chain, as well as rules for the FORWARD and OUTPUT chains, and possibly rules for the other tables NAT and MANGLE, but they are not listed, for brevity.

We can now explain the "anatomy" of a rule. The first column is obviously the rule number. Upon arrival of a packet, the rules will be examined in the order in the "num" column. The "target" column represents the action that will be taken against a packet that matches a rule. We see here the DROP and ACCEPT targets (these are built-in) but for the first rule, we have a LOG target, which logs the packets to a system log file (/var/log/messages).

The remaining columns show the parameters used by each rule to match a packet. These criteria may include the protocol, various options, the source and the target address, the destination port (e.g. dpt:1214, dpt:68), the source port (e.g. spt:67), as well as the STATE of the packet. Yes, iptables is statefull, i.e. it can keep track of packets according to their state. For instance, if a packet is part of an already established connection (e.g. an ftp transfer), then it is in state ESTABLISHED.

Let us explain the first rule.

1    LOG        tcp  --  0.0.0.0/0            0.0.0.0/0          tcp flags:!0x16/0x02 state NEW LOG flags 0 level 4 prefix `NEW NOT SYN: ' 
All tcp packets, coming from anywhere (source=0.0.0.0/0) addressed anywhere (destination=0.0.0.0/0) which are in state NEW, but have/do not have certain flags set (SYN, ACK/SYN, RST) will be LOGged. In fact, we would like to drop these packets, and we will shortly (rule number 2), but before we drop them, we want to log. The packets matching rule (1) will be logged using a string ("NEW NOT SYN"). This way we can grep after this string in the log file. The second rule simply drops the packets logged by the first rule.

Rule number 3
3    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0          tcp dpt:1214 
DROPs all tcp packets, from anywhere to anywhere, addressed to port 1214 (on the destination machine, obviously). Rule 4 is similar to 3, except that we drop the udp packets. Why this rule? To get rid of the Kazaa people looking for music around the globe. Notice that the default policy in the INPUT chain is set to DROP, so why do we need an explicit rule to drop the port 1214 packets? It's all part of a "grand scheme" which will be explained after the examples. For now just try to understand the structure of a rule.

Rule 5 is a little more interesting:
5    ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0          udp spt:67 dpt:68 
It ACCEPTs all udp packets from (source) port 67 on any machine to port 68 (on any machine). These are the dhcp packets. At boot, when the connection is negociated, we do not know the IP address of the dhcp server, nor do we know our own IP address. That's why we must set both the source and the destination address to 0.0.0.0/0 (any). If we knew the IP address of the dhcp server and we were certain it never changes, then we could be specific and use that address as the source address (instead of "any").

Finally, rule 6:
6    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0          state RELATED,ESTABLISHED 
All packets (in any protocol, from anywhere to anywhere) which are in state RELATED or ESTABLISHED will be allowed to come through. Why? Without this rule, the firewall will drop anything in sight, heading towards our computer. When we initiate a connection (e.g. telnet work.com, or ftp some.ftp.site.org or open a URL) we usually expect a reply to our request. The remote site will send us replies (e.g. a login prompt, or a web page), but the firewall will drop them, if it were not for this rule.

Do not worry too much why we need these particular rules. Each computer will require a different security policy, so the administrator will end up writing up his own set of rules. For now the goal is to understand what a firewall is, and what rules look like.

Rule insertion and removal

This section explains how we create the rules and insert them in the firewall. It is the core of building a firewall. The command for this is still /sbin/iptables, with the flags -A or -I, depending if we want to append a rule to whatever we already have, or if we want to insert a rule at a specific point in the firewall.

Here is the precise command used to put the first rule in the firewall:


4) root:~> /sbin/iptables -A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j LOG --log-prefix "NEW NOT SYN: "

Here -A INPUT means the obvious: we want to append a rule to the INPUT chain (in the default table FILTER). The part
-p tcp... --state NEW
is the parameters part: the rule will affect the (a) tcp packets that (b) do not have the SYN,RST,ACK, SYN flags set (! --tcp-flags) and (c) are in state NEW. The action taken on these packets is -j LOG (jump to target LOG), whose effect is to log the packet in /var/log/messages. Finally, in order to be able to grep after these packets, we use a log preffix - the string "NEW NOT SYN". We are not specifying any particular source address/port, nor a destination/port, so these will be set to "any". If this computer firewalls all traffic to an entire LAN, then this rule will be applied to packets intended for any of the local machines.
Complicated? Let's look at a simpler rule, for instance rule number 3:
5) root:~> /sbin/iptables -A INPUT -p tcp -m tcp --dport 1214 -j DROP
Here we append to the INPUT chain the rule that simply DROPs the tcp packets whose destination port is 1214 (regardless of the source address/port, destination address, flags, state, etc.). Again, no source/destination addresses, so no machine on the local network (if any) will receive these packets.

Suppose now that we already have a list of rules in the firewall. Suppose also, that for some reason, we want to place one extra rule, somewhere in the middle of the list, just before rule X. The append command will only add rules to the end of the list. We already mentioned that to insert, we use -I rather than -A. For the sake of example, let us assume again we have the first 6 rules listed above with -L --line-numbers. Suppose also that we want to insert just before rule (3) a new rule. To keep things simple, assume we want the new rule to drop all tcp packets coming from the following address: 207.46.249.190 (nothing personal, just an example). Before insertion:

17) root:~> /sbin/iptables -L -n --line-numbers
Chain INPUT (policy DROP)
num  target     prot opt source               destination         
1    LOG        tcp  --  0.0.0.0/0            0.0.0.0/0          tcp flags:!0x16/0x02 state NEW LOG flags 0 level 4 prefix `NEW NOT SYN: ' 
2    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0          tcp flags:!0x16/0x02 state NEW 
3    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0          tcp dpt:1214 
4    DROP       udp  --  0.0.0.0/0            0.0.0.0/0          udp dpt:1214 
5    ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0          udp spt:67 dpt:68 
6    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0          state RELATED,ESTABLISHED 
Insertion proper:
18) root:~> /sbin/iptables -I INPUT 3 -p tcp -m tcp -s 207.46.249.190 -j DROP
Now, if we list again:
19) root:~> /sbin/iptables -L -n --line-numbers
Chain INPUT (policy DROP)
num  target     prot opt source               destination         
1    LOG        tcp  --  0.0.0.0/0            0.0.0.0/0          tcp flags:!0x16/0x02 state NEW LOG flags 0 level 4 prefix `NEW NOT SYN: ' 
2    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0          tcp flags:!0x16/0x02 state NEW 
3    DROP       tcp  --  207.46.249.190       0.0.0.0/0          tcp 
4    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0          tcp dpt:1214 
5    DROP       udp  --  0.0.0.0/0            0.0.0.0/0          udp dpt:1214 
6    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0          
7    ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0          udp spt:67 dpt:68 
Observe how the new rule has been inserted in the 3rd place, and the remaining rules have been pushed down one place. If we change our mind and we decide that we actually don't need this rule (or any rule, for that matter), we can remove it with the -R flag:
20) root:~> /sbin/iptables -R INPUT 3
It's as simple as that. Just specify that we want to remove (-R) rule number (3) from the INPUT chain (in the default table FILTER).

The Main Steps

Now that we have a few examples of how to append, insert and remove rules dynamically into the firewall, we can move on to actually building a viable firewall, to satisfy the security policy appropriate for our network.

  1. /etc/rc.d/init.d/iptables stop   # reset the firewall
  2. add new rules as needed   # details below
  3. /sbin/iptables-save > rules_file   # save the rules to a file, for further reference

Strategy for adding rules

The ability to insert rules dynamically into iptables comes in handy in case of an emergency, and in building the firewall, but it won't take us too far without a thorough consideration of the design of the firewall and without a sound security policy. Ad-hoc insertion/removal or rules, often leads to the inability to connect to the internet, or to excessive logging, or, worst of all, an insecure firewall.

We must have the correct mindset to build a firewall. If you were to build yourself a house and then wanted to protect it with fence, you wouldn't build the fence just in front of the front door, would you? You would want to surround the entire house with fence, and only allow your guests to come in one by one through a designated place that you control. Plain common sense. The most common mistake in designing the firewall is to set the policy to ACCEPT then try to drop the unwanted packets one by one. All firewalls that do that are plain stupid and unsafe. It's just too many packets to drop individually, and, more importantly, we cannot possibly anticipate all possible malitious packets that will hit us.

The correct logic is this: drop everyting by default, then punch holes into the firewall as needed, to let the "good" packets come through. Assume that all packets are bad, and single out the good ones, not viceversa. I cannot empahsize this enough. The DROP policy in the INPUT chain acts as a safety net.

Here is the logical structure of our INPUT chain.


ACCEPT/DROP packets that we do not want to log. ACCEPT packets in state ESTABLISHED, RELATED /sbin/iptables -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
ACCEPT udp packets on port 68 (dhcp) /sbin/iptables -A INPUT -p udp -m udp --sport 67 --dport 68 -j ACCEPT
ACCEPT all traffic on the lo interface /sbin/iptables -A INPUT -i lo -j ACCEPT
DROP harmless but frequent and annoying probes on various ports (e.g. 1214 - kazaa) /sbin/iptables -A INPUT -p tcp -m tcp --dport 1214 -j DROP
/sbin/iptables -A INPUT -p udp -m udp --dport 1214 -j DROP
Coarse logging: everything at and below this point will be logged. LOW TCP CONNECTION /sbin/iptables -A INPUT -p tcp -m tcp --dport 0:1023 -m state --state NEW -j LOG --log-prefix "LOW PORT TCP CONNECTION: "
LOW UDP CONNECTION /sbin/iptables -A INPUT -p udp -m state --state NEW -m udp --dport 0:1023 -j LOG --log-prefix "LOW PORT UDP CONNECTION: "
HIGH TCP CONNECTION /sbin/iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 1024:65535 -j LOG --log-prefix "HIGH PORT UDP CONNECTION: "
HIGH UDP CONNECTION /sbin/iptables -A INPUT -p udp -m state --state NEW -m udp --dport 1024:65535 -j LOG --log-prefix "HIGH PORT UDP CONNECTION:"
NEW NOT SYN /sbin/iptables -A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j LOG --log-prefix "NEW NOT SYN: "
ECHO /sbin/iptables -A INPUT -p icmp -j LOG --log-prefix "ECHO: "
Punch holes. These are below the LOG section, so they will be logged. ACCEPT ssh /sbin/iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
ACCEPT ntp /sbin/iptables -A INPUT -p udp -m udp --sport 123 -j ACCEPT
ACCEPT ping from a designated address only /sbin/iptables -A INPUT -s 35.9.20.20 -p icmp -j ACCEPT
Policy DROP /sbin/iptables -P INPUT DROP

The foundation of our firewall (again, only the INPUT chain in the FILTER table) is the red block: policy is set to DROP. We build on top of that (although the actual insertion of the rules can take place in a top-down manner, as it is indicated by the -A INPUT in the rightmost column). After we've set the policy to DROP, we punch holes to allow useful packets, such as ssh, ntp, http, smtp, ftp, and whatever the needs of your particular site require. Anything above the yellow block (logging) will not be logged. Anything below, will. All this is straightforward. We detail logging in a separate section.

Logging

Logging is not mandatory for the proper operation of the firewall, but it is useful. There are obviously two extremes: log nothing, or log everything. If we log everything (or nearly everything), we must decide on the granularity of the logging. Specifically, the logs can be coarse, i.e. we can log irrespective of the nature of the packet (e.g. the same log prefix, or no log prefix at all for all packets), or fine: a special log prefix for each type of packet. In the latter case, we would have to accompany each "real" rule in the firewall, with a log rule, with a special log prefix. This way, we would be able to figure out in the logs, which rule was responsible for dropping/accepting a packet. As an aside, ipchains had builtin the capability to report in the logs, the rule number of the particular rule that accepted/dropped a packet. That was a cheap and effective way to see what each rule did. We can still achieve this with iptables, but it requires a little more care.

Our approach is to try to find a compromise between these extremes. We will log nearly everything. Exceptions are packets that occur with high frequency. Candidates are in the first place, packets in state ESTABLISHED and RELATED. This is a must. These must be ACCEPTed without logging. If we log these, we will flood the log files each time we open a web page, transfer a file, etc. Additionally, we can DROP without logging known, harmless probes (e.g. on port 1214 - kazaa). We can also accept without logging the dhcp packets, or the ntp packets. These are numerous enough to clutter the logs. To make the long story short, there are a number of packets that should not be logged due to their large numbers, whether or not we ACCEPT or DROP them.

Once we've decided what packets to exclude from logging, we must decide how fine the logging should be. Should we write a log rule for each real rule? Or perhaps a more coarse categorization would be more appropriate? Our approach is shown in the yellow block in the above table. We divide the ports into low ports (1-1023) and high ports (1024-65335), with appropriate prefixes. With a single grep then we can see, for instance, all tcp attempts on the sensitive, privileged ports ( under 1023). A little script (iptlog) provided below using gawk can then provide a very nice summary of what's going on. We also have special log rules for icmp packets and for the new not syn packets. Chances are these packets are not exactly innocent, so we want to be able to see them quickly.

Referring again to the above table, what happens above and below the logging section (the yellow block)? A packet that we do not want to log, must be either ACCEPTed or DROPped BEFORE it reaches the LOG block. Hence, the place for the rules for packets not to be logged is above the LOG block (the purple block). On the other hand, anything that makes it to the LOG section, will make it below it as well (the green block). This is because LOG on its own, does not accept or drop packets. If a packet "hits" a log rule, it will continue to move down the rules list. Thus, if we allow, for instance, ssh connections (port 22), if we put the corresponding ACCEPT rule below the yellow block, the ssh packets will be allowed to come in, but they've just been logged. If we didn't want to log ssh connections, we would put the ACCEPT rule above the yellow block.

Here is a sample output of the iptlog) script, which greps in /var/log/messages after the log prefixes and summarizes the results:

1) root:~> iptlog
LOW PORT TCP:
Dec 1 09:46:32 	211.110.39.96	3171	my.att.add.ress	445
Dec 1 09:46:35 	211.110.39.96	3171	my.att.add.ress	445
Dec 1 09:46:41 	211.110.39.96	3171	my.att.add.ress	445
Dec 1 18:28:43 	12.245.219.154	4580	my.att.add.ress	80
Dec 1 18:28:46 	12.245.219.154	4580	my.att.add.ress	80
Dec 1 19:21:13 	12.84.7.138	1996	my.att.add.ress	80
Dec 1 19:21:16 	12.84.7.138	1996	my.att.add.ress	80
Dec 1 20:36:18 	12.245.219.154	3009	my.att.add.ress	80
Dec 1 20:36:21 	12.245.219.154	3009	my.att.add.ress	80
Dec 1 21:28:22 	12.245.219.154	4169	my.att.add.ress	80
Dec 2 19:33:59 	12.238.121.87	4023	my.att.add.ress	80
Dec 2 19:34:03 	12.238.121.87	4023	my.att.add.ress	80


LOW PORT UDP:


HIGH PORT TCP:
Dec 1 07:16:15 	80.178.106.143	1751	my.att.add.ress	1433
Dec 1 07:16:18 	80.178.106.143	1751	my.att.add.ress	1433


HIGH PORT UDP:
Dec 2 16:38:17 	204.127.198.4	53	my.att.add.ress	32845
Dec 2 16:38:34 	63.240.76.4	53	my.att.add.ress	32845
Dec 2 16:39:08 	204.127.198.4	53	my.att.add.ress	32846


ECHO:
Dec 2 07:52:05 	195.101.216.197		my.att.add.ress	
Dec 2 07:52:07 	195.101.216.197		my.att.add.ress	
Dec 2 07:52:08 	195.101.216.197		my.att.add.ress	


NEW NOT SYN:
Dec 1 10:16:21 	137.208.16.37	80	my.att.add.ress	40129
Dec 1 10:16:22 	137.208.16.37	80	my.att.add.ress	40129
Dec 1 10:16:24 	137.208.16.37	80	my.att.add.ress	40129
Dec 1 10:16:28 	137.208.16.37	80	my.att.add.ress	40129
Dec 1 10:16:36 	137.208.16.37	80	my.att.add.ress	40129
Dec 1 10:16:52 	137.208.16.37	80	my.att.add.ress	40129
Dec 1 10:21:49 	137.208.16.37	80	my.att.add.ress	40129
Dec 1 10:22:53 	137.208.16.37	80	my.att.add.ress	40129
Dec 1 10:23:57 	137.208.16.37	80	my.att.add.ress	40129
Dec 1 10:25:01 	137.208.16.37	80	my.att.add.ress	40129
Dec 1 10:26:05 	137.208.16.37	80	my.att.add.ress	40129
Dec 1 10:27:09 	137.208.16.37	80	my.att.add.ress	40129
Dec 1 10:28:13 	137.208.16.37	80	my.att.add.ress	40129
Dec 1 10:29:17 	137.208.16.37	80	my.att.add.ress	40129

There are a number of probes on my http port (port 80) - nothing new. The NEW NOT SYN probes originating from port 80 addressed to some high port (40129) on my machine I find worrisome (only in principle worrisome, they've been dropped by the firewall).

Starting/Stopping iptables

Manually

2) root:~> /etc/rc.d/init.d/ipchains stop
3) root:~> /etc/rc.d/init.d/iptables stop        (now we have no firewall at all)
4) root:~> cp /etc/sysconfig/iptables /etc/sysconfig/iptables.old  (backup any previous iptables rules table, if any). 

Insert the rules into the firewall dynamically, as discussed above, using /sbin/iptables -A INPUT. Then save the rules:

20) root:~> /sbin/iptables-save > rules_file

Let us now see how to load the rules. After we've saved the rules in the "rules_file", the rules are still loaded (check with /sbin/iptables -L). Unload them first, then load them with iptables-restore

21) root:~> /etc/rc.d/init.d/iptables stop     (turn off iptables)
22) root:~> /sbin/iptables-restore < rules_file   (the rules file we saved above)

At boot

When we're satisfied with the rules we have inserted/saved, we can store them in a more permanent file: /etc/sysconfig/iptables (back up any old version of this file first). The boot script that starts iptables is /etc/rc.d/init.d/iptables. It checks if the rules file /etc/sysconfig/iptables exists, and if it does, it loads some kernel iptables modules, then loads the rules file. Fairly straightforward.

So, if we have stored our rules as /etc/sysconfig/iptables, we can

30) root:~> /etc/rc.d/init.d/iptables start
30) root:~> /etc/rc.d/init.d/iptables stop
at will. These commands will of course be run at boot/shutdown.

Basic masquerading

Many home users now have more than a single computer, but only a single connection to the internet (e.g. ppp or dsl or dhcp). So by default, only one computer at the time can be connected to the internet. However, with nat and masquerading, it is possible to have all computers in the household connected to the internet, simultaneously, and transparently, using the same single connection. Addresses of the packets that are being routed through the internet cannot be arbitrary. Almost all combinations of the form a.b.c.d are routable addresses. Notable exceptions are the ranges of "private" addresses, intended to be used exclusively for internal machines on a LAN (local area network). These ranges are (RFC 1918): On your local LAN you are king - i.e. you can assign whatever addresses from a private range you want. Obviously, if you try to send a packet out on the internet from one of those private addresses, it won't work - routers drop packets containing a private address. So what needs to be done, is