Free SSL using Let’s Encrypt

Update – May 2017

After adding a ruby on rails application to my website I realised let’s encrypt wasn’t renewing. I had been using unicorn for my application and had done a proxy forward for incoming traffic. This had caused the .well-known path to not be recognised. I had to add in a path to the public folder in the application to get this working again.

Replaced

location ~ /.well-known {
allow all;
}

with

location ~ /.well-known {
allow all;
root /path/to/rails/app/public;
}

 

I have just recently set up a couple of sites with free SSL from Let’s Encrypt. Here is a summary of the commands I used for Nginx from this nice tutorial on Digital Ocean. There is also an Apache version.

sudo apt-get update
sudo apt-get -y install git bc
sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
sudo nano /etc/nginx/sites-available/default

Change SSL lines in nginx config
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

And add the following inside the server block
location ~ /.well-known {
allow all;
}

cd /opt/letsencrypt
./letsencrypt-auto certonly -a webroot --webroot-path=/usr/share/nginx/html -d example.com -d www.example.com

Add you email address and agree to T&Cs

Reload Nginx
sudo service nginx reload

Automatic renewal with crontab
sudo crontab -e
30 2 * * 1 /opt/letsencrypt/letsencrypt-auto renew >> /var/log/le-renew.log
35 2 * * 1 /etc/init.d/nginx reload

Mono server for ASP.NET

#install mono server
sudo apt-get install mono-fastcgi-server4

Add following to /etc/nginx/fastcgi_params
fastcgi_param PATH_INFO "";
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

Nginx configuration
server {
listen 80;
server_name [HOST_NAME];

location / {
root [APP_ROOT];
index index.html index.htm default.aspx Default.aspx;
fastcgi_index Default.aspx;
fastcgi_pass 127.0.0.1:9000;
include /etc/nginx/fastcgi_params;
}
}

Restart Nginx
sudo service nginx restart

Start mono server
fastcgi-mono-server4 /applications="[HOST_NAME]:/:[APP_ROOT]" /socket=tcp:127.0.0.1:9000
e.g. fastcgi-mono-server4 /applications="192.168.0.0:/:/var/www/net" /socket=tcp:127.0.0.1:9000

Mono Server initialization script
#!/bin/sh

### BEGIN INIT INFO
# Provides: monoserve.sh
# Required-Start: $local_fs $syslog $remote_fs
# Required-Stop: $local_fs $syslog $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start fastcgi mono server with hosts
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/bin/mono
NAME=monoserver
DESC=monoserver

MONOSERVER=$(which fastcgi-mono-server4)
MONOSERVER_PID=$(ps auxf | grep fastcgi-mono-server4.exe | grep -v grep | awk '{print $2}')

WEBAPPS="/:[APP_ROOT]"

case "$1" in
start)
if [ -z "${MONOSERVER_PID}" ]; then
echo "starting mono server"
${MONOSERVER} /applications=${WEBAPPS} /socket=tcp:127.0.0.1:9000 &
echo "mono server started"
else
echo ${WEBAPPS}
echo "mono server is running"
fi
;;
stop)
if [ -n "${MONOSERVER_PID}" ]; then
kill ${MONOSERVER_PID}
echo "mono server stopped"
else
echo "mono server is not running"
fi
;;
esac

exit 0

Add appropriate rights:
chmod +x /etc/init.d/monoserve

And install the script:
update-rc.d monoserve defaults

Capistrano3-nginx permissions

Capistrano3 has a plugin for Nginx called capistrano3-nginx which allows you to manage it using the cap command or through your deployment scripts e.g. nginx:reload

However, if you try to run any of these command on some systems, it may start to complain about not having permissions or your deploy my hang while asking for a sudo password.

To get round this you need to give the deploying user the permissions to run a sudo command without needing a password. If you’re like me the, the first time you hear that you think “that can’t be very secure”. Correct! Giving any user full sudo access without a password isn’t recommended.

To improve things we can restrict what commands the deploying user can run as sudo without a password. To do this edit the sudoers file using the following command

sudo visudo

Adding the following line will then allow the deploying user to run the require Nginx commands without the need for a password.

deploy ALL=NOPASSWD:/usr/sbin/service nginx *

You may need to adjust the Nginx service path if your set up is different. The ‘*’ just allows all commands on the Nginx service. You could restrict this further by only allowing specific commands like ‘restart’.

Once you have saved the changes you should be able to run Nginx service commands without the need to enter a password and Capistrano should in turn be able to do the same.

Boot script for Passenger Standalone

In extension to THIS POST, I created a boot script so the application loads when the server is rebooted. Everything in {} needs replaced with your own values.

Create /etc/init.d/{YOUR_APP_NAME}
Add the following code:

#!/bin/bash
### BEGIN INIT INFO
# Provides: boot passenger in standalone
# Required-Start: 2 3 4 5
# Required-Stop: 0 1 6
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start/stop app.name.com
### END INIT INFO

APP_NAME={YOUR_APP_NAME}
ENVIRONMENT=production
CURRENT="/{APPS_DIR}/$APP_NAME/current"
SHARED="/{APPS_DIR}/$APP_NAME/shared"
USER="{DEPLOYING_USER}" # e.g. www-data
RUBY_VERSION="{RUBY_VERSION}" # e.g. 1.9.3-p194

start() {
echo "Starting passenger"
cd $CURRENT;
/home/$USER/.rbenv/versions/$RUBY_VERSION/bin/passenger start --socket /tmp/$APP_NAME.socket -d --nginx-version 1.0.5 -e $ENVIRONMENT --pid-file $SHARED/pids/passenger.pid --log-file $SHARED/log/passenger.log --user $USER;
}

Save the file.

Edit /etc/rc.local
Add the following line before the end:

su {DEPLOYING USER} -c "/etc/init.d/{YOUR_APP_NAME} start"

UPDATE

Make sure you have installed the passenger gem for whichever version of ruby you are trying run against.

Adding multiple versions of ruby to run rails app through nginx

UPDATE: Since passenger 4 support of multiple versions of ruby is built in. Use the passenger_ruby parameter in the server block.

The following is how to setup nginx on Ubuntu to run additional ruby versions for rails applications.

$ -> rvm use 2.0.0-p0
or
$ -> rbenv use 2.0.0-p0

$ -> passenger start --socket /tmp/app_name.socket -d --nginx-version 1.0.5 -e production

nginx configuration

upstream app_upstream {
server unix:/tmp/app_name.socket;
}

server {
listen 80;
server_name app.me.com;
root /apps/app_name/public;

location / {
proxy_pass http://app_upstream;
proxy_set_header Host $host;
}
}

Install nginx on ubuntu

The following commands will use the passenger gem to install nginx on ubuntu 11.10

gem install passenger --no-rdoc --no-ri
rvmsudo passenger-install-nginx-module
sudo nano /etc/init.d/nginx

Paste in source from http://wiki.nginx.org/Nginx-init-ubuntu
sudo chmod +x /etc/init.d/nginx
sudo /usr/sbin/update-rc.d -f nginx defaults #(run at startup)
sudo /etc/init.d/nginx start