v. 1.2, 2002-07-21
Revision History | ||
---|---|---|
Revision v. 1.2 | 2002-07-21 | Revised by: hb |
A few small additions, and fix the usual broken links. | ||
Revision v. 1.1 | 2002-02-06 | Revised by: hb |
A few fixes, some additions and many touch-ups from the original. | ||
Revision v. 1.0 | 2001-11-07 | Revised by: hb |
Initial Release. |
The above is real, live data from a one week period for my home LAN. Much of the above would seem to be specifically targeted at Linux systems. Many of the targeted "destination" ports are used by well known Linux and Unix services, and all may be installed, and possibly even running, on your system.
The focus here will be on threats that are shared by all Linux users, whether a dual boot home user, or large commercial site. And we will take a few, relatively quick and easy steps that will make a typical home Desktop system or small office system running Linux reasonably safe from the majority of outside threats. For those responsible for Linux systems in a larger or more complex environment, you'd be well advised to read this, and then follow up with additional reading suitable to your particular situation. Actually, this is probably good advice for everybody.
We will assume the reader knows little about Linux, networking, TCP/IP, and the finer points of running a server Operating System like Linux. We will also assume, for the sake of this document, that all local users are "trusted" users, and won't address physical or local network security issues in any detail. Again, if this is not the case, further reading is strongly recommended.
The principles that will guide us in our quest are:
There is no magic bullet. There is no one single thing we can do to make us secure. It is not that simple.
Security is a process that requires maintenance, not an objective to be reached.
There is no 100% safe program, package or distribution. Just varying degrees of insecurity.
The steps we will be taking to get there are:
Step 1: Turn off, and perhaps uninstall, any and all unnecessary services.
Step 2: Make sure that any services that are installed are updated and patched to the current, safe version -- and then stay that way. Every server application has potential exploits. Some have just not been found yet.
Step 3: Limit connections to us from outside sources by implementing a firewall and/or other restrictive policies. The goal is to allow only the minimum traffic necessary for whatever our individual situation may be.
Awareness. Know your system, and how to properly maintain and secure it. New vulnerabilities are found, and exploited, all the time. Today's secure system may have tomorrow's as yet unfound weaknesses.
If you don't have time to read everything, concentrate on Steps 1, 2, and 3. This is where the meat of the subject matter is. The Appendix has a lot of supporting information, which may be helpful, but may not be necessary for all readers.
Security-Quickstart HOWTO for Linux
You can get a copy of the GNU GPL at at http://www.gnu.org/copyleft/gpl.html.
Many thanks to those who helped with the production of this document.
The current official version can always be found at http://www.tldp.org/HOWTO/Security-Quickstart-HOWTO/. Pre-release versions can be found at http://feenix.burgiss.net/ldp/quickstart/.
Other formats, including PDF, PS, single page HTML, may be found at the Linux Documentation HOWTO index page: http://tldp.org/docs.html#howto.
Changelog:
Version 1.2: Clarifications on example firewall scripts, and small additions to 'Have I been Hacked'. Note on Zonealarm type applications. More on the use of "chattr" by script kiddies, and how to check for this. Other small additions and clarifications.
Version 1.1: Various corrections, amplifications and numerous mostly small additions. Too many to list. Oh yea, learn to spell Red Hat correctly ;-)
Version 1.0: This is the initial release of this document. Comments welcomed.
Do you want to unwittingly participate in criminal activity?
Do you want to have to go through the time consuming steps of reclaiming your system?
These are all real possibilities, unless we take the appropriate precautions.
![]() | If you are reading this because you have already been broken into, or suspect that you have, you cannot trust any of your system utilities to provide reliable information. And the suggestions made in the next several sections will not help you recover your system. Please jump straight to the Have I been Hacked? section, and read that first. |
Before we get to the actual configuration sections, a couple of notes.
To get ready, what you will need for the configuration sections below:
A text editor. There are many available. If you use a file manager application , it probably has a built in editor. This will be fine. pico and mcedit are two relatively easy to use editors if you don't already have a favorite. There is a quick guide to Text editors in the Appendix that might help you get started. It is always a good idea to make a back up copy, before editing system configuration files.
For non-GUI editors and some of the commands, you will also need a terminal window opened. xterm, rxvt, and gnome-terminal all will work, as well as others.
You should also be familiar with your distribution's method of stopping services from running on each boot. Also, how they install (and uninstall) packages (rpm, deb, etc). And where to find the updates for your release. This information is available in your release's documentation, or on your vendor's web site.
We'll be using a hypothetical system here for examples with the hostname "bigcat". Bigcat is a Linux desktop with a fresh install of the latest/greatest Linux distro running. Bigcat has a full-time, direct Internet connection. Even if your installation is not so "fresh", don't be deterred. Better late than never.
In this section we will see which services are running on our freshly installed system, decide which we really need, and do away with the rest. If you are not familiar with how servers and TCP connections work, you may want to read the section on servers and ports in the Appendix first. If not familiar with the netstat utility, you may want to read a quick overview of it beforehand. There is also a section in the Appendix on ports, and corresponding services. You may want to look that over too.
Our goal is to turn off as many services as possible. If we can turn them all off, or at least off to outside connections, so much the better. Some rules of thumb we will use to guide us:
It is perfectly possible to have a fully functional Internet connection with no servers running that are accessible to outside connections. Not only possible, but desirable in many cases. The principle here is that you will never be successfully broken into via a port that is not opened because no server is listening on it. No server == no port open == not vulnerable. At least to outside connections.
If you don't recognize a particular service, chances are good you don't really need it. We will assume that and so we'll turn it off. This may sound dangerous, but is a good rule of thumb to go by.
Some services are just not intended to be run over the Internet -- even if you decide it is something you really do need. We'll flag these as dangerous, and address these in later sections, should you decide you do really need them, and there is no good alternative.
# netstat -tap |grep LISTEN *:exec *:* LISTEN 988/inetd *:login *:* LISTEN 988/inetd *:shell *:* LISTEN 988/inetd *:printer *:* LISTEN 988/inetd *: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 *:auth *:* LISTEN 388/in.identd *:telnet *:* LISTEN 988/inetd *:finger *:* LISTEN 988/inetd *:sunrpc *:* LISTEN 1290/portmap *:ftp *:* LISTEN 988/inetd *:smtp *:* LISTEN 1738/sendmail: accepting connections *:1694 *:* LISTEN 1319/rpc.mountd *:netbios-ssn *:* LISTEN 422/smbd |
You don't understand what any of this is telling you? Hopefully then, you've read the netstat tutorial in the Appendix, and understand how it works. Understanding exactly what each server is in the above example, and what it does, is beyond the scope of this document. You will have to check your system's documentation (e.g. Installation Guide, man pages, etc) if that service is important to you. For example, does "exec", "login", and "shell" sound important? Yes, but these are not what they may sound like. They are actually rexec, rlogin, and rsh, the "r" (for remote) commands. These are antiquated, unnecessary, and in fact, are very dangerous if exposed to the Internet.
Let's make a few quick assumptions about what is necessary and unnecessary, and therefore what goes and what stays on bigcat. Since we are running a desktop on bigcat, X11 of course needs to stay. If bigcat were a dedicated server of some kind, then X11 would be unnecessary. If there is a printer physically attached, the printer (lp) daemon should stay. Otherwise, it goes. Print servers may sound harmless, but are potential targets too since they can hold ports open. If we plan on logging in to bigcat from other hosts, sshd (Secure SHell Daemon) would be necessary. If we have Microsoft hosts on our LAN, we probably want Samba, so smbd should stay. Otherwise, it is completely unnecessary. Everything else in this example is optional and not required for a normally functioning system, and should probably go. See anything that you don't recognize? Not sure about? It goes!
To sum up: since bigcat is a desktop with a printer attached, we will need "x11", "printer". bigcat is on a LAN with MS hosts, and shares files and printing with them, so "netbios-ssn" (smbd) is desired. We will also need "ssh" so we can login from other machines. Everything else is unnecessary for this particular case.
Nervous about this? If you want, you can make notes of any changes you make or save the list of servers you got from netstat, with this command: netstat -tap |grep LISTEN > ~/services.lst. That will save it your home directory with the name of "services.lst" for future reference.
This is to not say that the ones we have decided to keep are inherently safe. Just that we probably need these. So we will have to deal with these via firewalling or other means (addressed below).
It is worth noting that the telnet and ftp daemons in the above example are servers, aka "listeners". These accept incoming connections to you. You do not need, or want, these just to use ftp or telnet clients. For instance, you can download files from an FTP site with just an ftp client. Running an ftp server on your end is not required at all, and has serious security implications.
There may be individual situations where it is desirable to make exceptions to the conclusions reached above. See below.
rpc.* services, Remote Procedure Call.*, typically NFS and NIS related (see above).
telnet server. There is no reason for this anymore. Use sshd instead.
BIND (named), DNS server package. With some work, this can be done without great risk, but is not necessary in many situations, and requires special handling no matter how you do it. See the sections on Exceptions and special handling for individual applications.
Mail Transport Agent, aka "MTA" (sendmail, exim, postfix, qmail). Most installations on single computers will not really need this. If you are not going to be directly receiving mail from Internet hosts (as a designated MX box), but will rather use the POP server of your ISP, then it is not needed. You may however need this if you are receiving mail directly from other hosts on your LAN, but initially it's safer to disable this. Later, you can enable it over the local interface once your firewall and access policies have been implemented.
This is not necessarily a definitive list. Just some common services that are sometimes started on default Linux installations. And conversely, this does not imply that other services are inherently safe.
The next step is to find where each server on our kill list is being started. If it is not obvious from the netstat output, use ps, find, grep or locate to find more information from the "Program name" or "PID" info in the last column. There is examples of this in the Process Owner section in the netstat Tutorial of the Appendix. If the service name or port number do not look familiar to you, you might get a real brief explanation in your /etc/services file.
Skeptical that we are going to break your system, and the pieces won't go back together again? If so, take this approach: turn off everything listed above in "The Danger Zone", and run your system for a while. OK? Try stopping one of the ones we found to be "unnecessary" above. Then, run the system for a while. Keep repeating this process, until you get to the bare minimum. If this works, then make the changes permanent (see below).
The ultimate objective is not just to stop the service now, but to make sure it is stopped permanently! So whatever steps you take here, be sure to check after your next reboot.
There are various places and ways to start system services. Let's look at the most common ways this is done, and is probably how your system works. System services are typically either started by "init" scripts, or by inetd (or its replacement xinetd) on most distributions. (The location of the init scripts may vary from distribution to distribution.)
You can get a listing of these scripts:
# ls -l /etc/init.d/ | less |
Or use whichever tools your distribution provides for this.
To stop a running service now, as root (on SysVinit style systems, which is pretty much everybody):
# /etc/init.d/<$SERVICE_NAME> stop |
# update-rc.d -f $SERVICE_NAME remove |
# chkconfig $SERVICE_NAME off |
# # inetd.conf This file describes the services that will be available # through the INETD TCP/IP super server. To re-configure # the running INETD process, edit this file, then send the # INETD process a SIGHUP signal. # # Version: @(#)/etc/inetd.conf 3.10 05/27/93 # # Authors: Original taken from BSD UNIX 4.3/TAHOE. # Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> # # Modified for Debian Linux by Ian A. Murdock <imurdock@shell.portal.com> # # Echo, discard, daytime, and chargen are used primarily for testing. # # To re-read this file after changes, just do a 'killall -HUP inetd' # #echo stream tcp nowait root internal #echo dgram udp wait root internal #discard stream tcp nowait root internal #discard dgram udp wait root internal #daytime stream tcp nowait root internal #daytime dgram udp wait root internal #chargen stream tcp nowait root internal #chargen dgram udp wait root internal time stream tcp nowait root internal # # These are standard services. # #ftp stream tcp nowait root /usr/sbin/tcpd in.ftpd -l -a #telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd # # Shell, login, exec, comsat and talk are BSD protocols. # #shell stream tcp nowait root /usr/sbin/tcpd in.rshd #login stream tcp nowait root /usr/sbin/tcpd in.rlogind #exec stream tcp nowait root /usr/sbin/tcpd in.rexecd #comsat dgram udp wait root /usr/sbin/tcpd in.comsat #talk dgram udp wait root /usr/sbin/tcpd in.talkd #ntalk dgram udp wait root /usr/sbin/tcpd in.ntalkd #dtalk stream tcp wait nobody /usr/sbin/tcpd in.dtalkd # # Pop and imap mail services et al # #pop-2 stream tcp nowait root /usr/sbin/tcpd ipop2d pop-3 stream tcp nowait root /usr/sbin/tcpd ipop3d #imap stream tcp nowait root /usr/sbin/tcpd imapd # # The Internet UUCP service. # #uucp stream tcp nowait uucp /usr/sbin/tcpd /usr/lib/uucp/uucico -l # <snip> |
# /etc/init.d/inetd restart |
Check your logs for errors, and run netstat again to verify all went well.
A quicker way of getting the same information, using grep:
$ grep -v '^#' /etc/inetd.conf time stream tcp nowait root internal pop-3 stream tcp nowait root /usr/sbin/tcpd ipop3d |
Unlike the init services configuration, this is a lasting change so only the one step is required.
# default: on # description: The wu-ftpd FTP server serves FTP connections. It uses \ # normal, unencrypted usernames and passwords for authentication. service ftp { disable = no socket_type = stream wait = no user = root server = /usr/sbin/in.ftpd server_args = -l -a log_on_success += DURATION USERID log_on_failure += USERID nice = 10 } |
You can get a quick list of enabled services:
$ grep disable /etc/xinetd.d/* |grep no /etc/xinetd.d/finger: disable = no /etc/xinetd.d/rexec: disable = no /etc/xinetd.d/rlogin: disable = no /etc/xinetd.d/rsh: disable = no /etc/xinetd.d/telnet: disable = no /etc/xinetd.d/wu-ftpd: disable = no |
# /etc/init.d/xinetd restart |
OK, if you can't find the "right" way to stop a service, or maybe a service is being started and you can't find how or where, you can "kill" the process. To do this, you will need to know the PID (Process I.D.). This can be found with ps, top, fuser or other system utilities. For top and ps, this will be the number in the first column. See the Port and Process Owner section in the Appendix for examples.
Example (as root):
# kill 1163 |
Then run top or ps again to verify that the process is gone. If not, then:
# kill -KILL 1163 |
Note the second "KILL" in there. This must be done either by the user who owns the process, or root. Now go find where and how this process got started ;-)
The /proc filesystem can also be used to find out more information about each process. Armed with the PID, we can find the path to a mysterious process:
$ /bin/ps ax|grep tcpgate 921 ? S 0:00 tcpgate |
# ls -l /proc/921/exe lrwxrwxrwx 1 root root 0 July 21 12:11 /proc/921/exe -> /usr/local/bin/tcpgate |
/usr/sbin/in.identd in.identd -l -e -o -n -N |
BIND (named) - This often is installed by default, but is only really needed if you are an authoritative name server for a domain. If you are not sure what this means, then you definitely don't need it. BIND is probably the number one crack target on the Internet. BIND is often used though in a "caching" only mode. This can be quite useful, but does not require full exposure to the Internet. In other words, it should be restricted or firewalled. See special handling of individual applications below.
But where to get this information in a timely fashion? There are a number of web sites that offer the latest security news. There are also a number of mailing lists dedicated to this topic. In fact, your vendor most likely has such a list where vulnerabilities and the corresponding fix is announced. This is an excellent way to stay abreast of issues effecting your release, and is highly recommended. http://linuxsecurity.com is a good site for Linux only issues. They also have weekly newsletters available: http://www.linuxsecurity.com/general/newsletter.html.
Also, many distributions have utilities that will automatically update your installed packages via ftp. This can be run as a cron job on a regular basis and is a painless way to go if you have ready Internet access.
This is not a one time process -- it is ongoing. It is important to stay current. So watch those security notices. And subscribe to your vendor's security mailing list today! If you have cable modem, DSL, or other full time connection, there is no excuse not to do this religiously. All distributions make this easy enough!
One last note: any time a new package is installed, there is also a chance that a new or revised configuration has been installed as well. Which means that if this package is a server of some kind, it may be enabled as a result of the update. This is bad manners, but it can happen, so be sure to run netstat or comparable to verify your system is where you want it after any updates or system changes. In fact, do it periodically even if there are no such changes.
We will include some brief examples. Our rule of thumb will be to deny everything as the default policy, then open up just what we need. We'll try to keep this as simple as possible since it can be an involved and complex topic, and just stick to some of the most basic concepts. See the Links section for further reading on this topic.
If constructing your own ipchains or iptables firewall rules seems a bit daunting, there are various sites that can automate the process. See the Links section. Also the included examples may be used as a starting point. And your distribution may be including a utility of some kind for generating a firewall script. This may be adequate, but it is still recommended to know the proper syntax and how the various mechanisms work as such tools rarely do more than a few very simple rules.
![]() | Various examples are given below. These are presented for illustrative purposes to demonstrate some of the concepts being discussed here. While they might also be useful as a starting point for your own script, please note that they are not meant to be all encompassing. You are strongly encouraged to understand how the scripts work, so you can create something even more tailored for your own situation. The example scripts are just protecting inbound connections to one interface (the one connected to the Internet). This may be adequate for many simple home type situations, but, conversely, this approach is not adequate for all situations! |
#!/bin/sh # # ipchains.sh # # An example of a simple ipchains configuration. # # This script allows ALL outbound traffic, and denies # ALL inbound connection attempts from the outside. # ################################################################### # Begin variable declarations and user configuration options ###### # IPCHAINS=/sbin/ipchains # This is the WAN interface, that is our link to the outside world. # For pppd and pppoe users. # WAN_IFACE="ppp0" WAN_IFACE="eth0" ## 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" # 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. 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 # 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. $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 ## 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 |
See the ipchains man page for a full explanation of syntax. The important ones we used here are:
�-A input: Adds a rule to the "input" chain. The default chains are input, output, and forward.
�-p udp: This rule only applies to the "UDP" "protocol". The -p option can be used with tcp, udp or icmp protocols.
�-i $WAN_IFACE: This rule applies to the specified interface only, and applies to whatever chain is referenced (input, output, or forward).
�-s <IP address> [port]: This rule only applies to the source address as specified. It can optionally have a port (e.g. 22) immediately afterward, or port range, e.g. 1023:4999.
�-d <IP address> [port]: This rule only applies to the destination address as specified. Also, it may include port or port range.
�-l : Any packet that hits a rule with this option is logged (lower case "L").
�-j ACCEPT: Jumps to the "ACCEPT" "target". This effectively terminates this chain and decides the ultimate fate for this particular packet, which in this example is to "ACCEPT" it. The same is true for other -j targets like DENY.
By and large, the order in which command line options are specified is not significant. The chain name (e.g. input) must come first though.
Remember in Step 1 when we ran netstat, we had both X and print servers running among other things. We don't want these exposed to the Internet, even in a limited way. These are still happily running on bigcat, but are now safe and sound behind our ipchains based firewall. You probably have other services that fall in this category as well.
The above example is a simplistic all or none approach. We allow all our own outbound traffic (not necessarily a good idea), and block all inbound connection attempts from outside. It is only protecting one interface, and really just the inbound side of that interface. It would more than likely require a bit of fine tuning to make it work for you. For a more advanced set of rules, see the Appendix. And you might want to read http://tldp.org/HOWTO/IPCHAINS-HOWTO.html.
Whenever you have made changes to your firewall, you should verify its integrity. One step to make sure your rules seem to be doing what you intended, is to see how ipchains has interpreted your script. You can do this by opening your xterm very wide, and issuing the following command:
# ipchains -L -n -v | less |
The output is grouped according to chain. You should also find a way to scan yourself (see the Verifying section below). And then keep an eye on your logs to make sure you are blocking what is intended.
Here is the same script as above, revised for iptables:
#!/bin/sh # # iptables.sh # # An example of a simple iptables configuration. # # This script allows ALL outbound traffic, and denies # ALL inbound connection attempts from the Internet interface only. # ################################################################### # Begin variable declarations and user configuration options ###### # 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" # ## end user configuration options ################################# ################################################################### # Any and all addresses from anywhere. ANYWHERE="0/0" # This module may need to be loaded: modprobe ip_conntrack_ftp # Start building chains and rules ################################# # # Let's start clean and flush all chains to an empty state. $IPTABLES -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 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 ## 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 -i $WAN_IFACE -j ACCEPT $IPTABLES -A INPUT -p icmp --icmp-type destination-unreachable \ -s $ANYWHERE -i $WAN_IFACE -j ACCEPT $IPTABLES -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 '-j # LOG'. Outgoing traffic is allowed as the default policy for the # 'output' chain. There are no restrictions on that. $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A INPUT -m state --state NEW -i ! $WAN_IFACE -j ACCEPT $IPTABLES -A INPUT -j LOG -m limit --limit 30/minute --log-prefix "Dropping: " echo "Iptables firewall is up `date`." ##-- eof iptables.sh |
# 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 |
There are many, many features of iptables that are not touched on here. For more reading on the Netfilter project and iptables, see http://netfilter.samba.org. And for a more advanced set of rules, see the Appendix.
Below is a small snippet from a typical inetd.conf file:
# Pop and imap mail services et al # #pop-2 stream tcp nowait root /usr/sbin/tcpd ipop2d #pop-3 stream tcp nowait root /usr/sbin/tcpd ipop3d #imap stream tcp nowait root /usr/sbin/tcpd imapd # |
ALL: ALL |
Now let's open up just the services we need, as restrictively as we can, with a brief example:
ALL: 127.0.0.1 sshd,ipop3d: 192.168.1. sshd: .myworkplace.com, hostess.mymomshouse.com |
As mentioned, xinetd is an enhanced inetd . It has much of the same functionality, with some notable enhancements. One is that tcpwrappers support can be compiled in, eliminating the need for explicit references to tcpd. Which means /etc/hosts.allow and /etc/hosts.deny are automatically in effect. Don't assume this is the case though. A little testing, then viewing the logs should be able to tell you whether tcpwrappers support is automatic or not.
Some of xinetd's other enhancements: specify IP address to listen on, which is a very effective method of access control; limit the rate of incoming connections and the total number of simultaneous connections; limit services to specific times of day. See the xinetd and xinetd.conf man pages for more details.
The syntax is quite different though. An example from /etc/xinetd.d/tftp:
service tftp { socket_type = dgram bind = 192.168.1.1 instances = 2 protocol = udp wait = yes user = nobody only_from = 192.168.1.0 server = /usr/sbin/in.tftpd server_args = /tftpboot disable = no } |
Notice the bind statement. We are only listening on, or "binding" to, the private, LAN interface here. No outside connections can be made since the outside port is not even opened. We are also only accepting connections from 192.168.1.0, our LAN. For xinetd's purposes, this denotes any IP address beginning with "192.168.1". Note that the syntax is different from inetd. The server statement in this case is the tftp daemon, in.tftpd. Again, this assumes that libwrap/tcpwrappers support is compiled into xinetd. The user running the daemon will be "nobody". Yes, there is a user account called "nobody", and it is wise to run such daemons as non-root users whenever possible. Lastly, the disable statement is xinetd's way of turning services on or off. In this case, it is "on". This is on here only as an example. Do NOT run tftp as a public service as it is unsafe.
Portsentry works quite differently than the other tools discussed so far. Portsentry does what its name implies -- it guards ports. Portsentry is configured with the /etc/portsentry/portsentry.conf file.
Unlike the other applications discussed above, it does this by actually becoming the listening server on those ports. Kind of like baiting a trap. Running netstat -taup as root while portsentry is running, will show portsentry as the LISTENER on whatever ports portsentry is configured for. If portsentry senses a connection attempt, it blocks it completely. And then goes a step further and blocks the route to that host to stop all further traffic. Alternately, ipchains or iptables can be used to block the host completely. So it makes an excellent tool to stop port scanning of a range of ports.
But portsentry has limited flexibility as to whether it allows a given connection. It is pretty much all or nothing. You can define specific IP addresses that it will ignore in /etc/portsentry/portsentry.ignore. But you cannot allow selective access to individual ports. This is because only one server can bind to a particular port at the same time, and in this case that is portsentry itself. So it has limited usefulness as a stand-alone firewall. As part of an overall firewall strategy, yes, it can be quite useful. For most of us, it should not be our first line of defense, and we should only use it in conjunction with other tools.
Suggestion on when portsentry might be useful:
As a second layer of defense, behind either ipchains or iptables. Packet filtering will catch the packets first, so that anything that gets to portsentry would indicate a misconfiguration. Do not use in conjunction with inetd services -- it won't work. They will butt heads.
As a way to catch full range ports scans. Open a pinhole or two in the packet filter, and let portsentry catch these and re-act accordingly.
If you are very sure you have no exposed public servers at all, and you just want to know who is up to what. But do not assume anything about what portsentry is protecting. By default it does not watch all ports, and may even leave some very commonly probed ports open. So make sure you configure it accordingly. And make sure you have tested and verified your set up first, and that nothing is exposed.
All in all, the packet filters make for a better firewall.
The dictionary defines "proxy" as "the authority or power to act on behalf of another". This pretty well describes software proxies as well. It is an intermediary in the connection path. As an example, if we were using a web proxy like "squid" (http://www.squid-cache.org/), every time we browse to a web site, we would actually be connecting to our locally running squid server. Squid in turn, would relay our request to the ultimate, real destination. And then squid would relay the web pages back to us. It is a go-between. Like "firewalls", a "proxy" can refer to either a specific application, or a dedicated server which runs a proxy application.
Proxies can perform various duties, not all of which have much to do with security. But the fact that they are an intermediary, makes them a good place to enforce access control policies, limit direct connections through a firewall, and control how the network behind the proxy looks to the Internet. So this makes them strong candidates to be part of an overall firewall strategy. And, in fact, are sometimes used instead of packet filtering firewalls. Proxy based firewalls probably make more sense where many users are behind the same firewall. And it probably is not high on the list of components necessary for home based systems.
Configuring and administering proxies can be complex, and is beyond the scope of this document. The Firewall and Proxy Server HOWTO, http://tldp.org/HOWTO/Firewall-HOWTO.html, has examples of setting up proxy firewalls. Squid usage is discussed at http://squid-docs.sourceforge.net/latest/html/book1.htm
options { directory "/var/named"; listen-on { 127.0.0.1; 192.168.1.1; }; version "N/A"; }; |
Recent versions of sendmail can be told to listen only on specified addresses:
# SMTP daemon options O DaemonPortOptions=Port=smtp,Addr=127.0.0.1, Name=MTA |
dnl This changes sendmail to only listen on the loopback device 127.0.0.1 dnl and not on any other network devices. DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA') |
SAMBA connections can be restricted in smb.conf:
bind interfaces = true interfaces = 192.168.1. 127. hosts allow = 192.168.1. 127. |
The CUPS print daemon can be told where to listen for connections. Add to /etc/cups/cupsd.conf:
Listen 192.168.1.1:631 |
This will only open a port at the specified address and port number.
So how to do this? There are several things you can do.
And then, scan yourself. nmap is the scanning tool of choice and may be available via your distribution , or from http://www.insecure.org/nmap/nmap_download.html. nmap is very flexible, and essentially is a "port prober". In other words, it looks for open ports, among other things. See the nmap man page for details.
If you do run nmap against yourself (e.g. nmap localhost), this should tell you what ports are open -- and visible locally only! Which hopefully by now, is quite different from what can be seen from the outside. So, scan yourself, and then find a trusted friend, or site (see the Links section), to scan you from the outside. Make sure you are not violating your ISPs Terms of Service by port scanning. It may not be allowed, even if the intentions are honorable. Scanning from outside is the best way to know how the rest of the world sees you. This should tell you how well that firewall is working. See the nmap section in the Appendix for some examples on nmap usage.
One caveat on this: some ISPs may filter some ports, and you will not know for sure how well your firewall is working. Conversely, they make it look like certain ports are open by using web, or other, proxies. The scanner may see the web proxy at port 80 and mis-report it as an open port on your system.
Another option is to find a website that offers full range testing. http://www.hackerwhacker.com is one such site. Make sure that any such site is not just scanning a relatively few well known ports.
Repeat this procedure with every firewall change, every system upgrade or new install, and when any key components of your system changes.
You may also want to enable logging all the denied traffic. At least temporarily. Once the firewall is verified to be doing what you think it should, and if the logs are hopelessly overwhelming, you may want to disable logging.
If relying on portsentry at all, please read the documentation. Depending on your configuration it will either drop the route to the scanner, or implement a ipchains/iptables rule doing the same thing. Also, since it "listens" on the specified ports, all those ports will show as "open". A false alarm in this case.
A nice log entry analyzer for ipchains and iptables from Manfred Bartz: http://www.logi.cc/linux/NetfilterLogAnalyzer.php3. What does all that stuff mean anyway?
LogSentry (formerly logcheck) is available from http://www.psionic.org/products/logsentry.html, the same group that is responsible for portsentry. LogSentry is an all purpose log monitoring tool with a flexible configuration, that handles multiple logs.
http://freshmeat.net/projects/firelogd/, the Firewall Log Daemon from Ian Jones, is designed to watch, and send alerts on iptables or ipchains logs data.
http://freshmeat.net/projects/fwlogwatch/ by Boris Wesslowski, is a similar idea, but supports more log formats.
Let's take a quick look at where to run our firewall scripts from.
script /usr/local/bin/ipchains.sh |
This is a lot of information to digest at all at one time and expect anyone to understand it all. Hopefully this can used as a starting point, and used for future reference as well. The packet filter firewall examples can be used as starting points as well. Just use your text editor, cut and paste into a file with an appropriate name, and then run chmod +x against it to make it executable. Some minor editing of the variables may be necessary. Also look at the Links section for sites and utilities that can be used to generate a custom script. This may be a little less daunting.
Now we are done with Steps 1, 2 and 3. Hopefully by now you have already instituted some basic measures to protect your system(s) from the various and sundry threats that lurk on networks. If you haven't implemented any of the above steps yet, now is a good time to take a break, go back to the top, and have at it. The most important steps are the ones above.
A few quick conclusions...
"What is best iptables, ipchains, tcpwrappers, or portsentry?" The quick answer is that iptables can do more than any of the others. So if you are using a 2.4 kernel, use iptables. Then, ipchains if using a 2.2 kernel. The long answer is "it just depends on what you are doing and what the objective is". Sorry. The other tools all have some merit in any given situation, and all can be effective in the right situation.
"Do I really need all these packages?" No, but please combine more than one approach, and please follow all the above recommendations. iptables by itself is good, but in conjunction with some of the other approaches, we are even stronger. Do not rely on any single mechanism to provide a security blanket. "Layers" of protection is always best. As is sound administrative practices. The best iptables script in the world is but one piece of the puzzle, and should not be used to hide other system weaknesses.
"If I have a small home LAN, do I need to have a firewall on each computer?" No, not necessary as long as the LAN gateway has a properly configured firewall. Unwanted traffic should be stopped at that point. And as long as this is working as intended, there should be no unwanted traffic on the LAN. But, by the same token, doing this certainly does no harm. And on larger LANs that might be mixed platform, or with untrusted users, it would be advisable.
This is where tools like tripwire (http://www.tripwire.org) play a role. Such tools monitor various aspects of the filesystem, and compare them against a stored database. And can be configured to send an alert if any changes are detected. Such tools should only be installed on a known "clean" system.
For home desktops and home LANs, this is probably not an absolutely necessary component of an overall security strategy. But it does give peace of mind, and certainly does have its place. So as to priorities, make sure the Steps 1, 2 and 3 above are implemented and verified to be sound, before delving into this.
RPM users can get somewhat the same results with rpm -Va, which will verify all packages, but without all the same functionality. For instance, it will not notice new files added to most directories. Nor will it detect files that have had the extended attributes changed (e.g. chattr +i, man chattr and man lsattr). For this to be helpful, it needs to be done after a clean install, and then each time any packages are upgraded or added. Example:
# rpm -Va > /root/system.checked |
Then we have a stored system snapshot that we can refer back to.
Debian users have a similar tool with debsums.
# debsums -s > /root/system.checked |
Another idea is to run chkrootkit (http://www.chkrootkit.org/) as a weekly cron job. This will detect common "rootkits".
Wierdness with other system commands (e.g. top or ps) should be cause for concern as well.
Logs that are missing completely, or missing large sections. Or a sudden change in syslog behavior.
/usr/bin/lsattr `echo $PATH | tr ':' ' '` | grep i-- |
# chattr +i /bin/ps # /usr/bin/lsattr `echo $PATH | tr ':' ' '` | grep "i--" ---i---------- /bin/ps # chattr -i /bin/ps |
Indications of a "sniffer", such as log messages of an interface entering "promiscuous" mode.
Packet sniffers, like tcpdump (http://www.tcpdump.org), might be useful in finding any uninvited traffic. Interpreting sniffer output is probably beyond the grasp of the average new user. snort (http://www.snort.org), and ethereal (http://www.ethereal.com), are also good. Ethereal has a GUI.
As mentioned, a compromised system will undoubtedly have altered system binaries, and the output of system utilities is not to be trusted. Nothing on the system can be relied upon to be telling you the whole truth. Re-installing individual packages may or may not help since it could be system libraries or kernel modules that are doing the dirty work. The point here is that there is no way to know with absolute certainty exactly what components have been altered.
RPM users can use rpm -Va |less to attempt to verify the integrity all packages. But again there is no assurance that rpm itself has not been tampered with, or the system components that RPM relies on.
If you have pstree on your system, try this instead of the standard ps. Sometimes the script kiddies forget about this one. No guarantees though that this is accurate either.
You can also try querying the /proc filesystem, which contains everything the kernel knows about processes that are running:
# cat /proc/*/stat | awk '{print $1,$2}' |
This will provide a list of all processes and PID numbers (assuming a malicious kernel module is not hiding this).
Another approach is to visit http://www.chkrootkit.org, download their rootkit checker, and see what it says.
Some interesting discussions on issues surrounding forensics can be found at http://www.fish.com/security/. There is also a collection of tools available, aptly called "The Coroner's Toolkit" (TCT).
Read below for steps on recovering from an intrusion.
The steps to take, in this order:
Restore from backups. After a clean install is the best time to install an IDS (Intrusion Detection System) such as tripwire (http://www.tripewire.org).
Apply all updates or patches for your distribution. Check your vendor's web site for security related notices.
Re-examine your system for unnecessary services. Re-examine your firewall and access policies, and tighten all holes. Use new passwords, as these were stolen in all likelihood.
Re-connect system ;-)
At this time, any rootkit cleanup tools that may be available on-line are not recommended. They probably do work just fine most of the time. But again, how to be absolutely sure that all is well and all vestiges of the intrusion are gone?
Avoid using programs that require clear text logins over untrusted networks like the Internet. Telnet is a prime example. ssh is much better. If there is any support for SSL (Secure Socket Layers), use it. For instance, does your ISP offer POP or IMAP mail via SSL? Recent distributions should include openssl, and many Linux applications can use SSL where support is available.
Set resource limits. There are various ways to do this. The need for this probably increases with the number of users accessing a given system. Not only does setting limits on such things as disk space prevent intentional mischief, it can also help with unintentionally misbehaved applications or processes. quota (man quota) can be used to set disk space limits. Bash includes the ulimit command (man ulimit or man bash), that can limit various functions on a per user basis.
Also, not discussed here at any length, but PAM (Pluggable Authentication Modules) has a very sophisticated approach to controlling various system functions and resources. See man pam to get started. PAM is configured via either /etc/pam.conf or /etc/pam.d/*. Also files in /etc/security/*, including /etc/security/limits.conf, where again various sane limits can be imposed. An in depth look at PAM is beyond the scope of this document. The User-Authentication HOWTO (http://tldp.org/HOWTO/User-Authentication-HOWTO/index.html) has more on this.
Make sure someone with a clue is getting root's mail. This can be done with an "alias". Typically, the mail server will have a file such as /etc/aliases where this can defined. This can conceivably be an account on another machine if need be:
# Person who should get root's mail. This alias # must exist. # CHANGE THIS LINE to an account of a HUMAN root: hal@bigcat |
Remember to run newaliases (or equivalent) afterward.
Be careful where you get software. Use trusted sources. How well do you trust complete strangers? Check your vendor first if looking for a specific package. It will probably be best suited for your system any way. Or, the original package's project site is good as well. Installing from raw source (either tarball or src.rpm) at least gives you the ability to examine the code. Even if you don't understand it ;-) While this does not seem to be a wide spread problem with Linux software sites, it is very trivial for someone to add a very few lines of code, turning that harmless looking binary into a "Trojan horse" that opens a backdoor to your system. Then the jig is up.
So someone has scanned you, probed you, or otherwise seems to want into your system? Don't retaliate. There is a good chance that the source IP address is a compromised system, and the owner is a victim already. Also, you may be violating someone's Terms of Service, and have trouble with your own ISP. The best you can do is to send your logs to the abuse department of the source IP's ISP, or owner. This is often something like "abuse@someisp.com". Just don't expect to hear much back. Generally speaking, such activity is not legally criminal, unless an actual break-in has taken place. Furthermore, even if criminal, it will never be prosecuted unless significant damage (read: big dollars) can be shown.
Red Hat,Mandrake and Debian users can install the "Bastille Hardening System", http://www.bastille-linux.org/. This is a multi-purpose system for "hardening" Red Hat and Mandrake system security. It has a GUI interface which can be used to construct firewall scripts from scratch and configure PAM among many other things. Debian support is new.
So you have a full-time Internet connection via cable-modem or DSL. But do you always use it, or always need it? There's an old saying that "the only truly secure system, is a disconnected system". Well, that's certainly one option. So take that interface down, or stop the controlling daemon (dhcpcd, pppoed, etc). Or possibly even set up cron jobs to bring your connection up and down according to your normal schedule and usage.
What about cable and DSL routers that are often promoted as "firewalls"? The lower priced units are mostly equating NAT (Network Address Translation), together with the ability to open holes for ports through it, as a firewall. While NAT itself does provide a fair degree of security for the systems behind the NAT gateway, this does not constitute anything but a very rudimentary firewall. And if holes are opened, there is still exposure. Also, you are relying on the router's firmware and implementation not to be flawed. It is wise to have some kind of additional protection behind such routers.
What about wireless network cards and hubs? Insecure, despite what the manufacturers may claim. Treat these connections just as you would an Internet connection. Use secure protocols like ssh only! Even if it is just one LAN box to another.
If you find you need to run a particular service, and it is for just you, or maybe a relatively small number of people, use a non-standard port. Most server daemons support this. For instance, sshd runs on port 22 by default. All worms and script kiddies will expect it there, and look for it there. So, run it on another port! See the sshd man page.
What about firewalls that block Internet connections according to the application (like ZoneAlarm from Windowsdom)? These were designed with this feature primarily because of the plethora of virii and trojans that are so common with MS operating systems. This is really not a problem on Linux. So, really no such application exists on Linux at this time. And there does not seem to be enough demand for it that someone has taken the time to implement it. A better firewall can be had on Linux, by following the other suggestions in this document.
Lastly, know your system! Let's face it, if you are new to Linux, you can't already know something you have never used. Understood. But in the process of learning, learn how to do things the right way, not the easiest way. There is several decades of history behind "the right way" of doing things. This has stood the test of time. What may seem unnecessary or burdensome now, will make sense in due time.
Be familiar with whatever services you are running, and the implications these services might have to the overall health of your system if something does go wrong. Read what you can, and ask questions. Don't run something as a service "just because I can", or because the installer put it there. You can't start out being an experienced System Administrator clearly. But you can work to learn enough about your own system, that you are in control. This is one thing that separates *nix from MS systems: we can never be in complete control with MS, but we can with *nix. Conversely, if something bad happens, we often have no one else to blame.
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 |
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.
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.
$ 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 *:* |
$ 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 |
Line two is a little different:
tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN |
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 |
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 |
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 |
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:* |
# 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 |
$ /bin/ps ax |grep 1051 |grep -v grep 1051 ? S 0:24 /usr/libexec/postfix/master |
$ /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 |
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 / -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) |
# 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.
# 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="$?" |
# ls -l /proc/1315/exe lrwxrwxrwx 1 root root 0 July 4 19:41 /proc/1315/exe -> /usr/sbin/cupsd |
# 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 |
So we found no big surprises in this hypothetical situation.
![]() | 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. |
Other relevant documents available from the Linux Documentation Project:
Security HOWTO: http://tldp.org/HOWTO/Security-HOWTO.html |
Firewall HOWTO: http://tldp.org/HOWTO/Firewall-HOWTO.html |
Ipchains HOWTO: http://tldp.org/HOWTO/IPCHAINS-HOWTO.html |
User Authentication: http://tldp.org/HOWTO/User-Authentication-HOWTO/index.html, includes a nice discussion on PAM. |
VPN (Virtual Private Network): http://tldp.org/HOWTO/VPN-HOWTO.html and http://tldp.org/HOWTO/VPN-Masquerade-HOWTO.html |
The Remote X Apps Mini HOWTO, http://www.tldp.org/HOWTO/mini/Remote-X-Apps.html, includes excellent discussions on the security implications of running X Windows. |
The Linux Network Administrators Guide: http://tldp.org/LDP/nag2/index.html, includes a good overview of networking and TCP/IP, and firewalling. |
The Linux Administrator's Security Guide: http://www.seifried.org/lasg/, includes many obvious topics of interest, including firewalling, passwords and authentication, PAM, and more. |
Securing Red Hat: http://tldp.org/LDP/solrhe/Securing-Optimizing-Linux-RH-Edition-v1.3/index.html |
Tools for creating custom ipchains and iptables firewall scripts:
Firestarter: http://firestarter.sourceforge.net |
Two related projects: http://seawall.sourceforge.net/ for ipchains, and http://shorewall.sourceforge.net/ for iptables. |
Port number assignments, and what that scanner may be scanning for:
http://www.linuxsecurity.com/resource_files/firewalls/firewall-seen.html |
http://www.sans.org/newlook/resources/IDFAQ/oddports.htm |
http://www.iana.org/assignments/port-numbers, the official assignments. |
Linux Security.com: http://www.linuxsecurity.com, loaded with good info, and Linux specific. Lots of good docs: http://www.linuxsecurity.com/docs/ |
CERT, http://www.cert.org |
The SANS Institute: http://www.sans.org/ |
The Coroner's Toolkit (TCT): http://www.fish.com/security/, discussions and tools for dealing with post break-in issues (and preventing them in the first place). |
Junkbuster: http://www.junkbuster.com, a web proxy and cookie manager. |
PGP: http://www.gnupg.org/ |
Other documentation and reference sites:
Linux Security.com: http://www.linuxsecurity.com/docs/ |
Linux Newbie: http://www.linuxnewbie.org/nhf/intel/security/index.html |
The comp.os.linux.security FAQ: http://www.linuxsecurity.com/docs/colsfaq.html |
The Internet Firewall FAQ: http://www.interhack.net/pubs/fwfaq/ |
The Site Security Handbook RFC: http://www.ietf.org/rfc/rfc2196.txt |
Miscellaneous sites of interest:
http://www.bastille-linux.org, for Mandrake and Red Hat only. |
SAINT: http://www.wwdsi.com/saint/, system security analysis. |
SSL: http://www.openssl.org/ |
SSH: http://www.openssh.org/ |
Scan yourself: http://www.hackerwhacker.com |
PAM: http://www.kernel.org/pub/linux/libs/pam/index.html |
Detecting Trojaned Linux Kernel Modules: http://members.prestige.net/tmiller12/papers/lkm.htm |
Rootkit checker: http://www.chkrootkit.org |
Port scanning tool nmap's home page: http://www.insecure.org |
Nessus, more than just a port scanner: http://www.nessus.org |
Tripwire, intrusion detection: http://www.tripwire.org |
Snort, sniffer and more: http://www.snort.org |
http://www.mynetwatchman.com and http://dshield.org are "Distributed Intrusion Detection Systems". They collect log data from subscribing "agents", and collate the data to find and report malicious activity. If you want to fight back, check these out. |
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.
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 |
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 |
# 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 |
# 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 |
#!/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 |
#!/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 |
#!/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 |
"Most people just have a single PPP connection to the Internet, and don't want anyone coming back into their network, or the firewall:"
## Insert connection-tracking modules (not needed if built into kernel). insmod ip_conntrack insmod ip_conntrack_ftp ## Create chain which blocks new connections, except if coming from inside. iptables -N block iptables -A block -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A block -m state --state NEW -i ! ppp0 -j ACCEPT iptables -A block -j DROP ## Jump to that chain from INPUT and FORWARD chains. iptables -A INPUT -j block iptables -A FORWARD -j block |
This simple script will allow all outbound connections that we initiate, i.e. any NEW connections (since the default policy of ACCEPT is not changed). Then any connections that are "ESTABLISHED" and "RELATED" to these are also allowed. And, any connections that are not incoming from our WAN side interface, ppp0, are also allowed. This would be lo or possibly a LAN interface like eth1. So we can do whatever we want, but no unwanted, incoming connection attempts are allowed from the Internet. None.
This script also demonstrates the creation of a custom chain, defined here as "block", which is used both for the INPUT and FORWARD chains.