Table of Contents
- 1 Accessing the VPS for the first time
- 2 Setting up the VPS
At the time of writing this post, a VM with a bare installation of Ubuntu Server 12.04 LTS was used to mimic a VPS. I manually added the host
/etc/hoststo emulate an actual internet domain name. Any occurrence of this host should be replaced with the IP address or the host name of your VPS.
1 Accessing the VPS for the first time
After getting your SSH access and credentials from your VPS provider, use the following command to access your newly created VPS.
Since this is the first time for you to access the VPS from your machine, you’ll be asked to add its fingerprint to the list of your known hosts. Just type yes and hit Enter to continue.
2 Setting up the VPS
Next, we will setup the VPS to prepare it for running our Rails application.
2.1 Configuring Ubuntu
Most of the VPSs that I’ve worked with came without a pre-installed language pack, which sometimes lead to problems when installing software using
aptitude (my favorite). To solve this issue, make sure you run the following before doing anything else. Note that you’ll have to repeat these steps for every user who accesses the server (Keep that in mind, since we’ll add a new user later in this tutorial).
export LANGUAGE=en_US.UTF-8 export LANG=en_US.UTF-8 export LC_ALL=en_US.UTF-8 sudo locale-gen en_US.UTF-8 sudo dpkg-reconfigure locales
To make sure these get set every time you login to the server, add the following lines to the end of your
# Fix Language export LANGUAGE=en_US.UTF-8 export LANG=en_US.UTF-8 export LC_ALL=en_US.UTF-8
While you’re at it, add the following lines as well to your
~/.bashrc. They’ll come in handy later.
# Rails export RAILS_ENV=production # Aliases alias rake="bundle exec rake" alias rails="bundle exec rails"
Moving on, let’s proceed with updating the packages currently installed on the VPS. To do so, make sure your sources are updated first, and then make the necessary upgrades, by running the following commands.
aptitude update aptitude safe-upgrade -y
Let’s install some necessary dependencies, that are required by most of the packages that we’ll need later in the tutorial. To do so, run the following command.
aptitude install build-essential -y
When it’s done, make sure to run the following command to reboot the server and apply the new updates. The SSH session will automatically get disconnected. Your can SSH again in a minute or two.
2.2 Adding the Deployer
root user as the sole and only user seemed like a good idea in the beginning, when I first started deploying Rails applications online, but later on I came to know that it’s not a very good practice. Instead, creating a dedicated “deployer” user sounded better, because it gave me more control over the permissions granted to the user, in case anything went south. To create a new user, run the following command.
You’ll be prompted to enter some details for your newly created user. Feel free to fill it in in any way you want. I usually use “VPS Deployer” as the name, and leave the rest of the fields to their defaults.
I found it convenient to create a dedicated user group to include the deployer user(s), to help me control their permissions easily. By convention, such group is called
wheel. To create a new user group, run the following command.
Then add the
deployer to it my running the following command.
usermod -a -G wheel deployer
To give the
sudo privileges, run the following command.
This will open the file
/etc/sudoers in edit mode, to allow you to make modifications. Add the following lines in the appropriate place in the file to add the
wheel group to the list of sudoers (those who can use
... # Members of the admin group may gain root privileges %admin ALL=(ALL) ALL # Members of the wheel group may gain root privileges %wheel ALL=(ALL) ALL ...
Run the following command to switch to
deployer. Make sure to amend
~/.bashrc as mentioned earlier in section 2.1.
2.3 Configuring SSH
A more secure way to access a server is to do so using a public/private key combination, instead of the regular way using passwords. This limits the access to the server to only those who have their public keys added to the server’s authorized keys. This method is usually used in 2 scenarios; when a user tries to access the server, and when a server tries to access the repository containing the code to be deployed, if it exists. In the latter, the server is considered to be a user, which tries to access another server (this on which the code resides).
To kick things off, the public/private key combination should be created. Both keys are usually present in
id_rsa (private key) and
id_rsa.pub (public key). If both files don’t exist or if the directory itself is not present, first create the
.ssh directory both on your machine (if it’s not there already).
Then generate the public/private keys using the following command. An extra
-C "comment" argument can be added to annotate the public key with a custom comment to make it easier to identify it later on among other keys.
ssh-keygen -t rsa
Make sure to copy the generated public key to
deployer‘s home directory on the server by running the following command on your local machine.
scp ~/.ssh/id_rsa.pub email@example.com:
Now let’s move on to the server. First, create the
.ssh directory using the same steps done above, and generate a public/private key combination for the server, then move your copied
~deployer/.ssh/authorized_keys using the following command.
mv ~deployer/id_rsa.pub ~deployer/.ssh/authorized_keys
Then run the following commands to configure the ownership and permissions of the created directory and files.
chmod 700 ~deployer/.ssh chmod 600 ~deployer/.ssh/authorized_keys
Ctrl+D to switch back to
For all this to be effective, a few configurations of Ubuntu’s SSH server should be changed. To access these configurations, use the following command.
The main things to change are:
Port 6311 # Or any other port rather than the default 22 PermitRootLogin no PasswordAuthentication no # Custom UseDNS no AllowUsers deployer
Run the following command to reload the modified configurations.
service ssh reload
To SSH into the server from now on, you’ll have to specify the new port. Please also note that you can only SSH using the
deployer user, since SSHing using the
root user is now disabled.
ssh -p 6311 firstname.lastname@example.org
2.4 Configuring the Firewall
The most know tool to configure access from and to a server running Ubuntu is
iptables. IMHO, I believe it’s a bit complicated to use. I prefer using a more user friendly tool called
ufw (Uncomplicated Firewall) to manage my server’s firewall. UFW comes pre-installed with Ubuntu. It provides a simple interface to manage firewall rules and
UFW is disabled by default. Let’s keep it that way until we’re done with configuring it, then we’ll eventually enable it.
We want to block any access to the server by default, and then define some white-list rules. This makes sure we don’t leave any rubbish behind, but it requires some concentration in order not to lock ourselves out for good by mistake. So basically, we close all the system ports, and only open the ones that we need. This part should be revisited every time new network dependent software is installed.
To deny access to all ports by default, run the following command.
sudo ufw default deny
Now let’s make a small change to the configurations of `ufw` before defining our access rules. This change isn’t necessary, but it comforts me, because it gives me the control I want to have over my server. To open the configurations, run the following command.
sudo nano /etc/default/ufw
And then find the following line and change it accordingly.
Now let the fun begin!
sudo ufw allow 80/tcp # HTTP sudo ufw allow 443/tcp # HTTPS sudo ufw allow 6311/tcp # SSH
If you made any mistakes, you can delete any declared rule by running the following command.
sudo ufw delete allow 443/tcp
To enable `ufw`, run the following command. It’ll show you a warning that can be safely skipped.
sudo ufw enable
Take a final look at the rules you defined by running the following command.
sudo ufw status
If everything looks good, make sure you still have access to the server by starting a new SSH session in another terminal window. If you can still get in, feel free to end the old session.