return to list of articles

Setting up a Ruby on Rails app on DigitalOcean

A walkthrough of setting up and securing a Ruby on Rails application on DigitalOcean VPS.

This is a walkthrough of setting up and securing a Ruby on Rails application on a VPS running Ubuntu 13.04. To beging, first create a droplet on DigitalOcean and access your newly created server, substituting IP below with the IP address of your VPS.

ssh root@IP
# Type yes and enter the root password

On the server

Change the root password. Make it really secure using the Ruby command SecureRandom.base64(64) to generate a password for you:

passwd

You’ll want to update everything:

apt-get update
apt-get upgrade

Setup the login user, we’ll call it deploy. This is because we don’t want to be using the root user:

useradd deploy
mkdir /home/deploy
mkdir /home/deploy/.ssh
chmod 700 /home/deploy/.ssh

You’ll want to reset locales to ensure there are no problems.

sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
# if this fails, exit and re-ssh

Install vim if you want.

apt-get install vim

Regenerate the locales. Substitute en_US for whatever locale if you wish.

sudo locale-gen en_US.UTF-8
sudo dpkg-reconfigure locales

Run locale to make sure there are no issues.

Now add you public ssh key to the server:

# get public key from ~/.ssh/id_rsa.pub on your local computer and enter the following on the server
vim /home/deploy/.ssh/authorized_keys

Now change the ownership of the authorized keys file to the deploy user.

chmod 400 /home/deploy/.ssh/authorized_keys
chown deploy:deploy /home/deploy -R

Open a new tab and ssh into the server to see that there are no issues but keep your root ssh session tab open.

ssh deploy@server

In the root tab, create a password for the deploy user to use for sudo commands. You may want something a bit shorter but still secure. I recommend using SecureRandom.base64(32):

passwd deploy # on the root ssh session

Next open the following to allow sudo privileges to the deploy and root users:

visudo # still in the root tab

Comment out all of the existing entries and replace them with:

root    ALL=(ALL) ALL
deploy  ALL=(ALL) ALL

Now prevent password and root logins via ssh by opening up the sshd_config using:

vim /etc/ssh/sshd_config

Here we change the port to 21212. This doesn’t make the server much more secure, but changing it from the default port will prevent a lot of “spray and pray” attacks from most hackers. Add the following:

Port 21212 # the new obscure port to use for ssh connections
PermitRootLogin no # here we'll only be able to ssh using the deploy user from now on
PasswordAuthentication no # we're only allowing ssh connections using ssh keys
UsePrivilegeSeparation yes
UseDNS no
AllowUsers deploy # be explicit about which users can ssh in

Restart ssh:

service ssh restart
# possibly also run: reload ssh

Try to ssh into the server on the new port in a new shell

ssh -p 21212 deploy@IP # we now have to pass in the port using the -p flag

Now enable the firewall and allow connections from ports 80 and 443 and 21212:

# if the following don't work first run sudo apt-get install ufw
sudo ufw allow 21212/tcp # ssh connections
sudo ufw allow 80/tcp # www traffic
sudo ufw allow 443 # ssl traffic
sudo ufw enable # now enable the firewall

Check that it worked by running:

sudo ufw status

This isn’t really necessary if you added the AllowUsers line in the config above. If you haven’t you may want to install Fail2ban:

sudo apt-get install fail2ban

Make a new configuration file

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# change the port = ssh to port = 21212

We’ll also be adding Kippo, an ssh honeypot. First we need to install the dependencies:

sudo apt-get install python-dev openssl python-openssl python-pyasn1 python-twisted

Install subversion for Kippo.

sudo apt-get install subversion

Add a Kippo user:

sudo useradd -d /home/kippo -s /bin/bash -m kippo -g sudo

Install Authbind

sudo apt-get install authbind
sudo touch /etc/authbind/byport/22
sudo chown kippo /etc/authbind/byport/22 # change ownership to kippo user
sudo chmod 777 /etc/authbind/byport/22 # change permissions of the file

Switch to the Kippo user and now install Kippo:

sudo su kippo
cd # ensure you are in the kippo directory
svn checkout http://kippo.googlecode.com/svn/trunk/ ./kippo
cd kippo
mv kippo.cfg.dist kippo.cfg
vim kippo.cfg

Change the port in the kippo.cfg file you’ve just opened:

ssh_port = 22
# save and quit using :wq

Change the startup script

vim start.sh
# from:
# twistd -y kippo.tac -l log/kippo.log --pidfile kippo.pid
# to:
# authbind --deep twistd -y kippo.tac -l log/kippo.log --pidfile kippo.pid
# save and quit

Start the script

./start.sh
# Events will be logged to /home/kippo/kippo/log/kippo.log

Close the ssh connection and reconnect as deploy (or just ctrl-c, or is it cmd-c?):

ssh -p 21212 deploy@IP

Install RVM

\curl -L https://get.rvm.io | bash -s stable

If the above fails, install the dependencies first:

sudo apt-get install build-essential openssl libreadline6 libreadline6-dev \
curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 \
libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison \
subversion pkg-config

You’ll have to reload RVM:

source /home/deploy/.rvm/scripts/rvm

Install Ruby 2.0.0

rvm install 2.0.0

Use this version of ruby by default

rvm use 2.0.0 --default

Create gemset

rvm gemset create YOURGEMSET

Install curl with SSL headers

sudo apt-get install libcurl4-openssl-dev

Install Nginx

sudo apt-get install nginx

Add the config files to /etc

sudo ln -s /opt/nginx/ /etc/nginx

In the http section of /etc/nginx/conf/nginx.conf add the following

server {
  listen 80;
  server_name YOURDOMAIN;
  root /home/deploy/YOURAPP/current/public;
}

Add Nginx to startup

update-rc.d nginx defaults
# If you see 'System start/stop links for /etc/init.d/nginx already exists.' then it already does.

Restart Nginx

sudo service nginx stop
sudo service nginx start

Test Nginx by getting the IP and visiting it in the browser. There should be a ‘welcome to Nginx’ message.

# get the IP of the server
ifconfig eth0 | grep inet | awk '{ print $2 }'

Install Postgres

sudo apt-get install postgresql libpq-dev

Create postgres role for current user

sudo su - postgres

Open up Postgres console:

psql

Add the following:

CREATE ROLE deploy WITH LOGIN CREATEDB;
\q

create the database:

createdb YOURDBNAME -O deploy

Get notified when Pawel releases new posts, guides, or projects