We all know firewalls are important, and we implement them in a variety of ways, from hardware to free or commercial products. Some firewalls use general rules to set up your security, and some allow you to fine-tune them to your heart's content (and often frustration). There are two categories when it comes to firewall implementation: The easiest to set up are generally the least flexible, while the more difficult to configure allow the most versatility.
One of the questions I am asked most frequently regarding firewalls is about ports. What should one protect and what should one leave open? The question requires more thought than most care to give it. The answer depends on what you are using your system for, what services need to be made available to the public, and so on.
Let's take a look at some of the more standard ports and determine how you should treat them depending on your situation.
The more common ports
One thing to keep in mind is that when we discuss ports in terms of a firewall, we usually refer to traffic coming in on a specific port. For instance, when we talk about FTP traffic on port 21, we are not talking about a user using an FTP client to connect to another FTP site. We are talking about a host running an FTP server where inbound connections are made to port 21, or in other words, the FTP server listens to port 21.
For a simple workstation with no servers running, you can block every port against incoming traffic and not suffer for it. In fact, this is something you should do. Globally denying all incoming traffic on any port on a simple workstation is ideal.
For a server system, this becomes a little tricky, because you have to determine which services you are providing and block off all ports except for those you need. But how do you know which ports you need to keep open? Table A shows a list of common ports and their uses in a server scenario:
|20||FTP data||The port the FTP server opens to send information back to the FTP client|
|21||FTP||The actual port that all FTP servers bind to by default|
|23||Telnet||Remote logins using Telnet|
|25||SMTP||The port a mail server receives mail on|
|53||DNS||The port your DNS (Domain Name Server) listens to for DNS requests|
|68||DHCP||The port your DHCP (Dynamic Host Configuration Protocol) server listens to for handing out IP addresses and network information|
|79||Finger||Used to identify users on your system|
|80||HTTP||The port Web servers listen to by default|
|110||POP3||The port a mail server listens to for clients to pick up mail from|
|111||RPC portmap||Required by NFS servers and other RPC-based programs|
|113||Auth||The port the ident server uses when a remote host wants to verify that the user is coming from the IP they claim to be coming from|
|137-139||NetBIOS||(Windows File and Print Sharing) The ports Windows and Samba use for sharing drives and printers with other clients|
|143||IMAP||The port a mail server listens to for clients using IMAP to read their mail instead of POP3|
|443||HTTPS||The port Web servers listen to by default for SSL-enabled Web activity|
|512-515||*NIX-specific ports||*NIX-specific ports for the exec, biff, login, who, shell, syslog, and lpd programs to listen to|
|2049||NFS||Used to export file systems to other *NIX-based computers|
Table A shows the standard ports that you will probably encounter and use most. Table B shows some other ports that you might use.
|98||Linuxconf||Linux-only, for the Linuxconf configuration program|
|465||SSMTP||SMTP over SSL|
|993||SIMAP||IMAP over SSL|
|995||SPOP3||POP3 over SSL|
|3306||MySQL||The port the MySQL server listens to|
|5432||PostgreSQL||The port the PostgreSQL server listens to|
|6000-6069||X Windows||*NIX-only, for the X Windows GUI desktop|
|6667||IRC||Internet Relay Chat server|
|8080||Used by many Web caching proxy servers|
There are a whole slew of other ports that are used for a variety of services. The others are not entirely obscure but are relatively rare in comparison to those listed.
Making the decisions
Now that you've looked at the list, you're probably wondering where to start. The answer isn't as hard as you might think. The first step is to determine which servers are running on your machine and explicitly allow those ports to the outside world.
For instance, if you run a mail server and provide your clients POP3 access, and you also run an FTP and Web server, you will want to allow external access to ports 25 (SMTP), 110 (POP3), 20 and 21 (FTP), and 80 (HTTP). If you also have SSL-enabled Web pages, you will want to open port 443 (HTTPS). You can safely lock down the other ports. If you are running these services on a machine that you typically browse from (which is a bad idea), you will also want to open port 113 (auth) so people can verify that you are who you say you are. If you run a DNS server, you will want to open port 53. If you run DHCP, you will want to open port 68.
This is a very simplistic approach, however. Let's assume for a moment that you have a server that handles both internal and external services, even though this is a very bad idea from a security standpoint. For instance, the machine in question is a Web and FTP server alone. So, in theory, you only want to allow ports 20, 21, and 80 to be open. However, your coworkers want to be able to easily modify Web pages and such without going through the pain of firing up an FTP client, uploading new pages, and so on. You can either tell your coworkers that they have no choice or get fancy (and insecure).
Most software-based firewalls will allow you to compromise a little without sacrificing too much security. For instance, let's say your Web server has two Ethernet cards: The first is connected to the external network (the Internet), and the second is connected to the internal network (the company LAN). You can configure your firewall to block all ports except the FTP and HTTP ports on the first Ethernet device. This protects you from the external network. You can then configure your firewall to deny all ports except for FTP, HTTP, and NetBIOS (or ports 20-21, 80, and 137-139, respectively) on the second, or internal, Ethernet device. This allows you to also run the Samba server (assuming your Web server is a Linux machine) and export the relevant parts of your Web site directory tree to your coworkers. They can connect to the Web server, copy files via Windows Explorer or any other means, and avoid working locally on files and then uploading the results to the site.
In the same way, you can take a system that runs DNS services for your company's domain and provides DHCP services to the internal LAN and secure it. You can allow access to the DHCP port (68) from the LAN while blocking access to that port from the external network and allow DNS access (via port 53) to both networks.
I highly recommend, however, that you separate your systems so that this is not required. You might not be able to get around sharing your Web site directory on your Web server, but you can certainly have the DNS server for your domain and the DHCP server for your LAN on separate machines. With this setup, you can rest assured that no one will be getting into your DHCP server from the outside. In this same way, you can provide internal DNS services, as well as external DNS services, by having two servers that are firewalled from each other.
Another aspect to look at is internal trust. You should not have the internal network interface unprotected and left completely open. This can cause serious problems if your server is ever compromised. The ideal solution would be to protect the internal LAN from the server, as well as protect the server from the external network.
With any comprehensive firewall package, you should be able to restrict both incoming and outgoing traffic of any kind on any port. On the Web and FTP serving machine we discussed previously, having it connected to both the internal and external networks can allow a successful cracker to get into your internal LAN if not properly protected. Aside from blocking all ports coming in, except for those being used by the services you choose to run on the external interface, you should also block all traffic on the internal interface except for those ports required. For instance, on the internal interface, you will block all incoming ports except for FTP, HTTP, and NetBIOS. You should also block all outgoing ports on that same interface except for those necessary ports.
By doing this, you restrict someone who is successful in penetrating your server to the server alone. By denying all outgoing requests to any port on the internal interface, you have created a dead end for them, unless they exploit the few open ports you have available. However, leaving five or six open ports compared to over 65,000 will ensure that you have far more protection than you otherwise would.
You should be doing the same to your external interface. If this is a simple server and not a router or gateway to the Internet itself, you can block all outgoing ports on the external interface, except for the FTP and HTTP ports. The last thing you want is to have the cracker who managed to worm his way into your server use it as a hop point to gain entry into another system.
A plethora of firewall tools exists for the Windows platform. I can't honestly recommend any of them since I've only used one and it wasn't that great (so I won't mention it by name). On the Linux platform, there are some commercial firewall tools, but your basic underlying tool is the kernel itself and the packet-filtering capabilities it provides.
In the 2.0.x kernels, the ipfwadm tool was used to configure firewall rules. With the 2.2.x kernel came ipchains, which was easier to use and afforded a little more flexibility. Now that the 2.4.x kernel is available, Linux users have Netfilter and iptables, which provide a stateful firewall system with amazing potential.
Since the 2.4.x kernel is still relatively new, we will instead look at ipchains, which comes with the 2.2.x kernel, as most Linux users are still using the 2.2.x kernel at this time.
This Daily Drill Down is concerned more with ports than with the basics of ipchains firewalling itself, so we will take a look at how to provide rules to ipchains to protect the ports on your system. Let's look at the basics of ipchains.
With ipchains, there are four categories of firewall rules or chains: the IP input chain, the IP output chain, the IP forwarding chain, and the user-defined chains. The two types of rules that deal with port protection are the input and output chains. By writing rules that handle input and output, or the acceptance of incoming or outgoing packets, you can protect your ports from unauthorized access.
The ipchains program itself is usually located in the /sbin directory. To write firewall rules, you must invoke the ipchains program with a set of parameters. A very simple firewall script to lock down all of your ports by default might look like this:
/sbin/ipchains -P input DENY
/sbin/ipchains -P output DENY
/sbin/ipchains -P forward DENY
The first command flushes the current chains or sets the firewall defaults to their primary state, which is to accept all packets coming in and going out. The next three commands turn the default policy for each of the three predefined chains (input, output, and forward) to DENY, which denies all packets coming in and going out.
At this point, you can selectively enable ports. For instance, if our system is a FTP and Web server and we want to allow access to the standard ports for those services (20/21 and 80), we would use the following rules:
/sbin/ipchains -A input -i eth0 -p TCP --dport 20:21 -j ACCEPT
/sbin/ipchains -A input -i eth0 -p TCP --dport 80 -j ACCEPT
This allows packets coming in on the ports specified with the --dports option on the Ethernet interface specified by the -i option. It will only allow TCP packets, defined with the -p option. Since this is for incoming packets, we append this to the input chain with the -A option and assign it the ACCEPT rule with the -j option.
For the FTP protocol to work properly, we also need to allow traffic out on port 20, which is the FTP DATA port. The FTP server will initiate a connection with the remote FTP client that originates on this port, so we need to allow outgoing traffic on this port. We can do this by specifying the next rule:
/sbin/ipchains -A output -i eth0 -p TCP --dport 20 -j ACCEPT
This appends a new rule to the output chain that allows outbound TCP packets on port 20 to be sent via the Ethernet device eth0.
The key parameter for ipchains to be concerned with when dealing with ports is the --dport option. This allows you to select a single port or a range of ports to either ACCEPT (allow) or DENY (drop) packets. Obviously, there is far more to ipchains than these few commands can illustrate, but for our purposes here, this is sufficient to give you an example of how to allow or deny traffic on specific ports. By specifying a specific interface, you can allow traffic on certain ports on one Ethernet interface while restricting it on another interface. (The previous example of FTP and Web access on one interface with FTP, Web, and Samba access on the other fits here.)
Knowing which ports to permit and which to deny can be an exact science if you want to completely secure your system. Obviously, this is only one aspect of an overall security policy. There are many other issues to deal with beyond filtering traffic on specific ports. However, by being aware of which ports are used by which resources, you can fine-tune your firewall so that you can run services that you require without making the world aware that you are doing so.
Most servers will mention in their documentation which ports they require and use. If you run a Linux or other *NIX system, taking a look at your /etc/services file will help as well. The /etc/services file is a map of the more commonly known (and some not so well-known) ports and which programs or protocols make use of them.
In the end, a well-detailed security policy will aid you in deciding which ports need to be open, as that policy should also cover which services need to be running on any given system. Getting specific with your firewall software or hardware will make things easier in the event that your system is compromised. By allowing only certain ports to be open, regardless of the software running on the system, you can minimize the number of points of entry available to malicious users.
The authors and editors have taken care in preparation of the content contained herein but make no expressed or implied warranty of any kind and assume no responsibility for errors or omissions. No liability is assumed for any damages. Always have a verified backup before making any changes.
Vincent Danen works on the Red Hat Security Response Team and lives in Canada. He has been writing about and developing on Linux for over 10 years and is a veteran Mac user.