DRAFT - NOT DONE YET!!! Slackware System Hardening Copyright (c) 2002, 2005 Jeffrey Denton Written by Jeffrey Denton <dentonj@gmail.com> ___ August 2005 version - 0.5 http://www.cochiselinux.org/files/system-hardening This is a list of some of the steps I take to improve the security of my Slackware systems. It is by no means complete. You can either do all of the things listed here, or you can choose only the ones you feel would help secure your system. WARNING: Hardening a system is a compromise between security and usability. Some of the things I do would adversely affect the usability of you system and may very well break things. Please have one of the following on hand just in case you lock yourself out of your system: Tom's Rootboot - http://www.toms.net/rb/ The "Live" CD that comes with the officail version of Slackware. Make sure you have a bootdisk. You should make a backup of anything that you feel is important, would be hard to replace, or that you simply could not do without. If you are either new to Linux or don't know what you are doing, you could very easily get carried away and end up with a system that is unusable. The contents of the document is only meant to be used on Slackware Linux. You have been warned. Note: - The settings assume that only one user is on the system, "dentonj". - Associated man pages are listed for further information. - I will comment this document if I ever get to it. -- Resources -- -- Keep Current -- -- Disable Daemons/Close Ports -- /etc/rc.d: chmod -R go-rwx /etc/rc.d /etc/inetd.conf: grep -v "^#" /etc/inetd.conf Comment the results man inetd /usr/etc/orbitrc: The location of the configuration file can vary. In Slackware, ORBit looks for /usr/etc/orbitrc. Here is a command that you can use to verify where ORBit looks for the configuration file on your system. for i in `ls /usr/bin/orbit*`; do echo $i; strings $i | grep orbitrc; done ORBit had a habit of opening up ports in Gnome a long, long time ago. The following enteries would stop that from happening. The default has changed so that ORBit doesn't open ports by default. I don't leave anything to chance: ORBIIOPUSock=1 ORBIIOPIPv4=0 ORBIIOPIPv6=0 /usr/X11R6/bin/startx: defaultserverargs="-nolisten tcp" man Xserver /etc/X11/xdm/Xservers: :0 local /usr/X11R6/bin/X -nolisten tcp man xdm /etc/X11xdm/xdm-config: DisplayManager.requestPort: 0 man xdm /etc/X11/gdm/gdm.conf: command=/usr/X11R6/bin/X -nolisten tcp /opt/kde/share/config/kdm/Xservers: :0 local@tty1 /usr/X11R6/bin/X vt7 -nolisten tcp man kdm /etc/rc.d/rc.4: exec /usr/X11R6/bin/xdm -nodaemon -udpPort 0 man xdm -- Limit Access -- /etc/lilo.conf: mandatory password="" prompt timeout=0 menu-title="Unauthorized Access Prohibited" message=/boot/boot_message.txt serial=0,9600n8 lilo -v -p man lilo.conf man lilo /etc/login.access: +:root dentonj:LOCAL -:ALL:ALL man login.access /etc/login.defs: FAIL_DELAY 20 DIALUPS_CHECK_ENAB no LOG_UNKFAIL_ENAB yes LOG_OK_LOGINS yes SULOG_FILE /var/log/sulog ISSUE_FILE /etc/issue #HUSHLOGIN_FILE LOGIN_TIMEOUT 300 CHFN_RESTRICT rwh DEFAULT_HOME no #ENVIRON_FILE PASS_MIN_LEN 12 PASS_MAX_DAYS 90 touch /var/log/btmp man login.defs man dpasswd /etc/suauth: ALL:ALL EXCEPT dentonj:DENY chmod 600 /etc/suath man suauth /etc/porttime: tty1,tty2,tty3,tty4,tty5,tty6:root,dentonj:Al0000-2400 *:*: chmod 600 /etc/porttime man porttime /etc/limits: dentonj C0F100000L1U150 * L0 chmod 600 /etc/limits man limits /etc/shells: Delete the following: /bin/ash /bin/csh /bin/ksh /bin/tcsh /bin/zsh man shells /etc/password: Delete the following: adm games gdm halt lp news operator pop rpc shutdown sync uucp find / -user adm -ls userdel adm man find man userdel Add /bin/false as the shell to the following: bin daemon ftp mail mysql news nobody smmsp sshd Note: Don't run these if you like to make the /etc/passwd and the /etc/shadow files immutable (chattr +i ...). It gets ugly.... /usr/bin/passwd -x 90 -w 7 root /usr/bin/passwd -x 90 -w 7 dentonj Check the status of all account when you are done: for i in `cat /etc/passwd | awk -F: '{print $1}'; do passwd -S $i; done /usr/bin/pwck man 1 passwd man 5 passwwd man 5 shadow man pwck /etc/group: Delete the following: adm news lp pop uucp find / -group adm -ls groupdel adm /usr/bin/grpck The above may crate a long list of files that no longer belong to any user or group. find / -nouser -o -nogroup -ls > unowned.txt Ignore any results in /dev. chown root.root <the results> man find man group man groupdel man grpck man chown /etc/sudoers: User_Alias ADMIN = dentonj Cmnd_Alias LOGS = /usr/bin/tail ADMIN ALL = LOGS sudo tail /var/log/messages man sudo man sudoers man visudo /etc/ftpusers: Add the following: bin sync halt operator mysql nobody daemon lp shutdown mail games gdm smmsp pop sshd anonymous man ftpusers /etc/host.conf: nospoof on spoofalert on spoof warn man host.conf /etc/hosts.allow: sshd:192.168.1.:ALLOW ALL:ALL EXCEPT localhost:banners /etc/issue.net:DENY /usr/bin/tcpdchk /usr/bin/tcpdmatch sshd localhost /usr/bin/tcpdmatch sshd 1.1.1.1 man 5 hosts_access man hosts_options man tcpd man tcpdchk man tcpdmatch /etc/hosts.deny: ALL:ALL@ALL EXCEPT localhost, PARANOID:DENY Optional, add: ALL:ALL:/bin/mail -s "%s connection attempt from %c" someone@email.com /usr/bin/tcpdchk /usr/bin/tcpdmatch sshd localhost /usr/bin/tcpdmatch sshd 1.1.1.1 man 5 hosts_access man hosts_options man tcpd man tcpdchk man tcpdmatch Access Control Lists: man acl man setfacl man getfacl /etc/inittab: Comment out the following line: #ca::ctrlaltdel:/sbin/shutdown -t5 -r now I actually don't think this is necessary. But I'm including it because just about every hardening document on Linux recommends it. It stops someone from being able to reboot the system by doing a three finger salute. The first thing is you need physical access to the system. Even if you disabled this feature, it doesn't stop someone from pulling the power cord to force a reboot. The second thing is that most Window Managers capture Ctrl-Alt-Del anyways and either bring up a shutdown menu or shutdown X Windows (in which case you'd have to hit Ctrl-Alt-Del again to reboot). The only time I see disabling this as being useful is when you have a Windows admin learning Linux. You don't want them rebooting the system everytime they want to lock the system or go to the Task Manager. Add the following to keep someone from booting into single user mode without a password: co:S:respawn:/sbin/sulogin /dev/console However, the way that Slackware sets up it's init scripts, a login prompt is already displayed when ever the system enters single user mode. They above line is unnecessary and may not even be called if placed in the wrong place in /etc/inittab (near the end of the file). man init man inittab man initscript man sulogin man telinit /etc/securetty: This file lists the devices that the root user can login on. It's common to find hardening docs that recommend commenting out some of the entries in this file. By default, phyical access is required for root to login to the devices uncommented in the file. If you have to worry about someone using those devices to login, you have other things to worry about. -- Logging -- /etc/rc.d/rc.syslog: /usr/sbin/syslogd -m 0 -r /usr/sbin/klogd -c3 -x -p man syslogd man klogd /etc/syslog.conf: kern.* /dev/console *.info;*.!warn; \ authpriv.none;cron.none;mail.none;news.none - /var/log/messages *.warn; \ authpriv.none;cron.none;mail.none;news.none - /var/log/syslog *.debug - /var/log/syslog authpriv.*;auth.* - /var/log/secure cron.* - /var/log/cron mail.* - /var/log/maillog *.emerg * uucp;news.crit - /var/log/spooler OR, log everything: *.* - /var/log/messages *.* @192.168.1.1 man syslog.conf /etc/logrotate.conf: rotate 20 compress OR: monthly #weekly rotate 12 compress man logrotate /etc/logrotate.d/syslog: /var/log/cron /var/log/debug /var/log/maillog /var/log/messages /var/log/secure /var/log/spooler /var/log/sulog /var/log/syslog { create 0640 root root sharedscripts postrotate /bin/kill -HUP `cat /var/run/syslogd.pid \ 2> /dev/null || true` endscript } man logrotate /etc/rc.d/rc.S: # Setup the /etc/motd to reflect the current kernel level: # THIS WIPES ANY CHANGES YOU MAKE TO /ETC/MOTD WITH EACH BOOT. # COMMENT THIS OUT IF YOU WANT TO MAKE A CUSTOM VERSION. # echo "$(/bin/uname -sr)." > /etc/motd man motd /etc/motd, /etc/issue.net, /boot/boot_message.txt: **************************************************************** Unauthorized access prohibited; all access and activities not explicitly authorized by the administrator are unauthorized. All activities are monitored and logged. There is no privacy on this system. Unauthorized access and activities or any criminal activity will be reported to appropriate authorities. **************************************************************** lilo -v -p man issue faillog: faillog -u dentonj -m 10 man faillog -- FIlesystem -- /etc/fstab: /dev/hdb1 swap swap defaults 0 0 /dev/hdb5 / ext3 defaults 1 1 /dev/hdb6 /var ext3 rw,nosuid,nodev 0 2 /dev/hdb7 /tmp ext3 rw,nosuid,nodev,noexec 0 2 /dev/hdb8 /usr ext3 ro 0 2 /dev/hdb9 /home ext3 rw,nosuid,nodev 0 0 /dev/hda1 /mnt/windows vfat rw,nosuid,nodev,noexec,noauto 0 0 /dev/hda2 /mnt/slack ext2 rw,noauto 0 0 /dev/fd0 /mnt/floppy auto rw,nodev,noauto 0 0 mkdir /mnt/windows mkdir /mnt/slack mkdir /mnt/floppy man fstab man nfs man mount I use to add 'noexec' to /home. But 'noexec' is pretty trivial to bypass. Plus, I like having a $HOME/bin directory for misc. scripts. Change how often fsck is run during boot: for i in hdb5 hdb6 hdb7 hdb8 hdb9; do tune2fs -c 0 /dev/$i tune2fs -m 3m /dev/$i done tune2fs -l /dev/hdb5 man tune2fs Remove the SUID bit from the following files: chmod a-s /usr/sbin/... man chmod Make some files immutable: chattr +i /etc/exports chattr +i /etc/hosts.equiv chattr +i /etc/hosts.lpd chattr +i /etc/inetd.conf chattr +i /etc/lilo.conf chattr +i /etc/login.access chattr +i /etc/login.defs chattr +i /etc/porttime chattr +i /etc/protocols chattr +i /etc/securetty chattr +i /etc/services chattr +i /etc/suauth man chattr lcap: The following files should be empty if they exist: /etc/d_passwd /etc/dialips /etc/environment /etc/exports /etc/hosts.lpd /etc/hosts.equiv /etc/shutdown.allow $HOME/.rhosts /root/.rhosts The following files shouldn't normally exist: /etc/fastboot /etc/forcefsck /etc/hushlogins /etc/initscript /etc/nologin Limit access to $HOME directories: chmod -R go-rwx /home/dentonj chmod -R go-rwx /root man chmod -- Network -- /etc/rc.d/rc.local: # Set static ARP entries for the default gateway arp -s 192.168.144.1 00:00:DE:AD:BE:EF -- rc.local -- (Should this be renamed and/or broken up?) # DANGEROUS!!! Could destroy your harddrive!!! # Improve harddrive performance # This is harddrive specific /usr/sbin/hdparm -c3 -a16 -W1 -u1 /dev/hdb # Turn on the Num Lock /usr/bin/setleds -D +num # Enforce login time restrictions set in /etc/porttime if [ -x /usr/sbin/logoutd ]; do /usr/sbin/logoutd fi # Log icmp packets to syslog /usr/sbin/icmpinfo -vvv -s -l # Turn on process accounting /sbin/accton /var/log/pacct man hdparm man setleds man logoutd man icmpinfo man acct man accton touch /var/log/pacct man sa man dump-acct -- Cron -- /etc/rc.d/rc.M: /usr/sbin/crond -l8 >> /var/log/cron 2>&1 man crond Change permissions on the cron directories. This prevents users from being able to use cron: chmod -R o-rwx /var/spool/cron/ chmod -R o-rwx /etc/cron.* less /usr/doc/dcron-2.3.3/README /var/spool/cron/crontabs/root: # Sync clocks 0 0 * * * /usr/sbin/ntpdate clock.via.net && hwclock --systohc # System cleanup 0 3 * * * /usr/bin/find / -type f -name core \ -exec /bin/rm -f {} \; 2> /dev/null 0 3 * * * /usr/bin/find /tmp -atime +7 \ -exec /bin/rm -f {} \; 2> /dev/null 0 3 * * * /usr/bin/find /var/tmp -atime +7 \ -exec /bin/rm -f {} \; 2> /dev/null 0 3 * * * /usr/bin/find /var/spool/lpd -type f \( -name "cf*" -o \ -name "df*" \) -atime +2 -exec /bin/rm -f {} \; 2> /dev/null # Paranoid stuff 0 3 * * * /bin/chmod -R go-rwx /home/dentonj 0 3 * * * /bin/chmod -R go-rwx /root 0 3 * * * /bin/rm -f /home/*/dead.letter 0 3 * * * /usr/bin/find /home -name .rhosts -o -name .forward -ls \ -exec /usr/bin/cat {} \; | mail -s \ ".rhosts or .forward files on $HOSTNAME" root@localhost 2> /dev/null # Security programs man crond man crontab -- Bash -- /root/.bashrc: ulimit -u unlimited /etc/inputrc: set bell-style none set editing-mode vi set mark-directories on set mark-modified-lines on set match-hidden-files on set show-all-if-ambiguous on set visible-stats on man bash man readline History: History can be turned off using the following: HISTSIZE=0 HISTFILESIZE=0 Or: set +o history -- Kernel -- Install GRSecurity Install PAX /etc/sysctl.conf: # Improve file system performance vm.bdflush = 60 64 64 256 500 300 80 0 0 # Increase swap bandwidth system perfomance vm.kswapd = 512 32 32 # Enables/Disables memory overcommitment vm.overcommit_memory = 0 # Increase number of pages kernel reads in at once vm.page-cluster = 5 # Improve number of page tables keeps in a per-processor cache vm.pagetable_cache = 25 50 # Increase limit of file-handles fs.file-max = 8192 # Enable/Disable ignoring ping request net.ipv4.icmp_echo_ignore_all = 1 # Enable/Disable ignoring broadcasts request net.ipv4.icmp_echo_ignore_broadcasts = 1 # Enable/Disable IP source routing net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 # Enable/Disable TCP SYN Cookie Protection net.ipv4.tcp_syncookies = 1 # Enable/Disable ICMP Redirect Acceptance net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 # Enable/Disable bad error message protection net.ipv4.icmp_ignore_bogus_error_responses = 1 # Enable/Disable IP spoofing protection net.ipv4.conf.all.rp_filter = 2 net.ipv4.conf.default.rp_filter = 2 # Enable/Disable Log Spoofed, Source Routed, Redirect Packets net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.default.log_martians = 1 # Improve shared memory size kernel.shmall = 134217728 kernel.shmmax = 134217728 # Improve default and maximum window size net.core.vmem_max = 2048000 net.core.vmem_default = 2048000 # Enable packet forwarding #net.ipv4.ip_forward = 1 # Change the default TTL to help obscure OS fingerprinting attempts # If you are using GRSecurity, this may be unnecessary net.ipv4.ip_default_ttl = 128 sysctl -A man sysctl man sysctl.conf -- Misc -- -- Program Hardening -- -- Security Programs/Scripts -- -- Mean Tricks -- /etc/rc.d/rc.6: touch /etc/forcefsck /etc/hotplug/blacklist: hid /etc/inittab: id:6:initdefault: iptables -m random iptables -A FORWARD -s 192.168.1.1 -m random --average 90 -j DROP iptables -A INPUT -j DROP Anywhere in /etc/rc.d: reboot enable -n enable -- Useful Commands -- ldd /usr/bin/lppasswd strings /usr/bin/lppasswd List some of the popular REM commands used. man -k cron grep crond /var/log/packages/* cd /bin && for i in `ls | grep -v "@$"`; do file $i | \ grep "not stripped"; done sa ac -- /etc/profile -- #Kick and lockout users that are UID 0 but are not root if [ `id -u` = "0" -a `echo $USER` != "root" ]; then #Lock the user out passwd -l $USER # Save some info date >> /root/SHIT netstat -peanut >> /root/SHIT ps auxww >> /root/SHIT w >> /root/SHIT w | mail -s "$USER has gained ROOT access" root@localhost # Let EVERYONE know wall << EOF *********************************************************** $USER has gained ROOT access!!! *********************************************************** EOF for i in `ls /dev/pts/`; do echo -e "\n$USER has gained ROOT access!!\n" >> /dev/pts/$i done # Log it logger -is -f /var/log/messages "$USER has gained ROOT access!!" # Let the luzer know echo -e "\a\n\n You are _NOT_ root!!\n\n\a" # Kill the user and his processes skill -9 -u $USER # For the paranoid ifconfig eth0 down # This should be redundant logout exit fi # Set ksh93 visual editing mode: if [ "$SHELL" = "/bin/ksh" ]; then # VISUAL=emacs # VISUAL=gmacs VISUAL=vi fi if [ `id -u` = "0" ]; then PS1="\[\033[1;31m\][\j][\u@\h:\w]#\[\033[0m\] " else PS1="\[\033[1;32m\][\j]\u@\h:\w\$\[\033[0m\] " #else # PS1='\u@\h:\w\$ ' fi # For non-root users, add the current directory to the search path: #if [ ! "`id -u`" = "0" ]; then # PATH="$PATH:." #fi # # Stuff I've added # # History # Normally these would be set to 20 for security reasons. # However, I've been getting lazy and started using HISTORY # as a log of what I've done. export HISTSIZE=10000 export HISTFILESIZE=10000 # Display timestamp information with each history entry export HISTTIMEFORMAT="%F %T " # Logout if root is not being used if [ `id -u` = "0" ]; then export TMOUT=1200 fi # Extra PATH stuff export PATH="$PATH:/usr/local/sleuthkit/bin:/usr/local/mysql/bin:/usr/local/tct/bin:/usr/local/tctutils/bin:/usr/local/autopsy" # Extra MANPATH stuff export MANPATH="$MANPATH:/usr/local/sleuthkit/man:/usr/local/tct/man:/usr/local/tctutils/man:/usr/local/autopsy/man" # Aliases alias matrix="cmatrix -bass" alias m="cmatrix -bass" alias td="tcpdump -nvvSi eth0 | grcat conf.tcpdump" alias tl="tcpdump -nvvSi lo | grcat conf.tcpdump" # shred doesn't delete recursively # use "/bin/rm -rf ..." for directories alias rm="shred -uz" # Set and editor export VISUAL=vim # Disable the Bash builtin command kill, forces the use # of /bin/kill. This was a nice idea, but it keeps # jobs from being able to be killed #enable -n kill # Misc shell settings shopt -s cdspell # correct minor misspelled dir names shopt -s cmdhist # save multiline commands in the same # history entry shopt -s dotglob # include hidden files in pathname expansion shopt -s extglob # extended pattern matching setterm -bfreq 0 # turn error bell off # grep options # the -i grep option causes problems with ./configure, ugly export GREP_OPTIONS="-n --color" export GREP_COLOR="1;33" # Secure less export LESSSECURE=1 # This works for single user systems # and if the dumbass uses an interactive shell #if [ `id -u` != "0" -a `id -u` != "1000" ]; then # logout #fi # Set shell variables as readonly, this should be last typeset -r HISTFILE typeset -r HISTFILESIZE typeset -r HISTSIZE typeset -r HISTNAME typeset -r USER typeset -r LOGNAME