Previous Section
 < Day Day Up > 
Next Section


IP Tables Scripts

Though you can enter iptables rules from the shell command line, when you shut down your system, these commands will be lost. On Red Hat, you can make use of the built-in support for saving and reading iptables rules using the iptables service script. Alternatively, you can manage the process yourself, saving to files of your own choosing. In either event, you will most likely need to place your iptables rules in a script that can then be executed directly. This way you can edit and manage a complex set of rules, adding comments and maintaining their ordering.

Note 

On Red Hat binaries, IPtables support in the kernel is enabled by default. If you re-compile the kernel that support for packet filtering is turned on, check Networking Options in the 2.4 kernel, and Networking Support/Networking Options under Device Drivers in the 2.6 kernel.

Red Hat iptables Support

Red Hat provides support for iptables as part of their system configuration. When you install the RPM package for iptables, an iptables service script is installed that will read and save iptables commands using the /etc/sysconfig/iptables file. If you have set iptables to be started up automatically when you boot your system, this file will be checked to see if it exists and is not empty. If so, iptables will automatically read the iptables commands that it holds. This helps to integrate iptables more smoothly into the system setup process.

The /etc/sysconfig/iptables script is automatically generated by redhat-config-securitylevel, which is run during the installation process. When you first start up your system, the /etc/sysconfig/iptables file will contain the iptables rules for the configuration you selected when you ran redhat-config-securitylevel. If you run redhat-config-securitylevel again, changing your configuration, the /etc/sysconfig/iptables file will be overwritten with the new iptables rules. You can access redhat-config-securitylevel as the Security Level entry on the System Settings menu or window.

You can sidestep this automatic iptables setup by simply deleting the /etc/sysconfig/iptables file. (Running redhat-config-securitylevel and choosing No Firewall will do the same). Be sure you back it up first in case it has important commands. It is possible to edit the /etc/sysconfig/iptables file directly and enter iptables commands, but it is not recommended. Instead, you should think of this file as holding a final installation of your iptables commands.

You should think of the iptables service script that Red Hat provide as a versatile management tool, not as a service startup script. The use of the service command for this script can be confusing. The iptables script only manages iptables rules, flushing, adding, or reporting them. It does not start and stop the iptables service. If Netfilter is not running, you will need to specify that it be started up when your system boots. For this, you can use redhat-config-service (Services in the Server Settings window), then select iptables from the list of services.

The service script /etc/rc.d/init.d/iptables supports several options with which to manage your rules. The status option displays a listing of all your current rules. The stop option will flush your current rules. Unlike stop and status, the start and save options are tied directly to the /etc/sysconfig/iptables file. The start option will flush your current iptables rules and add those in the /etc/sysconfig/iptables file. The save option will save your current rules to the /etc/sysconfig/iptables file. Keep in mind that the stop and status operations work on the current iptables rules, no matter if they were added manually on the command line, added by your own script, or added by the start option from /etc/sysconfig/iptables. The following command will list your current rules:

service iptables status

Perhaps the most effective way to think of the iptables service script is as an iptables development tool. When creating complex firewall rules (beyond the simple set generated by redhat-config-securitylevel), you should first create a script and place your rules in them, as described later in the iptables script example. Make the script executable. Any changes you need to make as you debug your firewall, you make to this script. Before you run it, run the iptables service script with the stop option to clear out any previous rules:

service iptables stop

Then run your script, as shown here for the myfilters script:

./myfilters

To see how the commands have been interpreted by iptables, use the service script with the status option:

service iptables status

For any changes, edit your iptables script. Then run the service script again to clear out the old rules. Run the iptables script again, and use the status option with the service script to see how they were implemented:

service iptables stop
./myfilters
service iptables status

Once you are satisfied that your iptables rules are working correctly, you can save your rules to the /etc/sysconfig/iptables file. Use the iptables service script with the save option. Now your rules will be read automatically when your system starts up. You can think of the save operation as installing your iptables rules on your system, making them part of your system setup whenever you start your system.

service iptables save

To make changes, modify your iptables script, run the service script with stop to clear out the old rules, run the iptables script, and then use the service script with the save option to generate a new /etc/sysconfig/iptables file.

Instead of using the service script, you can save your rules using the iptables-save script. The recommended file to use is /etc/iptables.rules. The service script actually used iptables-save with the -c option to save rules to the /etc/sysconfig/iptables file. The -c option for iptables-save includes counters in the output (the iptables service script is designed to parse counter information along with the commands). The iptables-save command outputs rules to the standard output. To save them in a file, you must redirect the output to a file with the redirection operator, >, as shown here:

iptables-save -c > /etc/sysconfig/iptables

You can also save your rules to a file of your choosing, such as /etc/iptables.rules. The /etc/rc.d/init.d/iptables service script defines the IPTABLES_CONFIG variable, which holds the name of the iptables configuration file, /etc/sysconfig/iptables.

iptables-save > /etc/iptables.rules

Then, to restore the rules, use the iptables-restore script to read the iptables commands from that saved file:

iptables-restore < /etc/iptables.rules

An iptables Script Example

You now have enough information to create a simple iptables script that will provide basic protection for a single system connected to the Internet. The following script, myfilter, provides an IP tables filtering process to protect a local network and a Web site from outside attacks. It configures a simple firewall for a private network (check the iptables HOWTO for a more complex example). If you have a local network, you could adapt this script to it. In this configuration, all remote access initiated from the outside is blocked, but two-way communication is allowed for connections that users in the network make with outside systems. In this example, the firewall system functions as a gateway for a private network whose network address is 192.168.0.0 (see Figure 19-1). The Internet address is, for the sake of this example, 10.0.0.1. The system has two Ethernet devices: one for the private network (eth1) and one for the Internet (eth0). The gateway firewall system also supports a Web server at address 10.0.0.2. Entries in this example that are too large to fit on one line are continued on a second line, with the newline quoted with a backslash.

Click To expand
Figure 19-1: A network with a firewall

The basic rules as they apply to different parts of the network are illustrated in Figure 19-2.

Click To expand
Figure 19-2: Firewall rules applied to a local network example
myfilter
Start example
Firewall Gateway system IP address is 10.0.0.1 using Ethernet device eth0
# Private network address is 192.168.0.0 using Ethernet device eth1
# Web site address is 10.0.0.2
# turn off IP forwarding
echo 0 > /proc/sys/net/ipv4/ip_forward
# Flush chain rules
iptables -F INPUT
iptables -F OUTPUT
iptables -F FORWARD
# set default (policy) rules
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
   
# IP spoofing, deny any packets on the internal network
that have an external source address.
iptables -A INPUT -j LOG  -i eth1 \! -s 192.168.0.0/24
iptables -A INPUT -j DROP  -i eth1 \! -s 192.168.0.0/24
iptables -A FORWARD -j DROP  -i eth1 \! -s 192.168.0.0/24
# IP spoofing, deny any outside packets (any not on eth1)
that have the source address of the internal network
iptables -A INPUT -j DROP \! -i eth1 -s 192.168.0.0/24
iptables -A FORWARD -j DROP \! -i eth1 -s 192.168.0.0/24
# IP spoofing, deny any outside packets with localhost address
# (packets not on the lo interface (any on eth0 or eth1)
that have the source address of localhost)
iptables -A INPUT -j DROP  -i \! lo  -s  127.0.0.0/255.0.0.0
iptables -A FORWARD -j DROP  -i \! lo  -s  127.0.0.0/255.0.0.0
   
# allow all incoming messages for users on your firewall system
iptables -A INPUT -j ACCEPT  -i lo
   
# allow  communication to the Web server (address 10.0.0.2), port www
iptables -A INPUT  -j ACCEPT -p tcp -i eth0  --dport www -s 10.0.0.2
# Allow  established connections from Web servers to internal network
iptables -A INPUT -m state --state ESTABLISHED,RELATED
-i eth0 -p tcp  --sport www -s 10.0.0.2 -d 192.168.0.0/24  -j ACCEPT
# Prevent new  connections from Web servers to internal network
iptables -A OUTPUT -m state --state  NEW -o eth0 -p tcp  --sport
www -d 192.168.0.0/24  -j DROP
   
# allow established and related outside communication to your system
# allow outside communication to the firewall, except for ICMP packets
iptables -A INPUT -m state --state ESTABLISHED,RELATED
-i eth0 -p \! icmp -j ACCEPT
# prevent outside initiated connections
iptables -A INPUT -m state --state NEW -i eth0 -j DROP
iptables -A FORWARD -m state --state NEW -i eth0 -j DROP
# allow all local communication to and from the firewall on eth1
from the local network
iptables -A INPUT -j ACCEPT -p all -i eth1 -s 192.168.0.0/24
# Set up masquerading to allow internal machines access to outside network
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# Accept ICMP Ping (0 and 8) and Destination unreachable (3) messages
# Others will be rejected by INPUT and OUTPUT DROP policy
iptables -A INPUT -j ACCEPT  -p icmp -i eth0 --icmp-type  echo-reply -d 10.0.0.1
iptables -A INPUT -j ACCEPT  -p icmp -i eth0 --icmp-type  echo-request -d 10.0.0.1
iptables -A INPUT -j ACCEPT -p icmp -i eth0 --icmp-type  destination-unreachable -d
10.0.0.1
# Turn on IP Forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
End example

Initially, in the script you would clear your current iptables with the flush option (-F), and then set the policies (default targets) for the non-user-defined rules. IP forwarding should also be turned off while the chain rules are being set:

echo 0 > /proc/sys/net/ipv4/ip_forward

Drop Policy

First, a DROP policy is set up for INPUT and FORWARD built-in IP chains. This means that if a packet does not meet a criterion in any of the rules to let it pass, it will be dropped. Then both IP spoofing attacks and any attempts from the outside to initiate connections (SYN packets) are rejected. Outside connection attempts are also logged. This is a very basic configuration that can easily be refined to your own needs by adding iptables rules.

iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

IP Spoofing

One way to protect the private network from IP spoofing any packets is to check for any outside addresses on the Ethernet device dedicated to the private network. In this example, any packet on device eth1 (dedicated to the private network) whose source address is not that of the private network (! -s 192.168.0.0) is denied. Also, check to see if any packets coming from the outside are designating the private network as their source. In this example, any packets with the source address of the private network on any Ethernet device other than for the private network (eth1) are denied. The same strategy can be applied to the local host.

# IP spoofing, deny any packets on the internal network
# that has an external source address.
iptables -A INPUT -j LOG  -i eth1 \! -s 192.168.0.0/24
iptables -A INPUT -j DROP  -i eth1 \! -s 192.168.0.0/24
iptables -A FORWARD -j DROP  -i eth1 \! -s 192.168.0.0/24
# IP spoofing, deny any outside packets (any not on eth1)
# that have the source address of the internal network
iptables -A INPUT -j DROP \! -i eth1 -s 192.168.0.0/24
iptables -A FORWARD -j DROP \! -i eth1 -s 192.168.0.0/24
# IP spoofing, deny any outside packets with localhost address
# (packets not on the lo interface (any on eth0 or eth1)
# that have the source address of localhost)
iptables -A INPUT -j DROP  -i \! lo  -s  127.0.0.0/255.0.0.0
iptables -A FORWARD -j DROP  -i \! lo  -s  127.0.0.0/255.0.0.0

Then, you would set up rules to allow all packets sent and received within your system (localhost) to pass:

iptables -A INPUT -j ACCEPT  -i lo

Server Access

For the Web server, you want to allow access by outside users but block access by anyone attempting to initiate a connection from the Web server into the private network. In the next example, all messages are accepted to the Web server, but the Web server cannot initiate contact with the private network. This prevents anyone from breaking into the local network through the Web server, which is open to outside access. Established connections are allowed, permitting the private network to use the Web server.

# allow  communication to the Web server (address 10.0.0.2), port www
iptables -A INPUT  -j ACCEPT -p tcp -i eth0  --dport www -s 10.0.0.2
# Allow  established connections from Web servers to internal network
iptables -A INPUT -m state --state ESTABLISHED,RELATED -i eth0 \
   -p tcp  --sport www -s 10.0.0.2 -d 192.168.0.0/24  -j ACCEPT
# Prevent new  connections from Web servers to internal network
iptables -A OUTPUT -m state --state  NEW -o eth0 -p tcp \
  --sport www -d 192.168.0.1.0/24  -j DROP

Firewall Outside Access

To allow access by the firewall to outside networks, you allow input by all packets except for ICMP packets. These are handled later. The firewall is specified by the firewall device, eth0. First, allow established and related connections to proceed:

# allow outside communication to the firewall,
# except for ICMP packets
iptables -A INPUT -m state --state ESTABLISHED,RELATED \
         -i eth0 -p \! icmp -j ACCEPT

Blocking Outside Initiated Access

To prevent outsiders from initiating any access to your system, create a rule to block access by SYN packets from the outside using the state option with NEW. Drop any new connections on the eth0 connection (assumes only eth0 is connected to the Internet or outside network).

# prevent outside initiated connections
iptables -A INPUT -m state --state NEW -i eth0 -j DROP
iptables -A FORWARD -m state --state NEW -i eth0 -j DROP

Local Network Access

To allow interaction by the internal network with the firewall, you allow input by all packets on the internal Ethernet connection, eth1. The valid internal network addresses are designated as the input source:

iptables -A INPUT -j ACCEPT -p all -i eth1 -s 192.168.0.0/24

Masquerading Local Networks

To implement masquerading, where systems on the private network can use the gateway's Internet address to connect to Internet hosts, you create a NAT table (-t nat) POSTROUTING rule with a MASQUERADE target:

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Controlling ICMP Packets

In addition, to allow ping and destination-reachable ICMP packets, you enter INPUT rules with the firewall as the destination. To enable ping operations, you use both echo-reply and echo-request ICMP types, and for destination unreachable, you use the destination- unreachable type:

iptables -A INPUT -j ACCEPT  -p icmp -i eth0 --icmp-type \
   echo-reply -d 10.0.0.1
iptables -A INPUT -j ACCEPT  -p icmp -i eth0 --icmp-type \
   echo-request -d 10.0.0.1
iptables -A INPUT -j ACCEPT -p icmp -i eth0 --icmp-type \
   destination-unreachable -d 10.0.0.1

At the end, IP forwarding is turned on again:

echo 1 > /proc/sys/net/ipv4/ip_forward

Listing Rules

A listing of these iptables options shows the different rules for each option, as shown here:

# iptables -L
Chain INPUT (policy DROP)
target   prot opt source          destination
LOG      all  -- !192.168.0.0/24  anywhere        LOG level warning
DROP     all  -- !192.168.0.0/24  anywhere
DROP     all  --  192.168.0.0/24  anywhere
DROP     all  --  127.0.0.0/8     anywhere
ACCEPT   all  --  anywhere        anywhere
ACCEPT   tcp  --  10.0.0.2        anywhere        tcp dpt:http
ACCEPT   tcp  --  10.0.0.2        192.168.0.0/24  state RELATED,ESTABLISHED
                                                             tcp spt:http
ACCEPT  !icmp --  anywhere        anywhere        state RELATED,ESTABLISHED
DROP     all  --  anywhere        anywhere        state NEW
ACCEPT   all  --  192.168.0.0/24  anywhere
ACCEPT   icmp --  anywhere        10.0.0.1        icmp echo-reply
ACCEPT   icmp --  anywhere        10.0.0.1        icmp echo-request
ACCEPT   icmp --  anywhere        10.0.0.1        icmp destination-unreachable
Chain FORWARD (policy ACCEPT)
target   prot opt source          destination
DROP     all  -- !192.168.0.0/24  anywhere
DROP     all  --  192.168.0.0/24  anywhere
DROP     all  --  127.0.0.0/8     anywhere
DROP     all  --  anywhere        anywhere        state NEW
   
Chain OUTPUT (policy ACCEPT)
target   prot opt source       destination
DROP       tcp  --  anywhere     192.168.0.0/24  state NEW tcp spt:http
   
# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target      prot opt source       destination
Chain POSTROUTING (policy ACCEPT)
target      prot opt source       destination
MASQUERADE  all  --  anywhere      anywhere
Chain OUTPUT (policy ACCEPT)
target     prot opt source       destination

User-Defined Rules

For more complex rules, you may want to create your own chain to reduce repetition. A common method is to define a user chain for both INPUT and FORWARD chains, so that you do not have to repeat DROP operations for each. Instead, you would have only one user chain that both FORWARD and INPUT chains would feed into for DROP operations. Keep in mind that both FORWARD and INPUT operations may have separate rules in addition to the ones they share. In the next example, a user-defined chain called arriving is created. The chain is defined with the -N option at the top of the script:

iptables -N arriving

A user chain has to be defined before it can be used as a target in other rules. So you have to first define and add all the rules for that chain, and then use it as a target. The arriving chain is first defined and its rules added. Then, at the end of the file, it is used as a target for both the INPUT and FORWARD chains. The INPUT chain lists rules for accepting packets, whereas the FORWARD chain has an ACCEPT policy that will accept them by default.

iptables -N arriving
iptables -F arriving
# IP spoofing, deny any packets on the internal network
# that has an external source address.
iptables -A arriving -j LOG  -i eth1 \! -s 192.168.0.0/24
iptables -A arriving -j DROP  -i eth1 \! -s 192.168.0.0/24
iptables -A arriving -j DROP \! -i eth1 -s 192.168.0.0/24
…………………………
# entries at end of script
iptables -A INPUT -j arriving
iptables -A FORWARD -j arriving

A listing of the corresponding rules is shown here:

Chain INPUT (policy DROP)
target    prot opt source          destination
arriving  all  --  0.0.0.0/0         0.0.0.0/0
Chain FORWARD (policy ACCEPT)
target    prot opt source          destination
arriving  all  --  0.0.0.0/0         0.0.0.0/0
Chain arriving (2 references)
target    prot opt source          destination
LOG       all  -- !192.168.0.0/24   0.0.0.0/0       LOG flags 0 level 4
DROP      all  -- !192.168.0.0/24   0.0.0.0/0
DROP      all  --  192.168.0.0/24   0.0.0.0/0

For rules where chains may differ, you will still need to enter separate rules. In the myfilter script, the FORWARD chain has an ACCEPT policy, allowing all forwarded packets to the local network to pass through the firewall. If the FORWARD chain had a DROP policy, like the INPUT chain, then you may need to define separate rules under which the FORWARD chain could accept packets. In this example, the FORWARD and INPUT chains have different rules for accepting packets on the eth1 device. The INPUT rule is more restrictive. To enable the local network to receive forwarded packets through the firewall, you could enable forwarding on its device using a separate FORWARD rule, as shown here:

iptables -A FORWARD -j ACCEPT -p all -i eth1

The INPUT chain would accept packets only from the local network.

iptables -A INPUT -j ACCEPT -p all -i eth1 -s 192.168.0.0/24


Previous Section
 < Day Day Up > 
Next Section
This HTML Help has been published using the chm2web software.