Chapter 6 - Firewall Concepts
With all the possible security threats roaming around the Internet today, a security firewall should be considered a mandatory necessity for any computer systems connected to the Internet. A firewall is a networking device which is used to separate private networks from external access by providing a certain level of security rules and controls.
A simple firewall can be configured to block all access to certain networks, workstations and communication ports. A more complex firewall is capable of inspecting each individual packet that attempts to pass through it and ensures that they are correctly formatted and appropriate to the services provided for (or by) the internal network, this is called a packet filtering firewall.
This chapter will explain some of the concepts for iptables and packet forwarding which can be used to secure your private network. The example configurations provided in each section are only designed to provide an introduction into each of those specific sections, while an example firewall script has been included which will provide simple but effective security for your networked system.
Many of the newer broadband modems provide built-in firewall features that allow for stateful packet inspection and detailed network address translations, which are capable of providing a high security level for your internal network. |
Packet Forwarding
Packet forwarding is a simple concept where the server allows data packets to pass from one network to another. As with the diagram below, packets from the private network are allowed to be forwarded through the server and out to the ISP and vice versa.
There are a few initial considerations. First, the server must have networks or gateways defined in its routing table so it can make an informed decision where the packet needs to be passed to. Second, the server must have packet forwarding enabled. Thirdly, if the routed packets came from an RFC1918 private subnet, they must be translated into globally routed IP addresses (NAT covered later) before they will be accepted out on the Internet.
Packet forwarding can be enabled either manually as required by the superuser, or automatically when the system starts the networking service. To manually enable or disable packet forwarding, use the respective commands listed below.
[bash]# echo 1 > /proc/sys/net/ipv4/ip_forward |
[bash]# echo 0 > /proc/sys/net/ipv4/ip_forward |
To enable automatic packet forwarding for whenever the network service is active, make the following changes in your /etc/sysctl.conf file.
[bash]# vi /etc/sysctl.conf |
net.ipv4.ip_forward = 1 |
It is common practice for users to have manual control over packet forwarding, and to active or disable the function within their firewall control scripts. However setting packet forwarding to start automatically will be more suitable for a dedicated server. |
Packet Filtering
Packet filtering is also a reasonably simple concept (true), however it can be very daunting for new users that don't fully understand how it works, so let's cover the basics first and build it up.
In packet forwarding the kernel is either allowed to move packets between different subnets or is not, and if it is, the decisions are made from the kernel's routing table. In packet filtering an application called iptables (http://www.netfilter.org/) stores a list of programmed rules which are individually tested against every packet that either tries to enter, pass through, or exit any of the system's network devices. Each rule is used to test the packet in a sequential order and if the packet matches any of the rules it is either accepted or rejected depending on the global policy and rule definitions. iptables is your firewall application and is one of the networking frameworks for your Linux kernel.
iptables essentially has this name because it stores the rulesets into a group of three tables which each provide different capabilities depending on the rules and the order they are applied. We will only examine the filter and nat tables here, the mangle table is used for specialised packet alteration which is beyond our scope. The following table displays the filter iptables and the three built-in chains.
Table Name | Chain Name | Chain Details |
filter | INPUT | For any packet coming into the system |
FORWARD | For any packet that is being routed through the system | |
OUTPUT | For any packet that is leaving the system |
[bash]# iptables -t filter -nvL |
The filter table is the default table when working with iptables, so there is no need to add '-t filter' at the command prompt.
[bash]# iptables -nvL |
Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target - prot - opt - in - out - source - destination Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target - prot - opt - in - out - source - destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target - prot - opt - in - out - source - destination |
You should see an output similar to above, if not then stop the iptables service and output the table again. From the listing you can see the three built in chains, and their default policies are all set to ACCEPT, which means the firewall is inactive.
[bash]# /etc/init.d/iptables stop |
The output from the top listing does not provide much information, so let's populate the table with some of our own rules. Type the following commands at the prompt then output a listing of the table again.
01- [bash]# iptables -P INPUT DROP 02- [bash]# iptables -P FORWARD DROP 03- [bash]# iptables -P OUTPUT DROP 04- [bash]# iptables -A INPUT -i lo -j ACCEPT 05- [bash]# iptables -A OUTPUT -o lo -j ACCEPT 06- [bash]# iptables -A INPUT -i ppp0 -p tcp --sport 80 -j ACCEPT 07- [bash]# iptables -A OUTPUT -o ppp0 -p tcp --dport 80 -j ACCEPT 08- [bash]# iptables -A INPUT -i eth1 -s 192.168.1.0/24 -p tcp --dport 3128 -j ACCEPT 09- [bash]# iptables -A OUTPUT -o eth1 -d 192.168.1.0/24 -p tcp --sport 3128 -j ACCEPT [bash]# iptables -nvL |
01- 04- 06- 08- 02- 03- 05- 07- 09- | Chain INPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT tcp -- ppp0 * 0.0.0.0/0 0.0.0.0/0 tcp spt:80 0 0 ACCEPT tcp -- eth1 * 192.168.1.0/24 0.0.0.0/0 tcp dpt:3128 Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT tcp -- * ppp0 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 0 0 ACCEPT tcp -- * eth1 0.0.0.0/0 192.168.1.0/24 tcp spt:3128 |
Lines 01-03: The first three commands set the default (-P) policy on all the chains to DROP everything, unless suitable rules inside the chain will ACCEPT them. This is the most secure method of filtering as any packet that is now to pass through any of the chains, must have a specific rule written for it.
Lines 04-05: These two commands have (-A) appended two ACCEPT rules. The OUTPUT rule (05) allows any packet to (-o) leave via the loopback device and the INPUT rule (04) allows packets to re-enter (-i) via the loopback.
Because the chains are using a default DROP policy, they restrict the server from accessing any of its own services running on the local host, like DNS. A basic rule like this allows the server to access all loopback services without restriction.
Lines 06-07: The next two (-A) appended rules are more specific, lets look at the outbound one first. The OUTPUT rule (07) specifies that any packet going out the (-o) ppp0 interface using (-p) protocol TCP is ACCEPTed if its going to port 80. The INPUT rule (06) specifies that any packet coming in the (-i) ppp0 interface using (-p) protocol TCP is ACCEPTed if its coming from port 80.
You should be able to pick this up, it says that we are allowed to access external web servers from our own server, but there are no forward rules for the internal network to surf the Internet. We should also allow our internal network the ability to access external web servers too shouldn't we? Let's look at the next rules then.
Lines 08-09: The last INPUT rule (08) which has been (-A) appended to the chain allows any packets from the (-s) source network of 192.168.1.0/24 if they enter through the (-i) eth1 device and if they are the TCP (-p) protocol and are going to the (--dport) destination port of 3128. The matching OUTPUT rule (09) has been (-A) appended to the chain and allows any packets that are going out (-o) the eth1 interface to (-d) destination network 192.168.1.0/24 using the TCP (-p) protocol if it came from the (--sport) source port of 3128.
These two are fairly detailed rules, they say that anyone on the internal network (192.168.1.0/24) is allowed to send packets to the squid proxy server (3128) through the internal eth1 interface and the results can be returned to the workstation.
If you use a strict DROP policy like above, its important to note that you may need two rules that complement each other in order for data to flow out and back in again.
A Walk Through
To better understand the above filtering example, its best to walk the configuration through the same way a packet would be subject to the filtering table's definitions, one rule at a time. Remember, every packet of data has certain attributes, source/destination addresses, source/destination ports, the interfaces they are coming in and out and the type of protocol being used, the filtering will reject any packet whose attributes dont match any of the rules in our chains.
A person using the workstation (in the network example below) wishes to access the resources of the web server located on the Internet, can a direct connection be established? No, all the policies are set to DROP and there is no FORWARD rules defined, so it simply can not occur.
Can the proxy server access the web server on the Internet? Yes, the proxy server has the rights to access anything which is TCP based operating at port 80 out through the ppp0 link, which is to a web server. Can you see the ACCEPT rules for the packet's attributes in the complementing INPUT and OUTPUT chains?
The only way now for the workstation to access anything, is via the proxy server application running at port 3128, which in turn can access any web server resources on the Internet and return the requested information to the workstation. Are the required rules in the table?
How does this work without any forwarding rules? Easy, the proxy server is an application that requests resources on behalf of a client, so the request comes into the proxy from the client, and now the request goes out to the web server from the proxy, as though it was requesting the information itself. This happens at the application layer, because its the proxy application which forwards the clients original request, so forwarding at the IP layer is not required here.
Hopefully you have been able to pick up the filtering concepts mentioned above, if you have, well done. The proxy server situation was a little tricky, but was introduced to give you an understanding that particular packets and resources can still be shaped to suit your security requirements by incorporating them into your network design.
Thats a brief introduction to packet filtering, the ability to write and chain together rules that selectively accept or deny any packets that do not meet the security requirements for your network.
What happens to the filter table when you type these following commands? View the table's output after each one and see if you can recognise the effects of the rules, and which direction the packets can pass (i.e., are they going to an internal or external resource). View "man iptables" for further assistance.
[bash]# iptables -I INPUT 2 -i ppp0 -p tcp --dport ftp -j ACCEPT [bash]# iptables -I OUTPUT 2 -o ppp0 -p tcp --sport ftp -j ACCEPT [bash]# iptables -D INPUT -i ppp0 -p tcp --sport 80 -j ACCEPT [bash]# iptables -D OUTPUT -o ppp0 -p tcp --dport 80 -j ACCEPT [bash]# iptables -A INPUT -p icmp --icmp-type any -j ACCEPT [bash]# iptables -A OUTPUT -p icmp --icmp-type any -j ACCEPT [bash]# iptables -I INPUT -m state --state INVALID -j LOG --log-prefix "INVALID Input: " [bash]# iptables -I INPUT -m state --state INVALID -j DROP [bash]# iptables -F [bash]# /etc/init.d/iptables restart |
Network Address Translation (NAT) is the ability to change a data packets destination or source IP address on-the-fly, so the packet looks like it came from (or is going to) a different address than the original (also works on port numbers).
There are many reasons why we should use NAT, here are a few:
- Frees the requirement to use large amounts of 'real' IP addresses (cheaper),
- Allows packets from a private (RFC1918) network to be globally routed out to the Internet,
- Allows packets on the Internet to be routed into a private (RFC1918 network,
- It masks the true amount of private workstations, as all external traffic appears to come from the one source,
- It allows inbound traffic to be sent to different internal hosts (bastions) depending on the resources requested, and
- It does not disclose any security details of the internal private network.
Table Name | Chain Name | Chain Details |
nat | PREROUTING | For altering packets as they are entering the system (before filter INPUT) |
POSTROUTING | For altering packets as they are exiting the system (after filter OUTPUT) | |
OUTPUT | For altering packets before leaving the local system (before the routing table) |
[bash]# iptables -t nat -nvL |
- The packet has meet at least one rule in all three filter chains (INPUT, FORWARD, OUTPUT),
- The packet has been checked against the kernel routing table, and a decision on where to route has been made,
- As the packet leaves the NAT device, the source address is changed to the NATs external IP address,
- The NAT device remembers the real owner of the packet.
01- [bash]# iptables -P INPUT ACCEPT 02- [bash]# iptables -P FORWARD DROP 03- [bash]# iptables -P OUTPUT ACCEPT 04- [bash]# iptables -A FORWARD -i eth1 -o ppp0 -s 192.168.1.0/24 -p tcp --dport 80 -j ACCEPT 05- [bash]# iptables -A FORWARD -i ppp0 -o eth1 -d 192.168.1.0/24 -p tcp --sport 80 -j ACCEPT 06- [bash]# iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.1.0/24 -j SNAT --to-source 123.123.123.2 07- [bash]# echo 1 > /proc/sys/net/ipv4/ip_forward [bash]# iptables -nvL ; iptables -t nat -nvL |
01- 02- 04- 05- 03- 06- | Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT tcp -- eth1 ppp0 192.168.1.0/24 0.0.0.0/0 tcp dpt:80 0 0 ACCEPT tcp -- ppp0 eth1 0.0.0.0/0 192.168.1.0/24 tcp spt:80 Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 SNAT all -- * ppp0 192.168.1.0/24 0.0.0.0/0 to:123.123.123.2 Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination |
- SNAT is used in the POSTROUTING chain after the kernel routing decisions have been made,
- Forwarding rules need to be suitable to allow packets in both directions,
- The "--to-source" address should be the external IP address which will be visible on the packets return, and
- SNAT should not be used for dynamic links where the IP address is likely to change (see masquerading, next).
01- [bash]# iptables -P INPUT ACCEPT 02- [bash]# iptables -P FORWARD DROP 03- [bash]# iptables -P OUTPUT ACCEPT 04- [bash]# iptables -A FORWARD -i ppp0 -m state --state ESTABLISHED,RELATED -j ACCEPT 05- [bash]# iptables -A FORWARD -i eth1 -o ppp0 -s 192.168.1.0/24 -j ACCEPT 06- [bash]# iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.1.0/24 -j MASQUERADE 07- [bash]# echo 1 > /proc/sys/net/ipv4/ip_forward [bash]# iptables -nvL ; iptables -t nat -nvL |
01- 02- 04- 05- 03- 06- | Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- ppp0 * 0.0.0.0/0 0.0.0.0/0 state REL,ESTAB 0 0 ACCEPT tcp -- eth1 ppp0 192.168.1.0/24 0.0.0.0/0 Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 MASQUERADE all -- * ppp0 192.168.1.0/24 0.0.0.0/0 Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination |
[bash]# iptables -t nat -A POSTROUTING -j MASQUERADE |
[IMG]http://i240.photobucket.com/albums/ff240/jagoanneon09/Tutorial/warning0.gif[/IMG] | WARNING: The above rule is dangerous, it allows masquerading in both directions. |
01- [bash]# iptables -P INPUT ACCEPT 02- [bash]# iptables -P FORWARD DROP 03- [bash]# iptables -P OUTPUT ACCEPT 04- [bash]# iptables -A FORWARD -i eth1 -o ppp0 -s 192.168.1.0/24 -j ACCEPT 05- [bash]# iptables -A FORWARD -i ppp0 -o eth1 -p tcp --dport 80 -j ACCEPT 06- [bash]# iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.2:80 07- [bash]# echo 1 > /proc/sys/net/ipv4/ip_forward [bash]# iptables -nvL ; iptables -t nat -nvL |
01- 02- 04- 05- 03- 06- |
Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- eth1 ppp0 192.168.1.0/24 0.0.0.0/0 0 0 ACCEPT tcp -- ppp0 eth1 0.0.0.0/0 192.168.1.0/24 tcp dpt:80 Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 DNAT tcp -- ppp0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:192.168.1.2:80 Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination |