LINUX GAZETTE

[ Prev ][ Table of Contents ][ Front Page ][ Talkback ][ FAQ ][ Next ]

"Linux Gazette...making Linux just a little more fun!"


A Private Home Network

By Jan Stumpel


1. Introduction

Until recently I paid little attention to the security of my home network for the following reasons: Common human psychology suggests that this is how many ordinary Linux users think. In my case, unfortunately, all these points turned out to be pure wishful thinking, apart from the last one. Because of  the last one.

How did I find this out? In order to prepare for the happy day in the future when permanent, high-speed connections to the Internet will be offered in my area, I decided it was a good idea to start investigating security issues. The results were shocking.

The first shock came from looking at my long-neglected /var/log/syslog* files. A few 'refused connect from' entries. One 'connect from' to ftp which apparently succeeded. Oops. Dial-up Internet users are not overlooked by the crackers after all. And my security is not bullet-proof. Better to spend some time really looking at security. And to try to understand something of it this time. So this meant reading books, FAQ's, HOWTO's, and a lot of articles on the Web; and doing some experiments.

This is the result of my investigations. Mind: I am not an expert, but just an amateur, a home user trying to make things work. Nothing of this comes with any guarantee.

2. The system

I have a very simple home network with two machines: This local network uses one of the IP address ranges reserved for private networks, 192.168.1.0/24. heaven is 192.168.1.1, earth is 192.168.1.2.

The contents of /etc/hosts on heaven, and c:\windows\hosts on earth, is:

127.0.0.1               localhost
192.168.1.1             heaven.my.home  heaven
192.168.1.2             earth.my.home   earth
This shows that my network uses the domain name my.home. This name is unregistered and meant only for local use. Mail to the outside will have its 'message from' and 'envelope from' addresses translated (in the July and September issues, 1999, of LG I described how to do this).

3. 'Private' home networks

My notion of security is to have a private network. By this I mean a network that provides no public functions. It does not serve WWW pages or files. You cannot telnet into it. It does not even listen to anything coming in from the outside. If anyone comes knocking, there is simply no response. This idea was recently put forward by Sander Plomp, whose articles at rootprompt.org provided much of the inspiration for this piece.

A LAN which is not connected to the Internet is a private network by definition. Unplug your modem, and you make your network private. But that is a not the kind of private network that I mean. I want to use the Net, send and receive mail, browse the Web, download files, etc. I just do not want anyone from the outside to enter my network.

Linux systems generally aren't private networks. By default, the installation procedure of a Linux distribution sets up all sort of nice network services (like telnet, ftp, finger, etc.) which are accessible by anyone in the world, protected (if at all) only by a password. Also, Microsoft Windows home LAN's are generally not private. Connect two Win95 computers and enable 'file sharing', and the whole world can share your files while your Internet connection is up.

To make non-private networks safe, various techniques are used; passwords of course, and also other security techniques that have been discussed in the Linux Gazette many times, like tcpd (alias tcp wrappers) and kernel-level packet filtering (with ipchains as the user interface). These techniques give some privacy to a system which is essentially public. They are like guards at the door, put there to keep out unwanted characters, while letting the desirable customers in. But why should there be doors at all? I don't want any customers. My network is private!

If we have servers running, reachable by the outside world, we always have to worry about having made some configuration mistake which can be exploited. Also, server programs often have bugs in them which offer openings to crackers. Only recently one was discovered in named. OK, it was later patched, so people who got the newest version of named do not have to worry anymore about this bug. But what about the next one? Better not to to have any doors at all!

If you really want to enable services (mp3 distribution, or whatever) for use by computers outside your home, you must study more advanced security techniques. But if you simply want a private network for the home, read on.

4. How safe is your network?

To test the safety of a home network, you can have it 'scanned' from the outside, for instance by Secure Design. Click 'scan me now' and 'basic scan'. Try it both from the gateway machine and from the other machines on your network. When I did this, I got the second shock. It was embarrassing. A long list showing possible entry points into my system: Samba shares, telnet, the print service, X, the mail server, ftp, finger, etc. I had some rudimentary safety measures in place, so the system was somewhat protected from serious intrusion (I hope). But I consider it a breach of my privacy that the outside world even knows that I have a mail server (let alone letting them break into it). These services were meant for use within my home network. They are not the business of the outside world in any way.

So: have your system scanned! Apart from Secure Design, other scan services exist, e.g. Shields Up!, DSL Reports, Sygate Online Services, and many others. A whole lot of them can be found at an Austrian site, Sicherheit im Kabelnetzwerk ('Security in the Cable Network'; there is also an English version with almost the same information). Use several scan services. Print the results. What this 'scanning' actually means will hopefully become clearer in the course of this article.

You can also 'scan' your system yourself by calling (after su-ing to root) netstat -pan --inet. Use a wide xterm window when doing this, because the output consists of rather long lines. Programs which have 0.0.0.0 in the 'Local Address' column are visible to the whole world!

5. Servers and clients

The distinction between servers and clients is not always clear to users. If you want to use ftp, for instance (getting files from, and putting files into, another computer) you use an ftp client program to connect to the other computer. If that is all you want to do with ftp, the client program is all you need. An ftp server is only needed if you want to allow others to get files from, or put them into, your computer. Similarly with telnet: a client program for your own use, a server program for other peoples' use. The client and server programs are completely different and have different names; for instance /usr/bin/telnet for the telnet client, /usr/sbin/in.telnetd for the server. For novices, the distinction is not always clear. If a Linux setup program asks 'shall I set up the ftp server?', users may think 'well eh.. yes, I certainly want to use ftp, so go ahead'. Often you are not even asked, and an ftp server is installed by default.

One way of creating a private network is not to install servers at all, just clients. But that is too simple if you have a network at home connecting two or more computers. Inside your network you want to telnet from one machine to another, you want to run an internal mail service, etc. In other words you can't do without servers.

What servers do is listen. They listen for a signal that says: I want your service. The signal (at least for the TCP-based services) is a special IP packet, called a SYN packet, that enters your computer and specifies the number of a service. For instance, the number of the telnet service (that the in.telnetd program, if it is running, listens to) is 23. These numbers are usually called 'port numbers'. If the in.telnetd program is not running, no one listens to SYN packets with the number 23. So, as they say, 'port 23 is closed'.

Ports do not exist by themselves, like little doors in your computer that you can open or close. A port is open if a server listens to it. Otherwise it is closed. A TCP port comes into existence if there is a program which listens to it, and if not, it does not exist!

How do the SYN packets get into your computer? In the case of heaven, a packet can get 'into' it in three different ways:

Now the key point is that servers normally listen for any packets with 'their' port number, no matter which way they enter the system. If we want to make a private network, offering no services to the outside world, we must somehow change this.

It would be nice if all the server programs available on Linux systems had options specifying which interfaces they will listen to. In that case you could just tell all your servers never to listen to the ppp line, and you'd be all set. Hardly any security measures would be needed at all (tcpd, firewalls, etc.); you would only use them 'for good measure', as an extra precaution. Maybe this will happen at some time in the future, but at the moment only a few server programs have this (including the important cases of exim and samba). So we have to do several things to make our network private:

  1. it never hurts to follow the commonly-heard advice to 'close unneeded ports', in other words not to run servers that you do not need.
  2. for services that have the option, make them listen to internal interfaces (eth0 and, if necessary, loopback) only.
  3. the 'super-server' inetd (which is used for 'waking up' a lot of different servers on a Linux system) should be replaced by xinetd, which has the option to listen to internal interfaces only. NOTE: apparently, Red Hat Linux 7.0 installs xinetd by default.
  4. unsafe servers which cannot run from xinetd (like the print server lpd) should, where possible, be replaced.
  5. for the remaining difficult cases you need a firewall that blocks SYN packets from the outside. This could also be used for blocking unwanted UDP and ICMP access.
  6. for 'advanced' security, a few other possibilities suggest themselves. One is not to use IP masquerading and forwarding on your network.

6. Removing unneeded services

6.1 Unnecessary inetd services

First, there are some services which run 'from inetd.conf'. Almost all Linux systems have a 'super-server' called inetd, whose job it is to listen to a lot of ports at the same time, and to 'wake up' services when needed. However, it will also wake up services which you do not need.

Examples of unneeded services are:

These services can all be disabled by commenting out (putting a # character at the beginning of) the corresponding lines in /etc/inetd.conf, and restarting inetd (in Debian: /etc/init.d/inetd restart).

6.2 Other unnecessary services

If a service is not woken up by inetd, it runs independently, as a 'daemon' or background program.  Among the daemons which you may not need, apart from the portmapper (if run as a daemon) is a local nameserver (named, pronounced name-dee). There is no reason why a small home network should run such a thing. /etc/hosts and C:\windows\hosts files on your machines, and the addresses of your ISP's name servers in /etc/resolv.conf will enable address lookup on your network.

There is usually a command to prevent a service from starting automatically upon boot-up, by removing it from the start-up directories; for instance I got rid of a tamagotchi server, automatically installed by Debian 2.1, by calling

update-rc.d -f /etc/init.d/tama remove

7. Securing wanted services: non-inetd

Now we tackle services that we do want to use, but do not want to be visible to the outside world. Often there is some configuration option that will keep the service 'private'. Examples follow.

7.1 X

X was designed as a network-oriented window system, but in fact the network features are never used in most setups, and present a security risk. You can eliminate X's network capabilities by starting X with a command-line option: startx -- -nolisten tcp. Secure Design now no longer reports that 'X11 is open'.  To make this permanent, you can make an alias for startx in ~/.bashrc, /etc/profile, or some other good location, like this:
alias startx="startx  --  -nolisten tcp"
The -nolisten tcp command should really be in one of the X11 resource files, but so far I haven't found out which one. The 'alias' approach works in any case. To test, run (as root) netstat -pan --inet. X should no longer be mentioned. Of course it would be nicer if we could keep X's network abilities for the local network, only blocking them against outside access, but I couldn't find a way to do that.

7.2 Samba

In a Debian system, the configuration file for Samba is /etc/samba/smb.conf (on other systems, it may be /etc/smb.conf). When installing Samba, I chose 'let Samba run as daemons'; it did not work properly from inetd. Any lines referring to netbios (which is what Samba uses) in /etc/inetd.conf must therefore be commented out. Then in /etc/samba/smb.conf, section [global], I added
 bind interfaces only = True
 interfaces = 192.168.1.1
After /etc/init.d/samba restart, the Samba daemons only listen to our home LAN. They are no longer visible to the outside world. Check with netstat -pan --inet, and by having the system scanned.

7.3 Exim

Exim is the mail server (or Mail Transport Agent, MTA) on my system. You may have something else (like sendmail or postfix) but then the same principle applies: your private mail agent should not listen to the outside world. People who send mail to you, and to the other users in your home, send it to mail accounts at the ISP (or to several mail accounts at different ISP's). You retrieve it from there using, e.g., fetchmail. People cannot send mail to your network directly.

Exim turns out to have an option local_interfaces (which goes into the MAIN CONFIGURATION section of /etc/exim.conf). This is a list of (IP addresses of) interfaces that exim will listen to. This only works when exim runs as a daemon, independent of inetd. To set this up:

Letting exim run as a daemon means that it consumes some cycles and some memory all the time. But as a bonus, exim's RETRY CONFIGURATION now works properly as well, which it never did when running under inetd.

7.4 Junkbuster

Junkbuster is an http proxy server which you can configure to keep out ads and other unwanted stuff. It works very well. In a Debian system it listens to port 5865, in other systems to port 8000. This is set in the file /etc/junkbuster/config. By default, junkbuster listens to all interfaces (in other words, to the whole world). However, you can set in the config file

     listen-address      192.168.1.1:5865

and now only machines on our own network can connect to it (including the gateway machine that junkbuster runs on, heaven in this example, provided heaven is entered in the Netscape 'Preferences/Advanced/Proxies' menu, not localhost).

7.5 Other (non-inetd) services

The above examples are only examples. If your system runs other services outside inetd, check their documentation for ways to make them private. For instance, it appears that sendmail can be made to listen only to the local network by means of

     0 DaemonPortOptions=Addr=192.168.1.1

in the sendmail.cf file. I did not try this.

7.6 Remaining problem cases, like lpd

lpd remains a problem. It cannot be made to listen to the internal network only. Basically, it should be replaced by something safe. Sander Plomp recommends replacing it by pdq. I've been too lazy to do this yet, but it certainly needs attention in the near future.

Other problem cases may remain: servers which you need in your own network but which cannot be made private, and for which private alternatives do not exist. I have this problem with cannaserver, a system for inputting Japanese characters from the keyboard. Such services must be screened from the outside world by means of a packet-filtering firewall. See section 10 of this article.

8. Masking the inetd services through xinetd

By now the list of visible services on the system, according to the Secure Design scan, has become: Much fewer than there used to be, but still far too much. Telnet and pop3 are started by inetd/tcpd and thus are secured by hosts.allow and hosts.deny, but I'm not sure that this protection is 100% cracker-proof. lpd remains totally 'open', as far as I can guess, unsecured. It cannot, I think, be started from inetd.

8.1 Replacing inetd

Security for a home network really requires replacing inetd by something which can distinguish between requests for service from the local network and from the outside. Plomp recommends tcpserver; I tried xinetd. First kill inetd, then install xinetd. Important: The Debian script /etc/init.d/xinetd not only starts the xinetd daemon by itself, but also the portmapper. We do not need/want the portmapper, which is used for RPC calls and NFS, which we do not use. So anything related to the portmapper in /etc/init.d/xinetd must be commented out (# at the beginning of the line).

One way to configure xinetd for telnet and pop3 is to put in /etc/xinetd.conf:

defaults
    {
      instances = 10
      log_type = SYSLOG daemon
      log_on_success += DURATION HOST USERID
      log_on_failure += HOST
      interface = 192.168.1.1
    }

service telnet
    {
      socket_type = stream
      wait  = no
      user  = root
      server = /usr/sbin/in.telnetd
    }

service pop-3
    {
      socket_type = stream
      wait  = no
      user  = root
      server = /usr/sbin/in.qpopper
    }

So apart from a general 'defaults' section which specifies the interface, there is a separate section for each service that you want to run. Although the format is completely different, the data for the various sections can be found in your existing inetd.conf. See also man xinetd.conf.

I started xinetd and verified that is is now possible to telnet to heaven both from heaven itself and from earth. However, Secure Design no longer reports that my system has open telnet and pop3 ports! Success! NOTE: from my own machine, telnet heaven succeeds, but telnet localhost does not. xinetd can only bind to one interface; in this case 192.168.1.1, not at the same time to localhost, which is the loopback interface (127.0.0.1).

By now, all other services in /etc/inetd.conf have been commented out. Therefore inetd no longer does anything and we can get rid of it in the boot-up scripts. In Debian, it goes like this:

update-rc.d -f /etc/init.d/inetd remove
Its place is taken by xinetd:
update-rc.d xinetd defaults
OK; another step towards security successfully taken.

The output of netstat -pan --inet is now something like:

heaven:~# netstat -pan --inet
Active Internet connections (servers and established)
Proto  Local Address     Foreign Address  State   PID/Program name
tcp    127.0.0.1:25      0.0.0.0:*        LISTEN  11391/exim
tcp    192.168.1.1:25    0.0.0.0:*        LISTEN  11391/exim
tcp    192.168.1.1:139   0.0.0.0:*        LISTEN  10761/smbd
tcp    192.168.1.1:5865  0.0.0.0:*        LISTEN  1670/junkbuster
tcp    192.168.1.1:110   0.0.0.0:*        LISTEN  161/xinetd
tcp    192.168.1.1:23    0.0.0.0:*        LISTEN  161/xinetd
tcp    0.0.0.0:515       0.0.0.0:*        LISTEN  148/lpd MAIN
udp    192.168.1.1:138   0.0.0.0:*                10759/nmbd
udp    192.168.1.1:137   0.0.0.0:*                10759/nmbd
udp    0.0.0.0:138       0.0.0.0:*                10759/nmbd
udp    0.0.0.0:137       0.0.0.0:*                10759/nmbd
raw    0.0.0.0:1         0.0.0.0:*         7      -
raw    0.0.0.0:6         0.0.0.0:*         7      -

Almost all services now listen to a local interface. The print system is the exception: it listens to address 0.0.0.0 (i.e., everywhere) on port 515. Sure enough, if the system is scanned now, only port 515 is reported as 'open'. In fact some Windows-oriented scan services will report your system as totally 'closed', because they do not scan port 515.

9. What about IP Masquerading?

For ages I have used IP Masquerading, to give the Windows box in my home access to the Internet. Or so I thought. When recently, in the course of my investigations into system safety, I switched off Masquerading, the Windows box could use the Internet as before.

What happened? Simply that earth, the Windows machine, only does three Internet-related things:

  1. e-mail, which does not require earth to connect to the Internet, only to the smtp and pop3 servers running on heaven;
  2. Web browsing; for this, earth connects to junkbuster on heaven, again not directly to the Internet;
  3. fetching the outside mail from the ISP; for this, earth's user telnets to heaven and runs fetchmail from there.
So, ever since I installed junkbuster about six months ago, earth has never approached the Internet directly, and Masquerading is now superfluous. I had not realized this. Inadvertently I had created a 'proxying firewall'. This means that Masquerading can - and must - now simply be switched off. This has several advantages: The only 'downside' is that earth is now restricted to e-mail and http only. No ping and telnet to the outside world, no ftp, Real Audio, chat, etc. But for the moment mail and http is all that's required. If other services become necessary on earth, I suppose I shall have to install proxies for them on heaven.

To switch IP masquerading and forwarding off, in Debian, you do

10. Closing the last doors

Let's recapitulate: by eliminating services, reconfiguring other services so they don't listen to the gateway interface, by wrapping others inside xinetd, and by turning off Masquerading, we have created a system which is already quite secure without a firewall. Now it is time to add the final touch: we build a packet-filtering firewall around the system using ipchains. This should be the last step, not the first.

One often reads the advice to configure ipchains in such a way that 'everything is blocked by default', and then to make exceptions for the things that you want to allow. Theoretically this may be the right thing, but in practice it leads to much frustration. If everything is blocked, your system will basically not work. You are more or less groping in the dark when it comes to deciding what you have to allow. So I allow everything by default, and then add restrictions one by one. If the system breaks (e.g. no ping, or no Web page viewing) the last restriction has been too drastic, and must be undone. Setting the default policy of a chain to DENY or REJECT can then (again) be the last step, not the first.

I started by taking down the firewall (ipchains -F) and then running a simple firewall script with one rule:

#!/bin/sh
# simple firewall

ipchains -F input
ipchains -P input ACCEPT
ipchains -A input -i ppp0 -p TCP --syn -j DENY -l

This blocks SYN packets coming from the outside interface, enhancing the privacy of the system very considerably. Nobody from the outside can start a connection; outside scan services report that the site is completely closed (some now even call it 'stealthed' or 'invisible'). But we can add more restrictions. That is, we can use more general DENY/REJECT rules, and more specific ACCEPT rules.

Before you add restrictions, it is useful to do some experiments. You can make ipchains-type rules which let packets through while logging them (-j ACCEPT -l). So even if (like me) you do not really know which packets to block, you can see what is going on 'normally' by keeping a window open with tail -f /var/log/syslog in it. Then afterwards you can make rules to block packets which are not 'normal'. I strongly advise you to do your own experiments, and to make rules based on your own understanding.

After a few such experiments, my firewall script in /etc/ppp/ip-up.d looks as follows. This assumes you have no nameserver running, but have the addresses of TWO nameservers provided by your ISP in /etc/resolv/conf. Mind the important backquotes (`)! They may disappear if you cut-and-paste from this page.

#!/bin/sh
# A slightly more complicated firewall

# Find external name server addresses
ns="`grep nameserver /etc/resolv.conf | awk '{print $2}'`"
nameserver1="`echo $ns | sed -e 's/ .*//'`"
nameserver2="`echo $ns | sed -e 's/.* //'`"

# Set up INPUT rules
ipchains -F input
ipchains -P input ACCEPT

# Block outside input from reserved address ranges
ipchains -A input -i ppp0 -s 10.0.0.0/8      -j DENY
ipchains -A input -i ppp0 -s 172.16.0.0/12   -j DENY
ipchains -A input -i ppp0 -s 192.168.0.0/16  -j DENY

# Block TCP connections from the outside
ipchains -A input -i ppp0 -p TCP --syn -j DENY -l

# Block all UDP except nameserver replies
ipchains -A input -i ppp0 -p UDP -s $nameserver1 53 -j ACCEPT
ipchains -A input -i ppp0 -p UDP -s $nameserver2 53 -j ACCEPT
ipchains -A input -i ppp0 -p UDP -j DENY -l

# Allow (for now) but log all ICMP
ipchains -A input -i ppp0 -p ICMP -j ACCEPT -l

# From local net, allow only packets to us and broadcasts
# Forwarding is off, other packets won't go anywhere, but
# now we can log them to detect illegal activity on our net
ipchains -A input -i eth0 -d 192.168.1.1   -j ACCEPT
ipchains -A input -i eth0 -d 192.168.1.255 -j ACCEPT
ipchains -A input -i eth0 -j REJECT -l

# Set up OUTPUT rules
ipchains -F output
ipchains -P output ACCEPT

# Don't send packets out to reserved address ranges
ipchains -A output -i ppp0 -d 10.0.0.0/8      -j REJECT
ipchains -A output -i ppp0 -d 172.16.0.0/12   -j REJECT
ipchains -A output -i ppp0 -d 192.168.0.0/16  -j REJECT

# Block all UDP except nameserver requests
ipchains -A output -i ppp0 -p UDP -d $nameserver1 53 -j ACCEPT
ipchains -A output -i ppp0 -p UDP -d $nameserver2 53 -j ACCEPT
ipchains -A output -i ppp0 -p UDP -j REJECT -l

# Allow (for now) ICMP to the outside, but log
ipchains -A output -i ppp0 -p ICMP -j ACCEPT -l

# We do not have FORWARD rules; forwarding is off

Such a firewall (which you should adapt to your personal tastes and needs) will provide an extra 'shell' around the system. But basically, the security of your system should not depend on the firewall; if only because firewalls are complicated things, and it is far too easy to make mistakes with them. Many other things can be done first to ensure the privacy of your network.

11. References and further reading

  1. Amateur Fortress Building in Linux, part 1, by Sander Plomp (rootprompt.org)
  2. Amateur Fortress Building in Linux, part 2, by Sander Plomp (rootprompt.org)
  3. Real World Linux Security, by Bob Toxen (Prentice-Hall, 2001).
  4. What is the difference between REJECT and DENY? (Linux@home)
  5. Ipchains log format (Linux@home). For understanding what you see while running tail -f /var/log/syslog.
  6. ICMP Type numbers (IANA)
  7. Setting Up Mail for a Home Network Using Exim (Linux Gazette, July 1999)
  8. Experiments with SMTP (Linux Gazette, September 1999)


Copyright © 2001, Jan Stumpel.
Copying license http://www.linuxgazette.net/copying.html
Published in Issue 65 of Linux Gazette, April 2001

[ Prev ][ Table of Contents ][ Front Page ][ Talkback ][ FAQ ][ Next ]