Learn-a-holic Geek Notes

Human compiled Brainwork by Kornelije Sajler.

Ubuntu VPS Step-By-Step Configuration Notes

UPDATED (June 30th, 2015)


June 30th, 2015

  • Covering Ubuntu 14.04 LTS.
  • Adde extra SSH security, using Public Keys and some more tweaks in sshd_config.
  • Added usual PHP & MySQL install and configure.
  • Using service <COMMAND> <ACTION> seems Ubuntu nowdays have problem with /etc/init.d, it is old school, but I’ve liked it. (Thanks to Rapha for mention it in comments).
  • Latest Ruby 2.2.2

January 9th, 2014

  • First version covering Ubuntu 13.

Here are notes and step-by-step tutorial to set Ubuntu VPS secure and with nginx, node.js, ruby, PostgreSQL, …

It should work for Ubuntu 12 or 13 or 14 versions. My VPS provider still doesn’t have support Ubuntu 15, but I don’t think that there would be any problem using this for Ubuntu 15.

It assumes knowledge of SSH and connecting to your fresh VPS install.

Throughout the install process for editing I’m using vi, you can use what ever makes you happy: emacs, nano, …

Those are just my notes, if someone has something better or can improve it please do comment!


Update and installing essential software

sudo apt-get -y update
sudo apt-get -y install curl git-core python-software-properties software-properties-common

Locale problem

Very annoying error in apt: locale: Cannot set LC_CTYPE. It is probably due to your local machine, add this to your .bashrc or .zshrc:

export LANGUAGE=en_US.UTF-8
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

User - Admin Group & SSH

sudo groupadd admin
sudo adduser <USERNAME>
sudo usermod -a -G admin <USERNAME>
sudo dpkg-statoverride --update --add root admin 4750 /bin/su

Test new user and test that has sudo privileges:


Secure SSH:

sudo vi /etc/ssh/sshd_config

Make these changes:

  • Port (Don’t use default 22)
  • PermitRootLogin no
  • X11Forwarding no
  • AllowTcpForwarding no

If your SSH is very slow setting X11Forwarding to no can really help in this case!

sudo service ssh restart

Connect to VPS SSH:


SSH Extra Security

The idea is to not permit passwords and use SSH keys for authentication, and some other tweaks to SSH.

mkdir ~/.ssh
vi ~/.ssh/authorized_keys

And paste the content of your local machine Public Key file: .ssh/id_rsa.pub and make it rw only for current user:

chmod 600 ~/.ssh/authorized_keys

Or use ssh-copy-id from your local machine, which isn’t on Mac, and can be installed with brew but I have no luck:

brew install ssh-copy-id
ssh-copy-id "<USERNAME>@<VPS_DOMAIN_OR_IP> -p <PORT>"

Try to connect to SSH and it should not ask you for password, it should be instant login:


Open SSH config file, uncomment PasswordAuthentication which is by default set to yes:

sudo vi /etc/ssh/sshd_config

Change it to no:

PasswordAuthentication no

Restart SSH and try to connect again:

sudo service ssh restart

Exit the VPS shell and try to connect to VPS SSH.


To have ping and apt-get working, add the following into iptables, as ufw just interfaces with it.

sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

sudo apt-get -y install ufw
sudo vi /etc/default/ufw

Make this change:


Allow some ports and services:

sudo ufw limit ssh
sudo ufw allow 80/tcp
sudo ufw allow out 53
sudo ufw logging on

Be sure that you allowed the changed port for SSH because otherwise, you’ll be unable to get into VPS!!!

sudo ufw enable

Check the Firewall status with:

sudo ufw status verbose


sudo mv /etc/sysctl.conf /etc/sysctl.conf.orig
sudo vi /etc/sysctl.conf

Add this to a sysctl.conf:

# IP Spoofing protection
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Ignore ICMP broadcast requests
net.ipv4.icmp_echo_ignore_broadcasts = 1

# Disable source packet routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.default.accept_source_route = 0

# Ignore send redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

# Block SYN attacks
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 5

# Log Martians
net.ipv4.conf.all.log_martians = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1

# Ignore ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0

# Ignore Directed pings
net.ipv4.icmp_echo_ignore_all = 1

Then run, there can be possible some errors, especially on VPS with OpenVZ

sudo sysctl -p

Denyhost or Fail2Ban

Before Denyhost was uset but it seems it is no longer maintained and there is no Ubuntu package anymore so the Fail2Ban is alternative, but since the SSH is set to permit only SSH keys, both of those are redundant.

Remove Samba File Sharing

If for some reason you have completely unnecessary Samba installed by default on VPS you can remove it with:

sudo apt-get -y remove --purge samba

Remove Bind DNS Server

Same with Bind, if you don’t need it, remove it!

sudo apt-get -y remove --purge bind9
sudo rm -rf /var/cache/bind
sudo rm -rf /usr/share/bind9
sudo rm -rf /etc/bind

SSH Key and GitHub

Check if ~/.ssh has *.pub files, if not generate the SSH key:

ssh-keygen -t rsa -C "<YOUR_EMAIL>"

Use default place to store: ~/.ssh

Do not use passphrase, unless you want to type every time you commit to GitHub. (Or anyone knows better way?).

cat ~/.ssh/id_rsa.pub

Copy the contents to clipboard. Go to GitHub > Account Settings > SSH Keys. Hit Add SSH Key give title and in Key paste public key from clipboard.

ssh git@github.com
eval `ssh-agent -s`
ssh-add -k

Software Install

Instal nginx

sudo add-apt-repository ppa:nginx/stable
sudo apt-get -y update
sudo apt-get -y install nginx
sudo service start nginx

If error is nginx: [emerg] bind() to [::]:80 failed (98: Address already in use) then probably Apache is installed beforehand:

sudo apt-get remove apache2-mpm-prefork
sudo apt-get remove apache2-mpm-worker
sudo apt-get remove apache2

You can check and purge installed Apache:

sudo dpkg --get-selections | grep  apache
# Purge others that are given as result from above command
sudo dpkg --purge apache2
sudo service nginx start

If something is wrong look for nginx logs:

sudo vi /var/log/nginx/error.log

Install and configure PostgreSQL, create DB and DB User

sudo add-apt-repository ppa:pitti/postgresql
sudo apt-get -y update
sudo apt-get install -y postgresql libpq-dev

Log into postgres change main password, create db user with password and create new database with previously created user as owner:

sudo -u postgres psql
\password  "<PASSWORD>"
create user <USERNAME> with password '<USER_PASSWORD>';
create database <DB_NAME> owner <USERNAME>;

Install MySQL, create DB and DB User

sudo apt-get install mysql-server

The install will prompt you for root user password that needs to be re-entered, choose password wisely and try to remember it! After install log into MySQL:

mysql -u root -p # After enter there is need to write password and hit enter again

Use mysql command line app for interacting with MySQL, lets create user and DB with user granted on this DB:

mysql> SHOW DATABASES;  # The new db should be listed.
mysql> CREATE USER '<DB_USERNAME>'@'localhost';
mysql> SELECT User,Host FROM mysql.user; # The new user should be listed on host localhost.
mysql> GRANT ALL ON <DB_NAME>.* to '<DB_USERNAME>'@'localhost' identified by '<DB_PASSWORD>'; # It will grant all on this DB by this user.
mysql> exit # Or new command \q

If you need to run SQL script for database, use this from command line:

mysql -u <DB_USERNAME> -p <DB_NAME> < <SCRIPT_NAME>.sql

Install Ruby with rbenv and rbenv-installer

curl https://raw.github.com/fesplugas/rbenv-installer/master/bin/rbenv-installer | bash
vi .bashrc

At top add:

export RBENV_ROOT="${HOME}/.rbenv"

if [ -d "${RBENV_ROOT}" ]; then
  export P
  eval "$(rbenv init -)"

Reset .bashrc:

. ~/.bashrc

Note that bootstrap-ubuntu-12-04 works fine for Ubuntu 13 & 14 (probably 15 too):

rbenv bootstrap-ubuntu-12-04

Firstly list rbenv available Ruby versions and pick one to install:

rbenv install -l
rbenv install 2.2.2

Set chosen Ruby version to be “global”, and test it:

rbenv global 2.2.2
ruby -v

Install PHP & friends

The long list of PHP packages covering Imagemagick, MySQL, bcrypt,…:

sudo apt-get install imagemagick php5-fpm php5-mysql php5-curl php5-gd php5-intl php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-ming php5-ps php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl php5-xcache

Change usaul suspects of php.ini properties:

sudo vi /etc/php5/fpm/php.ini
  • upload_max_filesize = (SOME_NUMBER)M (Default 2Mb - safe to use 25M)
  • post_max_size = (SOME_NUMBER)M (Default 8Mb - safe to use 25M)
  • memory_limit = (SOME_NUMBER)M (Default 128Mb - safe to use 512M)

Restart PHP-FPM and Nginx:

sudo pkill php5-fpm; service php5-fpm start
sudo service nginx restart

Install node.js

sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get -y update
sudo apt-get install -y nodejs

Install and Configure redis

sudo apt-get -y install redis-server
sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.default
  • pidfile /var/run/redis-server.pid
  • logfile /var/log/redis-server.log

Esoteric Installments

Install erlang

sudo apt-get -y install erlang-nox

Install and Configure riak

curl http://apt.basho.com/gpg/basho.apt.key | sudo apt-key add -
sudo bash -c "echo deb http://apt.basho.com $(lsb_release -sc) main > /etc/apt/sources.list.d/basho.list"

If Ubuntu is not LTS instead of lsb_release -sc use name of LTS, eg. Ubuntu 14.10 (Utopic) is not LTS use 14.04 codename trusty instead. Use this Wikipedia table to help with names for particular Ubuntu version(s).

sudo apt-get -y update
sudo apt-get -y install riak

Change PAM Based Limits for riak

sudo vi /etc/pam.d/common-session

Add at the end of file:

session required    pam_limits.so

Update limits.conf:

sudo vi /etc/security/limits.conf

# Add this to limits.conf
*               soft     nofile          65536
*               hard     nofile          65536

If accessing riak nodes via SSH:

sudo vi /etc/ssh/sshd_config
UseLogin yes

Reboot machine and test that limit of open files is 65536 with:

ulimit -a
> open files                      (-n) 65536

or with:

ulimit -n

Hope it helps, please give feedback and comments with any missing/wrong parts to this Ubunt VPS install, because I’m far from Linux guru, but appreciate secure and stable Linux machine!