Designing a Safe Network Using Firewalls

Configuring the Firewall

There are basically two ways of configuring your firewall. The first and most secure setup is “Deny everything unless we explicitly allow it.” The disadvantage is that you will have a lot of users wondering why certain things don't work. You might consider this approach in a setup where your firewall protects a very small subnet containing only servers and no clients. A script for setting up this type of firewall is shown in Listing 2. “Deny Everything..” Firewall. This type of firewall requires quite a bit of knowledge about how certain protocols work. Do not attempt it unless you have proper documentation and plenty of time to devote to it.

The second, and easier setup is “Allow everything unless we explicitly deny it.” This one makes your network fairly open, but controls a few dangerous or unwanted protocols. For example, some ISPs use this feature to block all “CU-SeeMe” traffic, as this type of traffic can congest their entire network. A script setting up this type of firewall is shown in Listing 3. “Allow Everything...” Firewall.

How Do We Monitor What is Going On?

As you might have noticed in the two previous examples, all deny rules have the option -o set to instruct the Linux kernel to explicitly log all denied packets using the syslog facility. If you deny packets without logging them, someday you will be bug hunting for hours before you realize the problem was a packet filter. Depending on how you have configured the syslog daemon (/etc/syslog.conf), these messages will show up in either the /var/log/messages file or the /var/log/syslog file. You should regularly check these log files on your firewall machines. Make sure there is enough disk space to log even an attack that floods you with messages. If possible, use a separate partition for your log files.

Here are a few log entries from our syslog to demonstrate some common problems. These log entries come from our Livingston router, as well as our Linux machine.

Jan  2 15:17:57 15 deny: UDP from

This is perhaps the most frequent hit our firewall rules get. Port 137 is the NetBios name-service port used by Microsoft Windows machines to look up names in the local network. However, poor implementation and bad configuration often lead to Windows machines making NetBios requests to another machine. These requests might have been generated by a user's telnet, FTP or even WWW request. You might want to enable your deny rule without the -o flag, so that your log file is not filled up with these very common errors. One of our clients had his root partition entirely filled with netbios logs, stopping his genuine logging from operating and almost crashing the server.

Jan  2 17:12:34  2 deny: TCP from to seq 1471CB0, ack 0x0, win 8192, SYN
This message is caused by a badly configured host. The IP numbers in the 10.*.*.* range are reserved for local area networks. We found out this host was a misconfigured masquerading host on the Internet, which used its IP number from the local masqueraded network instead of its real Internet IP number. This misconfiguration traveled through many other routers before being caught by our firewall. Large backbone ISPs don't filter out bogus packets, resulting in easy IP spoofing from almost anywhere on the Internet to anywhere else. Don't trust your ISP to filter out anything; do it yourself.
Jan 20 06:57:33 14 deny: UDP from xx.yy.zz.aa.904
Our firewall proved its value on this attack. Someone tried to ask our RPC daemon (udp port 111) which daemons we are running. Even though an attacker can still find most RPC services by doing a total port scan, it is still a good idea not to give them the information so readily. There is almost never a need to have RPC services exchanged with a server on the Internet. Port scans are easily spotted because they leave a giant trace of occurrences of all your filter rules in your log files.
Jan  3 22:16:55 44 deny: TCP from xx.yy.zz.aa.17231
to seq 7A3731D0, ack 0x0, win 49152, SYN
This is another true firewall hit. We banned this host after we received a couple of the above attacks on our RPC server. Since the postmaster of this particular site didn't respond, we blocked access for the host on all ports.
Feb  4 09:10:17 kernel: IP fw-in deny eth1 UDP L=328 S=0x00 I=4 F=0x0000 T=60
Port 68 is bootp (DHCP). Some machine was broadcasting and asking for a bootp server. This could be a Win95 computer or even some intelligent HUB which needs an IP number to support SNMP. (This one had us puzzled for months.)
Jan 27 09:47:00 kernel: IP fw-in deny eth1 TCP L=48 S=0x00 I=2993 F=0x0040 T=255
This machine didn't define the masquerading host as router, so it tried to be smart—but it still didn't find the right gateway.
Jan 28 12:23:50 kernel: IP fw-in deny eth0 TCP L=44 S=0x00 I=23859 F=0x0000 T=63
To understand what happened, we need to dig a little into the inner workings of TCP/IP. All connections are identified by a unique combination of source IP, source port, destination IP and destination port. However, to find well-known services, such as telnet, WWW or cache, it is a common practice to use specific ports. To uniquely identify connections to such a well-known service, a random but unique port is allocated on the local machine. If this machine now makes a connection to a well-known service on another machine, it is guaranteed to have a distinguishable TCP/IP connection. Port numbers below 1024 are normally not assigned as random ports, because they're often used or reserved for the well-known services.

Now, let us look back at the log entry. The computer wanted to set up a connection to the machine on port 3128 (the cache server). It first asked the operating system for a unique random port and was given port 2049. It then initiated the connection to the cache server ( port 3128). The cache server responded by sending its answer back in a packet to port 2049. But is also using firewall rules, and one of its rules is to block all attempts to connect to the NFS service, which, unlike many other well-known services, is not located on a port below 1024, but on port 2049. Thus, the cache server's response is filtered out. You can solve this problem of distinguishing the connection based on whether or not it originated from your site. You can determine the point of origin by whether the SYN or ACK flag in the TCP header is set. The correct way of filtering out connections to port 2049, while still allowing connections to be initiated from it, is as follows:

/sbin/ipfwadm -I -i deny -S \
 -D 2049 -P tcp -y -Weth0 -o
Jan  2 11:22:58 38 deny: TCP from
to seq F72DA7C6, ack 0xED8FDEA1, win 31744, SYN ACK

A similar situation happened here. Port 1642 was assigned by some machine as the random unique port, but the firewall decided that port 1642 was bad. Livingston Portmaster software uses this port to communicate between a Unix host and their routers/firewalls, so that is why we filter these ports for the outside.

In general, try to avoid blocking high ports, and if you do block out a high port, block that port only for the machine that needs the protection. For example, block port 1642 only for your routers and terminal servers, but leave it open for Unix servers. Then, if the router/firewall receives a packet destined for port 1642 on an internal machine, it will pass it to that internal machine even if port 1642 on the router itself is blocked.

A minor drawback is that we are giving away a bit of information to potential hackers. They can check all your IP numbers to see which ones are routers, firewalls or Unix hosts that talk to the routers or firewalls; however, they can usually find that same information through other means as well. For example, the traceroute command yields a lot of information about which machines are used for packet transfer and are therefore either a router, a firewall or both. You can also use the -y option mentioned in the previous example. Not all hardware routers/firewalls offer these options.



Comment viewing options


Dedicated Servers

James Raynor's picture
