Saturday, 24 September 2011
This article is specifically for hardening and increasing the security of a 1and1 CentOS 5 server which was installed or re imaged as;
CentOS 5 with Parallels SB Panel 10 (64-bit) or CentOS 5 with Parallels Plesk Panel 10 (64-bit).
The concepts can be applied to any Linux server distribution, but of course the commands and file locations may be different.
Rationale for writing this
After one ~ two years of using my 1and1 server as is with Parallels® Plesk control Panel my server got hacked.
more on my server hack experience...
I am definitely not a linux expert, but I can read. There are a lot of articles out there on things you can do, but not being an expert they didn't always work and I didn't know why. I do now, though. I have incorporated steps steps, paths, and explanations experts take for granted, but stymy those just learning. All of these steps and procedure come from somewhere else. I've done my best to reference all my sources.
If you have additional ideas or suggestions on [CentOS 5] server hardening please comment. I'll try the suggestions and incorporate them in further posts if they work.
To help distinguish comments from commands, I'll bold commands.
Step by step server hardening, lets begin;
To start, use a ssh client to connect to your server and login with root. If you haven't changed the initial password, the one you use to log in to you parrallel plesk control panel, this is the password for the root account.
First off, the only command prompt editor I know reasonably well is nano, so my first step is to install it.
yum install nano
You can get some really nice graphical reports from Webalizer so I install it.
yum install webalizer
The Parrallel Plesk control panel gives you good control over hosted websites but insulates you from the internal workings of the server. I don't know quite enough to run a server from the command prompt so I install webmin for more detailed server side administration.
rpm -Uvh http://download.webmin.com/download/yum/webmin-1.560-1.noarch.rpm
Some of the packages we need to install are not in the regular repositories, but in the Extra Packages for Enterprise Linux (or EPEL)repository, so we need to enable that repository.
rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm
Mod_security is a collection of rules designed to detect common web application attacks, which turns ModSecurity into a Web Intrusion Detection tool.
yum install mod_security
Logwatch is a customizable log analysis system that will create and e-mail you a report analyzing areas that you specify.
yum install logwatch
You will need to make some minor changes to the logwatch default config file, found at /usr/share/logwatch/default.conf/logwatch.conf.
nano /usr/share/logwatch/default.conf/logwatch.conf
To prevent the error " Can't execute sendmail -t: No such file or directory " change mailer = "sendmail -t" to mailer = "/usr/sbin/sendmail -t".
Also, it is a good idea to change the e-mail report recipient to an account not on the server you are monitoring, in case server gets compromised [i.e.; hacked].
Still in /usr/share/logwatch/default.conf/logwatch.conf change
MailTo = root to MailTo = outside e-mail address.
This command will manually run logwatch, and e-mail a report to the e-mail account you specified.
/etc/cron.daily/0logwatch
Now, we will install fail2ban, a package that blocks ip addresses after so many failed login attempts. It updates firewall rules to reject the IP address.
yum install fail2ban
Gamin, which is used by fail2ban, is a file and directory monitoring system which detects when a file or a directory has been modified.
yum install gamin
We need to make one minor adjustment to the fail2ban configuration file. Change backend = auto to backend = gamin.
nano /etc/fail2ban/jail.conf
The following command will start fail2ban.
fail2ban-client start
If we are going to truly harden our server and follow proper security protocol we really should not be logging as root, but using our own account to log in, and then su to become root.
So, add a new user account for yourself.
useradd <username>
And give the new user ID a password to activate it.
passwd <username>
Logout and log back in with you new account and execute su to become root.
su
when prompted enter root's password.
No one should be logging in directly as root, so we will now restrict Root's ability to logon.
echo "tty1" > /etc/securetty
We also should restrict who can see in roots directory.
chmod 700 /root
Next we need to secure OpenSSH. To do this we need to make some changes to OpenSSH's configuration file.
nano /etc/ssh/sshd_config
We have restricted root's ability to login, but we should also disable root Logins within the OpenSSH service.
Change # PermitRootLogin yes to PermitRootLogin no.
Also, so a hacker cannot try multiple login attempts with any account change #MaxAuthTries 6 to MaxAuthTries 6.
For added security you can allow only certain users ssh access to the server. Add an AllowUsers line followed by a space separated list of usernames to /etc/ssh/sshd_config. For example:
AllowUsers alice bob lbridge
By default ssh runs on port 22. To reduce hack attempts you can run it on a non standard port, say 2345.
Change the line port = 22 to port = 2345.
Before restarting the ssh server we need to allow access to that port through our firewalls. There is a firewall within your 1 and 1 control panel, but I never had much luck modifying it so I just disabled the 1 and 1 firewall.
However, once we disable that firewall we must update and enable iptables on your server.
Edit the iptables config file and enter everything below between [ but not including] the ---- lines [you can copy and paste].
nano /etc/sysconfig/iptables
--------------------------------------------------------------------------
#Drop anything we aren't explicitly allowing. All outbound traffic is okay
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type echo-reply -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
# Log anything on eth0 claiming it's from a local or non-routable network
# If you're using one of these local networks, remove it from the list below
-A INPUT -i eth0 -s 10.0.0.0/8 -j LOG --log-prefix "IP DROP SPOOF A: "
-A INPUT -i eth0 -s 172.16.0.0/12 -j LOG --log-prefix "IP DROP SPOOF B: "
-A INPUT -i eth0 -s 192.168.0.0/16 -j LOG --log-prefix "IP DROP SPOOF C: "
-A INPUT -i eth0 -s 224.0.0.0/4 -j LOG --log-prefix "IP DROP MULTICAST D: "
-A INPUT -i eth0 -s 240.0.0.0/5 -j LOG --log-prefix "IP DROP SPOOF E: "
-A INPUT -i eth0 -d 127.0.0.0/8 -j LOG --log-prefix "IP DROP LOOPBACK: "
# Accept any established connections
-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# accept common used ports
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 25 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 110 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 143 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 465 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 993 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 995 -j ACCEPT
# accept standard port 21 - ftp
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT
# Accept ssh traffic, but we will be changing this to a new port 2374. Restrict this to known ips if possible.
# port 22 - ssh, but eventually changing to 2374
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 2374 -j ACCEPT
# port 10000 - webmin
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 10000 -j ACCEPT
# port 80 - http
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
# port 443 - https
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
# to Accept Pings uncomment below
# -A RH-Firewall-1-INPUT -p icmp --icmp-type echo-request -j ACCEPT
# port 8443 - plesk control panel
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 8443 -j ACCEPT
#Log and drop everything else
-A RH-Firewall-1-INPUT -j LOG
# reject or drop ping traffic, better to drop
# reject ping traffic
# -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
# drop ping traffic
# -A RH-Firewall-1-INPUT -j DROP
COMMIT
--------------------------------------------------------------------------
To start|stop|restart iptables and reload the configuration file run the following command;
/etc/init.d/iptables restart
We now need to restart the OpenSSH service so it listens on the newly assigned port. To start|stop|restart sshd service run the following command;
/etc/init.d/sshd restart
Log out, change your ssh client to use the new port, log back in and become root.
Next, we need to update all the installed packages. This is something you should do at least every three or four months.
yum update
Lastly we should limit who can run cron jobs. You can do this with the file /etc/cron.allow.
Root can always create cron jobs, but really, no other users need that ability. If there is a legitimate reason why another user needs this ability you can always add that account to the cron.allow file.
To prevent anyone but root from running cron jobs just put
one blank line [one enter] in the file.
nano /etc/cron.allow
This isn't part of the hardening process, but it is always a good idea to have a list of users, installed packages, and running processes from a point in time where you know everything is working properly. This will give you a reference, a starting point, when and if things go bad, if your server gets compromised [hacked].
Change directory to roots home directory,
cd /root
and then run the following commands;
The following Will give you a text file list of users.
cat /etc/passwd | cut -d ":" -f1 > users.txt
The following gets you a list of installed packages
yum list installed >installedpackages.txt
# the following Will give you a text file list of running processes.
ps aux > runningprocesses.txt
that should be it! I hope this helps you in hardening your centos linux server.
references
Centos howto's and security
http://wiki.centos.org/HowTos/
http://wiki.centos.org/HowTos/OS_Protection
http://www.linux-books.us/centos_0004.php
http://www.nsa.gov/ia/guidance/security_configuration_guides/operating_systems.shtml
http://www.centos.org/docs/4/pdf/rhel-sg-en.pdf
http://www.nsa.gov/ia/_files/os/redhat/NSA_RHEL_5_GUIDE_v4.2.pdf
Description and website of installed packages
http://www.webmin.com/
http://www.modsecurity.org/
http://fedoraproject.org/wiki/EPEL
http://sourceforge.net/projects/logwatch/
http://www.fail2ban.org/wiki/index.php/Main_Page
http://people.gnome.org/~veillard/gamin/
http://www.openssh.com/
http://www.netfilter.org/projects/iptables/index.html
My other blogs:
OpenVZ on Debian - http://openvzondeb.blogspot.ca/
Linux Server Hardening - http://linuxserverhardening.blogspot.ca/
Icecast on Debian - http://icecastondebian.blogspot.ca/2013/10/page-one_31.html
SSHFS with rcync - http://usingsshfs.blogspot.ca/
SOCKS Tunneling - http://sockstunneling.blogspot.ca/
Kobo Arc 7", 64GB - http://koboarc.blogspot.ca/ [*new*]
and, a few works in progress:
Short Stories - http://louisebridgewrites.blogspot.ca/
Android TV Sticks - http://tvsticks.blogspot.ca/
My Streams:
Ices information panel - http://www.eclectica.mx:8000/
One of my streams is an all Neil Young stream.To see its listing on the Icecast Directory [at: http://dir.xiph.org/ ] search for Neil.
The search results will be: Neil Young [x listeners] " All Neil Young, and only Neil Young."