12/17/2001 Updated 1/8/05 Building a good shell server Most of the philosophy of this document extends to all publicly-attackable servers. Prudence, minimalism, and concise functionality are the goals of this document and the installation it describes. 1. Always do a fresh OS install. * NEVER include X windows on a server. period. * Only install those things which you are CERTAIN you need. If you aren't sure of a lot of things, then you shouldn't be building a publicly-accessible server. Go do more testing and learning. * Do your research on packages which have had root exploits in the last few years. Even if they are useful (but not necessary) things, like BIND 8.2.x or minicom, do not install them. * Don't use a stock network application unless it's completely necessary. inetd and identd are generally necessary. * If there is a more secure third-party tool for a particular service, use it!! Examples: sendmail vs qmail, wu-ftpd vs proftpd. * Have a user/group structure plan in place when building the server. The goal is to isolate users to their own space as much as possible. This promotes strong file security. 2. Lock the box down tighter than a military submarine. * Disable the automatic startup of any network services other than inetd, identd, and ones you specifically configure. * edit the inetd.conf and disable everything except for "auth", unless you plan on running identd in standalone mode (recommended). * setuid-root programs: * Do a filesystem search for setuid-root programs. (find / -perm 4755) (find / -perm 4711) Simply un-setuid root any application you can get away with. TEST it, both as root and as a user. * If an application must be suid root, but will only be used by your staff, chmod it to 4710 or 4750 as appropriate and set the GID to your staff's group. * Alternately, create /root/setuid/bin and /root/setuid/sbin directories, move the offending program to the appropriate of those two paths, and symlink the file to its old location. This will make it so that (literally) only root can run this program. * There may be some applications you want users to use (such as screen) which must be setuid-root. Install these applications as rarely and as judiciously as possible. Keep on top of all updates for these applications, in case a root-hole is discovered. * chmod /var/man/cat* to 700. This will avoid nearly every user-exploit of "man". * Minimize the number of available shells in the system. We currently have only bash and zsh listed in the /etc/shells file. I don't recommend using ksh on a prod. shell server due to the difficulty with its ulimit settings. csh/tcsh are famous for security problems, so don't use them either. * Restrict Perl usage of Socket modules. In /usr/lib/perl5/5.8.4/i486-linux/, chgrp staff Socket.pm IO/Socket.pm chmod 440 Socket.pm IO/Socket.pm * Restrict compilation to only administrators. This involves changing the permissions on a LOT of binaries in /usr/bin. * Configure the machine to set ulimits when users login. This is currently done by creating an /etc/profile.d/ulimit.sh as root and making it executable. Our current script is listed below: #!/bin/sh ##### ## Implements ulimit resource limits at logon for all regular users. # if (( $UID > 1017 )); then if [ "$SHELL" = "/bin/zsh" ]; then ulimit -Hm 5120 ulimit -Hu 10 ulimit -Hn 64 ulimit -Hl 5120 ulimit -Hv 10240 elif [ "$SHELL" = "/bin/bash" ]; then ulimit -m 5120 ulimit -u 10 ulimit -n 64 ulimit -l 5120 ulimit -v 10240 fi fi It sets virtual memory limit to 10mb, real memory to 5mb, file descriptors to 64, running processes to 10, and resident set size (memory size) to 5mb. * Another way of handling ulimits is to use a standard shell for staff (and set exclusive permissions accordingly) and compile a restrictive shell for users, setting ulimits and other restrictions at compile-time. That way, the ulimit restrictions are MUCH harder for users to circumvent. * Where possible, limit redundancy in applications. Enforce application standards for a particular task. For example, don't have mutt, elm, and pine installed. Just have one of them installed. Don't have both vim and elvis installed - just have one. If you need to, symlink one's name to the other for somewhat compatibility. * Set resource settings beyond the norm in anticipation of DoS attacks. For example (linux), set /proc/sys/fs/file-max to 65536, instead of the default 51097. This one in particular isn't as much a problem as it used to be when the default was 4096. Watch the IPC configurables such as /proc/sys/kernel/msgmax and msgmnb. * POLICE /tmp AND /var/tmp ALL THE TIME! At the very least, set up a script to flush /tmp and /var/tmp often (every 5 minutes?). * Check netstat for open IP sockets you don't want open. Fix 'em. 3. Grab a few l33t hax0r attack programs and hammer away at your new server. Test every conceiveable application you can, as a regular user. Ensure that everything works properly and is as secure as possible. 4. Install your new service apps (bind9 or djbdns, apache, proftpd, qmail, etc). * Check them for setuid-root binaries. Fix them as described above. * Research the most recent exploits for the service and TEST them. * Test the user-experience of the service to ensure it works properly. * Whenever possible, have service apps run as a non-root user. 5. Plan for disaster recovery. * If at all possible, have syslog log (copies) to another server. If this server gets attacked, valid and trusted logs can then be got from the other server. * Do periodic backups of important things to archives. Keep them on a private server or off-site.