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

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

Building a Secure Gateway, part II

By Chris Stoddard


In the last article, we installed Linux with only those packages we absolutly needed. (If you have not read my previous article, you should do so now, as it is the base from which this is built on.) Now comes the detail work, turning your gateway into fortress. The first thing to understand is there is no way to be completely secure. There is just not enough time to do it all, Corporations employ huge IT departments, whose sole purpose in life is to secure their networks, and still they get cracked. Just accept it and get on with your life. Our real goal here is to keep honest people honest, keep the Script Kiddies out and slow the rest down, giving you opprotunity to discover them. Ideally, this should be done right after the clean install, before the system ever gets put on the Internet. This article assumes you know something about Linux, how to install it, how to edit various configuration files, and that you can log in as root.

I also assume you are setting up a firewall system and have no intention of running DNS, DHCP, web, ftp or telnet server. If you intend to run any of these services, of these services, I recommend setting up seperate machines. Setup a DMZ on your network, a system which is secured but allows connections from system outside your network. This way if an intruder does penetrate your server, he will have to start all over to penetrate your firewall system and you will hopefully discovered his breakin before he is able to get access to your internal network.

System Updates and Security Advisories

In the world of Computer Security, Knowledge is Power. Frankly the Security Experts are always one step behind the Crackers, most security issues are not discovered by the Experts, but by the Crackers and are plugged only after they have been exploited. You need to keep up to date on new problems, at the very least you should be updating the packages as they come out. Type "rpm -qa > packages.txt", this gives you a list of the packages and version numbers installed on your system, then go to Redhat's web site and download the updated packages. While you are there you should read the security advisories and implement any changes they suggest. If you are really proactive, subscribe to both the BugTraq and CERT mailing lists.

Physical Security

Since this article is aimed at the home cable modem user, I will assume physical security is not a problem. If you have child or a nosey baby sitter, consider using the BIOS password protection built into most computers.

User Accounts and Passwords

Besides the root account and the special accounts, which I'll go into in a moment, there should be only one user account. The user and the root accounts should have good passwords. A good password is one that is at least 8 characters long, has a mix of small letters, capital letters and numbers, and is not a dictionary word. It is also a good idea to change these passwords from time to time and do not write the passwords on a sticky note and put it on the monitor where everyone can see it. Use different passwords on each computer on your network, that way, if one system is cracked an intruder will still not have access to the other systems on the network. Again, because password cracking takes time, you will hopefully discover the cracker before he gets too far.

Along this same line, there are several special purpose accounts, which are installed by default with most Linux distributions, for our purposes these accounts are useless and pose a security risk, so we will remove them using the userdel command. The syntax for this command is "userdel username", substituting username with the appropriate account name. The accounts we want to remove are; adm, lp, sync, shutdown, halt, news, uucp, operator, games, gopher, and ftp. We also want to remove the associated groups with groupdel, the syntax is the same. Groups to delete are; adm, lp, news, uucp, games, dip, pppusers, popusers, and slipusers.

Configuration files

This is without a doubt the most important section. Poorly-maintained configuration files are the highest risk factor on any system. In this section you will be typing many of the same commands over and over again, this is a good opportunity to write a shell script to make this easier. What we want to do, after we are finished with each file, is to first make sure it's owned by root; second, that the only account which can read and write to it is root; and third, that it's unalterable even by root. This keeps the files from being accidentally deleted or changed and also prevents the file from being linked to, which could be a security risk. Type "touch secure-it", then type "chmod +x secure-it", now Open the file in your text editor of choice and put these lines in: (text version)


# Change owner to root
chown root.root $1

# Change permissions so only root has access
chmod 600 $1

# Make the file unalterable
chattr +i $1

Now save the file and copy it to /usr/sbin by typing "cp secure-it /usr/sbin". Now when we are finished with a file we can lock it down simply by typing "secure-it filename".

This file tells the system which system on you network are allowed to mount NFS drives from this system. This file should be empty, if it is not, delete it with "rm /etc/exports" and create a new empty one with "touch /etc/exports". Now lock the file down by typing "secure-it /etc/exports".

This where many of the TCP/IP services start. Since the only service we want is ssh--which is not started by inetd--this file should be empty as well. So remove it, "rm /etc/inetd.conf", create an empty one with "touch /etc/inetd.conf". Lock it down with "secure-it /etc/inetd.conf".

This tells the system which systems to deny access to your system's TCP/IP services. We want to deny everybody not listed in /etc/hosts.allow everything, so we edit this file so the following lines are the only thing in it, then we want to lock it down.

This file tells the system which other system may access the services started in inetd.conf, Since inetd.conf is empty, this file should be emty as well. Remove it with "rm /etc/hosts.allow", create an empty one with "touch /etc/hosts.allow", and lock it down with "secure-it /etc/hosts.allow"

The next thing we want to do is keep your system from giving away too much information about itself through attempted logons and ICMP packets. First, delete the /etc/issue and /etc/ files from the system. Next open /etc/rc.d/rc.local in your text editor and remove the following lines;
echo "" > /etc/issue
echo "$R" >> /etc/issue
echo "Kernel $(uname -r) on $a $SMP$(uname -m)" >> /etc/issue
cp -f /etc/issue /etc/
echo >> /etc/issue 
Before you save and close the /etc/rc.d/rc.local file, we want to keep the system from responding to ICMP requests, such as ping and traceroute, so we add the following lines right after the #!/bin/sh line:
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
This will make your system all but invisible to the outside world; the Script Kiddies can't crack what they can't find. The second line helps protect your system from SYN Denial of Service Attacks. Go ahead and save the file and exit. Please note, this will also keep you from pinging the system, but should not interfere with other functions, such as ssh or IP forwarding. Finally, lock it down.

While we are setting up defenses against outside attacks, we should add as the last line in /etc/host.conf the following;
nospoof on
This will cause the system to reject any requests coming from a source outside your network, claiming to be a system on the inside of your LAN, this type of a attack is called IP Spoofing. Go ahead and lock it down with secure-it. Other files we don't need to alter, but need to be locked down are, /etc/services, /etc/passwd, /etc/shadow, /etc/group and /etc/gshadow. If you plan to change your passwd or add a user you will have to run "chattr -i filename" on /etc/passwd, /etc/shadow, /etc/group and /etc/gshadow or you will get an error message.

This is where the system gets information about what drives and partitions should be mounted at bootup and where. If you configured your system with one large root partition or you did not setup a separate partition for /home and /tmp, you can skip this section and go on to setiing up disk quotas. /home and /tmp are important areas because they can be written to by users other than root. What we want to do is limit what a user can do on these partitions. In /home, we do not want the user to be able to create an SUID program or a device, additionally in /tmp we don't want any programs to be able to execute. We do this by changing the /etc/fstab. Mine looks like this and likely yours is similar.
/dev/hda1      /              ext2      defaults        1 1
/dev/hda9      /boot          ext2      defaults        1 2
/dev/cdrom     /mnt/cdrom     iso9660   noauto,owner,ro 0 0
/dev/hda5      /home          ext2      defaults        1 2
/dev/hda6      /tmp           ext2      defaults        1 2
/dev/sda1      /usr           ext2      defaults        1 2
/dev/hda7      /var           ext2      defaults        1 2
/dev/hda8      swap           swap      defaults        0 0
/dev/fd0       /mnt/floppy    msdos     noauto,owner    0 0
none           /proc          proc      defaults        0 0
none           /dev/pts       devpts    gid=5,mode=620  0 0
We want to change the /home and /tmp lines to read as follows:
/dev/hda5      /home          ext2        rw,nosuid,nodev 1 2
/dev/hda6      /tmp           ext2 rw,nosuid,nodev,noexec 1 2

Disk Quota
If you setup a seperate partition for /home, this step is optional. If, instead, you setup your hard drive as one large partition, you should use the disk quota system, this will limit the amount of drive space a user can consume and prevent an intruder who has stolen the account from filling up your hard drive. The default line in /etc/fstab will look something like this.
/dev/hda1      /              ext2      defaults        1 1
Change it to this,
/dev/hda1      /              ext2  defaults,usrquota   1 1
Add the following lines to /etc/rc.d/rc.local
/sbin/quotacheck -avug
/sbin/quotaon -avug
now type "touch /quota.user" and then "chmod 700 /quota.user" and reboot the system. There may have some error messages about quota; ignore them. Once the system is back up, you will need to set the quota for, what should be the only user account, type the following command, replacing "username" the the name of your user account, type "edquota -u username". This should bring up the vi text editor showing something similar to this.
Quotas for user username:
/dev/hda1: blocks in use: 7, limits (soft = 0, hard = 0)
    inodes in use: 6, limits (soft = 0, hard = 0)
By setting a block limit, you are limiting how much drive space the user can consume in KB, by setting the inodes you will be limiting the amount of files the user can have. Soft limits when exceeded will warn the user, hard limits are absolute. Unless you have a very good reason to set them higher, such as you plan on transfering MP3's to this machine, I suggest setting the limits fairly low, something like 10 MB of disk space and 100 files. Edit the lines so they look like like this, then save the file and exit.
Quotas for user username:
/dev/hda1: blocks in use: 7, limits (soft = 5120, hard = 10240)
    inodes in use: 6, limits (soft = 50, hard = 100)
This will set a soft limit of 50 files taking up 5 MB and an absolute limit of 100 files consuming 10 MB of drive space.

Next we want to make sure all the startup scripts in /etc/rc.d/init.d have the proper permissions set, so type the following command, "chmod -R 700 /etc/rc.d/init.d/*".

SUID Programs
We must find all the SUID files on the system. These are programs which take on the identity of root when they are executed, this is a very large security risk. This makes these programs targets for buffer overflow attacks and replacement with Trojans. To find all the SUID programs on the system type "ls -alF `find / -perm -4000` > /root/suid.txt". Now open the suid.txt file and the output should look something like this.
-rwsr-xr-x 1 root root 35168 Sep 22 23:35 /usr/bin/chage
-rwsr-xr-x 1 root root 36756 Sep 22 23:35 /usr/bin/gpasswd
-r-xr-sr-x 1 root tty 6788 Sep 6 18:17 /usr/bin/wall
-rwsr-xr-x 1 root root 33152 Aug 16 16:35 /usr/bin/at
-rwxr-sr-x 1 root man 34656 Sep 13 20:26 /usr/bin/man
-r-s--x--x 1 root root 22312 Sep 25 11:52 /usr/bin/passwd
-rws--x--x 2 root root 518140 Aug 30 23:12 /usr/bin/suidperl
-rws--x--x 2 root root 518140 Aug 30 23:12 /usr/bin/sperl5.00503
-rwxr-sr-x 1 root slocate 24744 Sep 20 10:29 /usr/bin/slocate
-rws--x--x 1 root root 14024 Sep 9 01:01 /usr/bin/chfn
-rws--x--x 1 root root 13768 Sep 9 01:01 /usr/bin/chsh
-rws--x--x 1 root root 5576 Sep 9 01:01 /usr/bin/newgrp
-rwxr-sr-x 1 root tty 8328 Sep 9 01:01 /usr/bin/write
-rwsr-xr-x 1 root root 21816 Sep 10 16:03 /usr/bin/crontab
-rwsr-xr-x 1 root root 5896 Nov 23 21:59 /usr/sbin/usernetctl
-rwsr-xr-x 1 root bin 16488 Jul 2 10:21 /usr/sbin/traceroute
-rwxr-sr-x 1 root utmp 6096 Sep 13 20:11 /usr/sbin/utempter
-rwsr-xr-x 1 root root 14124 Aug 17 22:31 /bin/su
-rwsr-xr-x 1 root root 53620 Sep 13 20:26 /bin/mount
-rwsr-xr-x 1 root root 26700 Sep 13 20:26 /bin/umount
-rwsr-xr-x 1 root root 18228 Sep 10 16:04 /bin/ping
-rwxr-sr-x 1 root root 3860 Nov 23 21:59 /sbin/netreport
-r-sr-xr-x 1 root root 26309 Oct 11 20:48 /sbin/pwdb_chkpwd
As you can see right hand side shows the permissions of each file: anything with an "s" in it has its SUID bit set. By disabling SUID bit, only root will be able to run the program. What needs to be done now is decide which ones can have the SUID bit safely turned off--many of these programs require it for normal operations. Many, however, should be run only by root anyway. How you turn the SUID bit off is with the following command:"chmod a-s filename". My suggestions for this step are; /usr/bin/chage, /usr/bin/gpasswd, /usr/bin/wall, /usr/bin/chfn, /usr/bin/chsh, /usr/bin/newgrp, /usr/bin/write, /usr/sbin/usernetctl, /usr/sbin/traceroute, /bin/mount, /bin/umount, /bin/ping, and /sbin/netreport.

Checking system integrity

The last thing you want to do is setup your system to warn you of any changes to your system. If any intruders do get in and plant a Trojan or create a new account, we want the system to be able to tell what was altered. There are several good programs available for this, the easiest to implement that I've found is fcheck, which can be downloaded from, Follow the instructions for installing and configuring the software, it is very straight forward. Once this is done, you will want it to run at least once a day and redirect the results to a file in the root directory. This can be done through crond, to setup a cron job, type "crontab -e" this will open vi, now type the following line:

1 0 * * * /usr/local/fcheck/fcheck -a > /root/fcheck.txt
Replace the path to check with your own path, save and exit. Now at 12:01 every night, fcheck will run and the output will be placed in /root/fcheck.txt. If at any time fcheck detects altered files which you cannot account for, immeaditly remove the package from the system and reinstall it from the RedHat CD. Anytime you make a change to a file, you will need to rerun "fcheck -ca" and build another baseline.


It is relatively safe to put the system on the internet. Once this is done you will want to test your security. Gibson Research Corporation provides a port scanning service. In a perfect world, all the ports should be in stealth mode, meaning the ports do not respond to requests at all and will appear as though there is no system at your IP address. In a pinch the ports should be closed, meaning the port responds, but will not take requests; closed ports are still vulnerable to some types of attacks. Open ports are vulnerable ports, if any of your ports are open go back to the inetd.conf file, make sure it is empty, check to make sure apache, wu-ftpd or similar are not installed, also review your ipchains settings to ensure it is denying packets properly. It is a good idea to do this regularly to ensure an intruder has not opened a port for his personal use.

Again, as with my last article, I'd like to point out, this is not the end-all and be-all of Linux security, this is only a starting point. I have simplified this down to the very basics, there are many more things which could be done. Whether or not you should seek out these solutions, depends on what you are protecting. For a home user this will probably do just fine, however even a small business with more machines and data to protect, you should do more research and implement as much security as is possible. Better yet, hire a Network Security Consultant to implement it for you.

Copyright © 2000, Chris Stoddard
Published in Issue 55 of Linux Gazette, July 2000

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