What is a firewall? In the non-computer world, a firewall is a physical barrier that keeps a fire from spreading. Computer firewalls serve a similar purpose, but the “fires” that they attempt to block are attacks from crackers on the Internet. In this context, a firewall, also known as a packet filter, is a physical piece of computer hardware that sits between your network and the Internet, regulating and controlling the flow of information.
The most common types of firewalls used today are filtering firewalls. A filtering firewall filters the traffic flowing between your network and the Internet, blocking certain things that may put your network at risk. It can limit access to and from the Internet to only specific computers on your network. It can also limit the type of communication, selectively permitting or denying various Internet services.
For Fedora to act as a filtering firewall, you can use the iptables features. The iptables feature replaced ipchains as the default Red Hat Linux firewall several releases ago. With Fedora Core 2, ipchains was dropped altogether. The iptables facility is described in this chapter.
You can read about differences between ipchains and iptables in the Iptables HOWTO, at www.netfilter.org/documentation/HOWTO//packet-filtering-HOWTO-10.html.
The iptables firewall feature (also referred to as netfilter) is the default firewall software when you install Fedora. The ipchains firewall facility, once available with Red Hat Linux and Fedora Core 1, is no longer available with Fedora Core 2.
If you currently use ipchains on your Red Hat Linux system (for example, if you just upgraded to Fedora Core 2) and you want to convert to iptables, you need to disable ipchains before you can use iptables. In fact, if you try to use the iptables script (/etc/init.d/iptables) to start iptables while the ipchains module is loaded, the iptables startup script silently fails and exits.
While iptables is generally considered to be more complex than ipchains to work with, it is also considered to be more powerful and flexible. Because development is not continuing for ipchains, the few broken ipchains features that exist will probably stay broken.
This section describes how to turn on iptables and set up firewall rules for several different types of situations. It also tells how to turn on features related to firewalls that allow your iptables firewall to do Network Address Translation (NAT), IP masquerading, port forwarding, and transparent proxies.
The Fedora startup scripts will "punch a hole" through your firewall if you use certain services, and will therefore work even if they are not explicitly enabled in your iptables configuration. For example, NTP (which sets your system time from a network time server) and DNS resolution (which lets you contact a DNS server to resolve addresses) both open the ports they need in your firewall.
The following procedure describes how to get iptables going on your Fedora system.
During the time that you turn off ipchains, turn on iptables, and configure the filtering rules for iptables, your computer may be unprotected from the network. You should test your firewall rules on non critical computers, and then perform the switch on critical computers either quickly or by temporarily shutting down your network interfaces.
Stop the ipchains script from starting automatically at boot time:
# chkconfig ipchains off
Set the iptables script to start automatically at boot time:
# chkconfig iptables on
Now you can either reboot Fedora, or stop ipchains and unload the ipchains module, as follows:
# service ipchains stop # modprobe -r ipchains
Before you can start iptables you must have a working set of rules that have been placed in your /etc/sysconfig/iptables file. To create those rules, refer to the examples in the following sections. (Without the configuration file in place, iptables fails silently.)
If you are new to iptables, you can start with a workable set of default values by configuring your firewall during Fedora installation. I recommend selecting a Medium security firewall and configuring a few services to be allowed. The resulting /etc/sysconfig/iptables file will let you study how Fedora creates its firewalls rules.
If you are doing NAT or IP Masquerading, turn on IP packet forwarding. One way to allow this is to change the value of net.ipv4.ip_forward to 1 in the /etc/sysctl.conf file. Open that file as root user with any text editor and change the line to appear as follows:
net.ipv4.ip_forward = 1
Restart your network interfaces to have IP packet forwarding take effect.
# /etc/init.d/network restart
Once the rules file is in place, start up iptables:
# /etc/init.d/iptables start
At this point, iptables is installed as your firewall. You can check to see that the modules used by iptables are loaded by using the lsmod command, as follows:
# lsmod |grep ip ipt_REJECT 4736 1 ipt_state 1536 7 ip_conntrack 24368 1 ipt_state iptable_filter 2176 1 ip_tables 13568 3 ipt_REJECT,ipt_state,iptable_filter
If you want to allow passive FTP or IRC connections from computers on your LAN, you may need to load those modules by adding them to the /etc/modules.conf file. The basic connection tracking module, ip_conntrack, should be loaded by default already. (See the description of passive FTP and IRC after the firewall-example sections.)
If your iptables service didn’t start, make sure that:
An ipchains module is not loaded. (Unload it with modprobe -r as shown previously.)
The /etc/sysconfig/iptables file exists. (You need to create one if one was not already created for you when you installed Fedora.)
As you add iptables rules, more modules will have to be loaded. Appropriate modules should be loaded automatically when a new rule is entered. Run lsmod | grep ip again after you have added a few rules to see which modules were added. Note that these modules will not be unloaded if you decide to stop iptables. They will stay loaded until the next reboot or until you remove them (modprobe -r).
The following sections contain examples of iptables firewall rules.
One way to configure iptables is to start by adding and deleting rules to your kernel from the command line. Then when you get a set of rules that you like, you save the rules that are currently running on your system. The tools you use to create your firewall rules and then make them permanent are as follows:
iptables — Use this command to append (-A), delete (-D), replace (-R) or insert (-I) a rule. Use the -L option to list all current rules.
service iptables save — Use this command to save the rules from the kernel and install them in the configuration file.
/etc/sysconfig/iptables — This is the configuration file that contains the rules that were saved from the iptables-save command.
/etc/sysconfig/iptables-config — You can add settings for managing your iptables rules to the iptables-config file. For example, any iptables modules, such as ip_conntrack and others described later in this chapter, can be added to the IPTABLES_MODULES line to be loaded automatically. You can also set whether the iptables table in your running kernel is saved to a file when iptables stops.
/etc/init.d/iptables — This is the iptables start-up script that must run automatically each time Fedora reboots. When it starts, it clears all iptables rules and counters and installs the new rules from the /etc/sysconfig/iptables file. You can also use this script with different options from the command line to check the status of iptables (status) or to run iptables-save for you to save the current rules (save).
To get you started with iptables, I’m providing a sample set of iptables rules along with descriptions of how you might change those rules for different situations. Here’s how you could load and save any of the sets of rules described in the following example:
If you are currently running ipchains, complete the procedure in the previous “Turning on iptables” section.
Stop iptables and clear all existing rules:
# /etc/init.d/iptables stop
Add the rules shown in the following example to a file, using any text editor. Modify the rules to suit your situation and save the file.
As root user, run the file as a shell script. For example, if you named the file firescript, you could run it as follows:
# sh firescript
See how the rules were loaded into the kernel:
# iptables -L
If everything looks okay, save the rules that are now in the kernel into the /etc/sysconfig/iptables file:
# cp /etc/sysconfig/iptables /etc/sysconfig/iptables-old # service iptables save
From now on the rules will be read each time you reboot or restart iptables. Save a copy of the script you used to create the rules, in case you ever need it again.
Because firewall configurations can be vastly different, depending on what you are trying to achieve, I've illustrated how to configure firewalls based on several different example setups. These setups combine different levels of security requirements.
This example features a home or small-office LAN with a Fedora system acting as an iptables firewall between the LAN and the Internet. The firewall computer also acts as a Web server, FTP server, and DNS server. Figure 14-1 shows this configuration.
Figure 14-1: Using iptables as a firewall between the Internet and a LAN.
If you want to use the sample firewall script that follows, you must change the following information to match your configuration:
Firewall computer — The firewall computer is set up as follows:
Local host — 127.0.0.1 (IP address) and lo (interface). You shouldn’t need to change these.
Connection to the Internet — 22.214.171.124 (IP address) and eth0 (interface). Replace them with the static IP address and interface name associated with your connection to the Internet, respectively.
Connection to the LAN — 10.0.0.1 (IP address) and eth1 (interface). Replace 10.0.0.1 and eth1 with the static IP address and interface name associated with your connection to your LAN, respectively.
Computers on the LAN — Each computer on the LAN in the example has an IP address between 10.0.0.2 to 10.0.0.254. Change 10.0.0.255 to a number that matches your LAN's range of addresses.
Here is an example of a script to load firewall rules that could be used for the configuration shown in Figure 14-1:
# (1) Policies (default) iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP # (2) User-defined chain for ACCEPTed TCP packets iptables -N okay iptables -A okay -p TCP --syn -j ACCEPT iptables -A okay -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A okay -p TCP -j DROP # (3) INPUT chain rules # Rules for incoming packets from LAN iptables -A INPUT -p ALL -i eth1 -s 10.0.0.0/24 -j ACCEPT iptables -A INPUT -p ALL -i lo -s 127.0.0.1 -j ACCEPT iptables -A INPUT -p ALL -i lo -s 10.0.0.1 -j ACCEPT iptables -A INPUT -p ALL -i lo -s 126.96.36.199 -j ACCEPT iptables -A INPUT -p ALL -i eth1 -d 10.0.0.255 -j ACCEPT # Rules for incoming packets from the Internet # Packets for established connections iptables -A INPUT -p ALL -d 188.8.131.52 -m state --state \ ESTABLISHED,RELATED -j ACCEPT # TCP rules iptables -A INPUT -p TCP -i eth0 -s 0/0 --destination-port 21 -j okay iptables -A INPUT -p TCP -i eth0 -s 0/0 --destination-port 22 -j okay iptables -A INPUT -p TCP -i eth0 -s 0/0 --destination-port 80 -j okay iptables -A INPUT -p TCP -i eth0 -s 0/0 --destination-port 113 -j okay # UDP rules iptables -A INPUT -p UDP -i eth0 -s 0/0 --destination-port 53 -j ACCEPT iptables -A INPUT -p UDP -i eth0 -s 0/0 --destination-port 2074 -j ACCEPT iptables -A INPUT -p UDP -i eth0 -s 0/0 --destination-port 4000 -j ACCEPT # ICMP rules iptables -A INPUT -p ICMP -i eth0 -s 0/0 --icmp-type 8 -j ACCEPT iptables -A INPUT -p ICMP -i eth0 -s 0/0 --icmp-type 11 -j ACCEPT # (4) FORWARD chain rules # Accept the packets we want to forward iptables -A FORWARD -i eth1 -j ACCEPT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # (5) OUTPUT chain rules # Only output packets with local addresses (no spoofing) iptables -A OUTPUT -p ALL -s 127.0.0.1 -j ACCEPT iptables -A OUTPUT -p ALL -s 10.0.0.1 -j ACCEPT iptables -A OUTPUT -p ALL -s 184.108.40.206 -j ACCEPT # (6) POSTROUTING chain rules iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 220.127.116.11
I divided the commands in the preceding script into six sections. The following text describes each of those sections.
Policies — The iptables -P commands set the default policies for INPUT, OUTPUT, and FORWARD chains. By assigning each of those policies to DROP, any packet that isn’t matched is discarded. In other words, for a packet to get through, it has to be specifically matched and ACCEPTed by one of the other rules in the script.
User-defined chain — A user-defined chain I call okay is created to do a few more checks on packets requesting certain TCP services that I’m going to allow through (Web, FTP, and DNS services). The -N okay option creates the okay chain. The next line says that a SYN packet (--syn), which requests a new connection, is fine to let through. The next line allows through packets associated with an ESTABLISHED connection (one that has already had traffic pass through the interface) or a RELATED connection (one that is starting a new connection related to an already established connection). The final line in this set tells iptables to DROP packets that don’t meet one of those checks.
INPUT chain rules — The bulk of the packet filtering is done in the INPUT chain. The first sets of input rules indicates to iptables when to always accept packets from the Internet and from the LAN. The next three sets determine which requests for specific protocols (TCP, UDP, and ICMP) are accepted.
Packets from LAN — Because you want the users on your LAN and the firewall computer itself to be able to use the Internet, this set of rules lets through packets that are initiated from those computers. The first line tells iptables to accept packets for ALL protocols for which the source is an acceptable addresses on your LAN (-s 10.0.0.0/24, which represents IP numbers 10.0.0.1 through 10.0.0.254). The next three lines allow packets that come from all valid IP addresses on the firewall computer itself (-s 127.0.0.1, 10.0.0.1 and 18.104.22.168). The last line accepts broadcast packets (-d 10.0.0.255) on the LAN.
Packets from Internet (already connected) — This line is split in two (I just used the backslash to join the lines because the page wasn't wide enough to show it as one line). It ACCEPTs packets that are both associated with connections that are already established (--state ESTABLISHED,RELATED) and are requested directly to the firewall's IP address (22.214.171.124).
TCP rules (new connections) — Here is where you open up the ports for the TCP services you want to provide to anyone from the Internet. In these lines you open ports for FTP service (--destination-port 21), secure shell service (22), Web service (80), and IDENTD authentication (113), the last of which might be necessary for protocols such as IRC. Instead of accepting these requests immediately, you jump to the okay chain you defined to further check that the packets were formed properly.
You want to ensure that the services on the ports to which you are allowing access are properly configured before you allow packets to be accepted to them.
UDP rules (new connections) — These lines define the ports where connection packets are accepted from the Internet for UDP services. In this example I chose to accept requests for DNS service (--destination-port 53) because the computer is set up as a DNS server. The example also illustrates lines that accept requests for a couple of other optional ports. Port 2074 is needed by some multimedia applications the users on your LAN might want to use, and port 4000 is used by the ICQ protocol (for online chats).
ICMP rules — ICMP messages are really more for reporting conditions of the server than for actually providing services. Packets from the Internet that are accepted for ICMP protocol requests in our example are those for ICMP types 8 and 11. Type 8 service, which allows your computer to accept echo reply messages, makes it possible for people to ping your computer to see if it is available. Type 11 service relates to packets whose time to live (TTL) was exceeded in transit, and for which you are accepting a Time Exceeded message that is being returned to us. (You need to accept type 11 messages to use the traceroute command to find broken routes to hosts you want to reach.)
FORWARD chain rules — Because this firewall is also acting as a router, FORWARD rules are needed to limit what the firewall will and will not pass between the two networks (Internet and local LAN). The first line forwards everything from the local LAN (-A FORWARD -i eth1). The second line forwards anything from the Internet that is associated with an established connection (--state ESTABLISHED,RELATED).
OUTPUT chain rules — These rules basically exist to prevent anyone from your local computer from spoofing IP addresses (that is, from saying packets are coming from somewhere that they are not). According to these three rules, each packet output from your firewall must have as its source address one of the addresses from the firewall computer’s interfaces (127.0.0.1, 10.0.0.0.1, or 126.96.36.199).
POSTROUTING chain rules — The POSTROUTING chain defines rules for packets that have been accepted, but need additional processing. This is where the actual network-address translation (NAT) work takes place. For the NAT table (-t nat), in the POSTROUTING chain, all packets that go out to the Internet have their addresses translated to that of the firewall’s external interface (--to-source 188.8.131.52). In this case I used the Source Network Address Translation (SNAT) chain because I have a static IP address (184.108.40.206) associated with my Internet connection. If I were using a dynamic IP address (via DHCP), I would use MASQUERADE instead of SNAT. I would also have to change any references to -d 220.127.116.11 to -i eth0. (Of course, you would be using a different IP address and possibly a different Ethernet interface.)
In this scenario, the firewall is protecting a Linux system (firewall) and several systems on the LAN that only want to connect to the Internet. No servers are behind this firewall, so you want to prevent people from the Internet from requesting services.
You could use the same script shown in Example 1, but not use lines that request TCP services. So you could drop the user-defined chain in section 2 and drop the TCP rules from section 3. You could also remove the ICMP rules, if you don’t want your firewall to be visible to ping requests (Type 8) and if you don’t care about receiving messages when your packets exceed their time to live values (Type 11), such as when a packet runs into a broken router.
In this example, there is one network interface, connecting your Fedora system to the Internet. You are not sharing that connection with other computers and you are not offering any services from your computer.
In this case, you could cut sections 2, 4, and 6. From section 3, you could cut all rules relating to incoming requests from the LAN and all TCP services. As I mentioned in Example 2, you could also remove the Type 8 ICMP rule to make your firewall invisible to ping requests from the Internet and the Type 11 ICMP rule to not accept messages about failed time-to-live packets.
Now that you’ve seen something about what iptables rules look like and how you can get them going, step back a bit and see how iptables works.
The iptables feature works by having IP packets (that is, network data) that enter or leave the firewall computer, traverse a set of chains that define what is done with the packet. Each rule that you add essentially does both of the following:
Checks whether a particular criterion is met (such as that a packet requests a particular service or comes from a particular address)
Takes an action (such as dropping, accepting, or further processing a packet)
Different sets of rules are implemented for different types of tables. For example, tables exist for filtering (filter), network address translation (nat), and changing packet headers (mangle). Depending on the packet’s source and destination, it traverses different chains. Most of the rules you create will relate to the filter table (which is implied if no other table is given).
The chains associated with the filter table are INPUT, OUTPUT, and FORWARD. You can add user-defined chains as well. You will probably be most interested in adding or removing particular TCP and UDP services using the basic rules shown in the previous example. Assign ACCEPT to packets you want to go through and DROP to those you want to discard. You can also assign REJECT to drop a packet but return a message to the sender, or LOG to neither drop nor accept the message, but to log information about the packet.
A lot of great features are built into iptables. The following descriptions tell you about some cool things you can do with iptables and give you some tips on using it.
With passive FTP, the FTP client sends its IP address and the port number on which it will listen for data to the server. If that client is on a computer that is behind your firewall, for which you are doing NAT, that information must be translated as well or the FTP server will not be able to communicate with the client.
iptables uses connection-tracking modules to track connections. Using this feature, it can look inside the FTP data themselves (that is, not in the IP packet header), to get the information it needs to do NAT (remember that computers from the Internet can’t talk directly to your private IP addresses). To do FTP connection tracking (to allow passive FTP connections to the clients on your LAN), you need to have the following modules loaded:
The same is true for chats (IRC) and DCC sends. Addresses and port numbers are stored within the IRC protocol packets, so those packets must be translated too. To allow clients on your LAN to use IRC services, you need to load the following modules:
The default port for IRC connections is 6667. If you don’t want to use the default you can add different port numbers when you load the connection-tracking modules:
modprobe ip_conntrack_irc ports=6668,6669
As noted in the iptables example, you can use Source Network Address Translation (SNAT) or IP Masquerading (MASQUERADE) to allow computers on your LAN with private IP addresses to access the Internet through your iptables firewall. Choose SNAT if you have a static IP address for your Internet connection and MASQUERADE if the IP address is assigned dynamically.
When you create the MASQUERADE or SNAT rule, it is added to the NAT table and the POSTROUTING chain. For MASQUERADE you must provide the name of the interface (such as eth0, ppp0, or slip0) to identify the route to the Internet or other outside network. For SNAT you must also identify the actual IP address of the interface. Here is an example of a MASQUERADE rule:
# iptables –t nat –A POSTROUTING –o eth0 –j MASQUERADE
Here is an example of a SNAT rule:
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 18.104.22.168
You can add several source addresses if you have multiple addresses that provide a route to the Internet (for example, --to-source 22.214.171.124.1-126.96.36.199.254). Although MASQUERADE uses some additional overhead, you probably need to use it instead of SNAT if you have a dial-up connection to the Internet for which the IP address changes on each connection.
Remember that you need to make sure that IP forwarding is turned on in the kernel. (It is off by default.) To turn it on permanently, edit the /etc/sysctl.conf file as described earlier. To turn it on temporarily, you can do the following:
# echo 1 > /proc/sys/net/ipv4/ip_forward
If you require dynamic IP addressing (in cases such as a dial-out link where you don't know the IP address when you first establish the connection to the Internet), turn on that service:
# echo 1 > /proc/sys/net/ipv4/ip_dynaddr
With the REDIRECT target you can cause traffic for a specific port on the firewall computer to be directed to a different one. Using this feature you can direct host computers on your local LAN to a proxy service on your firewall computer without those hosts knowing it.
The following is an example of a set of command-line options to the iptables command that causes a request for Web service (port 80) to be directed to a proxy service (port 3128):
-t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 3128
You can only use REDIRECT targets in PREROUTING and OUTPUT chains within a nat table. You can also give a range of port numbers to spread the redirection across multiple port numbers.
What if you have only one static IP address, but you want to use a computer other than your firewall computer to provide Web, FTP, DNS, or some other service? You can use the Destination Network Address Translation (DNAT) feature to direct traffic for a particular port on your firewall to another computer.
For example, if you want all requests for Web service (port 80) that are directed to the firewall computer (-d 188.8.131.52) to be directed to another computer on your LAN (such as 10.0.0.25), you can use the following iptables command:
# iptables -t nat -A PREROUTING -p tcp -d 184.108.40.206 --dport 80 \ -j DNAT --to-destination 10.0.0.25
(Note that the preceding example should actually appear on one line. The backslash indicates continuation on the next line.)
You can also spread the load for the service you are forwarding by providing a range of IP addresses (for example, --to-destination 10.0.0.1-10.0.0.25). Likewise, you can direct the request to a range of ports as well.
Using the LOG target you can log information about packets that meet the criteria you choose. In particular you might want to use this feature to log packets that seem like they might be improper in some way. In other words, if you don’t want to drop a packet for some reason, you can just log its activity and decide later if something needs to be corrected.
The LOG target directs log information to the standard tools used to do logging in Fedora: dmesg and syslogd. Here’s an example of a rule using a LOG target:
-A FORWARD -p tcp -j LOG --log-level info
Instead of info, you could use any of the following log levels available with syslog: emerg, alert, crit, err, warning, notice, info, or debug. Using the --log-prefix option as follows, you could also add information to the front of all messages produced from this logging action:
-A FORWARD -p tcp -j LOG --log-level info --log-prefix "Forward INFO "
You can modify or expand on the iptables examples given in this chapter in many ways. iptables is tremendously flexible.
When you actually create your own iptables firewall, you should refer to the iptables man page (type man iptables) for detailed descriptions of options, ways of matching, ways of entering addresses, and other details. I also recommend an excellent iptables Tutorial by Oskar Andreasson (http://iptables-tutorial.frozentux.net).
Here are a few tips for using iptables features:
Reduce rules — Try to improve performance by reducing the number of rules. Using subchains can keep a packet from seeing rules that don’t apply to it.
Deal with fragments — Use the -f option to refer to the second and subsequent packets of a packet that was split into fragments. In general, it is safe to not drop second and third fragments for which you don’t have a first packet fragment because they won’t be reassembled. If you use NAT the fragments are assembled before filtering, so you shouldn’t have problems with unfiltered fragments being sent through.
Opposite — To make a rule its opposite, use an exclamation mark (!).
All interfaces — To match all interfaces of a type, use a plus sign (+), as in eth+.
Blocking connections — Use the --syn option to block SYN packets (that is, those packets requesting connections). This option only applies to TCP packets.
Limiting — Use the --limit option to restrict the rate of matches that result in log messages. This option allows matches to only produce messages a limited number of times per second (the default is three per hour with burst of five).
DOS Attacks — You can use the --limit option to reduce the impact of DOS attacks, but it still won’t stop them altogether. As long as the traffic is directed at your server, your network bandwidth is being leeched away, and the machine still utilizes resources to ignore the data.
Table types — The default table type is filter. The other types of tables are nat (for IP Masquerading) and mangle (for altering packets). To use a table other than filter you must add a –t table_type option, where table_tape is either nat or mangle.