8. Appendix

8.1. Servers, Ports, and Packets

Let's take a quick, non-technical look at some networking concepts, and how they can potentially impact our own security. We don't need to know much about networking, but a general idea of how things work is certainly going to help us with firewalls and other related issues.

As you may have noticed Linux is a very network oriented Operating System. Much is done by connecting to "servers" of one type or another -- X servers, font servers, print servers, etc.

Servers provide "services", which provide various capabilities, both to the local system and potentially other remote systems. The same server generally provides both functionalities. Some servers work quietly behind the scenes, and others are more interactive by nature. We may only be aware of a print server when we need to print something, but it is there running, listening, and waiting for connection requests whether we ever use it or not (assuming of course we have it enabled). A typical Linux installation will have many, many types of servers available to it. Default installations often will turn some of these "on".

And even if we are not connected to a real network all the time, we are still "networked" so to speak. Take our friendly local X server for instance. We may tend to think of this as just providing a GUI interface, which is only true to a point. It does this by "serving" to client applications, and thus is truly a server. But X Windows is also capable of serving remote clients over a network -- even large networks like the Internet. Though we probably don't really want to be doing this ;-)

And yes, if you are not running a firewall or have not taken other precautions, and are connected to the Internet, it is quite possible that someone -- anyone -- could connect to your X server. X11 "listens" on TCP "port" 6000 by default. This principle applies to most other servers as well -- they can be easily connected to, unless something is done to restrict or prevent connections.

In TCP/IP (Transmission Control Protocol/Internet Protocol) networks like we are talking about with Linux and the Internet, every connected computer has a unique "IP Address". Think of this like a phone number. You have a phone number, and in order to call someone else, you have to know that phone number, and then dial it. The phone numbers have to be unique for the system to work. IP address are generally expressed as "dotted quad" notation, e.g. 152.19.254.81.

On this type of network, servers are said to "listen". This means that they have a "port" opened, and are awaiting incoming connections to that port. Connections may be local, as is typically the case with our X server, or remote -- meaning from another computer "somewhere". So servers "listen" on a specific "port" for incoming connections. Most servers have a default port, such as port 80 for web servers. Or 6000 for X11. See /etc/services for a list of common ports and their associated service.

The "port" is actually just an address in the kernel's networking stack, and is a method that TCP, and other protocols, use to organize connections and the exchange of data between computers. There are total of 65,536 TCP and UDP ports available, though usually only a relatively few of these are used at any one time. These are classified as "privileged", those ports below 1024, and "unprivileged", 1024 and above. Most servers use the privileged ports.

Only one server may listen on, or "bind" to, a port at a time. Though that server may well be able to open multiple connections via that one port. Computers talk to each other via these "port" connections. One computer will open a connection to a "port" on another computer, and thus be able to exchange data via the connection that has been established between their respective ports.

Getting back to the phone analogy, and stretching it a bit, think of calling a large organization with a complex phone system. The organization has many "departments": sales, shipping, billing, receiving, customer service, R&D, etc. Each department has it's own "extension" number. So the shipping department might be extension 21, the sales might be department 80 and so on. The main phone number is the IP Address, and the department's extension is the port in this analogy. The "department's" number is always the same when we call. And generally they can handle many simultaneous incoming calls.

The data itself is contained in "packets", which are small chunks of data, generally 1500 bytes or less each. Packets are used to control and organize the connection, as well as carry data. There are different types of packets. Some are specifically used for controlling the connection, and then some packets carry our data as their payload. If there is a lot of data, it will be broken up into multiple packets which is almost always how it works. The packets will be transmitted one at a time, and then "re-assembled" at the other end. One web page for instance, will take many packets to transmit -- maybe hundreds or even thousands. This all happens very quickly and transparently.

We can see a typical connection between two computers in this one line excerpt from netstat output:


 tcp    30    0 169.254.179.139:1359    18.29.1.67:21      CLOSE_WAIT

 

The interesting part is the IP addresses and ports in the fourth and fifth columns. The port is the number just to the right of the colon. The left side of the colon is the IP address of each computer. The fourth column is the local address, or our end of the connection. In the example, 169.254.179.139 is the IP address assigned by my ISP. It is connected to port 21 (FTP) on 18.29.1.67, which is rpmfind.net. This is just after an FTP download from rpmfind.net. Note that while I am connected to their FTP server on their port 21, the port on my end that is used by my FTP client is 1359. This is a randomly assigned "unprivileged" port, used for my end of the two-way "conversation". The data moves in both directions: me:port#1359 <-> them:port#21. The FTP protocol is actually a little more complicated than this, but we won't delve into the finer points here. The CLOSE_WAIT is the TCP state of the connection at this particular point in time. Eventually the connection will close completely on both ends, and netstat will not show anything for this.

The "unprivileged" port that is used for my end of the connection, is temporary and is not associated with a locally running server. It will be closed by the kernel when the connection is terminated. This is quite different than the ports that are kept open by "listening" servers, which are permanent and remain "open" even after a remote connection is terminated.

So to summarize using the above example, we have client (me) connecting to a server (rpmfind.net), and the connection is defined and controlled by the respective ports on either end. The data is transmitted and controlled by packets. The server is using a "privileged" port (i.e. a port below number 1024) which stays open listening for connections. The "unprivileged" port used on my end by my client application is temporary, is only opened for the duration of the connection, and only responds to the server's port at the other end of the connection. This type of port is not vulnerable to attacks or break-ins generally speaking. The server's port is vulnerable since it remains open. The administrator of the FTP server will need to take appropriate precautions that his server is secure. Other Internet connections, such as to web servers or mail servers, work similar to the above example, though the server ports are different. SMTP mail servers use port 25, and web servers typically use port 80. See the Ports section for other commonly used ports and services.

One more point on ports: ports are only accessible if there is something listening on that port. No one can force a port open if there is no service or daemon listening there, ready to handle incoming connection requests. A closed port is a totally safe port.

And a final point on the distinction between clients and servers. The example above did not have a telnet or ftp server in the LISTENER section in the netstat example above. In other words, no such servers were running locally. You do not need to run a telnet or ftp server daemon in order to connect to somebody else's telnet or ftp server. These are only for providing these services to others that would be making connections to you. Which you don't really want to be doing in most cases. This in no way effects the ability to use telnet and ftp client software.

8.2. Common Ports

A quick run down of some commonly seen and used ports, with the commonly associated service name, and risk factor. All have some risk. It is just that some have historically had more exploits than others. That is how they are evaluated below, and not necessarily to be interpreted as whether any given service is safe or not.

1-19, assorted protocols, many of which are antiquated, and probably none of which are needed on a modern system. If you don't know what any of these are, then you definitely don't need them. The echo service (port 7) should not be confused with the common ping program. Leave all these off.

20 - FTP-DATA. "Active" FTP connections use two ports: 21 is the control port, and 20 is where the data comes through. Passive FTP does not use port 20 at all. Low risk, but see below.

21 - FTP server port, aka File Transfer Protocol. A well entrenched protocol for transferring files between systems. Very high risk, and maybe the number one crack target.

22 - SSH (Secure Shell), or sometimes PCAnywhere. Low to moderate risk (yes there are exploits even against so called "secure" services).

23 - Telnet server. For LAN use only. Use ssh instead in non-secure environments. Moderate risk.

25 - SMTP, Simple Mail Transfer Protocol, or mail server port, used for sending outgoing mail, and transferring mail from one place to another. Moderate risk. This has had a bad history of exploits, but has improved lately.

37 - Time service. This is the built-in inetd time service. Low risk. For LAN use only.

53 - DNS, or Domain Name Server port. Name servers listen on this port, and answer queries for resolving host names to IP addresses. High Risk.

67 (UDP) - BOOTP, or DHCP, server port. Low risk. If using DHCP on your LAN, this does not need to be exposed to the Internet.

68 (UDP) - BOOTP, or DHCP, client port. Low risk.

69 - tftp, or Trivial File Transfer Protocol. Extremely insecure. LAN only, if really, really needed.

79 - Finger, used to provide information about the system, and logged in users. Low risk as a crack target, but gives out way too much information and should not be run.

80 - WWW or HTTP standard web server port. The most commonly used service on the Internet. Low risk.

98 - Linuxconf web access administrative port. LAN only, if really needed at all.

110 - POP3, aka Post Office Protocol, mail server port. POP mail is mail that the user retrieves from a remote system. Low risk.

111 - sunrpc (Sun Remote Procedure Call), or portmapper port. Used by NFS (Network File System), NIS (Network Information Service), and various related services. Sounds dangerous and is high risk. LAN use only. A favorite crack target.

113 - identd, or auth, server port. Used, and sometimes required, by some older style services (like SMTP and IRC) to validate the connection. Probably not needed in most cases. Low risk, but could give an attacker too much information about your system.

119 -- nntp or news server port. Low risk.

123 - Network Time Protocol for synchronizing with time servers where a high degree of accuracy is required. Low risk, but probably not required for most users. rdate makes an easier and more secure way of updating the system clock. And then inetd's built in time service for synchronizing LAN systems is another option.

137-139 - NetBios (SMB) services. Mostly a Windows thing. Low risk on Linux, but LAN use only. 137 is a very commonly seen port attempt. A rather obnoxious protocol from Redmond that generates a lot of "noise", much of which is harmless.

143 - IMAP, Interim Mail Access Protocol. Another mail retrieval protocol. Low to moderate risk.

161 - SNMP, Simple Network Management Protocol. More commonly used in routers and switches to monitor statistics and vital signs. Not needed for most of us, and low risk.

177 - XDMCP, the X Display Management Control Protocol for remote connections to X servers. Low risk, but LAN only is recommended.

443 - HTTPS, a secure HTTP (WWW) protocol in fairly wide use. Low risk.

465 - SMTP over SSL, secure mail server protocol. Low risk.

512 (TCP) - exec is how it shows in netstat. Actually the proper name is rexec, for Remote Execution. Sounds dangerous, and is. High risk, LAN only if at all.

512 (UDP) - biff, a mail notification protocol. Low risk, LAN only.

513 - login, actually rlogin, aka Remote Login. No relation to the standard /bin/login that we use every time we log in. Sounds dangerous, and is. High risk, and LAN only if really needed.

514 (TCP) - shell is the nickname, and how netstat shows it. Actually, rsh is the application for "Remote Shell". Like all the "r" commands, this is a throw back to kindler, gentler times. Very insecure, so high risk, and LAN only usage, if at all.

514 (UDP) - syslog daemon port, only used for remote logging purposes. The average user does not need this. Probably low risk, but definitely LAN only if really required.

515 - lp or print server port. High risk, and LAN only of course. Someone on the other side of the world does not want to use your printer for it's intended purpose!

587 - MSA, or "submission", the Mail Submission Agent protocol. A new mail handling protocol supported by most MTA's (mail servers). Low risk.

631 - the CUPS (print daemon) web management port. LAN only, low risk.

635 - mountd, part of NFS. LAN use only.

901 - SWAT, Samba Web Administration Tool port. LAN only.

993 - IMAP over SSL, secure IMAP mail service. Very low risk.

995 - POP over SSL, secure POP mail service. Very low risk.

1024 - This is the first "unprivileged" port, which is dynamically assigned by the kernel to whatever application requests it. This can be almost anything. Ditto for ports just above this.

1080 - Socks Proxy server. A favorite crack target.

1243 - SubSeven Trojan. Windows only problem.

1433 - MS SQL server port. A sometimes target. N/A on Linux.

2049 - nfsd, Network File Service Daemon port. High risk, and LAN usage only is recommended.

3128 - Squid proxy server port. Low risk, but for most should be LAN only.

3306 - MySQL server port. Low risk, but for most should be LAN only.

5432 - PostgreSQL server port. LAN only, relatively low risk.

5631 (TCP), 5632 (UDP) - PCAnywhere ports. Windows only. PCAnywhere can be quite "noisy", and broadcast wide address ranges.

6000 - X11 TCP port for remote connections. Low to moderate risk, but again, this should be LAN only. Actually, this can include ports 6000-6009 since X can support multiple displays and each display would have its own port. ssh's X11Forwarding will start using ports at 6010.

6346 - gnutella.

6667 - ircd, Internet Relay Chat Daemon.

6699 - napster.

7100-7101 - Some font servers use these ports. Low risk, but LAN only.

8000 and 8080 - common web cache and proxy server ports. LAN only.

10000 - webmin, a web based system administration utility. Low risk at this point.

27374 - SubSeven, a commonly probed for Windows only Trojan. Also, 1243.

31337 - Back Orifice, another commonly probed for Windows only Trojan.

More services and corresponding port numbers can be found in /etc/services. Also, the "official" list is http://www.iana.org/assignments/port-numbers.

A great analysis of what probes to these and other ports might mean from Robert Graham: http://www.linuxsecurity.com/resource_files/firewalls/firewall-seen.html. A very good reference.

Another point here, these are the standard port designations. There is no law that says any service has to run on a specific port. Usually they do, but certainly they don't always have to.

Just a reminder that when you see these types of ports in your firewall logs, it is not anything to go off the deep end about. Not if you have followed Steps 1-3 above, and verified your firewall works. You are fairly safe. Much of this traffic may be "stray bullets" too -- Internet background noise, misconfigured clients or routers, noisy Windows stuff, etc.

8.3. Netstat Tutorial

8.3.1. Overview

netstat is a very useful utility for viewing the current state of your network status -- what servers are listening for incoming connections, what interfaces they listen on, who is connected to us, who we are connect to, and so on. Take a look at the man page for some of the many command line options. We'll just use a relative few options here.

As an example, let's check all currently listening servers and active connections for both TCP and UDP on our hypothetical host, bigcat. bigcat is a home desktop installation, with a DSL Internet connection in this example. bigcat has two ethernet cards: one for the external connection to the ISP, and one for a small LAN with an address of 192.168.1.1.

   
$ netstat -tua
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 *:printer               *:*                     LISTEN     
tcp        0      0 bigcat:8000             *:*                     LISTEN     
tcp        0      0 *:time                  *:*                     LISTEN     
tcp        0      0 *:x11                   *:*                     LISTEN
tcp        0      0 *:http                  *:*                     LISTEN     
tcp        0      0 bigcat:domain           *:*                     LISTEN     
tcp        0      0 bigcat:domain           *:*                     LISTEN     
tcp        0      0 *:ssh                   *:*                     LISTEN     
tcp        0      0 *:631                   *:*                     LISTEN     
tcp        0      0 *:smtp                  *:*                     LISTEN     
tcp        0      1 dsl-78-199-139.s:1174   64.152.100.93:nntp      SYN_SENT   
tcp        0      1 dsl-78-199-139.s:1175   64.152.100.93:nntp      SYN_SENT   
tcp        0      1 dsl-78-199-139.s:1173   64.152.100.93:nntp      SYN_SENT   
tcp        0      0 dsl-78-199-139.s:1172   207.153.203.114:http    ESTABLISHED
tcp        1      0 dsl-78-199-139.s:1199   www.xodiax.com:http     CLOSE_WAIT 
tcp        0      0 dsl-78-199-139.sd:http  63.236.92.144:34197     TIME_WAIT
tcp      400      0 bigcat:1152             bigcat:8000             CLOSE_WAIT 
tcp     6648      0 bigcat:1162             bigcat:8000             CLOSE_WAIT 
tcp      553      0 bigcat:1164             bigcat:8000             CLOSE_WAIT 
udp        0      0 *:32768                 *:*                                
udp        0      0 bigcat:domain           *:*                                
udp        0      0 bigcat:domain           *:*                                
udp        0      0 *:631                   *:*                               

 

This output probably looks very different from what you get on your own system. Notice the distinction between "Local Address" and "Foreign Address", and how each includes a corresponding port number (or service name if available) after the colon. "Local Address" is our end of the connection. The first group with LISTEN in the far right hand column are services that are running on this system. These are servers that are running in the background on bigcat, and "listen" for incoming connections. So they have a port opened, and this is where they "listen". These connections might come from the local system (i.e. bigcat itself), or remote systems. This is very important information to have! The others just below this are connections that have been established from this system to other systems. The respective connections are in varying states as indicated by the key words in the last column. Those with no key word in the last column at the end are servers responding to UDP connections. UDP is a different protocol from TCP altogether, but is used for some types of low priority network traffic.

Now, the same thing with the "-n" flag to suppress converting to "names" so we can actually see the port numbers:


$ netstat -taun
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address      State
tcp        0      0 0.0.0.0:515             0.0.0.0:*            LISTEN     
tcp        0      0 127.0.0.1:8000          0.0.0.0:*            LISTEN     
tcp        0      0 0.0.0.0:37              0.0.0.0:*            LISTEN     
tcp        0      0 0.0.0.0:6000            0.0.0.0:*            LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*            LISTEN     
tcp        0      0 192.168.1.1:53          0.0.0.0:*            LISTEN     
tcp        0      0 127.0.0.1:53            0.0.0.0:*            LISTEN     
tcp        0      0 0.0.0.0:22              0.0.0.0:*            LISTEN     
tcp        0      0 0.0.0.0:631             0.0.0.0:*            LISTEN     
tcp        0      0 0.0.0.0:25              0.0.0.0:*            LISTEN     
tcp        0      1 169.254.179.139:1174    64.152.100.93:119    SYN_SENT   
tcp        0      1 169.254.179.139:1175    64.152.100.93:119    SYN_SENT   
tcp        0      1 169.254.179.139:1173    64.152.100.93:119    SYN_SENT   
tcp        0      0 169.254.179.139:1172    207.153.203.114:80   ESTABLISHED
tcp        1      0 169.254.179.139:1199    216.26.129.136:80    CLOSE_WAIT 
tcp        0      0 169.254.179.139:80      63.236.92.144:34197  TIME_WAIT 
tcp      400      0 127.0.0.1:1152          127.0.0.1:8000       CLOSE_WAIT 
tcp     6648      0 127.0.0.1:1162          127.0.0.1:8000       CLOSE_WAIT 
tcp      553      0 127.0.0.1:1164          127.0.0.1:8000       CLOSE_WAIT 
udp        0      0 0.0.0.0:32768           0.0.0.0:*                    
udp        0      0 192.168.1.1:53          0.0.0.0:*                      
udp        0      0 127.0.0.1:53            0.0.0.0:*                     
udp        0      0 0.0.0.0:631             0.0.0.0:*          
   
 

Let's look at the first few lines of this in detail. On line one,


 tcp        0      0 0.0.0.0:515            0.0.0.0:*          LISTEN     

 

"Local Address" is 0.0.0.0, meaning "all" interfaces that are available. The local port is 515, or the standard print server port, usually owned by the lpd daemon. You can find a listing of common service names and corresponding ports in the file /etc/services.

The fact that it is listening on all interfaces is significant. In this case, that would be lo (localhost), eth0, and eth1. Printer connections could conceivably be made over any of these interfaces. Should a user on this system bring up a PPP connection, then the print daemon would be listening on that interface (ppp0) as well. The "Foreign Address" is also 0.0.0.0, meaning from "anywhere".

It is also worth noting here, that even though this server is telling the kernel to listen on all interfaces, the netstat output does not reflect whether there may be a firewall in place that may be filtering incoming connections. We just can't tell that at this point. Obviously, for certain servers, this is very desirable. Nobody outside your own LAN has any reason whatsoever to connect to your print server port for instance.

Line two is a little different:


 tcp        0      0 127.0.0.1:8000         0.0.0.0:*          LISTEN     

 

Notice the "Local Address" this time is localhost's address of 127.0.0.1. This is very significant as only connections local to this machine will be accepted. So only bigcat can connect to bigcat's TCP port 8000. The security implications should be obvious. Not all servers have configuration options that allow this kind of restriction, but it is a very useful feature for those that do. Port 8000 in this example, is owned by the web proxy Junkbuster.

With the next three entries, we are back to listening on all available interfaces:


 tcp        0      0 0.0.0.0:37             0.0.0.0:*           LISTEN     
 tcp        0      0 0.0.0.0:6000           0.0.0.0:*           LISTEN
 tcp        0      0 0.0.0.0:80             0.0.0.0:*           LISTEN     

 

Looking at /etc/services, we can tell that port 37 is a "time" service, which is a time server. 6000 is X11, and 80 is the standard port for HTTP servers like Apache. There is nothing really unusual here as these are all readily available services on Linux.

The first two above are definitely not the kind of services you'd want just anyone to connect to. These should be firewalled so that all outside connections are refused. Again, we can't tell from this output whether any firewall is in place, much less how effectively implemented it may be.

The web server on port 80 is not a huge security risk by itself. HTTP is a protocol that is often open to all comers. For instance, if we wanted to host our own home page, Apache can certainly do this for us. It is also possible to firewall this off, so that it is for use only to our LAN clients as part of an Intranet. Obviously too, if you do not have a good justification for running a web server, then it should be disabled completely.

The next two lines are interesting:


 tcp        0      0 192.168.1.1:53         0.0.0.0:*           LISTEN     
 tcp        0      0 127.0.0.1:53           0.0.0.0:*           LISTEN     

 

Again notice the "Local Address" is not 0.0.0.0. This is good! The port this time is 53, or the DNS port used by nameserver daemons like named. But we see the nameserver daemon is only listening on the lo interface (localhost), and the interface that connects bigcat to the LAN. So the kernel only allows connections from localhost, and the LAN. There will be no port 53 available to outside connections at all. This is a good example of how individual applications can sometimes be securely configured. In this case, we are probably looking at a caching DNS server since a real nameserver that is responsible for handling DNS queries would have to have port 53 open to the world. This is a security risk and requires special handling.

The last three LISTENER entries:


 tcp        0      0 0.0.0.0:22             0.0.0.0:*           LISTEN     
 tcp        0      0 0.0.0.0:631            0.0.0.0:*           LISTEN     
 tcp        0      0 0.0.0.0:25             0.0.0.0:*           LISTEN     

 

These are back to listening on all available interfaces. Port 22 is sshd, the Secure Shell server daemon. This is a good sign! Notice that the service for port 631 does not have a service name if we look at the output in the first example. This might be a clue that something unusual is going on here. (See the next section for the answer to this riddle.) And lastly, port 25, the standard port for the SMTP mail daemon. Most Linux installations probably will have an SMTP daemon running, so this is not necessarily unusual. But is it necessary?

The next grouping is established connections. For our purposes the state of the connection as indicated by the last column is not so important. This is well explained in the man page.


 tcp        0      1 169.254.179.139:1174    64.152.100.93:119    SYN_SENT   
 tcp        0      1 169.254.179.139:1175    64.152.100.93:119    SYN_SENT    
 tcp        0      1 169.254.179.139:1173    64.152.100.93:119    SYN_SENT   
 tcp        0      0 169.254.179.139:1172    207.153.203.114:80   ESTABLISHED
 tcp        1      0 169.254.179.139:1199    216.26.129.136:80    CLOSE_WAIT 
 tcp        0      0 169.254.179.139:80      63.236.92.144:34197  TIME_WAIT 
 tcp      400      0 127.0.0.1:1152          127.0.0.1:8000       CLOSE_WAIT 
 tcp     6648      0 127.0.0.1:1162          127.0.0.1:8000       CLOSE_WAIT 
 tcp      553      0 127.0.0.1:1164          127.0.0.1:8000       CLOSE_WAIT 

 

There are nine total connections here. The first three is our external interface connecting to a remote host on their port 119, the standard NNTP (News) port. There are three connections here to the same news server. Apparently the application is multi-threaded, as it is trying to open multiple connections to the news server. The next two entries are connections to a remote web server as indicated by the port 80 after the colon in the fifth column. Probably a pretty common looking entry for most of us. But the one just after is reversed and has the port 80 in the fourth column, so this is someone that has connected to bigcat's web server via its external, Internet-side interface. The last three entries are all connections from localhost to localhost. So we are connecting to ourselves here. Remembering from above that port 8000 is bigcat's web proxy, this is a web browser that is connected to the locally running proxy. The proxy then will open an external connection of its own, which probably is what is going on with lines four and five.

Since we gave netstat both the -t and -u options, we are getting both the TCP and UDP listening servers. The last few lines are the UDP ones:


 udp        0      0 0.0.0.0:32768          0.0.0.0:*                    
 udp        0      0 192.168.1.1:53         0.0.0.0:*                      
 udp        0      0 127.0.0.1:53           0.0.0.0:*                     
 udp        0      0 0.0.0.0:631            0.0.0.0:*          

 

The last three entries have ports that are familiar from the above discussion. These are servers that are listening for both TCP and UDP connections. Same servers in this case, just using two different protocols. The first one on local port 32768 is new, and does not have a service name available to it in /etc/services. So at first glance this should be suspicious and pique our curiosity. See the next section for the explanation.

Can we draw any conclusions from this hypothetical situation? For the most part, these look to be pretty normal looking network services and connections for Linux. There does not seem to be an unduly high number of servers running here, but that by itself does not mean much since we don't know if all these servers are really required or not. We know that netstat can not tell us if any of these are effectively firewalled, so there is no way to say how secure all this might be. We also don't really know if all the listening services are really required by the owner here. That is something that varies widely from installation to installation. Does bigcat even have a printer attached for instance? Presumably it does, or this is a completely unnecessary risk.

8.3.2. Port and Process Owners

We've learned a lot about what is going on with bigcat's networking from the above section. But suppose we see something we don't recognize and want to know what started that particular service? Or we want to stop a particular server and it is not obvious from the above output?

The -p option should give us the process's PID and the program name that started the process in the last column. Let's look at the TCP servers again (with first three columns cropped for spacing). We'll have to run this as root to get all the available information:


# netstat -tap
Active Internet connections (servers and established)
  Local Address           Foreign Address      State       PID/Program name
  *:printer               *:*                  LISTEN       988/inetd
  bigcat:8000             *:*                  LISTEN       1064/junkbuster
  *:time                  *:*                  LISTEN       988/inetd
  *:x11                   *:*                  LISTEN       1462/X
  *:http                  *:*                  LISTEN       1078/httpd
  bigcat:domain           *:*                  LISTEN       956/named
  bigcat:domain           *:*                  LISTEN       956/named
  *:ssh                   *:*                  LISTEN       972/sshd
  *:631                   *:*                  LISTEN       1315/cupsd
  *:smtp                  *:*                  LISTEN       1051/master

 

Some of these we already know about. But we see now that the printer daemon on port 515 is being started via inetd with a PID of "988". inetd is a special situation. inetd is often called the "super server", since it's main role is to spawn sub-services. xinetd replaces inetd as of Red Hat 7.0. If we look at the first line, inetd is listening on port 515 for printer services. If a connection comes for this port, inetd intercepts it, and then will spawn the appropriate daemon, i.e. the print daemon in this case. The configuration of how inetd handles this is typically done in /etc/inetd.conf. This should tell us that if we want to stop an inetd controlled server on a permanent basis, then we will have to dig into the inetd (or perhaps xinetd) configuration. Also the time service above is started via inetd as well. This should also tell us that these two services can be further protected by tcpwrappers (discussed in Step 3 above). This is one benefit of using inetd to control certain system services.

We weren't sure about the service on port 631 above since it did not have a standard service name, which means it is something maybe unusual or off the beaten path. Now we see it is owned by cupsd (not included with Red Hat by the way), which is one of several print daemons available under Linux. This happens to be the web interface for controlling the printer service. Something cupsd does that is indeed a little different than other print servers.

The last entry above is the SMTP mail server on bigcat. Often, this is sendmail. But not in this case. The command is "master", which may not ring any bells. Armed with the program name we could go searching the filesystem with tools like the locate or find commands. After we found it, we could then probably discern what package it belonged to. But with the PID available now, we can look at ps output, and see if that helps us any:


 $ /bin/ps ax |grep 1051 |grep -v grep
  1051 ?        S        0:24 /usr/libexec/postfix/master

 

We took a shortcut here by combining ps with grep. It looks like that this file belongs to postfix, which is indeed a mail server package comparable to sendmail ( and is included with Powertools, not the base distribution).

Running ps with the --forest flag (-f for short) can be helpful in determining what processes are parent or child process or another process. An edited example:


 $ /bin/ps -axf
  956 ?        S      0:00 named -u named
  957 ?        S      0:00  \_ named -u named
  958 ?        S      0:46      \_ named -u named
  959 ?        S      0:47      \_ named -u named
  960 ?        S      0:00      \_ named -u named
  961 ?        S      0:11      \_ named -u named
 1051 ?        S      0:30 /usr/libexec/postfix/master
 1703 ?        S      0:00  \_ tlsmgr -l -t fifo -u -c
 1704 ?        S      0:00  \_ qmgr -l -t fifo -u -c
 1955 ?        S      0:00  \_ pickup -l -t fifo -c
 1863 ?        S      0:00  \_ trivial-rewrite -n rewrite -t unix -u -c
 2043 ?        S      0:00  \_ cleanup -t unix -u -c
 2049 ?        S      0:00  \_ local -t unix
 2062 ?        S      0:00  \_ smtpd -n smtp -t inet -u -c

 

A couple of things to note here. We have two by now familiar daemons here: named and postfix (smtpd). Both are spawning sub-processes. In the case of named, what we are seeing is threads, various sub-processes that it always spawns. Postfix is also spawning sub-processes, but not as "threads". Each sub-process has its own specific task. It is worth noting that child processes are dependent on the parent process. So killing the parent PID, will in turn kill all child processes.

If all this has not shed any light, we might also try locate:


 $ locate /master
 /etc/postfix/master.cf
 /var/spool/postfix/pid/master.pid
 /usr/libexec/postfix/master
 /usr/share/vim/syntax/master.vim
 /usr/share/vim/vim60z/syntax/master.vim
 /usr/share/doc/postfix-20010202/html/master.8.html
 /usr/share/doc/postfix-20010202/master.cf
 /usr/share/man/man8/master.8.gz

 

find is perhaps the most flexible file finding utility, but doesn't use a database the way locate does, so is much slower:


 $ find / -name master         
 /usr/libexec/postfix/master

 

If lsof is installed, it is another command that is useful for finding who owns processes or ports:


 # lsof -i :631       
 COMMAND  PID  USER    FD   TYPE DEVICE SIZE NODE NAME
 cupsd   1315  root    0u   IPv4   3734       TCP *:631 (LISTEN)

 

This is again telling us that the cupsd print daemon is the owner of port 631. Just a different way of getting at it. Yet one more way to get at this is with fuser, which should be installed:


 # fuser -v -n tcp 631

                      USER        PID  ACCESS  COMMAND
 631/tcp              root       1315  f....   cupsd

 

See the man pages for fuser and lsof command syntax.

Another place to look for where a service is started, is in the init.d directory, where the actual init scripts live. Something like ls -l /etc/rc.d/init.d/, should give us a list of these. Often the script name itself gives a hint as to which service(s) it starts, though it may not necessarily exactly match the "Program Name" as provided by netstat. Or we can use grep to search inside files and match a search pattern. Need to find where rpc.statd is being started, and we don't see a script by this name?


 # grep rpc.statd /etc/init.d/*
 /etc/init.d/nfslock: [ -x /sbin/rpc.statd ] || exit 0
 /etc/init.d/nfslock:    daemon rpc.statd
 /etc/init.d/nfslock:    killproc rpc.statd
 /etc/init.d/nfslock:    status rpc.statd
 /etc/init.d/nfslock:    /sbin/pidof rpc.statd >/dev/null 2>&1; STATD="$?"

 

We didn't really need all that information, but at least we see now exactly which script is starting it. Remember too that not all services are started this way. Some may be started via inetd, or xinetd.

The /proc filesystem also keeps everything we want to know about processes that are running. We can query this to find out more information about each process. Do you need to know the full path of the command that started a process?


 # ls -l /proc/1315/exe
 lrwxrwxrwx  1 root  root   0 July 4 19:41 /proc/1315/exe -> /usr/sbin/cupsd

 

Finally, we had a loose end or two in the UDP listening services. Remember we had a strange looking port number 32768, that also had no service name associated with it:


 # netstat -aup
 Active Internet connections (servers and established)
  Local Address           Foreign Address         State       PID/Program name   
   *:32768                 *:*                                 956/named           
   bigcat:domain           *:*                                 956/named           
   bigcat:domain           *:*                                 956/named           
   *:631                   *:*                                 1315/cupsd          

 

Now by including the "PID/Program name" option with the -p flag, we see this also belongs to named, the nameserver daemon. Recent versions of BIND use an unprivileged port for some types of traffic. In this case, this is BIND 9.x. So no real alarms here either. The unprivileged port here is the one named uses to to talk to other nameservers for name and address lookups, and should not be firewalled.

So we found no big surprises in this hypothetical situation.

If all else fails, and you can't find a process owner for an open port, suspect that it may be an RPC (Remote Procedure Call) service of some kind. These use randomly assigned ports without any seeming logic or consistency, and are typically controlled by the portmap daemon. In some cases, these may not reveal the process owner to netstat or lsof. Try stopping portmap, and then see if the mystery service goes away. Or you can use rpcinfo -p localhost to see what RPC services may be running (portmap must be running for this to work).

Warning

If you suspect you have been broken into, do not trust netstat or ps output. There is a good chance that they, and other system components, has been tampered with in such a way that the output is not reliable.

8.4. Attacks and Threats

In this section, we will take a quick look at some of the common threats and techniques that are out there, and attempt to put them into some perspective.

The corporate world, government agencies and high profile Internet sites have to be concerned with a much more diverse and challenging set of threats than the typical home desktop user. There are many reasons someone may want to break in to someone else's computer. It may be just for kicks, or any number of malicious reasons. They may just want a base from which to attack someone else. This is a very common motivation.

The most common "attack" for most of us is from already compromised systems. The Internet is littered with computers that have been broken into, and are now doing their master's bidding blindly, in zombie-like fashion. They are programmed to scan massively large address ranges, probing each individual IP address as they go. Looking for one or more open ports, and then probing for known weaknesses if they get the chance. Very impersonal. Very methodical. And very effective. We are all in the path of such robotic scans. All because those responsible for these systems fail to do what you are doing now - taking steps to protect their system(s), and avoid being r00ted.

These scans do not look at login banners that may be presented on connection. It will do little good to change your /etc/issue.net to pretend that you are running some obscure operating system. If they find something listening, they will try all of the exploits appropriate to that port, without regard to any indications your system may give. If it works, they are in -- if not, they will move on.

8.4.1. Port Scans and Probes

First, let's define "scan" and "probe" since these terms come up quite a bit. A "probe" implies testing if a given port is open or closed, and possibly what might be listening on that port. A "scan" implies either "probing" multiple ports on one or more systems. Or individual ports on multiple systems. So you might "scan" all ports on your own system for instance. Or a cracker might "scan" the 216.78.*.* address range to see who has port 111 open.

Black hats can use scan and probe information to know what services are running on a given system, and then they might know what exploits to try. They may even be able to tell what Operating System is running, and even kernel version, and thus get even more information. "Worms", on the other hand, are automated and scan blindly, generally just looking for open ports, and then a susceptible victim. They are not trying to "learn" anything, the way a cracker might.

The distinction between "scan" and "probe"is often blurred. Both can used in good ways, or in bad ways, depending on who is doing it, and why. You might ask a friend to scan you, for instance, to see how well your firewall is working. This is a legitimate use of scanning tools such as nmap. But what if someone you don't know does this? What is their intent? If it's your ISP, they may be trying to enforce their Terms of Service Agreement. Or maybe, it is someone just playing, and seeing who is "out there". But more than likely it is someone or something with not such good intentions.

Full range port scans (meaning probing of many ports on the same machine) seem to be a not so common threat for home based networks. But certainly, scanning individual ports across numerous systems is a very, very common occurrence.

8.4.3. Worms and Zombies

A "worm" is a self replicating exploit. It infects a system, then attempts to spread itself typically via the same vulnerability. Various "worms" are weaving their way through the entire Internet address space constantly, spreading themselves as they go.

But somewhere behind the zombie, there is a controller. Someone launched the worm, and they will be informed after a successful intrusion. It is then up to them how the system will be used.

Many of these are Linux systems, looking for other Linux systems to "infect" via a number of exploits. But most Operating Systems share in this threat. Once a vulnerable system is found, the actual entry and take over is quick, and may be difficult to detect after the fact. The first thing an intruder (whether human or "worm") will do is attempt to cover their tracks. A "rootkit" is downloaded and installed. This trend has been exacerbated by the growing popularity of cable modems and DSL. The number of full time Internet connections is growing rapidly, and this makes fertile ground for such exploits since often these aren't as well secured as larger sites.

While this may sound ominous, a few simple precautions can effectively deter this type of attack. With so many easy victims out there, why waste much effort breaking into your system? There is no incentive to really try very hard. Just scan, look, try, move on if unsuccessful. There is always more IPs to be scanned. If your firewall is effectively bouncing this kind of thing, it is no threat to you at all. Take comfort in that, and don't over re-act.

It is worth noting, that these worms cannot "force" their way in. They need an open and accessible port, and a known vulnerability. If you remember the "Iptables Weekly Log Summary" in the opening section above, many of those may have all been the result of this type of scan. If you've followed the steps in this HOWTO, you should be reasonably safe here. This one is easy enough to deflect.

8.5. Links

Some references for further reading are listed below. Not listed is your distribution's site, security page or ftp download site. You will have to find these on your own. Then you should bookmark them!

8.6. Editing Text Files

By Bill Staehle

All the world is a file.

There are a great many types of files, but I'm going to stretch it here, and class them into two really broad families:



 Text files are just that.
 Binary files are not.

    

Binary files are meant to be read by machines, text files can be easily edited, and are generally read by people. But text files can be (and frequently are) read by machines. Examples of this would be configuration files, and scripts.

There are a number of different text editors available in *nix. A few are found on every system. That would be '/bin/ed' and '/bin/vi'. 'vi' is almost always a clone such as 'vim' due to license problems. The problem with 'vi' and 'ed' is that they are terribly user unfriendly. Another common editor that is not always installed by default is 'emacs'. It has a lot more features and capability, and is not easy to learn either.

As to 'user friendly' editors, 'mcedit' and 'pico' are good choices to start with. These are often much easier for those new to *nix.

The first things to learn are how to exit an editing session, how to save changes to the file, and then how to avoid breaking long lines that should not be broken (wrapped).

The 'vi' editor

'vi' is one of the most common text editors in the Unix world, and it's nearly always found on any *nix system. Actually, due to license problems, the '/bin/vi' on a Linux system is always a 'clone', such as 'elvis', 'nvi', or 'vim' (there are others). These clones can act exactly like the original 'vi', but usually have additional features that make it slightly less impossible to use.

So, if it's so terrible, why learn about it? Two reasons. First, as noted, it's almost guaranteed to be installed, and other (more user friendly) editors may not be installed by default. Second, many of the 'commands' work in other applications (such as the pager 'less' which is also used to view man pages). In 'less', accidentally pressing the 'v' key starts 'vi' in most installations.

'vi' has two modes. The first is 'command mode', and keystrokes are interpreted as commands. The other mode is 'insert' mode, where nearly all keystrokes are interpreted as text to be inserted.

==> Emergency exit from 'vi' 1. press the <esc> key up to three times, until the computer beeps, or the screen flashes. 2. press the keys :q! <Enter>

That is: colon, the letter Q, and then the exclamation point, followed by the Enter key.

'vi' commands are as follows. All of these are in 'command' mode:


a    Enter insertion mode after the cursor.
A    Enter insertion mode at the end of the current line.
i    Enter insertion mode before the cursor.
o    Enter insertion mode opening a new line BELOW current line.
O    Enter insertion mode opening a new line ABOVE current line.
h    move cursor left one character.
l    move cursor right one character.
j    move cursor down one line.
k    move cursor up one line.
/mumble  move cursor forward to next occurrence of 'mumble' in 
         the text
?mumble  move cursor backward to next occurrence of 'mumble' 
         in the text
n    repeat last search (? or / without 'mumble' to search for 
     will do the same thing)
u    undo last change made

^B   Scroll back one window.
^F   Scroll forward one window.
^U   Scroll up one half window.
^D   Scroll down one half window.

:w   Write to file.
:wq  Write to file, and quit.
:q   quit.
:q!  Quit without saving.

<esc>   Leave insertion mode.
  
    

NOTE: The four 'arrow' keys almost always work in 'command' or 'insert' mode.

The 'ed' editor.

The 'ed' editor is a line editor. Other than the fact that it is virtually guaranteed to be on any *nix computer, it has no socially redeeming features, although some applications may need it. A _lot_ of things have been offered to replace this 'thing' from 1975.

==> Emergency exit from 'ed'

1. type a period on a line by itself, and press <Enter> This gets you to the command mode or prints a line of text if you were in command mode. 2. type q and press <Enter>. If there were no changes to the file, this action quits ed. If you then see a '?' this means that the file had changed, and 'ed' is asking if you want to save the changes. Press q and <Enter> a second time to confirm that you want out.

The 'pico' editor.

'pico' is a part of the Pine mail/news package from the University of Washington (state, USA). It is a very friendly editor, with one minor failing. It silently inserts a line feed character and wraps the line when it exceeds (generally) 74 characters. While this is fine while creating mail, news articles, and text notes, it is often fatal when editing system files. The solution to this problem is simple. Call the program with the -w option, like this:

pico -w file_2_edit

Pico is so user friendly, no further instructions are needed. It _should_ be obvious (look at the bottom of the screen for commands). There is an extensive help function. Pico is available with nearly all distributions, although it _may_ not be installed by default.

==> Emergency exit from 'pico'

Press and hold the <Ctrl> key, and press the letter x. If no changes had been made to the file, this will quit pico. If changes had been made, it will ask if you want to save the changes. Pressing n will then exit.

The 'mcedit' editor.

'mcedit' is part of the Midnight Commander shell program, a full featured visual shell for Unix-like systems. It can be accessed directly from the command line ( mcedit file_2_edit ) or as part of 'mc' (use the arrow keys to highlight the file to be edited, then press the F4 key).

mcedit is probably the most intuitive editor available, and comes with extensive help. "commands" are accessed through the F* keys. Midnight Commander is available with nearly all distributions, although it _may_ not be installed by default.

==> Emergency exit from 'mcedit'

Press the F10 key. If no changes have been made to the file, this will quit mcedit. If changes had been made, it will ask if you want to Cancel this action. Pressing n will then exit.

8.7. nmap

Let's look at a few quick examples of what nmap scans look like. The intent here is to show how to use nmap to verify our firewalling, and system integrity. nmap has other uses that we don't need to get into. Do NOT use nmap on systems other than your own, unless you have permission from the owner, and you know it is not a violation of anyone's Terms of Service. This kind of thing will be taken as hostile by most people.

As mentioned previously, nmap is a sophisticated port scanning tool. It tries to see if a host is "there", and what ports might be open. Barring that, what states those ports might be in. nmap has a complex command line and can do many types of "scans". See the man page for all the nitty gritty.

A couple of words of warning first. If using portsentry, turn it off. It will drop the route to wherever the scan is coming from. You might want to turn off any logging also, or at least be aware that you might get copious logs if doing multiple scans.

A simple, default scan of "localhost":


 # nmap localhost

 Starting nmap V. 2.53 by fyodor@insecure.org ( www.insecure.org/nmap/ )
 Interesting ports on bigcat (127.0.0.1):
 (The 1507 ports scanned but not shown below are in state: closed)

 Port       State       Service
 22/tcp     open        ssh                     
 25/tcp     open        smtp                    
 37/tcp     open        time                    
 53/tcp     open        domain                  
 80/tcp     open        http                    
 3000/tcp   open        ppp                     

 Nmap run completed -- 1 IP address (1 host up) scanned in 2 seconds

 

If you've read most of this document, you should be familiar with these services by now. These are some of the same ports we've seen in other examples. Some things to note on this scan: it only did 1500+ "interesting" ports -- not all ports. This can be configured differently if more is desirable (see man page). It only did TCP ports too. Again, configurable. It only picks up "listening" services, unlike netstat that shows all open ports -- listening or otherwise. Note the last "open" port here is 3000 is identified as "PPP". Wrong! That is just an educated guess by nmap based on what is contained in /etc/services for this port number. Actually in this case it is ntop (a network traffic monitor). Take the service names with a grain of salt. There is no way for nmap to really know what is on that port. Matching port numbers with service names can at times be risky. Many do have standard ports, but there is nothing to say they have to use the commonly associated port numbers.

Notice that in all our netstat examples, we had two classes of open ports: listening servers, and then established connections that we initiated to other remote hosts (e.g. a web server somewhere). nmap only sees the first group -- the listening servers! The other ports connecting us to remote servers are not visible, and thus not vulnerable. These ports are "private" to that single connection, and will be closed when the connection is terminated.

So we have open and closed ports here. Simple enough, and gives a pretty good idea what is running on bigcat -- but not necessarily what we look like to the outside world since this was done from localhost, and wouldn't reflect any firewalling or other access control mechanisms.

Let's do a little more intensive scan. Let's check all ports -- TCP and UDP.


 # nmap -sT -sU -p 1-65535 localhost

 Starting nmap V. 2.53 by fyodor@insecure.org ( www.insecure.org/nmap/ )
 Interesting ports on bigcat (127.0.0.1):
 (The 131050 ports scanned but not shown below are in state: closed)

 Port       State       Service
 22/tcp     open        ssh                     
 25/tcp     open        smtp                    
 37/tcp     open        time                    
 53/tcp     open        domain                  
 53/udp     open        domain                  
 80/tcp     open        http                    
 3000/tcp   open        ppp                     
 8000/tcp   open        unknown                 
 32768/udp  open        unknown                 

 Nmap run completed -- 1 IP address (1 host up) scanned in 385 seconds

 

This is more than just "interesting" ports -- it is everything. We picked up a couple of new ones in the process too. We've seen these before with netstat, so we know what they are. That is the Junkbuster web proxy on port 8000/tcp and named on 32768/udp. This scan takes much, much longer, but it is the only way to see all ports.

So now we have a pretty good idea of what is open on bigcat. Since we are scanning localhost from localhost, everything should be visible. We still don't know how the outside world sees us though. Now I'll ssh to another host on the same LAN, and try again.


 # nmap bigcat

 Starting nmap V. 2.53 by fyodor@insecure.org ( www.insecure.org/nmap/ )
 Interesting ports on bigcat (192.168.1.1):
 (The 1520 ports scanned but not shown below are in state: closed)

 Port       State       Service
 22/tcp     open        ssh
 3000/tcp   open        ppp

 Nmap run completed -- 1 IP address (1 host up) scanned in 1 second

 

I confess to tampering with the iptables rules here to make a point. Only two visible ports on this scan. Everything else is "closed". So says nmap. Once again:


 # nmap bigcat

 Starting nmap V. 2.53 by fyodor@insecure.org ( www.insecure.org/nmap/ )
 Note: Host seems down. If it is really up, but blocking our ping probes, try -P0
 
 Nmap run completed -- 1 IP address (0 hosts up) scanned in 30 seconds

 

Oops, I blocked ICMP (ping) while I was at it this time. One more time:


 # nmap -P0 bigcat

 Starting nmap V. 2.53 by fyodor@insecure.org ( www.insecure.org/nmap/ )
 All 1523 scanned ports on bigcat (192.168.1.1) are: filtered
 
 Nmap run completed -- 1 IP address (1 host up) scanned in 1643 seconds

 

That's it. Notice how long that took. Notice ports are now "filtered" instead of "closed". How does nmap know that? Well for one, "closed" means bigcat sent a packet back saying "nothing running here", i.e. port is closed. In this last example, the iptables rules were changed to not allow ICMP (ping), and to "DROP" all incoming packets. In other words, no response at all. A subtle difference since nmap seems to still know there was a host there, even though no response was given. One lesson here, is if you want to slow a scanner down, "DROP" (or "DENY") the packets. This forces a TCP time out for the remote end on each port probe. Anyway, if your scans look like this, that is probably as well as can be expected, and your firewall is doing its job.

A brief note on UDP: nmap can not accurately determine the status of these ports if they are "filtered". You probably will get a false-positive "open" condition. This has to do with UDP being a connectionless protocol. If nmap gets no answer (e.g. due to a "DROP"), it assumes the packets reached the target, and thus the port will be reported as "open". This is "normal" for nmap.

We can play with firewall rules in a LAN set up to try to simulate how the outside world sees us, and if we are smart, and know what we are doing, and don't have a brain fart, we probably will have a pretty good picture. But it is still best to try to find a way to do it from outside if possible. Again, make sure you are not violating any ISP rules of conduct. Do you have a friend on the same ISP?

8.8. Sysctl Options

The "sysctl" options are kernel parameters that can be configured via the /proc filesystem. These can be dynamically adjusted at run-time. Typically these options are off if set to "0", and on if set to "1".

Some of these have security implications, and thus is why we are here ;-) We'll just list the ones we think are relevant. Feel free to cut and paste these into a firewall script, or other file that is run during boot (like /etc/rc.local). Red Hat provides the sysctl command for dynamically adjusting these values (see man page). Or they can permanently be set in /etc/sysctl.conf with your text editor of choice. sysctl is executed during init, and uses these values. You can read up on what these mean in /usr/src/linux/Documentation/sysctl/README and other files in the kernel Documentation directories.

The traditional method:


#!/bin/sh
# 
# Configure kernel sysctl run-time options. 
#
###################################################################

# Anti-spoofing blocks
for i in /proc/sys/net/ipv4/conf/*/rp_filter; 
do
 echo 1 > $i
done

# Ensure source routing is OFF
for i in /proc/sys/net/ipv4/conf/*/accept_source_route;
 do
  echo 0 > $i
 done

# Ensure TCP SYN cookies protection is enabled
[ -e /proc/sys/net/ipv4/tcp_syncookies ] &&\
 echo 1 > /proc/sys/net/ipv4/tcp_syncookies 

# Ensure ICMP redirects are disabled
for i in /proc/sys/net/ipv4/conf/*/accept_redirects; 
 do
  echo 0 > $i
 done

# Ensure oddball addresses are logged
[ -e /proc/sys/net/ipv4/conf/all/log_martians ] &&\
 echo 1 > /proc/sys/net/ipv4/conf/all/log_martians

[ -e /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts ] &&\
 echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

[ -e /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses ] &&\
 echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

## Optional from here on down, depending on your situation. ############

# Ensure ip-forwarding is enabled if
# we want to do forwarding or masquerading.
[ -e /proc/sys/net/ipv4/ip_forward ] &&\
 echo 1 > /proc/sys/net/ipv4/ip_forward

# On if your IP is dynamic (or you don't know).
[ -e /proc/sys/net/ipv4/ip_dynaddr ] &&\
 echo 1 > /proc/sys/net/ipv4/ip_dynaddr        

# eof

 

The same effect by using /etc/sysctl.conf instead:


# 
# Add to existing sysctl.conf
#

# Anti-spoofing blocks
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1

# Ensure source routing is OFF
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.accept_source_route = 0

# Ensure TCP SYN cookies protection is enabled
net.ipv4.tcp_syncookies = 1

# Ensure ICMP redirects are disabled
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.accept_redirects = 0

# Ensure oddball addresses are logged
net.ipv4.conf.default.log_martians = 1
net.ipv4.conf.all.log_martians = 1


net.ipv4.icmp_echo_ignore_broadcasts = 1

net.ipv4.icmp_ignore_bogus_error_responses = 1

## Optional from here on down, depending on your situation. ############

# Ensure ip-forwarding is enabled if
# we want to do forwarding or masquerading.
net.ipv4.ip_forward = 1

# On if your IP is dynamic (or you don't know).
net.ipv4.ip_dynaddr = 1

# end of example

 

8.9. Secure Alternatives

This section will give a brief run down on secure alternatives to potentially insecure methods. This will be a hodge podge of clients and servers.

8.10. Ipchains and Iptables Redux

This section offers a little more advanced look at some of things that ipchains and iptables can do. These are basically the same scripts as in Step 3 above, just with some more advanced configuration options added. These will provide "masquerading", "port forwarding", allow access to some user definable services, and a few other things. Read the comments for explanations.

8.10.1. ipchains II


#!/bin/sh
#
# ipchains.sh
#
# An example of a simple ipchains configuration. This script 
# can enable 'masquerading' and will open user definable ports.
#
###################################################################
# Begin variable declarations and user configuration options ######
#
# Set the location of ipchains (default).
IPCHAINS=/sbin/ipchains

# Local Interfaces
#
# This is the WAN interface, that is our link to the outside world.
# For pppd and pppoe users.
# WAN_IFACE="ppp0"
WAN_IFACE="eth0"
#
# Local Area Network (LAN) interface.
#LAN_IFACE="eth0"
LAN_IFACE="eth1"

# Our private LAN address(es), for masquerading.
LAN_NET="192.168.1.0/24"

# For static IP, set it here! 
#WAN_IP="1.2.3.4"

# Set a list of public server port numbers here...not too many!
# These will be open to the world, so use caution. The example is
# sshd, and HTTP (www). Any services included here should be the
# latest version available from your vendor. Comment out to disable
# all PUBLIC services.
#PUBLIC_PORTS="22 80 443"
PUBLIC_PORTS="22"

# If we want to do port forwarding, this is the host 
# that will be forwarded to.
#FORWARD_HOST="192.168.1.3"

# A list of ports that are to be forwarded. 
#FORWARD_PORTS="25  80"

# If you get your public IP address via DHCP, set this.
DHCP_SERVER=66.21.184.66

# If you need identd for a mail server, set this.
MAIL_SERVER=

# A list of unwelcome hosts or nets. These will be denied access 
# to everything, even our 'PUBLIC' services. Provide your own list.
#BLACKLIST="11.22.33.44 55.66.77.88"

# A list of "trusted" hosts and/or nets. These will have access to 
# ALL protocols, and ALL open ports. Be selective here.
#TRUSTED="1.2.3.4/8  5.6.7.8"

## end user configuration options #################################
###################################################################

# The high ports used mostly for connections we initiate and return
# traffic.
LOCAL_PORTS=`cat /proc/sys/net/ipv4/ip_local_port_range |cut -f1`:\
`cat /proc/sys/net/ipv4/ip_local_port_range |cut -f2`

# Any and all addresses from anywhere.
ANYWHERE="0/0"

# Start building chains and rules #################################
#
# Let's start clean and flush all chains to an empty state.
$IPCHAINS -F  

# Set the default policies of the built-in chains. If no match for any 
# of the rules below, these will be the defaults that ipchains uses.
$IPCHAINS -P forward DENY
$IPCHAINS -P output ACCEPT
$IPCHAINS -P input DENY 

# Accept localhost/loopback traffic.
$IPCHAINS -A input -i lo -j ACCEPT

# Get our dynamic IP now from the Inet interface. WAN_IP will be our
# IP address we are protecting from the outside world. Put this
# here, so default policy gets set, even if interface is not up
# yet.
[ -z "$WAN_IP" ] &&\
  WAN_IP=`ifconfig $WAN_IFACE |grep inet |cut -d : -f 2 |cut -d \  -f 1`

# Bail out with error message if no IP available! Default policy is 
# already set, so all is not lost here.
[ -z "$WAN_IP" ] && echo "$WAN_IFACE not configured, aborting." && exit 1

WAN_MASK=`ifconfig $WAN_IFACE | grep Mask | cut -d : -f 4`
WAN_NET="$WAN_IP/$WAN_MASK"

## Reserved IPs:
#
# We should never see these private addresses coming in from outside 
# to our external interface.
$IPCHAINS -A input -l -i $WAN_IFACE -s 10.0.0.0/8     -j DENY
$IPCHAINS -A input -l -i $WAN_IFACE -s 172.16.0.0/12  -j DENY
$IPCHAINS -A input -l -i $WAN_IFACE -s 192.168.0.0/16 -j DENY
$IPCHAINS -A input -l -i $WAN_IFACE -s 127.0.0.0/8    -j DENY
$IPCHAINS -A input -l -i $WAN_IFACE -s 169.254.0.0/16 -j DENY
$IPCHAINS -A input -l -i $WAN_IFACE -s 224.0.0.0/4    -j DENY
$IPCHAINS -A input -l -i $WAN_IFACE -s 240.0.0.0/5    -j DENY
# Bogus routing
$IPCHAINS -A input -l -s 255.255.255.255 -d $ANYWHERE -j DENY

## LAN access and masquerading
#
# Allow connections from our own LAN's private IP addresses via the LAN
# interface and set up forwarding for masqueraders if we have a LAN_NET
# defined above. 
if [ -n "$LAN_NET" ]; then 
 echo 1 > /proc/sys/net/ipv4/ip_forward
 $IPCHAINS -A input  -i $LAN_IFACE  -j ACCEPT
 $IPCHAINS -A forward -s $LAN_NET -d $LAN_NET -j ACCEPT
 $IPCHAINS -A forward  -s $LAN_NET -d ! $LAN_NET -j MASQ
fi

## Blacklist hosts/nets
#
# Get the blacklisted hosts/nets out of the way, before we start opening 
# up any services. These will have no access to us at all, and will be
# logged.
for i in $BLACKLIST; do
 $IPCHAINS -A input -l -s $i -j DENY
done

## Trusted hosts/nets
#
# This is our trusted host list. These have access to everything.
for i in $TRUSTED; do
 $IPCHAINS -A input -s $i -j ACCEPT
done

# Port Forwarding
#
# Which ports get forwarded to which host. This is one to one 
# port mapping (ie 80 -> 80) in this case.
# NOTE: ipmasqadm is a separate package from ipchains and needs 
# to be installed also. Check first!
[ -n "$FORWARD_HOST" ] && ipmasqadm portfw -f &&\
 for i in $FORWARD_PORTS; do
   ipmasqadm portfw -a -P tcp -L $WAN_IP $i -R $FORWARD_HOST $i
 done

## Open, but Restricted Access ports/services
#
# Allow DHCP server (their port 67) to client (to our port 68) UDP traffic
# from outside source.
[ -n "$DHCP_SERVER" ] &&\
 $IPCHAINS -A input -p udp -s $DHCP_SERVER 67 -d $ANYWHERE 68 -j ACCEPT 

# Allow 'identd' (to our TCP port 113) from mail server only.
[ -n "$MAIL_SERVER" ] &&\
 $IPCHAINS -A input -p tcp -s $MAIL_SERVER  -d $WAN_IP 113 -j ACCEPT 

# Open up PUBLIC server ports here (available to the world):
for i in $PUBLIC_PORTS; do
 $IPCHAINS -A input -p tcp -s $ANYWHERE -d $WAN_IP $i -j ACCEPT 
done

# So I can check my home POP3 mailbox from work. Also, so I can ssh 
# in to home system. Only allow connections from my workplace's
# various IPs. Everything else is blocked.
$IPCHAINS -A input -p tcp -s 255.10.9.8/29 -d $WAN_IP 110 -j ACCEPT 

# Uncomment to allow ftp data back (active ftp). Not required for 'passive'
# ftp connections.
#$IPCHAINS -A input -p tcp -s $ANYWHERE 20 -d $WAN_IP $LOCAL_PORTS -y -j ACCEPT

# Accept non-SYN TCP, and UDP connections to LOCAL_PORTS. These are
# the high, unprivileged ports (1024 to 4999 by default). This will
# allow return connection traffic for connections that we initiate
# to outside sources. TCP connections are opened with 'SYN' packets.
# We have already opened those services that need to accept SYNs
# for, so other SYNs are excluded here for everything else.
$IPCHAINS -A input -p tcp -s $ANYWHERE -d $WAN_IP $LOCAL_PORTS ! -y -j ACCEPT 

# We can't be so selective with UDP since that protocol does not know 
# about SYNs.
$IPCHAINS -A input -p udp -s $ANYWHERE -d $WAN_IP $LOCAL_PORTS -j ACCEPT 

# Allow access to the masquerading ports conditionally. Masquerading
# uses it's own port range -- on 2.2 kernels ONLY! 2.4 kernels, do not 
# use these ports, so comment out!
[ -n "$LAN_NET" ] &&\
 $IPCHAINS -A input -p tcp -s $ANYWHERE -d $WAN_IP 61000: ! -y -j ACCEPT &&\
 $IPCHAINS -A input -p udp -s $ANYWHERE -d $WAN_IP 61000: -j ACCEPT

## ICMP (ping)
#
# ICMP rules, allow the bare essential types of ICMP only. Ping
# request is blocked, ie we won't respond to someone else's pings,
# but can still ping out. 
$IPCHAINS -A input  -p icmp  --icmp-type echo-reply \
   -s $ANYWHERE -i $WAN_IFACE -j ACCEPT
$IPCHAINS -A input  -p icmp  --icmp-type destination-unreachable \
   -s $ANYWHERE -i $WAN_IFACE -j ACCEPT
$IPCHAINS -A input  -p icmp  --icmp-type time-exceeded \
   -s $ANYWHERE -i $WAN_IFACE -j ACCEPT

#######################################################################
# Set the catchall, default rule to DENY, and log it all. All other
# traffic not allowed by the rules above, winds up here, where it is
# blocked and logged. This is the default policy for this chain
# anyway, so we are just adding the logging ability here with '-l'.
# Outgoing traffic is allowed as the default policy for the 'output'
# chain. There are no restrictions on that.

$IPCHAINS -A input -l -j DENY

echo "Ipchains firewall is up `date`."

##-- eof ipchains.sh

 

8.10.2. iptables II


#!/bin/sh
#
# iptables.sh
#
# An example of a simple iptables configuration. This script 
# can enable 'masquerading' and will open user definable ports.
#
###################################################################
# Begin variable declarations and user configuration options ######
#
# Set the location of iptables (default).
IPTABLES=/sbin/iptables

# Local Interfaces
# This is the WAN interface that is our link to the outside world.
# For pppd and pppoe users.
# WAN_IFACE="ppp0"
WAN_IFACE="eth0"
#
# Local Area Network (LAN) interface.
#LAN_IFACE="eth0"
LAN_IFACE="eth1"

# Our private LAN address(es), for masquerading.
LAN_NET="192.168.1.0/24"

# For static IP, set it here! 
#WAN_IP="1.2.3.4"

# Set a list of public server port numbers here...not too many!
# These will be open to the world, so use caution. The example is
# sshd, and HTTP (www). Any services included here should be the
# latest version available from your vendor. Comment out to disable
# all Public services. Do not put any ports to be forwarded here,
# this only direct access.
#PUBLIC_PORTS="22 80 443"
PUBLIC_PORTS="22"

# If we want to do port forwarding, this is the host 
# that will be forwarded to.
#FORWARD_HOST="192.168.1.3"

# A list of ports that are to be forwarded. 
#FORWARD_PORTS="25  80"

# If you get your public IP address via DHCP, set this.
DHCP_SERVER=66.21.184.66

# If you need identd for a mail server, set this.
MAIL_SERVER=

# A list of unwelcome hosts or nets. These will be denied access 
# to everything, even our 'Public' services. Provide your own list.
#BLACKLIST="11.22.33.44 55.66.77.88"

# A list of "trusted" hosts and/or nets. These will have access to 
# ALL protocols, and ALL open ports. Be selective here.
#TRUSTED="1.2.3.4/8  5.6.7.8"

## end user configuration options #################################
###################################################################

# Any and all addresses from anywhere.
ANYWHERE="0/0"

# These modules may need to be loaded:
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp

# Start building chains and rules #################################
#
# Let's start clean and flush all chains to an empty state.
$IPTABLES -F
$IPTABLES -X


# Set the default policies of the built-in chains. If no match for any 
# of the rules below, these will be the defaults that IPTABLES uses.
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P INPUT DROP 

# Accept localhost/loopback traffic.
$IPTABLES -A INPUT -i lo -j ACCEPT

# Get our dynamic IP now from the Inet interface. WAN_IP will be the
# address we are protecting from outside addresses.
[ -z "$WAN_IP" ] &&\
  WAN_IP=`ifconfig $WAN_IFACE |grep inet |cut -d : -f 2 |cut -d \  -f 1`

# Bail out with error message if no IP available! Default policy is 
# already set, so all is not lost here.
[ -z "$WAN_IP" ] && echo "$WAN_IFACE not configured, aborting." && exit 1

WAN_MASK=`ifconfig $WAN_IFACE |grep Mask |cut -d : -f 4`
WAN_NET="$WAN_IP/$WAN_MASK"

## Reserved IPs:
#
# We should never see these private addresses coming in from outside 
# to our external interface.
$IPTABLES -A INPUT -i $WAN_IFACE -s 10.0.0.0/8      -j DROP
$IPTABLES -A INPUT -i $WAN_IFACE -s 172.16.0.0/12   -j DROP
$IPTABLES -A INPUT -i $WAN_IFACE -s 192.168.0.0/16  -j DROP
$IPTABLES -A INPUT -i $WAN_IFACE -s 127.0.0.0/8     -j DROP
$IPTABLES -A INPUT -i $WAN_IFACE -s 169.254.0.0/16  -j DROP
$IPTABLES -A INPUT -i $WAN_IFACE -s 224.0.0.0/4     -j DROP
$IPTABLES -A INPUT -i $WAN_IFACE -s 240.0.0.0/5     -j DROP
# Bogus routing
$IPTABLES -A INPUT -s 255.255.255.255 -d $ANYWHERE -j DROP

# Unclean
$IPTABLES -A INPUT -i $WAN_IFACE -m unclean -m limit \
  	--limit 15/minute -j LOG --log-prefix "Unclean: "
$IPTABLES -A INPUT -i $WAN_IFACE -m unclean -j DROP

## LAN access and masquerading
#
# Allow connections from our own LAN's private IP addresses via the LAN
# interface and set up forwarding for masqueraders if we have a LAN_NET
# defined above. 
if [ -n "$LAN_NET" ]; then 
 echo 1 > /proc/sys/net/ipv4/ip_forward
 $IPTABLES -A INPUT -i $LAN_IFACE  -j ACCEPT
# $IPTABLES -A INPUT -i $LAN_IFACE -s $LAN_NET -d $LAN_NET  -j ACCEPT  
 $IPTABLES -t nat -A POSTROUTING -s $LAN_NET -o $WAN_IFACE -j MASQUERADE
fi

## Blacklist
#
# Get the blacklisted hosts/nets out of the way, before we start opening 
# up any services. These will have no access to us at all, and will 
# be logged.
for i in $BLACKLIST; do
 $IPTABLES -A INPUT -s $i -m limit --limit 5/minute \
   -j LOG --log-prefix "Blacklisted: "
 $IPTABLES -A INPUT -s $i -j DROP
done

## Trusted hosts/nets
#
# This is our trusted host list. These have access to everything.
for i in $TRUSTED; do
 $IPTABLES -A INPUT -s $i -j ACCEPT
done

# Port Forwarding
#
# Which ports get forwarded to which host. This is one to one 
# port mapping (ie 80 -> 80) in this case.
[ -n "$FORWARD_HOST" ] &&\
 for i in $FORWARD_PORTS; do
   $IPTABLES -A FORWARD -p tcp -s $ANYWHERE -d $FORWARD_HOST \
     --dport $i -j ACCEPT
   $IPTABLES -t nat -A PREROUTING -p tcp -d $WAN_IP --dport $i \
     -j DNAT --to $FORWARD_HOST:$i
 done

## Open, but Restricted Access ports
#
# Allow DHCP server (their port 67) to client (to our port 68) UDP
# traffic from outside source.
[ -n "$DHCP_SERVER" ] &&\
 $IPTABLES -A INPUT -p udp -s $DHCP_SERVER --sport 67 \
   -d $ANYWHERE --dport 68 -j ACCEPT 

# Allow 'identd' (to our TCP port 113) from mail server only.
[ -n "$MAIL_SERVER" ] &&\
 $IPTABLES -A INPUT -p tcp -s $MAIL_SERVER  -d $WAN_IP --dport 113 -j ACCEPT 

# Open up Public server ports here (available to the world):
for i in $PUBLIC_PORTS; do
 $IPTABLES -A INPUT -p tcp -s $ANYWHERE -d $WAN_IP --dport $i -j ACCEPT 
done

# So I can check my home POP3 mailbox from work. Also, so I can ssh 
# in to home system. Only allow connections from my workplace's
# various IPs. Everything else is blocked.
$IPTABLES -A INPUT -p tcp -s 255.10.9.8/29 -d $WAN_IP --dport 110 -j ACCEPT 

## ICMP (ping)
#
# ICMP rules, allow the bare essential types of ICMP only. Ping
# request is blocked, ie we won't respond to someone else's pings,
# but can still ping out.
$IPTABLES -A INPUT  -p icmp  --icmp-type echo-reply \
   -s $ANYWHERE -d $WAN_IP -j ACCEPT
$IPTABLES -A INPUT  -p icmp  --icmp-type destination-unreachable \
   -s $ANYWHERE -d $WAN_IP -j ACCEPT
$IPTABLES -A INPUT  -p icmp  --icmp-type time-exceeded \
   -s $ANYWHERE -d $WAN_IP -j ACCEPT

# Identd Reject
#
# Special rule to reject (with rst) any identd/auth/port 113
# connections. This will speed up some services that ask for this,
# but don't require it. Be careful, some servers may require this
# one (IRC for instance).
#$IPTABLES -A INPUT -p tcp --dport 113 -j REJECT --reject-with tcp-reset

###################################################################
# Build a custom chain here, and set the default to DROP. All
# other traffic not allowed by the rules above, ultimately will
# wind up here, where it is blocked and logged, unless it passes
# our stateful rules for ESTABLISHED and RELATED connections. Let
# connection tracking do most of the worrying! We add the logging
# ability here with the '-j LOG' target. Outgoing traffic is
# allowed as that is the default policy for the 'output' chain.
# There are no restrictions placed on that in this script.

# New chain...
$IPTABLES -N DEFAULT
# Use the 'state' module to allow only certain connections based 
# on their 'state'.
$IPTABLES -A DEFAULT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A DEFAULT -m state --state NEW -i ! $WAN_IFACE -j ACCEPT
# Enable logging for anything that gets this far.
$IPTABLES -A DEFAULT -j LOG -m limit --limit 30/minute --log-prefix "Dropping: "
# Now drop it, if it has gotten here.
$IPTABLES -A DEFAULT -j DROP

# This is the 'bottom line' so to speak. Everything winds up
# here, where we bounce it to our custom built 'DEFAULT' chain
# that we defined just above. This is for both the FORWARD and 
# INPUT chains. 

$IPTABLES -A FORWARD -j DEFAULT
$IPTABLES -A INPUT   -j DEFAULT

echo "Iptables firewall is up `date`."

##-- eof iptables.sh
 
 

8.10.3. Summary

A quick run down of the some highlights...

We added some host based access control rules: "blacklisted", and "trusted". We then showed several types of service and port based access rules. For instance, we allowed some very restrictive access to bigcat's POP3 server so we could connect only from our workplace. We allowed a very narrow rule for the ISP's DHCP server. This rule only allows one port on one outside IP address to connect to only one of our ports and only via the UDP protocol. This is a very specific rule! We are being specific since there is no reason to allow any other traffic to these ports or from these addresses. Remember our goal is the minimum amount of traffic necessary for our particular situation.

So we made those few exceptions mentioned above, and all other services running on bigcat should be effectively blocked completely from outside connections. These are still happily running on bigcat, but are now safe and sound behind our packet filtering firewall. You probably have other services that fall in this category as well.

We also have a small, home network in the above example. We did not take any steps to block that traffic. So the LAN has access to all services running on bigcat. And it is further "masqueraded", so that it has Internet access (different HOWTO), by manipulating the "forward" chain. And the LAN is still protected by our firewall since it sits behind the firewall. We also didn't impose any restrictive rules on the traffic leaving bigcat. In some situations, this might be a good idea.

Of course, this is just a hypothetical example. Your individual situation is surely different, and would require some changes and likely some additions to the rules above. For instance, if your ISP does not use DHCP (most do not), then that rule would make no sense. PPP works differently and such rules are not needed.

Please don't interpret that running any server as we did in this example is necessarily a "safe" thing to do. We shouldn't do it this way unless a) we really need to and b) we are running the current, safe version, and c) we are able to keep abreast of security related issues that might effect these services. Vigilance and caution are part of our responsibilities here too.