Page 1 of 1

Subsonic on CentOS with NGINX SSL offloading

PostPosted: Fri Dec 18, 2015 2:43 am
by TheOmegaShadow
Requirements:

A working Subsonic installation accessible through 127.0.0.1 or a lan ip configured only for HTTP access on port 4040.

This tutorial is based on the subsonic server running on port 4040 and the https port set to 4043 throughout, feel free to change these to fit your own preferences. Your hostname also needs to be determined, I'm using subsonic.your-domain.com for this tutorial, yours will be different if you buy/already have your own DNS
name.


Use Case:

Typically if you care somewhat about your passwords being encrypted especially over a WAN connection you would make sure encryption is setup on you subsonic server, but the self signed certificate subsonic installs will always produce a hostname mismatch when using your own url. to get around this I use nginx as a reverse proxy, my WAN port only allows connections from outside my home lan through an SSL port, so security is acceptable and encryption is simpler to administer because it's offloaded from the subsonic java executable which is minutely more efficient because it uses executables written in a lower level programming language than instead of java.

Client=====>[Router/Firewall]===[switch]===>[Centos7-server]
[-^--------------Encrypted session-----------------------------------^-]

You'll need port 4043 open and port forwarded / static NAT'ed from your firewall / router to your Centos server.

On Centos 7 you can use:
#> nmtui
to configure your NIC and
#> firewalld
to open ports to your hosted services, please google for support on getting those settings right before proceeding.


Getting Started

If not root user

$> su -
to get your # prompt.
#> mkdir -p /root/sslworkingforder && cd /root/sslworkingforder

SSL PKI Prep:

#> yum install openssl nginx nano

Generate private key:

#> openssl genrsa -des3 -out private.key 1024

enter a passphrase when prompted and note it down.

Generate Certificate Signing Request (CSR file):

When making the Certificate Signing Request you will be prompted for details:

Country Code (2 letter code)
State / Province
Locality / City
Organisation Name / business name
Organisation Unit / department
Common Name / server url (public FQDN hostname like: subsonic.your-domain.com)


Make sure you record all these details down somewhere they are important, especially if you are buying a CA certificate as re-issues of those certificates
usually require the exact same details in those fields when submitting another CSR file.

You have 2 options here:
1) Sign your own certificate (Self Signed)
Cheaper option but you'll need to import your certificate certificate into your OS trusted certificate store via MMC and the certificate snap-in to avoid untrusted certificate warnings. The subsonic client app iSub for IOS does not require it to be signed so I went with self signed.


#> openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt

--OR--

2) Pay for a CA signed certificate from Verisign/RapidSSL/Thawte/Geotrust/Comodo. This prevents browsers from displaying untrusted certificate warnings or the subsonic site getting blocked outright by some particular platforms. If you go this rout it's preferable to get a wildcard certificate for your domain (*.your-domain.com), so any additional sites/services you choose to encrypt can be just assigned additional sub-domains.

#> openssl req -new -key private.key -out server.csr

You'll need to upload you server.csr file to their site and await a download of the server.crt, if it's in a different format goole how to convert it with openssl, but on windows you can usually import it then export it from the certificate store and it gives you options for output format in the certificate export wizard.

Once you have your signed certificate file in BASE64 format rename the file to server.crt and relocate it to the directory in the following instuctions.

Make your private key accessible without a passphrase being required:

#> mv priver.key private.key.org
enter passphrase...
#> openssl rsa -in private.key.org -out server.key

The purpose if this is so that everytime you start / restart nginx, it will not require you to enter the passpharase every single time.


Relocate certificate files:

#> mkdir -p /etc/nginx/cert
#> mv server.crt /etc/nginx/cert && mv server.key /etc/nginx/cert


NGINX setup:

Alter your nginx config file as follows

#> nano /etc/nginx/nginx.conf

# START OF FILE

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;

include /etc/nginx/mime.types;
default_type application/octet-stream;

# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;

upstream backends {
server 127.0.0.1:4040;
}

server {
listen 4043 ssl;
server_name subsonic.your-domain.com;
ssl_certificate /etc/nginx/cert/server.crt;
ssl_certificate_key /etc/nginx/cert/server.key;
location / {
proxy_pass http://backends;
}
}
}

# END OF FILE

Permitting selinux permissions to allow nginx to do what it does.
#> setsebool -P httpd_can_network_connect 1
#> semanage port -a -t http_port_t -p tcp 4043

-OR-

if you hate NSA backdoors, disable selinux

#> nano /etc/sysconfig/selinux
1)alter the following line from:
SELINUX=enforcing
to:
SELINUX=disabled

2) save and exit then reboot your server to make the change effective.

Re-login as root

Start nginx
#> systemctl start nginx
restarting:
#> systemctl restart nginx
stopping:
#> systemctl stop nginx

To check config errors:
#> journalctl -xn

google any outputs from ngix for clues on how to resolve.

Once you're all up and running:

#> systemctl enable nginx
#> chkconfig subsonic on

to make sure the services restart if the server is rebooted.

#> exit

Your server should be accessible through https://<your.wan.ip>:4043
Or if you've pointed your DNS record/s to your WAN ip and all the prerequisites are all met:
https://subsonic.your-domain.com:4043


Helpful URLs for alternative config options:

https://deviantengineer.com/2015/05/nginx-reverseproxy-centos7/
https://www.digitalocean.com/community/ ... or-jenkins
https://www.digitalocean.com/community/ ... for-apache
https://www.nginx.com/blog/nginx-ssl/



Enjoy :D