Host subsonic at home with SSL (Ubuntu install)

home of a content challenger

Host subsonic at home with SSL (Ubuntu install)

I fell in love with subsonic. It allows me to play my media (music and movies) while I am away from home, getting bored in a hotel. For the installation I had a couple of requirements:

  • To prevent people from snooping on my passwords, https will be used as the protocol.
  • It must work on the default https port (443) to prevent potential problems with firewalls.

Now on Ubuntu (the Linux of choice for this installation) any port below 1024 can only be used by a process running as root. Since I didn’t want to run subsonic itself as root, I decided to use Apache in front of my subsonic installation. Apache can bind the port as root and then drop its privileges to the “www-data” user, something I don’t think subsonic is able to do.

The result of my installation is the following setup:

  • Apache running with https (ssl) on port 443. Apache will be reachable from the internet.
  • Subsonic running on port 4040 as a “normal” http service. Since the connection from apache to subsonic runs on the same machine, there is no need for encryption here. With this configuration subsonic itself is not directly reachable from the internet, but only through apache.
  • Apache will be configured as a so called reverse proxy to pass requests from apache to subsonic. This means your browser will talk to apache and Apache will talk to Subsonic.

Install Apache

The following command will install apache with support for https:

sudo apt-get install apache2 libapache-mod-ssl

Take note that for https, you will need the libapache-mod-ssl package, apache2 alone will not do https.

For ssl encryption we need to generate a so called “self signed certificate”.  There are a couple of ways to do this, I used the one described here. The steps are:

sudo mkdir /etc/apache2/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/apache.key -out /etc/apache2/ssl/apache.crt

This last one will ask you a lot of questions. The most important one however is the “common name”, which shall not be empty. Enter your official domain name, or your IP. If you don’t have an official domain name, or your IP keeps changing, Please set up a dynamic DNS somewhere on the net. I got mine at afraid.org. For the rest of the article I will assume that your host will be called supersonic.mydomain.com, you will need to replace that with your personal URL.

Now we need to configure in such a way that it will proxy all the requests to subsonic. Since subsonic will be installed on port 4040 afterwards, apache will forward all requests to port 4040. Create the following file for your domain /etc/apache2/sites-available/supersonic-mydomain.com-ssl with the following content:

  
    ServerName supersonic.mydomain.com
    ServerAlias supersonic.mydomain.com
    ErrorLog ${APACHE_LOG_DIR}/error.log
    LogLevel warn
    CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined
    SSLEngine on
    SSLCertificateFile /etc/apache2/ssl/apache.crt
    SSLCertificateKeyFile /etc/apache2/ssl/apache.key
    BrowserMatch "MSIE [2-6]" \
    nokeepalive ssl-unclean-shutdown \
    downgrade-1.0 force-response-1.0
    # MSIE 7 and newer should be able to use keepalive
    BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
    ProxyRequests Off

      Order allow,deny
      Allow from all

    ProxyPass / http://127.0.0.1:4040/
    ProxyPassReverse / http://127.0.0.1:4040/

Now enable this configuration:

sudo a2ensite supersonic-mydomain.com-ssl
sudo service apache2 reload

Install subsonic

First you need to install some dependencies for the subsonic package:

sudo apt-get install lame flac faad vorbis-tools ffmpeg openjdk-6-jre

Then head over to subsonic.org and download the latest package for your distribution. After you have downloaded change to the directory holding the package and type:

sudo dpkg -i subsonic-4.7.deb

Please note that we will install subsonic to run without https support. The https protocol will be handled by apache, so the communication between apache and subsonic is unencrypted. Since both services run on the same machine this should not be an issue at all. Now modify the file /etc/default/subsonic to look like the one below:

#
# This is the configuration file for the Subsonic service
# (/etc/init.d/subsonic)
#
# To change the startup parameters of Subsonic, modify
# the SUBSONIC_ARGS variable below.
#
# Type "supersonic --help" on the command line to read an
# explanation of the different options.
#
# For example, to specify that Subsonic should use port 80 (for http)
# and 443 (for https), and use a Java memory heap size of 120 MB, use
# the following:
#
SUBSONIC_ARGS="--port=4040 --max-memory=512"

# The user which should run the Subrsonic process. Default "root".
# Note that non-root users are by default not allowed to use ports
# below 1024. Also make sure to grant the user write permissions in
# the music directories, otherwise changing album art and tags will fail.
SUBSONIC_USER=[the_name_of_your_unprivileged_user]

Now restart subsonic

sudo service subsonic restart

and check in your browser whether it all worked as intended:

https://supersonic.mydomain.com

 

9 Responses

  1. tomber says:

    Hey Jord, please check your posting: Host subsonic at home with SSL (Ubuntu install)
    its allways the same …

    thank you

  2. Jord says:

    Hi Tomber,

    Thanks for pointing out. There were some multi-language settings still active. I removed all traces on this page now.

  3. Marc says:

    Just curious if you could use iptables to forward port 443 to 4041 (or whichever port you configure) and use Subsonic’s built in ssl cert?

  4. Jord says:

    You can probably do such a thing. It is nicer though to go for a signed certificate, for instance one you can get with startssl.

  5. Marc says:

    Startssl would be nicer for avoiding the untrusted certificate error in a browser but I believe you would still receive that with the method outlined above (creating a self-signed cert in Apache). Wouldn’t forwarding the port through iptables accomplish the same encryption while removing Apache from the entire setup? Also, the untrusted cert wouldn’t change the way a mobile app accesses the server would it? Thanks for your input.

  6. Jord says:

    Not sure about the mobile app. Depends on the app, if it can do https, it should not be a problem.

    Just forwarding with iptables can only work if subsonic can handle the encryption. Since there are so many problems with bad implementation of encryption standards, I think it is a good idea to have a trusted product (apache in this case) handle the https for you. It also allows you to “hide” multiple services behind your apache. Apache then does the rerouting based on the url it receives.

  7. Swah Mii says:

    This is more of an update than anything else. Two things, http://www.letsencrypt.com for free SSL and a client to keep things up-to-date. Secondly apache mod_proxy for proxy/reverseproxy to handle SSL autentication (and you can use apache to determine the forwarded port you want coming in externally) with signed certs. I broke something on mine, probably unlrelated and came across this forum in my search for answers, so figured I’d put the info out there for anyone interested. Cheers.

  8. Swah Mii says:

    Update 2: Using letsencrypt SSL certificate I was able to ‘bundle’ the ssl cert into the java container and set subsonic to run on 443 without the need to proxy via apache.
    Visit the let’s encrypt website and get the SSL certs for your server (forward port 443 to server on your router if NAT/firewalled)
    Once client is installed on their website you basically take care of the back and forth of testing/verifying it all works.
    Next you update the ssl cert using the java keystore method. This will update the self signed key that comes with subsonic with your new ssl info.

    Some stuff to know going forward (I will use a real-worldish example at the bottom to help remove confusion):
    letsencrypt stuff is usually found (based on Ubuntu 14.04.3 LTS) :
    /etc/letsencrypt

    the stuff you want to use to create the final file for the keystore are
    /etc/letsencrypt/live/your.domain (or like me work with the host name — if so make sure your certificate was for the host.your.domain)

    When I run the openssl commands I do it in the root level of the letsencrypt directory:
    /etc/letsencrypt

    So here goes (using the host.domain.name music.superfabboyeah.com as a fictitious name — not meant to be real):

    cd /etc/letsencrypt
    openssl pkcs12 -in live/music.superfabboyeah.com/fullchain.pem -export -out subsonic.pkcs12

    (whenever you are prompted for passwords and such, remember, you are creating them, so make them good and write them down)

    cat live/music.superfabboyeah.com/privkey.pem > subsonic.crt
    cat live/music.superfabboyeah.com/cert.pem >> subsonic.crt
    cat live/music.superfabboyeah.com/chain.pem >> subsonic.crt

    openssl pkcs12 -in subsonic.crt -export -out subsonic.pkcs12

    (at this point you have two new files under /etc/letsencrypt — subsonic.crt and subsonic.pkcs12 — just sayin’)
    (also remember, passwords are your creation. I used the same password performing all the steps to save confusion)

    keytool -importkeystore -srckeystore subsonic.pkcs12 -destkeystore subsonic.keystore -srcstoretype PKCS12 -srcalias 1 -destalias subsonic

    (now you have a third file called subsonic.keystore — this is the one you want to remember for future usage)

    If you have your subsonic installed the same as me it will have the jar file under /usr/share/subsonic. Double check this and note the jar file name it should resemble the following. If not, I don’t know why (maybe you renamed it or its a different version from mine).

    Make sure you have zip installed (its free too) and we will add it to the jar file as follows:

    zip /usr/share/subsonic/subsonic-booter-jar-with-dependencies.jar subsonic.keystore

    Then we restart subsonic

    service subsonic restart

    If all is good we have only one more thing to do, set the https port from 0 (which disables it) to 443 (assuming nothing else is using it) or some other port of your choosing if needed

    modify /etc/default/subsonic to show –https-port=443 or your chosen port (the max-memory value is for another time, please read up on it before using my value)

    SUBSONIC_ARGS=”–https-port=443 –max-memory=300″

    Once done
    service subsonic restart

    (Good recovery note: I had to delete my jar file, so I lost my updated ssl cert info. To fix it really simply I ran the zip command from the /etc/letsencrypt directory against the vanilla jar file I had placed in /usr/share/subsonic and it worked like a treat. Just sayin’.)

    Point your browser to your site https://music.superfabboyeah.com/ and it will show a green “https:” safe secure page.

    If it is still red then make sure your server has it’s name in the hosts file and that you have dns setup correctly for the network card.

    I’m using split dns so I can get to the name internally and externally. But I had to make sure the server knew its own name firstly, pretty easy oversight on a fresh vanilla install.

    Cheers.

  9. Jake 'The Snake' Fitz says:

    Swah Mii,

    I was able to use your method after /usr/bin/subsonic was modified to include the password ‘-Dsubsonic.ssl.password=yourpassword’ , line 115.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: