Post Thu Apr 26, 2018 4:06 pm

HOWTO: Remote Access SSL certificate with DDNS (Linux)

It took some effort to get this to work so Chrome wouldn't complain about the connection being insecure. I figured I would share my process with anyone who might be interested. There are some old guides that used some proprietary windows software that didn't work for me but were immensely helpful for figuring this out. My server is hosted on an Ubuntu 16.04 installation but should work on any linux distro that has curl, cron, apache2, jdk and supports the certbot client.

Overview
The idea is to use the DDNS service duckdns.org to get a url, then use the services from letsencrypt.org to get a certificate using Apache2 and Certbot. Finally configure Serviio to use that certificate. This guide assumes a pre-existing Serviio installation.

Step 0 - Have a static local IP.
In order for this to work your server machine has to have a static IP address on your network. I achieve this by having a DHCP reservation on my router but it could easily be done in the operating system.

Step 1 - Install prerequisite software.
On ubuntu this can be done by running the following command:
  Code:
sudo apt install cron curl apache2 default-jdk


Once this is done you Apache should be started and thus accessible by typing your servers local IP address into the browser.

Step 2 - Get a URL
Goto duckdns.org and register. Proceed to their install page and follow it's instructions for "linux cron". Duck DNS the only DNS I have found that works with letsencrypt/certbot.

Step 3 - Configure your router
In order for the certificate work we must configure the router so that regular HTTP requests goto Apache2, while HTTPS requests goto Serviio so we can actually view our library. I prefer to leave Serviio configured to it's default port and map it in the router configuration. To accomplish this add the following port forwarding configurations to your router to forward them to your server machine:
  Code:
External Port - Internal Port
80            - 80
443           - 23524


Consult the documentation on your router model for how to do this.

After this is done you should be able to get to Apache's "It works" page by typing the URL you created in step two into your browser (with HTTP://, not HTTPS://).

Step 4 - Install Certbot and obtain a certificate
Follow the handy instructions at certbot.eff.org for Apache and your version of linux. Obtain your certificate using the certonly option.

Step 5 - Import certificate into Serviio
This part turned out to be quite tricky, so I wrote a script to make it quite easy. The keystore and key will have the same password as the ones included with Serviio to avoid having to modify serviio.properties in the jar file. I like to place my scripts in a hidden folder in my home directory. Thus create the script with this command:
  Code:
nano ~/.scripts/MigrateScriptToServiio.sh

Paste the following code into the script:
  Code:
#!/bin/bash
(
    domain='[Your Domain]'
    serviioLoc='[Serviio Location]'
    # Export certificate to pkcs12 file.
    openssl pkcs12 -password pass:'h,U)-RM!j,]9H2nwKq/cKb]{5&ST2wt/' -export -in /etc/letsencrypt/live/$domain/cert.pem -inkey /etc/letsencrypt/live/$domain/privkey.pem > server.p12


    # Clear out the old certificate store
    rm $serviioLoc/config/serviio.jks
    # Import key into serviio keystore
    keytool -importkeystore -srckeystore server.p12 -destkeystore $serviioLoc/config/serviio.jks -storepass '>[Z=@Ahjr,(pA[{4,u8Q?T`gzKp^mAf&' -srcstorepass 'h,U)-RM!j,]9H2nwKq/cKb]{5&ST2wt/' -srcstoretype pkcs12

    # Delete the pkcs12 file
    rm server.p12

    chmod 755 $serviioLoc/config/serviio.jks

    # Find the existing serviio process
    pid=`jps | grep MediaServer | cut -d ' ' -f 1`
    # and kill it and wait for it to die
    kill $pid
    while kill -0 $pid;do sleep 1;done;

    # Start it in the background
    sh $serviioLoc/bin/serviio.sh &
)

Be sure to change the domain and serviioLoc values to match the domain you created in step 2 and the root location of your serviio installation. (The folder containing bin, config, legal, lib, etc)

Make the script executable and run it with the following commands:
  Code:
chmod 755 ~/.scripts/MigrateCertToServiio.sh
sudo ~/.scripts/MigrateCertToServiio.sh


After this Serviio should be running your trusted certficate. If you got the type the domain you created in step 2 into the browser using HTTPS:// you should get the Serviio media browser with the lovely green lock next to the URL (in at least, not sure how other browser denote it)

Step 6 - Setup certificate renewal
The letsencrypt documentation recommends checking for certificate renewal twice a day. This is easy with cron. Certificate renewal must be run as an administrator so edit the cron table for administrator using sudo:
  Code:
sudo crontab -e

And add the following line to the table making sure to change [user] to reflect your linux username:
  Code:
23 06,18 * * * /usr/bin/certbot renew --deploy-hook /home/[user]/.scripts/MigrateCertToServiio.sh


The by setting our migrate script as the deploy-hook we can make sure that the script serviio uses is changed when the cert is renewed, keeping it up to date all the time.

Step 7 - Configure Apache redirect
In this step we will configure apache to redirect and http requests it received to the serviio browser. This will be accomplished using a .htaccess file, which we must first enable in the apache configuration. Edit apache2.conf:
  Code:
sudo nano /etc/apache2/apache2.conf

Find the directory configuration for /var/www/:
  Code:
<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
</Directory>

Modify it to allow override:
  Code:
<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
</Directory>

After this you will need to restart apache for the changes to take effect:
  Code:
sudo service apache2 restart

Create the .htaccess file in the server root:
  Code:
sudo nano /var/www/html/.htaccess

Enter the following lines:
  Code:
RewriteEngine On
RewriteCond %{HTTPS}  !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/mediabrowser [R,L]

Save the file and you are now done. Any requests on the unsecure HTTP will redirect to the main entry page for the media browser. Enjoy your secure media server!