TL;DR
Next series of blog posts is about Ruby on Rails bottom up security. I will cover all aspects of web application written in Ruby on Rails framework. Described security concepts could be applied to any other modern web framework because we will describe which security problem particular concept resolves. I will start with hardening the server that runs the web application.
You probably think that hardening (reducing the surface of vulnerability) the server is impossible task. But I will prove you wrong. I found this excellent blog post that is foundation for hardening the server.
It has all instructions for Ubuntu linux how to harden the server. And you could be done with this task in 5 minutes!
Precondition is that server is up and running, and you know root password. You should first login as root.
- Select linux distribution
As you probably know, there are various linux distributions. I suggest latest CentOS for two reasons:
- it has excellent database about security patches
- it is tailored for servers that run server side services (e.g. web application)
2. Change root password
Unix command is
passwd
Tip. We suggest that you use LastPass password manager for creating and storing that password.
2. Update the system
You want to have latest software version as starting point.
yum -y -d 0 -e 0 update yum yum -y -e 0 -d 0 update
3. Install fail2ban
yum install fail2ban
fail2ban is daemon written in Python that monitors suspicious activities and if detected, automatically bans client ip addresses for some time.
4. create new user
useradd deploy
mkdir /home/deploy
mkdir /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
You will use only that user to connect to your server! Never use root user for establishing ssh connection. Note important command, chmod and number 700. At first, this look very cryptic. Read this for more info, and for now, remember that 700 gives all access ONLY to deploy user to .ssh folder (1+2+4 = 7).
5. ssh using public/private key authentication
In order to connect to your server, you will use ssh without password. How to set up that type of access? I recommend github tutorial:
Check for existing ssh keys is not needed, since you have new fresh server.
Generate new ssh key pair. You should set up password phrase (which is by default optional). Also, add private key to ssh agent, so you will not need to enter password phrase. Be sure to store password phrase to lastpass!
Test your ssh connection.
Add your public key to the server. Previous link contains instructions how to copy your public key. The you have to paste it:
vim /home/deploy/.ssh/authorized_keys
Save file and run:
chmod 400 /home/deploy/.ssh/authorized_keys chown deploy:deploy /home/deploy -R
Mode 400 is read only. This is highest security, and without that mode, you will get cryptic error when you will try to establish ssh connection.
6. Test The New User
Keep existing terminal open, and from new terminal type:
ssh deploy@server_ip_address
7. Enable sudo
In your first terminal as root, first set deploy user password:
passwd deploy
Save deploy user password in LastPass!
visudo
You are now in vi editor. Comment all lines and add at the bottom:
root ALL=(ALL) ALL
deploy ALL=(ALL) ALL
That means when you will run sudo as deploy user, you WILL BE ASKED TO ENTER PASSWORD!
8. Lock Down SSH
Via ssh, you will not be able to:
- connect as as root user
- connect using password
- connect from any client, but only from clients that you will list in setting.
vim /etc/ssh/sshd_config
Enter this, and be sure that original entries ARE DELETED:
PermitRootLogin no PasswordAuthentication no AllowUsers deploy@(your-ip) deploy@(another-ip-if-any)
systemctl sshd restart
9. What about firewall ?
I strongly do not recommend that your server is directly exposed to the Internet. It must be BEHIND dedicated FIREWALL. Ask your IAAS provider about details.
10. Enable Automatic Security Updates
This should be set, at least for security update. Set it in cron to run automatically on daily basis.
vi /etc/cron.daily/yumupdate.sh #!/bin/bash YUM=/usr/bin/yum $YUM -y -d 0 -e 0 update yum $YUM -y -e 0 -d 0 update
11. Install Logwatch To Keep An Eye On Things
Logwatch is tool that automatically monitors server logs and its logs can give you a hint about server intrusion.
yum install logwatch
vi /etc/cron.daily/logwatch_daily.sh
/usr/sbin/logwatch --output mail --mailto test@gmail.com --detail high
You are done with basic server hardening. In next post, I will explain how to harden servers based on their purpose. Web server, database server, cache server, job server have a slightly different security configuration.