|
By Bri Hatch. Summary: Create a simple but effective host firewall for your machine in ten minutes or less. One of my friends finds himself in a very annoying situation: he started a new job and now has a Windows machine on his desk. Worse yet, he's not allowed, by corporate policy, to wipe it clean and install Linux on it "for security reasons". Being that we both live up here in Seattle, close to the belly of the beast itself, it's not surprising that the Microsoft FUD machine is strong. The IT department grudgingly agreed that he could use Linux if he had an adequate firewall installed. They intend to port scan him and, if all ports refuse inbound connections, they'll consider his machine secure. Now this is not my definition of a very secure firewall.[1] However it is immeasurably better than no firewall rules at all, and it takes no more than a few minutes to set it up.
First, let's assume we're on a 2.4 kernel that has Netfilter
( In this minimal setup, we want to allow all outbound access, and deny all inbound access that isn't in response to one of our outbound connections. This is surprisingly easy to manage.
We'll be adding rules to the
# iptables -P INPUT DROP You now have a very secure machine - nothing can get in. Perhaps we should open things up a bit... There are three protocols we'll want to support, TCP, UDP, and ICMP. TCP is the IP protocol that does the majority of the work on the Internet. It's a connection-based protocol that underlies all the major services, such as web (HTTP/HTTPS), mail (SMTP, POP, IMAP), remote login (SSH), and file transfer (FTP). Any TCP connection has the oft-mentioned "three way handshake". The machine that wants to create a connection sends a packet to the destination with the SYN (synchronise) flag set. The server responds with a packet that has both SYN and ACK (acknowledge) set, and thereafter the SYN bit is never seen again. If we configure our firewall ACLs to drop any packets which contain the SYN bit without that ACK, we can prevent the first packet of TCP connections from reaching our machine, and no TCP connections can be created at all.
Iptables[2] can selectively
block packets based on the SYN flag using the
Voila! No machines can connect to your machine with TCP, but you can
make outbound connections and the associated packets will be allowed
back in. You can't be a server (no SSH to your machine, for example)
but all outbound TCP stuff should work fairly well.
Well, that's true about most 'well behaved' TCP-based protocols. Some
protocols like to use more than one port. FTP is the classic example of
a bastardly-designed protocol. Each time you type 'get', 'put', or 'ls'
a new TCP connection is initiated to snag the data.
Note also that even though outsiders can't connect to your TCP ports,
scanning tools such as Nmap will be able to see that the port is open
if they are used in any mode other than straight TCP connection scanning.
Newer Nmap versions use stealth scanning by default when run as root.
If the protocol you use wants to have the client (your newly
firewalled machine) make an additional connection to the server,
then your
Protocols that create these ephemeral side connections include many
P2P protocols, and most notably FTP. Most of these offer both a
'client connects to server' and 'server connects back to client' option.
In the case of FTP, the former is called "Passive", while the latter
is called "Active". Active was the original (really annoying for firewalls
and proxies) model,
and Passive has been favoured for some time now. Most FTP clients let
you choose Passive if it's not already the default. For example typing
Now, to be a bit more restrictive, let's block UDP as well. UDP is
a connectionless protocol, so it's harder to proxy and firewall.
However it's also less commonly used. DNS is the the most important
UDP protocol. Without DNS you're going to need to memorise many
IP addresses, so we best open this up.
DNS servers live on UDP port 53.[4]
Our machine will need to send packets to port 53 on one or more DNS
servers, and receive packets that come from port UDP 53. So, restricting
on the source port (the port on the DNS server) you'd have
This will allow any DNS servers to reply to you, which may be helpful
if you get your DNS servers from DHCP and want to be lazy. If you
want to hard code your DNS server's IP addresses to be most restrictive,
you can use the following
If your machine needs to get an IP address from the network using
BOOTP or DHCP, then you'll need the following rule as well:
Any packets that aren't for DNS or BOOTP/DHCP will be dropped by
the
What services are likely to brake when you're blocking UDP? Most
streaming media uses UDP for it's highest-speed connections, but may
offer TCP based connections as well. Filesharing protocols such as NFS
may die, but again may offer TCP versions that get around this limitation.
It all depends on your setup.
Now we haven't listed which interfaces these rules apply on. If you want
them to apply to all interfaces, this is probably good. However you should
allow packets that go on the localhost interface to work universally, lest
you break some daemons that expect to be able to communicate within
your machine, or features like SSH port forwarding. So, as the very first
rule, you should include the following:
The
Lastly, we can lock down allowed ICMP packets, which are
used in conjunction with TCP and UDP protocols to indicate
error conditions and the like. Here I'll be a bit more
permissive than may be necessary in order to fit the needs of a wider
audience. To get a full list of possible ICMP codes, run
You may wish to exclude some of these, such as
Next week I'll bring this all together in one big script and show
you how to let these rules be created at reboot automatically.[6]
NOTES:
[1] I much
prefer to have my firewall rules explicitly define what packets are
allowed to go in *and go out*. This helps block outbound access
that could be created by trojans, viruses, or evil hax0rs.
[2] Iptable's predecessors and other firewall/filtering
products have also used this trick for years.
[3] Netfilter has modules that you can load as well to support
specific protocols such as FTP or IRC that do wacky things
like this.
[4] They may also listen
on TCP port 53 for larger queries and DNS zone transfers, but outbound
TCP is already covered by our previous
[5] For more information about this and other
helpful
[6] I
understand the irony of having a 10 minute firewall discussion
spread out over two weeks...
Bri Hatch is Chief Hacker at Onsight, Inc and author of Hacking Linux Exposed and Building Linux VPNs.
In the rare times where he gets uninterrupted time to write,
he never seems to stop. The muses smiled upon him today.
Bri can be reached at bri@hackinglinuxexposed.com. Copyright Bri Hatch, 2003
This is the July 03, 2003 issue of the Linux Security: Tips, Tricks, and Hackery newsletter. If you wish to subscribe, visit http://lists.onsight.com/ or send email to Linux_Security-request@lists.onsight.com. |