Firewalling is the practice of filtering network traffic, typically at the point where your network connects to another (e.g. the Internet, a customers LAN, etc.) network, that may be untrusted (in the case of the Internet) or perhaps even trusted (another floor of your building). Like firewalls in a large building, a network firewall can prevent and even block the spread of an attack if one segment is compromised successfully, like their namesake firewalls can stop your network from being further compromised.
Linux has had firewalling capacity for quite a while now in the form of ipfwadm, which was a very simple packet-level filter. With the advent of kernel 2.1 this has been replaced with ipchains which is quite a bit more sophisticated. This will be replaced in kernel 2.4 (proposed) with an even more advanced packet filter that is more independent. Both are still basic packet filters however and do not allow for advanced features such as stateful inspection or some types of proxying connections. However, Linux does support IPMASQ, an advanced form of NAT (Network Address Translation). IPMASQ allows you to hook up a network of computers to the Internet but proxy their connections at the IP level. Thus all traffic appears to be coming and going to one machine (the Linux IPMASQ box) which affords a high degree of protection to the internal network. As an added bonus the clients on the internal network require NO proxy configuration; as long as the Linux IPMASQ server is configured correctly, and the clients use it as their default gateway, things will work quite well.
Both ipchains and ipfwadm provide the following basic capabilities:
ž blocking / allowing data to pass based on IP/port/interface source/destination
ž masquerading of connections, based on IP/port/interface source/destination
In addition to which ipchains supports:
ž port forwarding
ž creation of chains, for more intricate rules and conditions, easier to maintain
ž quality of service (QOS) routing, useful on low speed connections or otherwise saturated connections
ž specification of IP/port/interface as well as inverse specification (using the !)
The Firewall-HOWTO and "man <command>" (ipchains or ipfwadm) page both cover in great detail the mechanics for setting up rules, but don't really cover the strategy for firewalling safely. Your first choice to make is whether to go with default deny or default allow policies, followed by which services and hosts you wish to allow and block.
When deciding policy you should choose a policy that will default to denying everything unless specifically allowed through (that is if there is a failure it will hopefully be minimized via default policies) or a policy that allows everything and blocks certain services/hosts. I typically use a policy of default denial as it can accommodate mistakes and changes more safely then a policy that defaults to allowing data through.
Case in point, you have a server secured via firewalling, currently running Apache, you install WU-FTPD on it for internal use (so people can upload files) at 3 am, you forget to change the firewall rules. If you have chosen a policy of default allowal, anyone on the Internet can access the ftp server, and silly you, you installed an old version which allowed someone to compromise the machine. If on the other hand you go with a policy of default denial, they would not have access to the ftp server, and neither would your users, but you would find out quite quickly. Annoyed users are much easier to appease then fixing a network that has been compromised.
I have decided to not cover specific firewalling rules in this section, for each network service I will provide examples, as to properly firewall a protocol you need to understand how it behaves. There is a huge difference between firewalling www and ftp for inbound and outbound access for example. Some general concepts/rules:
Ipfwadm is a solid packet filter for Linux, although it lacks a lot of features available in Ipchains. Ipfwadm only supports 3 targets for a packet: accept, deny or reject, whereas ipchains rules can be targeted at 6 built-in targets, or a user defined target. Ipfwadm is really only appropriate for a simple IP-level firewall, ipmasquerading and if you plan to use FreeS/WAN (which currently does not support kernel 2.2.x). The basic options are: specify a direction (in, out, or both, useful with the interface flag), input rules, output rules, forwarding rules (say you have multiple interfaces, also covers the masquerading rules) and masquerade rules which control the behavior of masquerading (timeouts, etc). You can insert, append and delete rules, set default policies, and list all the rules. Other then that it is very similar to ipchains, with some minor variations. The following is a script appropriate for a server bridging 2 networks (10.0.0.x on eth0, 10.0.0.1 and 192.168.0.x on eth1, 192.168.0.1) with a mail server running.
#!/bin/bash # # Flush all the rule sets first # ipfwadm -f -I ipfwadm -f -O ipfwadm -f -F # # Allow forwarding between the two networks and otherwise deny it for security # ipfwadm -F -a accept -P all -S 10.0.0.0/24 -i eth0 -D 192.168.0.0/24 ipfwadm -F -a accept -P all -S 192.168.0.0/24 -i eth1 -D 10.0.0.0/24 ipfwadm -F -p deny # # And of course we have to allow those packets in # ipfwadm -I -a accept -P tcp -S 10.0.0.0/24 -i eth0 -D 192.168.0.0/24 ipfwadm -I -a accept -P tcp -S 192.168.0.0/24 -i eth1 -D 10.0.0.0/24 # # Let them access the mail server port on the server but nothing else # ipfwadm -I -a accept -P tcp -S 10.0.0.0/24 -i eth0 -D 10.0.0.1 25 ipfwadm -I -a accept -P tcp -S 192.168.0.0/24 -i eth0 -D 192.168.0.1 25 ipfwadm -I -p deny
FreeS/WAN now supports the 2.2.x series of kernels, you should never choose ipfwadm over ipchains. ipchains offers a much finer degree of control and is much more flexible then ipfwadm.
ipchains contains several new features as compared to ipfwadm; you can create chains of rules (hence the name) and link them together, making administration of firewalls far easier. Ipchains supports more targets then ipfwadm; you can point a rule at: ACCEPT, DENY, REJECT, MASQ, REDIRECT, or RETURN or a user defined chain. As such it is very powerful, for example I could redirect all packets bound for port 80 (www traffic) going through my gateway machine to be redirected to local port 3128, the Squid proxy server. You can also use this in conjunction with quality of service routing, the example given in ipfwadm's documentation is that of prioritizing traffic going over a PPP link, you can give telnet traffic a much higher priority then say ftp, reducing latency problems caused by a saturated link. Typically I create an /etc/rc.d/init.d/ipchains-sh (or wherever appropriate) and call it immediately after the networking is brought up, this leaves a small time in which the server is vulnerable, but minimally so since no network daemons are running.
The following script is appropriate for a gateway with 2 interfaces running, the reason I have used the DENY instead of REJECT target is so that the packet is dropped and not responded to in any way, this slows down network scans (as they wait for the packet to timeout instead of receiving a response) and gives away less information. I would also advise against logging data unless you have a significant amount of drive space available, for each packet I send (several bytes) many bytes of drive space is used up to create a log entry, making it easy to overwhelm syslog and/or your drive space on a fast connection. The ipchains homepage is at: http://www.rustcorp.com/linux/ipchains/.
#!/bin/bash # # This script sets up firewall rules appropriate for a server with 2 interfaces # running as a gateway # This script needs to be edited if you plan to use it. # We assume the internal machines call all talk to the gateway, so no rules block # internal traffic # # A couple of variables # # ETH0 is the IP address on ETH0 (the external interface) # ETH0NET is the network # ETH0NETMASK is the network mask # TRUSTEDHOST1 is a trusted host (for webmin/ssh) # TRUSTEDHOST2 is a trusted host (for webmin/ssh) # ETH1IP is the IP address on ETH1 (internal interface) # ETH1NET is the network # ETH1NETMASK is the network mask # ETH0IP=18.104.22.168 ETH0NET=22.214.171.124 ETH0NETMASK=24 TRUSTEDHOST1=126.96.36.199 TRUSTEDHOST2=188.8.131.52 ETH1IP=10.0.0.1 ETH1NET=10.0.0.0 ETH1NETMASK=24 # PATH=/sbin # FLUSH ALL RULES ipchains -F input ipchains -F output ipchains -F forward # ANTI-SPOOFING ipchains -A input -p all -j DENY -s 10.0.0.0/8 -i eth0 -d 0.0.0.0/0 ipchains -A input -p all -j DENY -s 127.0.0.0/8 -i eth0 -d 0.0.0.0/0 ipchains -A input -p all -j DENY -s 192.168.0.0/16 -i eth0 -d 0.0.0.0/0 ipchains -A input -p all -j DENY -s 172.16.0.0/16 -i eth0 -d 0.0.0.0/0 ipchains -A input -p all -j DENY -s $ETH0IP -i eth0 -d 0.0.0.0/0 # ICMP FIRST ipchains -A input -p icmp -j ACCEPT -s $ETH0NET/$ETH0NETMASK -i eth0 -d 0.0.0.0/0 ipchains -A input -p icmp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 # SSH ipchains -A input -p tcp -j ACCEPT -s $TRUSTEDHOST1 -i eth0 -d 0.0.0.0/0 22 ipchains -A input -p tcp -j ACCEPT -s $TRUSTEDHOST2 -i eth0 -d 0.0.0.0/0 22 # BLOCKING 1:1023 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 1:1023 ipchains -A input -p udp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 1:1023 # BLOCKING OTHER THINGS ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 1109 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 1524 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 1600 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 2003 ipchains -A input -p udp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 2049 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 2105 ipchains -A input -p udp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 3001 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 3001 ipchains -A input -p udp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 3128:3130 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 3128:3130 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 3306 ipchains -A input -p udp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 3306 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 4444 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 6000:6100 ipchains -A input -p udp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 6000:6100 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 6667 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 7000 # WEBMIN ipchains -A input -p tcp -j ACCEPT -s $TRUSTEDHOST1 -i eth0 -d 0.0.0.0/0 10000 ipchains -A input -p tcp -j ACCEPT -s $TRUSTEDHOST2 -i eth0 -d 0.0.0.0/0 10000 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 10000 # FORWARD RULES ipchains -P forward DENY ipchains -A forward -p all -j MASQ -s $ETH1NET/$ETH1NETMASK -d 0.0.0.0/0
NETFILTER is the next generation of packet firewalling for Linux. It should make a variety of activities easier, such as firewalling, IPSec, anything to do with packet management really. The HOWTO is available at: http://netfilter.kernelnotes.org/.
Some scripts for Red Hat Linux in rpm format: http://www.webideal.de/rh-isdn/downloads/.
A simple script that converts ipfwadm rules to ipchains rules, making migration a snap. The script is available at: http://users.dhp.com/~whisper/ipfwadm2ipchains/
Mason is an automated firewall rule generator for ipfwadm and ipchains. You load it up and it monitors the packets flowing through the machine, then based on that creates a set of rules to allow that type of activity (i.e. if your ftp into your server from a remote site it will allow that type of access in the rules it creates). A good tool for first time firewall admins, available from: http://users.dhp.com/~whisper/mason/.
Mklinuxfw is a Perl tool that aims to provide a variety of interfaces (CGI, KDE, command line, etc.) to creation of firewall rules. It currently supports a CGI interface and GTK is in progress. You can download it from: http://www.madhouse.org.uk/~red/framepage.phtml?/mklinuxfw/index.html.
fwconfig is a rather nice www based configuration utility for ipfwadm and ipchains. You can download it from: http://www.mindstorm.com/~sparlin/fwconfig.shtml.
SINUS Firewall is an alternate firewall for Linux (kernel 2.0.x only I believe). You can get it at: http://www.sinusfirewall.org/.
Written by Kurt Seifried