Installation
Keep your future Linux box in an isolated network until you
are ready to begin.
Don't install more than the essentials.
Make a separate partition for /var, this is where all the system logging and
email goes. By isolating the /var partition, you protect your root partition
from overfilling. I've found 400 MB to be more then enough for /var.
/
- everything else
/var - 400 MB
swap - (I normally go with
256 MB)
Once the system has rebooted after the installation, be sure to install the recommend security patches. For Red Hat, you can find these security patches at Red Hat's errata support site. Patches are critical to armoring a system and should always be updated. bugtraq@securityfocus.com or redhat-watch-list-request@redhat.com are excellent sources for following bugs and system patches. Without these patches, your system can be easily compromised. For Red Hat, once you download the rpm, you can easily update your system using the following syntax. An excellent example of this is the security update for wu-ftpd
rpm -Uvh wu-ftpd-2.6.0-14.6x.i386.rpm
For systems that are already on-line, you can ftp the rpm and install it at the same time, using the following syntax.
rpm -Uvh ftp://updates.redhat.com/6.1/i386/wu-ftpd-2.6.0-14.6x.i386.rpm
autorpm. (http://www.kaybee.org/~kirk) determines which .rpm's need to be updated, gets those rpm's from Red Hats's web site, and then downloads and installs the updated files (if you so desire).
Eliminating Services
Turn off all non-essential services. Comment out everything in /etc/inetd.conf
is configured for a variety of services, you most likely only need two, ftp
and telnet. With SSH you don't need those, either.
Change all unneccessary scripts in /etc/rc.d/rc3.d (or /etc/rc.d/rc5.d) by replacing
the capital S with a small s. Here's what they do:
S05apmd
(You only need this for laptops)
S10xntpd (Network
time protocol)
S11portmap (Required if
you have any rpc services, such as NIS or NFS)
S15sound (Saves
sound cared settings)
S15netfs (This
is the nfs client, used for mounting filesystems from a nfs server)
S20rstatd (Try to avoid running
any r services, they provide too much information to remote users)
S20rusersd
S20rwhod
S20rwalld
S20bootparamd (Used for diskless clients, you
probably don't need this vulnerable service)
S25squid (Proxy
server)
S34yppasswdd (Required if you are a
NIS server, this is an extremely vulnerable service)
S35ypserv (Required
if you are a NIS server, this is an extremely vulnerable service)
S35dhcpd (Starts dhcp
server daemon)
S40atd (Used
for the at service, similar to cron, by not required by the system)
S45pcmcia (You only need this
script for laptops)
S50snmpd (SNMP daemon,
can give remote users detailed information about your system)
S55named (DNS
server. If you are setting up DNS, upgrade to the latest version of BIND,
http://www.isc.org/bind.html)
S55routed (RIP, don't
run this unless you REALLY need it)
S60lpd
(Printing services)
S60mars-nwe (Netware file
and print server)
S60nfs
(Use for NFS server, do not run unless you absolutely have to).
S72amd
(AutoMount daemon, used to mount remote file systems)
S75gated (used
to run other routing protocols, such as OSPF)
S80sendmail (You can still send email
if you turn this script off, you just will not be able to receive or relay)
S85httpd (Apache
webserver, I recommend you upgrade to the latest version, http://www.apache.org/)
S87ypbind (Required
if you are a NIS client)
S90xfs
(X font server)
S95innd (News
server)
S99linuxconf (Used to remotely
configure Linux systems via browser, every black-hat's dream :)
To see how many services are running before you change the startup scripts, type
ps aux | wc -l Also, confirm which are left running by executing the following command:
netstat -na --ip
Logging and Tweaking
Enable logging. All system logging occurs in /var/log. By default,
Linux has excellent logging, except for ftp. You have two options for
logging for ftp, configure /etc/ftpaccess file or edit /etc/inetd.conf.
I prefer to edit /etc/inetd.conf, as it is simpler (i.e. harder to mess up :).
Edit /etc/inetd.conf as follows to ensure full logging of all FTP sessions.
ftp stream tcp nowait root /usr/sbin/tcpd in.ftpd -l -L -i -o
If the -l option is specified, each ftp session is logged in
the syslog
If the -L flag is used, command logging will be on by default as soon as the
ftp server is invoked. This will cause the server to
log all USER commands, which if a user accidentally enters a password for that
command instead of the username, will cause passwords to be logged via syslog.
If the -i option is specified, files received by the ftpd(8) server will be
logged to the xferlog(5).
If the -o option is specified, files transmitted by the ftpd(8) server will
be logged to the xferlog(5).
Run pwconv to make sure you're using shadow passwords.
Remove most of the default system accounts in /etc/passwd. Linux provides these accounts for various system activities which you may not need. If you do not need the accounts, remove them. The more accounts you have, the easier it is to access your system. An example is the "news" account. If you are not running nntp, a news group server, you do not need the account (be sure to update /etc/cron.hourly, as this looks for the user "news"). Also, make sure you remove the "ftp" account, as this is the account used for anonymous ftp. From the man pages.
man ftpd:
Ftpd authenticates users according to four rules.
4) If the user name is ``anonymous'' or ``ftp'', an anonymous ftp account must be pre-sent in the password file (user ``ftp''). In this case the user is allowed to log in by specifying any password (by convention this is given as the client host's name).
A minimal /etc/passwd file:
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:
daemon:x:2:2:daemon:/sbin:
adm:x:3:4:adm:/var/adm:
lp:x:4:7:lp:/var/spool/lpd:
mail:x:8:12:mail:/var/spool/mail:
uucp:x:10:14:uucp:/var/spool/uucp:
nobody:x:99:99:Nobody:/:
/etc/ftpusers . Any account listed in this file cannot ftp to
the system. This restricts common system accounts, such as root or bin, from
attempting ftp sessions.Ensure that root stays in this file, you never want
root to be able to ftp to this system. Ensure that any accounts that need
to ftp to the box are NOT in the file /etc/ftpusers. Example:
root
bin
daemon
adm
lp
mail
uucp
nobody
Also, ensure that root cannot telnet to the system. This forces users to login to the system as themselves and then su to root. The file /etc/securetty lists what ttys root can connect to. List only tty1, tty2, etc in this file, this restricts root logins to local access only. ttyp1, ttyp2, are pseudo terminals, they allow root to telnet to the system remotely. Example:
root
bin
daemon
adm
lp
mail
uucp
nobody
Last, create the file /etc/issue. This file is an ASCII text banner that appears for all telnet logins (example B). This legal warning will appear whenever someone attempts to login to your system. If you want to continue using the same /etc/issue file, you will have to modify /etc/rc.d/init.d/S99local. By default, Linux creates a new /etc/issue file on every reboot.
This is an example of the /etc/issue file.
# WARNING: You must have specific authorization to access
# this machine. All users are logged and monitored.
Connecting to
your server
Connect with ssh, you can find ssh
here, including source for both ssh clients and server daemon. I recommend
you use ssh version 1.2.x, as version 2.x has a limiting license. Another ssh
option is Openssh.
TCP Wrappers is already installed, the only thing left for us to do is edit the /etc/hosts.allow and /etc/hosts.deny file. These files determine who can and cannot access our systems. Also, TCP Wrappers allows us to do fancy things, such as banners or spawn additional programs, such as safe_finger. The syntax is relatively simple. Put the IP address or networks in /etc/hosts.allow that you want to permit connections from. Put IP addresses or networks in /etc/hosts.deny that you do not want to permit access. By default, Linux allows connections from everyone, so you will need to modify these files. 2 recommendations when working with TCP Wrappers.
Examples on how to setup /etc/hosts.allow and /etc/hosts.deny:.
This is an example of the access control lists for TCP Wrappers. The syntax is
Service: Source (IP address, network, or name): <optional> : ALLOW or DENY
Example of /etc/hosts.allow
in.telnetd: 192.168.1.0/255.255.255.0 : banners /etc/bannerfile
: ALLOW
in.ftpd: 192.168.1.30 :ALLOW
imapd: ALL : spawn (/usr/local/bin/ids.sh %d %h %H %u)
Example of /etc/hosts.deny. I highly recommend you always use this as your /etc/hosts.deny file.
ALL: ALL DENY
Extra measures
Create the wheel group. The wheel group is a group of select individuals that can execute powerful commands, such as /bin/su. By limiting the people that can access these commands, you enhance the system security. To create the group, vi the file /etc/group, create the group wheel, and add the system admins to the group. Then identify critical system binaries, such as /bin/su. Change the group ownership to wheel, and the permissions to owner and group executable only (be sure to maintain the suid or guid bit for specific binaries). For /bin/su, the commands would be:
/bin/chgrp wheel /bin/su
/bin/chmod 4750 /bin/su
Second, we will lock down the files .rhosts, .netrc, and /etc/hosts.equiv. The r commands use these files to access systems. To lock them down, touch the files, then change the permissions to zero, locking them down. This way no one can create or alter the files. For example,
/bin/touch /root/.rhosts /root/.netrc
/etc/hosts.equiv
/bin/chmod 0 /root/.rhosts /root/.netrc /etc/hosts.equiv
Third, we configure /etc/shadow to use MD5 hashes instead of the crypt(3) function. This makes the encrypted password file far more difficult to crack. This is done by modifying the PAM modules. PAM (Pluggable Authentication Modules) is a suite of shared libraries that enable you to choose how applications authenticate users. To learn more about PAM, check out ftp://ftp.us.kernel.org/pub/linux/libs/pam/Linux-PAM-html/pam.html
In the old days, you had to manually modify the PAM modules to use MD5 hashes. However, with Red Hat 6.0 or greater, you can select MD5 hashes with the setup utility. Just type "setup" at the command prompt, then select "authentication configuration". From there, you can choose to use MD5 hashes. However, the MD5 hashes will not take effect until the user re-enters their password. For those of you who do not have the setup utility (or have Red Hat 5.2 or earlier), you can still modify the PAM modules manually. Example:
Go to /etc/pam.d directory, where you will find all the configuration files for different binaries that require authentication. Most of the configuration files will have the following entry.
password required /lib/security/pam_pwdb.so nullok use_authtok
or
password required /lib/security/pam_pwdb.so shadow nullok use_authtokAll you need to do is find all the configuration files that have this entry, and add "md5" to the end, so it looks like this.
password required /lib/security/pam_pwdb.so nullok use_authtok md5
or
password required /lib/security/pam_pwdb.so shadow nullok use_authtok md5For my RedHat 6.0 system, I had to edit this line in the following configuration files in /etc/pam.d
chfn
chsh
login
passwd
rlogin
su
xdm
For us bash users, I'm not a big fan of the .bash_history file. I do not want people (including root) to know my command history. So, in my .bash_profile, I export the following entry:
HISTFILESIZE=0
This means that nothing will be logged to my .bash_history file. I will still have keystroke history and recall, the HISTSIZE env variable, but command history will not be written to the .bash_history file.
Last thing we can do is protect our system from physical access. This mainly consists of setting up a password for our BIOS. Also, you can password protect your system during boot-up by configuring /etc/lilo.conf with a password (password=xxx) where xxx is your password. However, keep in mind, once someone has physical access to your system, there is no guaranteed way to protect it.
IPChains
No discussion about Linux security would be complete without covering IPChains.
IPChains is packet filtering software that comes with the 2.2.x kernel and above.
This means if you are running Red Hat 6.0 or later, you have it as part of your
Linux installation kit. IPChains is similar to Cisco Access Control Lists,
it can control what packets can come in and out of your Linux box. Primarly
used as a firewall application, IPChains can also be used to armor your standalone
Linux box. To armor a standalone system, I configure IPChains
to allow only TCP connections I initiate. If anyone attempts to initate
any TCP connections to me, the connection is denied. Since IPChains is
not stateful, I do allow all UDP and ICMP connections. Last, I log all
denied connections, this lets me know if someone out there is being naughty
:) However, I drop but do not log all the broadcat/multicast traffic,
as this would quickly fill up the system logs. A simple IPChains configuration
to armor a standalone system would look something like this.
bash# ipchains -L
Chain input (policy DENY):
target prot opt source destination ports
DENY all ------ 0.0.0.0 anywhere n/a
DENY all ------ anywhere 255.255.255.255 n/a
DENY all ------ anywhere BASE-ADDRESS.MCAST.NET/8 n/a
ACCEPT tcp !y---- anywhere anywhere any -> any
ACCEPT udp ----l- anywhere anywhere any ->
any
ACCEPT icmp ----l- anywhere anywhere any ->
any
DENY all ----l- anywhere anywhere n/a
Chain forward (policy ACCEPT):
Chain output (policy ACCEPT):
Below is the configuration file for IPChains. You can easily implement this on your system using the command 'ipchains-restore' as follows:
mozart #cat ipchains.cfg | ipchains-restore
The contents of the ipchains.cfg file is as follows:
:input DENY
:forward ACCEPT
:output ACCEPT
-A input -s 0.0.0.0/255.255.255.255 -d 0.0.0.0/0.0.0.0 -j DENY
-A input -s 0.0.0.0/0.0.0.0 -d 255.255.255.255/255.255.255.255 -j DENY
-A input -s 0.0.0.0/0.0.0.0 -d 224.0.0.0/255.0.0.0 -j DENY
-A input -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -p 6 -j ACCEPT ! -y
-A input -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -p 17 -j ACCEPT -l
-A input -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -p 1 -j ACCEPT -l
-A input -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -j DENY -l