-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Activate the available shields to protect your server

The default CentOS installation provides many security features that are not enabled by default and that we all should take benefit of. Here are some to consider.

Prerequisites

The media used for this tutorial is the CentOS 6.2 minimal installation CD. There’s no way to make a mistake when choosing packages with this installation media, because you can’t. It just installs the minimal software. Make sure that you install the EPEL project repository.

rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-5.noarch.rpm
   Retrieving http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-5.noarch.rpm
   warning: /var/tmp/rpm-tmp.VseyUg: Header V3 RSA/SHA256 Signature, key ID 0608b895: NOKEY
   Preparing...                ########################################### [100%]
      1:epel-release           ########################################### [100%]

And make sure that your server is up to date.

yum update -y

Unnecessary services

To limit the available attack surface available on the server, we’ll simply shut down the unnecessary services (well, those that I do think I don’t need for, let’s say, a webserver) and prevent them from starting at next reboot. These are the following services I’m going to disable :

rpcbind
The rpcbind utility is a server that converts RPC program numbers into universal addresses. It must be running on the host to be able to make RPC calls on a server on that machine.
nfslock
Starts up the NFS file locking service
lldpad
Link Layer Discovery Protocol Agent Daemon
fcoe
Open-FCoE Initiator
rpdidmapd
This deamon maps user names and groups to UID and GID numbers on NFSv4 mounts
for i in rpcbind  nfslock  lldpad fcoe rpcidmapd; do service $i stop; chkconfig $i off; done
   Stopping rpcbind:                                          [  OK  ]
   Stopping NFS statd:                                        [  OK  ]
   Stopping lldpad:                                           [  OK  ]
   Stopping FCoE initiator service:                           [  OK  ]
   Stopping RPC idmapd:                                       [  OK  ]

Protecting SSH service

As this is one the core and mostly attacked services, we need to protect ourselves against one of the most common threats : brute force attacks. For this, we are going to set up Fail2ban that will account for us the number of times a server will occur with failed authentications attempts and add the corresponding ip address to iptables reject list (a specific iptables user chain that returns until the ip is listed in it, to be exact). The package file comes from the EPEL project, and I build a configuration file specifically for this simple purpose :

[DEFAULT]
ignoreip = 127.0.0.1
# Block the attacking host for a day
bantime  = 86400
# If it appears in the watched log file for the last hour
findtime  = 3600
# And generated 3 error messages
maxretry = 3
backend = auto

[ssh-iptables]

enabled  = true
filter   = sshd
action   = iptables[name=SSH, port=ssh, protocol=tcp]
# Optionnal : sendmail-whois[name=SSH, dest=root, sender=fail2ban@mail.com]
logpath  = /var/log/secure
maxretry = 3

So now, install it, configure it using the custom jail.conf and make the service start when the system boots.

yum install fail2ban
curl http://bkraft.fr/files/Configurations/fail2ban/jail.conf -o /etc/fail2ban/jail.conf
chkconfig fail2ban on
service fail2ban start
   Starting fail2ban:                                          [  OK  ]

We now can see that there is an iptables chain called fail2ban-SSH as you can see below.

iptables-save 
   # Generated by iptables-save v1.4.7 on Sat Mar 10 22:09:08 2012
   *filter
   :INPUT ACCEPT [0:0]
   :FORWARD ACCEPT [0:0]
   :OUTPUT ACCEPT [17:1492]
   :fail2ban-SSH - [0:0]
   -A INPUT -p tcp -m tcp --dport 22 -j fail2ban-SSH 
   -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
   -A INPUT -p icmp -j ACCEPT 
   -A INPUT -i lo -j ACCEPT 
   -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT 
   -A INPUT -j REJECT --reject-with icmp-host-prohibited 
   -A FORWARD -j REJECT --reject-with icmp-host-prohibited 
   -A fail2ban-SSH -j RETURN 
   COMMIT
   # Completed on Sat Mar 10 22:09:08 2012

Small things that matters

In single user mode, ask for password

perl -i -pe 's/sushell/sulogin/' /etc/sysconfig/init

Change the number of available gettys as there is too much of them available by default.

perl -i -pe 's/1-6/1/' /etc/sysconfig/init
perl -i -pe 's/1-6/1/' /etc/init/start-ttys.conf

Prevent prompting for interactive boot

perl -i -pe 's/PROMPT=yes/PROMPT=no/' /etc/sysconfig/init

Prevent rebooting when Control-Alt-Delete is being pressed on the console.

perl -i -pe 's/exec.*/exec \/bin\/echo "Control-Alt-Delete pressed, but no action will be taken"/' /etc/init/control-alt-delete.conf

Change the minimum password length from 5 to 9

perl -i -pe 's/PASS_MIN_LEN\s+5/PASS_MIN_LEN  9/' /etc/login.defs

Disconnect idle users after 15 minutes

cat > /etc/profile.d/inactive-users-disconnect.sh << EOF
readonly TMOUT=900
readonly HISTFILE
EOF 
chmod +x /etc/profile.d/inactive-users-disconnect.sh

Prevent anybody but root to run cron or at tasks

touch /etc/cron.allow
chmod 600 /etc/cron.allow
awk -F: '{print $1}' /etc/passwd | grep -v root > /etc/cron.deny
touch /etc/at.allow
chmod 600 /etc/at.allow
awk -F: '{print $1}' /etc/passwd | grep -v root > /etc/at.deny

Be careful, consistency of at.deny and cron.deny is not guaranteed over time. you should care about it (rerun the awks by hand or by cron)

Change /etc/issue to something scary

cat >/etc/issue << EOF
USE OF THIS COMPUTER SYSTEM, AUTHORIZED OR UNAUTHORIZED, CONSTITUTES CONSENT TO MONITORING OF THIS SYSTEM.
UNAUTHORIZED USE MAY SUBJECT YOU TO CRIMINAL PROSECUTION.
EVIDENCE OF UNAUTHORIZED USE COLLECTED DURING MONITORING MAY BE USED FOR ADMINISTRATIVE, CRIMINAL, OR OTHER ADVERSE ACTION.
USE OF THIS SYSTEM CONSTITUTES CONSENT TO MONITORING FOR THESE PURPOSES.
EOF

Narrow down rights

Many of the files have by default too wide rights that might led to disclose some important informations.

# Narrow down right on /root
chmod 700 /root

# Audit logs should be available only for root
chmod 700 /var/log/audit

# Remove too wide rights on iptables binary and init scripts
chmod 740 /etc/rc.d/init.d/iptables
chmod 740 /sbin/iptables

# Change the rights of the default user skeleton
chmod -R 700 /etc/skel

# Restrict access to rsyslog configuration to root
chmod 600 /etc/rsyslog.conf

# Locking down LNX00440
chmod 640 /etc/security/access.conf

# Sysctl configuration should only accessible to root
chmod 600 /etc/sysctl.conf

Secure network via sysctl

cat << 'EOF' >> /etc/sysctl.conf
	# disable packet forwarding
	net.ipv4.ip_forward = 0
	# drop icmp redirects
	net.ipv4.conf.all.send_redirects = 0
	net.ipv4.conf.default.send_redirects = 0
	net.ipv4.conf.all.accept_redirects = 0
	net.ipv4.conf.all.secure_redirects = 0
	net.ipv4.conf.default.accept_redirects = 0
	net.ipv4.conf.default.secure_redirects = 0
	# double the syn backlog size
	net.ipv4.tcp_max_syn_backlog = 2048
	# ignore ping broadcasts
	net.ipv4.icmp_echo_ignore_broadcasts = 1
	# drop the source routing ability
	net.ipv4.conf.all.accept_source_route = 0
	net.ipv4.conf.default.accept_source_route = 0
	# log packets destinated to impossible addresses
	net.ipv4.conf.all.log_martians = 1
	# ignore bogus icmp error responses
	net.ipv4.icmp_ignore_bogus_error_responses = 1
	# protect a bit from SYN flood attacks
	net.ipv4.tcp_syncookies = 1
	# drop packets that come in using a bad interface
	# (they will be logged as martian)
	net.ipv4.conf.all.rp_filter = 1
	net.ipv4.conf.default.rp_filter = 1
	# don't send timestamps
	net.ipv4.tcp_timestamps = 0
EOF

Delete unnecessary users

By default many users are present that aren’t necessary, let’s just get rid of them.

/usr/sbin/userdel shutdown
/usr/sbin/userdel halt
/usr/sbin/userdel games
/usr/sbin/userdel operator
/usr/sbin/userdel ftp
/usr/sbin/userdel gopher

Tuning OpenSSH

As per this setup, the SSH service is opened on internet, and we need to make sure that it is secured. By default, it is already well secured, but there is some things we should change.

# Prevent ssh connections from root
perl -i -pe 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
# Set our scary issue message as ssh banner
perl -i -pe 's/#Banner.*/Banner \/etc\/issue/g' /etc/ssh/sshd_config

# Make the server keys a bit bigger
perl -i -pe 's/^#ServerKeyBits 1024/ServerKeyBits 2048/g' /etc/ssh/sshd_config
# We need now to drop previously created 1024 keys and regenerate them.
rm -vf /etc/ssh/ssh_host*
	removed `/etc/ssh/ssh_host_dsa_key'
	removed `/etc/ssh/ssh_host_dsa_key.pub'
	removed `/etc/ssh/ssh_host_key'
	removed `/etc/ssh/ssh_host_key.pub'
	removed `/etc/ssh/ssh_host_rsa_key'
	removed `/etc/ssh/ssh_host_rsa_key.pub'
/etc/init.d/sshd restart
	Stopping sshd:                                             [  OK  ]
	Generating SSH1 RSA host key:                              [  OK  ]
	Generating SSH2 RSA host key:                              [  OK  ]
	Generating SSH2 DSA host key:                              [  OK  ]
	Starting sshd:                                             [  OK  ]

# Restrict max authentications
perl -i -pe 's/^#MaxAuthTries 6/MaxAuthTries 3/g' /etc/ssh/sshd_config

Removing kernel modules

As the machine that I’m running is a virtual one, I don’t need wireless drivers to be loaded and neither do I need fcoe, so let’s just blacklist them.

for i in $(find /lib/modules/`uname -r`/kernel/drivers/net/wireless -name "*.ko" -type f) ; do echo blacklist $i >> /etc/modprobe.d/blacklist-wireless.conf ; done
for i in $(find /lib/modules/`uname -r`/kernel/drivers/scsi/fcoe -name "*.ko" -type f) ; do echo blacklist $i >> /etc/modprobe.d/blacklist-fcoe.conf ; done

Run the whole configuration script

If you want to run all the modifications done here in one shot, it’s possible. The script is available in the file repository.

Be very careful, use this script with caution, because it really changes the security configuration of your server. Benjamin KRAFT is not liable with all impacts the use of this script would have.
If you know that you need to secure your server, but don’t know how to proceed, or what this script will modify, a better idea would be to ask for help as you really risk some downtime if your server is already in production.

curl http://bkraft.fr/files/scripts/Secure_CentOS.sh | sh
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - http://gpgtools.org

iQIcBAEBCAAGBQJW5eRKAAoJEBeKS2x6xuR7CAQQAJvobVEPV7Z3Ql30slACps+C
vbFL8n91MlDj5m59y0RdXyhiHx3WGNNzGiP3H8rX2+fdMXmJXNzj+Jdl9QprM6L3
0xIUis+M/AZcdXy1jbmWpBl9NCrnWcPVeF33FcXzuwD4aMF2K/2M70AOMaxfMDee
fy0MMcdHV3NPAUShMokcKnatmUZx8gBlVy3lBSzMdtKnhwNqycjat25p9+RILLt3
qUi4RvydKmf5SJua8hmh6S/JMDCPZ3JDKgaWUGWwBGf3gGUAeH+NLwzDR0q6Tzgj
6BX8v4wFJ0KPGOS5sHNTmXh2sJI/TDT2WYevZ1p8xg6u6mel8FXahqR/JTE/5iT8
UqazaR2ekUp+BBkWgwqvNfeMKC6JSer40QjhYd/QJjj91vWpZILqMW45uKUPgDvB
Jj8WlHpv0Xr9YdH5WkTXeVM0RWGyHfs3Qp82GsV/j3OYySk2F7Rbpf/v2xnS79HM
95QE771+wv2GyLCJjDGe82hbh2I56dGSbcC9IoQ9HuLkPdCohH6akv6XZYRiGwDX
/oq8CKt6liEmLpOB4eVm5KDqulQ941GopH4A8nhJCFfSqOL1iHR0YoqeosCp8PG2
0LjmpNUP4DBCb2ySgbVCYH53uNSGsHYHnApTzZhKoYcprsclGryrTn8pfaqSxtgY
/R5KUq4cx4aVTQBd6xM/
=mzdu
-----END PGP SIGNATURE-----

Hint: To validate signature, please view page source and copy html code between BEGIN PGP Signed message and END PGP Signature anchors.

Created the 2012-03-18

Share this


Article content

Resources

10 last blog posts

Related to this article

blog comments powered by Disqus