IP Filter at SIPB

Last modified: 9 August 2004

Introduction

IP Filter is a software package for packet filtering. On SIPB servers, it is used only in a standalone host configuration. The purpose of the software is to change the kernel's handling of IP packets. The kernel usually arranges for delivery of many types of packets to application programs. SIPB typically establishes an IP Filter configuration intended to deliver fewer types of packets to application programs. The justification is that it can be easier to ensure system security when this is done.

IP Filter is commonly used for other purposes, especially on machines that have more than one physical network interface. It can be used to create firewalls and NAT (Network Address Translation) servers. IP Filter has not been used in these roles by SIPB.

Many other types of software can be used for packet filtering. Probably the best known is iptables, which is used on Linux. The access-list command in Cisco's IOS (Internetwork Operating System) is another widely used approach to packet filtering. SIPB chose IP Filter because it was the only feasible no-cost software for Solaris at the time packet filtering was first needed for SIPB's Solaris servers.

The official web site for IP Filter is http://coombs.anu.edu.au/~avalon/. Most of the documentation, such as the FAQ file, is located on other web sites. The official web site has links to all of the other commonly used web sites about IP Filter.

SIPB

On SIPB machines, the two main components of IP Filter are the software package and the rules file. On Solaris 9, we have version 4.x. This version requires that the pfil package be installed first. The pfil package is described at http://coombs.anu.edu.au/~avalon/ipf-mentat.html. On Solaris 7, we have version 3.x. This version does not require pfil.

Copies of rules files have, in the past, been maintained in /afs/sipb.mit.edu/service/solaris/src/ipf/usr/local/share. This has examples of somewhat complex configurations. Our minimal local documentation about IP Filter has, in the past, been maintained in /afs/sipb.mit.edu/machine/dandelion-patch/README. The relevant excerpt from this file is:

     The IP Filter package is installed and blocks access to most TCP
     ports. Two particular visible effects are (a) outgoing rsh connections
     to most machines will not work, and (b) in outgoing ftp sessions,
     it will be useful to type "passive". To block access to dandelion-patch
     from a specific IP address, a new rule needs to be added in the file
     /usr/local/share/ipf.in, and needs to occur earlier in the file than
     the first "pass in quick" rule. The new rule would have the form

        block return-rst in quick on hme0 proto tcp from 208.47.125.33/32 to any port = 80

     Once the file is edited, run these two commands. The first command
     removes all rules, and the second one loads the new file.

       /sbin/ipfstat -i | /sbin/ipf -rf -
       /sbin/ipf -f /usr/local/share/ipf.in

     To undo the blocking, a single command can be run to remove the specific
     rule. In this example it would be:

         echo block return-rst in quick on hme0 proto tcp from 208.47.125.33/32 to any port = 80 | /sbin/ipf -rf -

     Then, /usr/local/share/ipf.in would be edited to make it consistent with
     the currently active rules.

Four of the commonly used types of rules are:

  1. Blocking unwanted traffic from a specific source
  2. Blocking traffic to a potentially insecure network service
  3. Blocking traffic to unused TCP ports
  4. Detecting whether the system is the target of a port scan

These will be discussed in more detail here.

Blocking unwanted traffic from a specific source
This type of rule was described above for the example IP address 208.47.125.33. In this scenario, we imagine that there is some type of unwanted traffic from 208.47.125.33 directed to one of SIPB's Apache web servers. For example, suppose it is sending 100 requests per second for a web page. It would be possible to deny access to the web page via the Apache configuration file (httpd.conf). However, it is much more efficient to block the IP address in the kernel. When the block return-rst rule shown above is in place, the unwanted traffic is never received by the Apache httpd. Therefore, any application-level costs, such as for processes or log file I/O, are avoided. From the perspective of the client application, the behavior is (roughly) equivalent to a situation in which SIPB's machine were not listening on TCP port 80. If the blocked client tries to connect to port 80, it gets the equivalent of a "Connection refused" error. If any other client tries to connect to port 80, it reaches the Apache web server in the normal manner.

Blocking traffic to a potentially insecure network service
One situation in which this type of rule occurs is blocking syslog traffic. Typically, it is worthwhile for a Solaris syslog daemon (syslogd) to accept incoming IP traffic on UDP port 514. Some application programs (such as perl) communicate with syslogd over this port. It is undesirable to configure syslogd to not listen on the UDP port, even though this is a supported configuration option (syslogd -t). Also, it is undesirable to allow every computer on the Internet to send data on UDP port 514. First, the syslog protocol has no authentication, and therefore outside persons could transmit arbitrarily large amounts of forged log information and fill the disk. Second, there may be some type of vulnerability (such as a buffer overflow) in syslogd that allows remote attackers to execute arbitrary code. To address this, we create a rule that disallows incoming IP traffic on UDP port 514 on the Internet interface. The rule looks like block return-icmp(port-unr) in log on hme0 proto udp from any to any port = 514. Here, return-icmp(port-unr) means that IP Filter will engage in behavior that matches the situation of a "closed" UDP port. If a client sends traffic to a UDP port on which no application is listening, the server normally sends back an ICMP port-unreachable message. With this configuration, the server-to-client network traffic is the same, even though UDP port 514 is actually an "open" UDP port. Next, log means that we wish to record (via syslog) any attempts by outside machines to send traffic to UDP port 514. The on hme0 refers to the network interface: in other words, traffic that arrives over the network is blocked, whereas traffic originating on the local machine ("loopback") is not blocked. The proto udp and port = 514 together specify that the rule is exclusively about UDP port 514. Finally, from any to any means that we are blocking all external IP addresses, and blocking them from sending traffic to all of the local IP addresses on the hme0 interface. (There may be more than one local IP address on the hme0 interface because of virtual interfaces.)

Blocking traffic to unused TCP ports
For every TCP port that is not in use, it is often a good idea to block the port via IP Filter. A typical rule might be block return-rst in on hme0 proto tcp from any to any port = 1524. A common question is why is it useful to block the port, rather than just not listening on the port. The reason is to stop some types of breakin attempts. An attacker may launch an exploit program that starts a service listening on a port. If the port they tried to use was blocked by the kernel, the attacker would probably conclude that the exploit didn't work, and move on to other targets. There are lots of private exploit programs for vulnerabilities that aren't publicly known, or ones that are publicly known but don't happen to get fixed quickly enough on a specific machine. It's very difficult to stay ahead of this. It's not unusual to hear reports of incidents where blocking incoming traffic to (originally) non-listening ports was the one factor that prevented an otherwise usable compromise approach on an important, well-maintained machine. Clearly an attacker could make arbitrary use of a vulnerable machine without starting a new listening TCP service, but often it's not efficient for them to bother trying, or they just have a private exploit program without source code and don't have an option. Port 1524, mentioned in the example rule above, happens to be the most common port used by an intruder for a new service on a compromised Solaris system. Usually the new service runs /bin/sh from inetd.

Detecting whether the system is the target of a port scan
One might want to know whether outsiders are port scanning the system, because it may occasionally mean that a breakin attempt is being considered. A rule such as block return-rst in log on hme0 proto tcp from any to any port = 1 flags S/SA would create a log entry whenever someone began a port scan that included TCP port 1. The flags S/SA indicates that only TCP SYN packets should be logged. These are the most common types of packets used in a port scan. Logging port scans is not of very high importance but sometimes the logs end up being useful.

Finally, here is one additional note about IP Filter rules. The default behavior of IP Filter is to decide about each packet based on the last matching rule. In other words, if you wrote a specific rule about TCP port 1, and later in the rules file wrote a more general rule about all TCP packets on ports less than 22, only the latter rule would be relevant. The first rule would be ignored.

This is different from the behavior of other packet-filtering software, and may be confusing at first to persons who have used other packet-filtering software. IP Filter does, however, provide a way for earlier rules to take effect. If a rule includes the quick keyword, and the rule matches the packet, no other rules are read.