- Free Software Firewall Guide -
Specific Applications of IP Filter - Things that don't fit, but should be mentioned anyway.
Keep State With Servers and Flags
Keeping state is a good thing, but it's quite easy to make a mistake in the
direction that you want to keep state in. Generally, you want to have
a keep state keyword on the first rule that interacts with a packet
for the connection. One common mistake that is made when mixing state tracking
with filtering on flags is this:
block in all
pass in quick proto tcp from any to 20.20.20.20/32 port = 23 flags S
pass out all keep state
That certainly appears to allow a connection to be created to the telnet
server on 20.20.20.20, and the replies to go back. If you try using this rule,
you'll see that it does work--Momentarily. Since we're filtering for the SYN
flag, the state entry never fully gets completed, and the default time to live
for an incomplete state is 60 seconds.
We can solve this by rewriting the rules in one of two ways:
1)
block in all
pass in quick proto tcp from any to 20.20.20.20/32 port = 23 keep state
block out all
or:
2)
block in all
pass in quick proto tcp from any to 20.20.20.20/32 port = 23 flags S keep state
pass out all keep state
Either of these sets of rules will result in a fully established state
entry for a connection to your server.
FTP is one of those protocols that you just have to sit back and ask "What
the heck were they thinking?" FTP has many problems that the firewall administrator
needs to deal with. What's worse, the problems the administrator must face are
different between making ftp clients work and making ftp servers work.
Within the FTP protocol, there are two forms of data transfer, called active and passive. Active transfers are those where the server connects to an open port on the client to send data. Conversely, passive transfers are those where the client connects to the server to recieve data.
In running an FTP server, handling Active FTP sessions is easy to setup. At
the same time, handling Passive FTP sessions is a big problem. First we'll cover
how to handle Active FTP, then move on to Passive. Generally, we can handle
Active FTP sessions like we would an incoming HTTP or SMTP connection; just
open the ftp port and let keep state do the rest:
pass in quick proto tcp from any to 20.20.20.20/32 port = 21 flags S keep
state
pass out proto tcp all keep state
These rules will allow Active FTP sessions, the most common type, to your
ftp server on 20.20.20.20.
The next challenge becomes handling Passive FTP connections. Web browsers
default to this mode, so it's becoming quite popular and as such it should be
supported. The problem with passive connections are that for every passive connection,
the server starts listening on a new port (usually above 1023). This is essentially
like creating a new unknown service on the server. Assuming we have a good firewall
with a default-deny policy, that new service will be blocked, and thus Active
FTP sessions are broken. Don't despair! There's hope yet to be had.
A person's first inclination to solving this problem might be to just open
up all ports above 1023. In truth, this will work:
pass in quick proto tcp from any to 20.20.20.20/32 port > 1023 flags
S keep state
pass out proto tcp all keep state
This is somewhat unsatisfactory, though. By letting everything above 1023
in, we actually open ourselves up for a number of potential problems. While
1-1023 is the designated area for server services to run, numerous programs
decided to use numbers higher than 1023, such as nfsd and X.
The good news is that your FTP server gets to decide which ports get assigned
to active sessions. This means that instead of opening all ports above 1023,
you can allocate ports 15001-19999 as ftp ports and only open that range of
your firewall up. In wu-ftpd, this is done with the passive ports option
in ftpaccess. Please see the man page on ftpaccess for details
in wu-ftpd configuration. On the ipfilter side, all we need do is setup corresponding
rules:
pass in quick proto tcp from any to 20.20.20.20/32 port 15000 ><
20000 flags S keep state
pass out proto tcp all keep state
If even this solution doesn't satisfy you, you can always hack IPF support
into your FTP server, or FTP server support into IPF.
While FTP server support is still less than perfect in IPF, FTP client support
has been working well since 3.3.3. As with FTP servers, there are two types
of ftp client transfers: passive and active.
The simplest type of client transfer from the firewall's standpoint is the
passive transfer. Assuming you're keeping state on all outbound tcp sessions,
passive transfers will work already. If you're not doing this already, please
consider the following:
pass out proto tcp all keep state
The second type of client transfer, active, is a bit more troublesome,
but nonetheless a solved problem. Active transfers cause the server to open
up a second connection back to the client for data to flow through. This is
normally a problem when there's a firewall in the middle, stopping outside connections
from coming back in. To solve this, ipfilter includes an ipnat proxy
which temporarily opens up a hole in the firewall just for the FTP server to
get back to the client. Even if you're not using ipnat to do nat, the
proxy is still effective. The following rules is the bare minimum to add to
the ipnat configuration file (ep0 should be the interface
name of the outbound network connection):
map ep0 0/0 -> 0/32 proxy port 21 ftp/tcp
For more details on ipfilter's internal proxies, see section 3.6
There are some useful kernel tunes that either need to be set for ipf to function,
or are just generally handy to know about for building firewalls. The first
major one you must set is to enable IP Forwarding, otherwise ipf will do very
little, as the underlying ip stack won't actually route packets.
IP Forwarding:
| << Previous section: Advanced firewalling |