Custom Search

Setting up a secure linux server

Setting up a secure linux server

Get the LFS LiveCD at

Get the latest official LFS book at, download all the packages and make sure everything is up to date. The livecd contains all the LFS packages, but I have a separate copy of the packages which I burn to another CD along with my personal notes and files.

It takes many days to install the LFS system. Take your time to do it right and make double-sure everything is as it should be. This server will last many moons with very little maintenance needed. Do it right.

Before you start the install, review the rest of this document. You'll need to decide on a boot manager and a partitioning scheme, and a plethora of little things.

Vaya con Dios.

Boot partition notes:
I use a separate boot partition (hda1) and root partition (hda5). You can keep an existing gnu/linux installation under (hdaX). Grub needs the following /boot/grub/menu.lst file:

title lfs1 -------------- kernel name
root (hd0,0) --------- boot partition
kernel /lfs1 root=/dev/hda5

title rh62
root (hd0,0)
kernel /vmlinuz-2.2.14-5.0smp root /dev/hda6
(note to self: it's menu.{small L}st, not menu.1st)

Note that the kernel path doesn't specify 'boot'. The LFS book doesn't mention this (because they are using a /boot folder on the LFS partition), and didn't help. Thanks, Joel! (
grub doesn't see the separate /boot partition or a folder called /boot, it sees /.

Below is the older, original document, still chock full of valuable tips and homespun wisdom. Adjust your perception accordingly.

text editor learning curves

Update: January 2009
CentOS 5.x is very similar in layout and packages as was RedHat, so
this can still be used as a reference.
OPINION PIECE: CentOS is a horrible server. Package management practices that you can't
easily change will force the installation of much unwanted software; bad news for a paranoid
sysadmin. I can't judge it as a desktop platform.
Here is a nice summation of what I've concluded:
"And remember: If you break it, you get to keep both pieces. There will be no support
from the IRC-Channel, for example."
And it's true. I've never seen more RTFM-related non-help as I've seen on the CentOS forums.
Slackware, oh slackware....where were you???

<-- start older document

RedHat6.2 or later && Linux From Scratch

Later RedHat editions can be used, of course

A computer
RedHat 6.2 or later CD-ROM
The latest from
I won't be going into theory very much...if you do the lab work as you read, everything should make sense. First is a basic RH 6.2 installation, then LFS.

I don't claim to know more than anyone. I'm just a poor, overworked and overtaxed sysadmin from Kansas. A lot of this, and most of my LFS notes, aren't meant as a standalone tutorial; they're just notes I've kept over time. All files in this directory should be considered obsolete and suspect. Never take anyone's word for anything.

This document assumes:
    You are using an IBM-compatible PC
    multiple mail/ftp accounts and multiple domain names/IP addresses
    Apache webserver, Sendmail, Qualcomm's qpopper, wu-ftpd, OpenSSH, BIND
This document puts everything on a single machine for simplicity, but of course a separate mail server, name server, etc. is safer (if you listen to "them.") It also assumes remote access is necessary, but console access only would be ideal.

Most software is and always have been and Always Will Be full of security holes, and old software is dead for a reason. Never plug into a network with the RedHat installation. Ever.

Server security is multiple redundancy, i.e. if someone gets past one layer of security, there's many more beneath it. Even such seemingly useless things like chattr can be useful to stop a scripted attack and must not be neglected.

Before you start, disconnect any and all network cables. No one gets access until everything is set up and ready to go live.

We'll start by installing RedHat 6.2.

I partition the disk as follows:
/ - 100M
/boot - 6M
/tmp - 50M
/usr - 400M
/var - 200M
/home - ?M
/root - 10M
/apache - ?M
/bind - ?M
We'll be setting mount flags later, e.g. read-only, no suid, etc.; remember that as you partition.
This is only a vague outline; the exact sizes depend on what you plan to install and how big your disk is. You may want a separate /apache & /bind partition for a little bit more control, perhaps just a /chroot partition. Root should be small/nonexistent because you don't play/experiment with a secure server; root and boot can be smaller than shown. Home gets all remaining disk space so the web sites can grow (nothing else but logs and mail will be saved to disk). The / partition can be smaller, too. Just make sure your stuff doesn't write to it.
Nothing from this base install will go into /opt so I don't create it, nor do I let anything else install there. I use non-standard paths wherever possible to reduce the chances of a scripted attack succeeding. Note to Windows users: change your temp directory!
Swap file advice from IBM

Package selection can be a long, involved process, but it's important. Take the time to do it right. If you get a message about needing additional packages to satisfy dependencies, push the Back button and start over.
Choose a 'Custom' install and in the Package Group Selection window, unselect all but Development, Kernel Development and Utilities, then select 'Select individual packages' at the bottom of the window.
What to choose during the installation

Useful files to have around:
# ls -lR / > filename ...This will save a permissions/directory tree for later reference.
# rpm -qa | sort > file ...get a list of all installed packages
Also copy /tmp/install-log to a safe place.

The rest of this isn't important for the RedHat system alone; this is the base system to build a Linux From Scratch system on and can be used on both.

Initial firewall setup
The first order of business is access control. Your default policy should be 'deny' or 'reject':
/sbin/ipchains -P input DENY
/sbin/ipchains -P output DENY
/sbin/ipchains -P forward DENY
The RedHat RPM will install a script in /etc/rc.d/rc3.d/ipchains. Verify that you have /etc/rc.d/rc3.d/S08ipchains, and that it's the lowest number of the 'S' files.
I use something like this  [ or this ]  which will ensure my firewall is up with DENY before the network comes up.

Enter ntsysv to bring up the list of services you have running. What a mess! Un-'X' all but:
crond inet ipchains keytable network random syslog

Now is a good time to reboot; it'll stop all the unneeded services, and you can make sure the firewall is ok with '$ipchains -L'

Even though you selected 'Let me choose' at install time, they insisted you needed more. Uninstall these packages (rpm -e anacron apmd ash ...):
( * is a wildcard, e.g. krb* = uninstall all packages starting with 'krb')
anacron apmd ash at authconfig cpio ed eject hdparm linuxconf gd gnupg gpm isapnptools kbdconfig kernel-pcmcia-cs kernel-smp kudzu mailcap mkbootdisk mkinitrd mt-st mouseconfig ntsysv pump raidtools redhat-logos rmt sash sendmail setserial slocate timeconfig
rm -R /etc/ppp
rm /etc/printcap
rm -R /etc/X11

Hopefully, no one but you will ever see this RedHat system so this is mostly just to save disk space.

There will be more or less, depending on what you did during the OS install. It's important to know about everything on your system, so using your 'rpm -qa' file as a guide, do a 'rpm -qi ElectricFence' , 'rpm -qi MAKEDEV' , etc. You'll need this information when you do your last round of uninstalls before going live.

My filesystem now holds 174869 bytes.

When you're done, cd to /etc/rc.d/rc3.d and look at your 'S' links. For now you should have: S08ipchains, S10network, S20random, S30syslog, S40crond, S50inet, S75keytable and S99local. Delete all the 'K' files and the files they point to in ../init/.

Cat /etc/passwd as a reference and remove some accounts.
$ userdel adm lp news uucp operator games gopher ftp
$ groupdel - the same as above, plus some more; some are needed by the system, but you can always groupadd them if needed. Remember that there's no lusers (local users) but root and you.

Fix /etc/syslog.conf:
*.* (tab) /dev/tty5
*.* (tab) /var/log/tty5
so I can see log messages in real time on tty5, with a backup to file. After installing LIDS you'll want to change it to:
if you want any useful information from tty5. Touch /var/log/tty5 before restarting syslog and edit /etc/inittab to comment out 'respawn:/sbin/mingetty/tty5' before rebooting.
I do the same setup with portsentry and kernel logs.
After editing syslog.conf and before restarting syslog, remember to
# touch /var/log/kernel
# touch /var/log/portsentry

/etc/logrotate.d/syslog.conf  /etc/logrotate.conf

Download and install the latest kernel RPM from RedHat, then after rebooting uninstall all traces of the old one. This shouldn't be needed; it's a fallback kernel in case something goes wrong. You'll have to update rpm first.
Download the latest kernel from You won't need to update your soon-to-be-superfluous redhat system.

As of today [August 20, 2002], I wouldn't use the 2.4.x line in a production server.

Download the kernel sources and patches you want to use. You should always plan on LIDS ( for both the 2.2x and 2.4x kernels and openwall (, but all patches probably aren't available for the kernel you choose.
The kernel configuration should be very limited, i.e. no serial port, parallel port, etc. With such a restricted kernel you can build a monolithic kernel, i.e. no modules, and still end up with a very small memory footprint, eliminating the threat of exploits that rely on loadable kernel modules.
If you have physical access to the server, you should restrict bootups with:
a CMOS password (and disable booting from a floppy or better yet, remove the floppy drive itself)
/etc/lilo.conf 'restricted' and 'password=' options

Download and install the latest iptables package. I use a file similar to this in the start-up scripts. It needs a file named /root/, which for now can be:
/sbin/iptables -P INPUT DROP
/sbin/iptables -P OUTPUT DROP
/sbin/iptables -P FORWARD DROP
Verify it works before you continue.
Of course the same principle applies to ipchains.

This is about where I start using LFS notes. Below is for reference && historical purposes.

Put any sensitive/critical machines in /etc/hosts, especially if you use someone else's DNS server. Don't plug the network cable in, though.

Fix up your PAM configuration files and then download the latest pam.x.src.rpm (rpm --rebuild pam*src.rpm ... cd /usr/src/redhat/RPMS/ ...rpm -Uvh pam* ) or get the tar.gz sources from, which installs flawlessly if you follow the INSTALL file instructions.
Go through the directories /lib/security/, /etc/pam.d/ and especially /etc/security/; it has lots of fun stuff to play with.
Fun Fact: if you add: ' -:ALL:ALL ' to access.conf without preceding it with something like ' +:root:ALL ', you'll be locked out.
/etc/pam.d/login  /etc/pam.d/other

Get the Stackguard compiler src.rpm ( and rebuild/install it. Afterwards, use it to compile sendmail, BIND, etc. Stackguard can't compile the kernel, dsniff, most likely other things, so don't throw away the old one yet.

Fix cron files in /etc : touch cron.allow and make the only entry: root . No one else will be able to log in anyway. Go through all of the cron.* directories and remove everything. You may want to keep logrotate and tmpwatch, but you'll have to disable LIDS and unchattr the files anyway, so you should do it manually.

Uninstall the compiler and related stuff (ElectricFence, yacc, etc)
Delete all sources and documentation ( /usr/doc/* /usr/man/*)
Search and destroy SUID/SGID files: # find / -perm -200 -o -perm -400 > suidfiles.txt careful; test everything.
S & D unowned files: #find / -nouser -o nogroup > unownedfiles.txt

Open /etc/fstab in your favorite editor (your favorite editor is vi, ya stinkin' commie) and add mount flags. The defaults are:
rw, suid, dev, exec, auto, nouser, async
Which is obviously ridiculous. They should be, at best:
/boot defaults,nodev,noexec,nosuid,ro
/lib defaults,nodev,nosuid,ro
/usr defaults,ro,nodev
/var defaults,nodev,nosuid,noexec
/tmp defaults,nodev,nosuid,noexec
/home defaults,nosuid,nodev,noexec
/mnt/floppy defaults,users,nodev,nosuid,noexec
/mnt/cdrom iso9660 ro,users,nodev,nosuid,noexec
# cp /bin/date /tmp/
# /tmp/date
bash: /tmp/date: Permission denied
# /lib/ /tmp/date
Fri Feb 9 12:36:57 CST 2001

Consult man chattr if needed, then chattr +i everything feasible; chattr +a all the log files, etc. This is a time-consuming task full of pitfalls, and many people will say unnecessary, but you have to remember that security is layers, and nothing is relied upon. chattr + LIDS is a great combination.

Make sure everything is set up properly in /etc/rc.d/rc.local to start the daemons, firewall, and eye-candy

Open /etc/inetd.conf and # out everything except ftp and pop3
Guess how many open ftp connections you'll need and fix inetd.conf as apropos:
ftp stream tcp nowait.6 root /path/to/tcpd in.ftpd -a -i -o

Write /etc/hosts.allow:
then add trusted hosts to /etc/hosts.allow for the services they need ONLY, e.g. if they need only ftp, then:
in.ftpd : (ip address) : ALLOW
to prevent giving them access to sshd which they aren't allowed to use anyway. Remember that it's trivial to spoof an IP address.

(miscellaneous files)
Nightly Backup
.bashrc get all files owned by users in /etc/passwd get all files owned by the named user

When everything is done, you should be able to connect to the web server, ftp, send and receive mail, log in with ssh, and use the DNS server, and nothing else. Logging in as root should feel like logging in as a normal unprivileged user and doing anything useful should be impossible without the LIDS password.

(miscellaneous notes)
You MUST check the vendor websites regularly for updates.
Never give out any more detail than you have to. Lie where needed/as wanted/for sport. When your server is the subject, never trust anyone. Ever.

"GUI's are for wimps"
"The program isn't debugged until the last user is dead."

Last modified ... June 07 2006

by Brent Kevin Krkosska

Custom Search