SSL connection problem with Subsonic API


#1

Hello,

I successfully set up my instance, and everything works smoothly, up to the connection through the Subsonic API.

I can access the frontend, add and listen music on it, everything works like a charm. When I try to connect with the Subsonic API from Dsub, the connection fails, and I get the following error on nginx logs:

2019/03/26 19:10:05 [crit] 4439#4439: *220 SSL_do_handshake() failed (SSL: error:1417D102:SSL routines:tls_process_client_hello:unsupported protocol) while SSL handshaking, client: xx.xx.xx.xx, server: 0.0.0.0:443

I have nothing in Funkwhale’s log related to this issue.

Setup:

  • non-docker install on Debian stretch (raspberry pi)
  • nginx as reverse proxy, HTTPS certificate with Let’s encrypt

Here is my nginx config file:
# This file was generated from funkwhale.template

upstream funkwhale-api {
    # depending on your setup, you may want to update this
    server 127.0.0.1:5000;
}

server {
    listen 80;
    listen [::]:80;
    # update this to match your instance name
    server_name funkwhale.jovuit.site;
    # useful for Let's Encrypt
    location /.well-known/acme-challenge/ { allow all; }
    location / { return 301 https://$host$request_uri; }
}

# required for websocket support
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen      443 ssl;
    listen [::]:443 ssl;
    server_name funkwhale.example.tld;

    # TLS
    # Feel free to use your own configuration for SSL here or simply remove the
    # lines and move the configuration to the previous server block if you
    # don't want to run funkwhale behind https (this is not recommended)
    # have a look here for let's encrypt configuration:
    # https://certbot.eff.org/all-instructions/#debian-9-stretch-nginx
    ssl_protocols TLSv1.2;
    ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_certificate /etc/letsencrypt/live/xxx/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/xxx/privkey.pem; # managed by Certbot
    # HSTS
    add_header Strict-Transport-Security "max-age=31536000";

    root /srv/funkwhale/front/dist;

    # compression settings
    gzip on;
    gzip_comp_level    5;
    gzip_min_length    256;
    gzip_proxied       any;
    gzip_vary          on;

    gzip_types
        application/javascript
        application/vnd.geo+json
        application/vnd.ms-fontobject
        application/x-font-ttf
        application/x-web-app-manifest+json
        font/opentype
        image/bmp
        image/svg+xml
        image/x-icon
        text/cache-manifest
        text/css
        text/plain
        text/vcard
        text/vnd.rim.location.xloc
        text/vtt
        text/x-component
        text/x-cross-domain-policy;

    # end of compression settings
    location / {
        include /etc/nginx/funkwhale_proxy.conf;
        # this is needed if you have file import via upload enabled
        client_max_body_size 100M;
        proxy_pass   http://funkwhale-api/;
    }

    location /front/ {
        alias /srv/funkwhale/front/dist/;
        expires 30d;
        add_header Pragma public;
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
    }

    location /federation/ {
        include /etc/nginx/funkwhale_proxy.conf;
        proxy_pass   http://funkwhale-api/federation/;
    }

    # You can comment this if you do not plan to use the Subsonic API
    location /rest/ {
        include /etc/nginx/funkwhale_proxy.conf;
        proxy_pass   http://funkwhale-api/api/subsonic/rest/;
    }

    location /.well-known/ {
        include /etc/nginx/funkwhale_proxy.conf;
        proxy_pass   http://funkwhale-api/.well-known/;
    }

    location /media/ {
        alias /srv/funkwhale/data/media/;
    }

    location /_protected/media {
        # this is an internal location that is used to serve
        # audio files once correct permission / authentication
        # has been checked on API side
        internal;
        alias   /srv/funkwhale/data/media;
    }

    location /_protected/music {
        # this is an internal location that is used to serve
        # audio files once correct permission / authentication
        # has been checked on API side
        # Set this to the same value as your MUSIC_DIRECTORY_PATH setting
        internal;
        alias   /srv/funkwhale/data/music;
    }

    location /staticfiles/ {
        # django static files
        alias /srv/funkwhale/data/static/;
    }

}

I tried commenting out this line ssl_protocols TLSv1.2;, but then I don’t have any error in the log anymore, but I still cannot connect from Dsub. I also tried replacing it with ssl_protocols SSLv2 SSLv3 TLSv1.2, no chance either…

Regarding the block
# You can comment this if you do not plan to use the Subsonic API
location /rest/ {
include /etc/nginx/funkwhale_proxy.conf;
proxy_pass http://funkwhale-api/api/subsonic/rest/;
}

Should it stay like that? I’m quite unsure about http://funkwhale-api/ but the docs doesn’t mention anything about it, and the same pattern is used for the federation, which works on my instance.

I precise that the Subsonic API is activated for my instance and I can generate the API password from the frontend, and “Browse by tags” is checked on Dsub (though given the error I don’t think it is related…).

I’m unsure whether the problem comes form funkwhale, the Subsonic API, nginx, Dsub, or something else. I looked for related issues, but couldn’t find something relevant.

I would be glad if someone could help me solve this issue, let me know if I missed some relevant configs/logs, etc. Thanks a lot in advance!


#2

Hi there!

The tls_process_client_hello:unsupported protocol error likely indicates the issue. I think your device may not be compatible with tls v1.2.

Can you try using ssl_protocols TLSv1.1 TLSv1.2; in your nginx config, reload nginx and retry?

Also, do you reproduce with another subsonic client, like the Clementine Music Player?


#3

Hi @eliotberriot,

I tried changing ssl_protocols, but it doesn’t work with DSub.

I cannot connect to https://demo.funkwhale.audio with DSub (I get the same network error as with my server). I use DSub to connect on a daily basis to another Funkwhale server that I don’t maintain and it works fine. (this server is on 0.18 and uses Apache as a reverse proxy).

With Subsonic Music Streamer, I can connect to demo.funkwhale.audio, but not to my server.

I can connect from Clementine to my server and to demo.funkwhale.audio.


#4

Are you on an adroid device? Do you know its version?


#5

I have DSub v.5.0.3. I just realised it’s quite old (2015), but it’s the suggested version on F-droid, I guess it’s because my android is quite outdated now (v4.4)…


#6

Yes it’s possible. You may even be using tlsv1.0.

What if you enable ssl_protocols TLSv1.0 TLSv1.0 TLSv1.2;? Does it work?


#7

I tried with ssl_protocols TLSv1 TLSv1.1 TLSv1.2; as it seems to be the correct syntax, no chance either. On DSub I still get those network errors, but nothing appears in the nginx error.log


#8

Hm, I running out of ideas. I’m using the same version of DSub as you (5.0.3) and the demo server works fine, so I really think this has to do with the Android version you’re running on :s


#9

Hm, strange… I’ll try to dig a little bit more and I’ll keep you updated if I find a solution.

Thanks for your help in any case!


#10

I found the trick!

The ssl_ciphers line should not exclude SHA as a valid cipher suite, and TLSv1 should be allowed, as it seems to be the combination used by Android, at least in my version (v4.4)…

So my working nginx conf files reads:
ssl_protocols TLSv1 TLSv1.2;
ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL;

I don’t know if this should be the default funkwhale config or not, as it seems to reduce the security a little bit…


#11

Thank you for sharing the solution @jovuit! It’s good to know!

I think I’ve seen a discussion some times ago about the ciphers, I should dig that up…