Page 1 of 1

Let's Encrypt - SSL - Debian 8 - Subsonic 6.0 - Tutorial

PostPosted: Wed Jul 13, 2016 12:27 am
by Lucatze
Hi!

This is a summary of the previous "Installing a proper SSL certificate chain" thread and aims systems as specified above. It should work pretty straight forward.

Important: When using Artist Info within the browser, files like artist image and cover are not transferred securely. They are linked directly and not gathered by the server before transfer, so in case you don't want anybody to know what you are doing, you might consider switching off Artist Info within settings. In Safari for example, the "Lock" will disappear as soon you are opening an album and downloading Artist Pictures.

1. Create certificates using Let's Encrypt.

2. Run this script provided by IwishIcanFLighT (just copy/paste code into a txt file ending with .sh and run it: root@ExampleServer:~ # sh MyLittleScript.sh

Code: Select all
# Color output
red=`tput setaf 1`
green=`tput setaf 2`
reset=`tput sgr0`

# CHANGE THIS LINE, DON'T FORGET THE DASH AT THE END
certpath="/etc/letsencrypt/live/domain.org/"

echo "${green}Generate as PKCS12 key file${reset}"
echo "Enter a password 2 times:"
openssl pkcs12 -inkey "${certpath}privkey.pem" -in "${certpath}cert.pem" -export -out subsonic.pkcs12

echo "${green}subsonic.pkcs12 key generated.${reset}"
echo "\n${green}Loading the key to a keystore.${reset}"
echo "${green}Please re-type the same password 3 times:${reset}"

keytool -importkeystore -srckeystore subsonic.pkcs12 -srcstoretype PKCS12 -destkeystore subsonic_cert.keystore

echo "${red}Deleting the PKCS12 file not needed anymore${reset}"
rm subsonic.pkcs12

echo "\n${green}### subsonic_cert.keystore successfully generated! :) ### ${reset}\n"
echo "\n${green}You can now copy the keystore file into Subsonic's main folder.${reset}\n"
echo "${green}Usual path is: /var/subsonic${reset}"

echo "\n${red}Make sure that subsonic.sh contains the following lines:${reset}\n"
echo "\n${red}Usual Path to config file: /usr/bin/subsonic${reset}\n"
echo "-Dsubsonic.ssl.keystore=subsonic_cert.keystore \ "
echo "-Dsubsonic.ssl.password=yourpassword \ "


3. If you haven't done so far, add the following strings to /usr/bin/subsonic. Scroll down till the end.

-Dsubsonic.ssl.keystore=/var/subsonic/subsonic_cert.keystore \
-Dsubsonic.ssl.password=subsonic \

The specific part should look like this:

Code: Select all
${JAVA} -Xmx${SUBSONIC_MAX_MEMORY}m \
  -Dsubsonic.home=${SUBSONIC_HOME} \
  -Dsubsonic.host=${SUBSONIC_HOST} \
  -Dsubsonic.port=${SUBSONIC_PORT} \
  -Dsubsonic.httpsPort=${SUBSONIC_HTTPS_PORT} \
  -Dsubsonic.contextPath=${SUBSONIC_CONTEXT_PATH} \
  -Dsubsonic.defaultMusicFolder=${SUBSONIC_DEFAULT_MUSIC_FOLDER} \
  -Dsubsonic.defaultPodcastFolder=${SUBSONIC_DEFAULT_PODCAST_FOLDER} \
  -Dsubsonic.defaultPlaylistFolder=${SUBSONIC_DEFAULT_PLAYLIST_FOLDER} \
  -Dsubsonic.ssl.keystore=/var/subsonic/subsonic_cert.keystore \
  -Dsubsonic.ssl.password=subsonic \
  -Djava.awt.headless=true \
  -verbose:gc \
  -jar subsonic-booter-jar-with-dependencies.jar > ${LOG} 2>&1 &


4. If you haven't done so, move subsonic_cert.keystore to /var/subsonic/

5. In case you are running subsonic as another user as root, you must change ownership of subsonic_cert.keystore. Adjust the path accordingly.

Code: Select all
chown user:user /var/subsonic/subsonic_cert.keystore


6. Edit /etc/default/subsonic and adjust the ports accordingly to your preferences. Mine looks like this:

Code: Select all
SUBSONIC_ARGS="--max-memory=150 --https-port=4030 --port=0"


7. Restart Subsonic Service.

Code: Select all
service subsonic restart



Hope that helps, enjoy ! :)
BIG Thank You to everybody involved in this project !

Re: Let's Encrypt - SSL - Debian 8 - Subsonic 6.0 - Tutorial

PostPosted: Sat Oct 22, 2016 11:10 pm
by thisisanull
Lucatze,

Thanks for this, it was a big help. I decided to go ahead and make the process automated and generate the keystore on each load of subsonic, that way it would automatically pick up renewals of the Let's Encrypt Certificate. The only thing an end user would need to do is define SUBSONIC_SSL_CERT and SUBSONIC_SSL_KEY (im grabbing these straight from the output of my acme client). I am using the chained certificate and not just the domain cert. SUBSONIC_SSL_PASSWORD generates a random password for the keystore each launch, but you can change SUBSONIC_SSL_PASSWORD to anything greater than 6 characters if you want.

Here are my modifications to the start of /usr/bin/subsonic (the last three lines are all I added here)
Code: Select all
#!/bin/sh

###################################################################################
# Shell script for starting Subsonic.  See http://subsonic.org.
#
# Author: Sindre Mehus
###################################################################################

SUBSONIC_HOME=/var/subsonic
SUBSONIC_HOST=0.0.0.0
SUBSONIC_PORT=4040
SUBSONIC_HTTPS_PORT=0
SUBSONIC_CONTEXT_PATH=/
SUBSONIC_MAX_MEMORY=150
SUBSONIC_PIDFILE=
SUBSONIC_DEFAULT_MUSIC_FOLDER=/var/music
SUBSONIC_DEFAULT_PODCAST_FOLDER=/var/music/Podcast
SUBSONIC_DEFAULT_PLAYLIST_FOLDER=/var/playlists
SUBSONIC_SSL_CERT=/path/to/chained_domain.crt
SUBSONIC_SSL_KEY=/path/to/domain.key
SUBSONIC_SSL_PASSWORD=$(head -c 16 /dev/urandom | md5sum | head -c 32)


And here are my modifications to the launch portion / end of /usr/bin/subsonic . I replaced the entire launch statement to catch potential errors and fallback to a standard launch if no ssl keystore can be created. This means that if the user simply doesn't define the ssl cert (or the subsonic user lacks access to it), subsonic launches as normal without attempting to use a non-existent keystore.
Code: Select all
# Create Subsonic home directory.
mkdir -p ${SUBSONIC_HOME}
LOG=${SUBSONIC_HOME}/subsonic_sh.log
rm -f ${LOG}

cd $(dirname $0)
if [ -L $0 ] && ([ -e /bin/readlink ] || [ -e /usr/bin/readlink ]); then
    cd $(dirname $(readlink $0))
fi
#begin ssl modifications
#delete old keystore (if it exists) as we are using randomly generated passwords
if [ -f ${SUBSONIC_HOME}/subsonic_cert.keystore ]; then
    rm -f ${SUBSONIC_HOME}/subsonic_cert.keystore
fi
#generate keystore from system certificates
SUBSONIC_SSL_PASSWORD_LENGTH=${#SUBSONIC_SSL_PASSWORD}
if [ ${SUBSONIC_HTTPS_PORT} -ge 1 -a -n "${SUBSONIC_SSL_CERT}" -a -n "${SUBSONIC_SSL_KEY}" -a $SUBSONIC_SSL_PASSWORD_LENGTH -ge 6 ]; then
   openssl pkcs12 -inkey $SUBSONIC_SSL_KEY -in $SUBSONIC_SSL_CERT -export -out ${SUBSONIC_HOME}/subsonic.pkcs12 -password pass:${SUBSONIC_SSL_PASSWORD}
   keytool -importkeystore -srckeystore ${SUBSONIC_HOME}/subsonic.pkcs12 -srcstoretype PKCS12 -srcstorepass ${SUBSONIC_SSL_PASSWORD} -destkeystore ${SUBSONIC_HOME}/subsonic_cert.keystore -deststorepass ${SUBSONIC_SSL_PASSWORD}
   rm -f ${SUBSONIC_HOME}/subsonic.pkcs12
fi
#if everything worked and the keystore exists, launch subsonic with keystore defined
if [ -f ${SUBSONIC_HOME}/subsonic_cert.keystore ]; then
if [ $quiet = 0 ]; then
    echo SSL keystore was generated successfully, launching with custom SSL certificate.
fi
   ${JAVA} -Xmx${SUBSONIC_MAX_MEMORY}m \
     -Dsubsonic.home=${SUBSONIC_HOME} \
     -Dsubsonic.host=${SUBSONIC_HOST} \
     -Dsubsonic.port=${SUBSONIC_PORT} \
     -Dsubsonic.httpsPort=${SUBSONIC_HTTPS_PORT} \
     -Dsubsonic.ssl.keystore=${SUBSONIC_HOME}/subsonic_cert.keystore \
     -Dsubsonic.ssl.password=${SUBSONIC_SSL_PASSWORD} \
     -Dsubsonic.contextPath=${SUBSONIC_CONTEXT_PATH} \
     -Dsubsonic.defaultMusicFolder=${SUBSONIC_DEFAULT_MUSIC_FOLDER} \
     -Dsubsonic.defaultPodcastFolder=${SUBSONIC_DEFAULT_PODCAST_FOLDER} \
     -Dsubsonic.defaultPlaylistFolder=${SUBSONIC_DEFAULT_PLAYLIST_FOLDER} \
     -Djava.awt.headless=true \
     -verbose:gc \
     -jar subsonic-booter-jar-with-dependencies.jar > ${LOG} 2>&1 &
else
#no keystore was found, launching subsonic with standard options
if [ $quiet = 0 ]; then
    echo  Could not generate SSL keystore, launching with default options.
fi
        ${JAVA} -Xmx${SUBSONIC_MAX_MEMORY}m \
          -Dsubsonic.home=${SUBSONIC_HOME} \
          -Dsubsonic.host=${SUBSONIC_HOST} \
          -Dsubsonic.port=${SUBSONIC_PORT} \
          -Dsubsonic.httpsPort=${SUBSONIC_HTTPS_PORT} \
          -Dsubsonic.contextPath=${SUBSONIC_CONTEXT_PATH} \
          -Dsubsonic.defaultMusicFolder=${SUBSONIC_DEFAULT_MUSIC_FOLDER} \
          -Dsubsonic.defaultPodcastFolder=${SUBSONIC_DEFAULT_PODCAST_FOLDER} \
          -Dsubsonic.defaultPlaylistFolder=${SUBSONIC_DEFAULT_PLAYLIST_FOLDER} \
          -Djava.awt.headless=true \
          -verbose:gc \
          -jar subsonic-booter-jar-with-dependencies.jar > ${LOG} 2>&1 &
fi
#end ssl modifications
# Write pid to pidfile if it is defined.
if [ $SUBSONIC_PIDFILE ]; then
    echo $! > ${SUBSONIC_PIDFILE}
fi

if [ $quiet = 0 ]; then
    echo Started Subsonic [PID $!, ${LOG}]
fi


On my system I've further modified the subsonic launch script by moving the ssl cert and ssl key into command line options which I can define in /etc/default/subsonic.