sintonia/docs/admin-manual/install/reverse-proxy.md

11 KiB

title sidebar_position
Reverse proxy 30

To secure the communication between the users and LibreTime, you have to serve LibreTime over https.

The recommended way is to put a reverse proxy in front of LibreTime, and terminating the https communication at the reverse proxy.

The benefits are managing your certificates in a single place, and being easier to extend your infrastructure. You also don't have to edit the LibreTime specific files which helps when upgrading LibreTime.

flowchart LR
    internet[Internet]

    subgraph internal[Your system or private network]
        libretime[LibreTime service, listen on :8080]

        icecast[Icecast service, listen on :8000 and :8443]
        liquidsoap[Liquidsoap service, listen on :8001 and 8002]

        subgraph proxy[Your reverse proxy]
            front_http[Listen on :80]
            front_https[Listen on :443]
        end
        front_http --> libretime
        front_https --> libretime
    end

    internet =====> icecast
    internet =====> liquidsoap

    internet ==> front_http
    internet ==> front_https

:::warning

The current input and output streams are Icecast based protocols and doesn't support being behind a reverse proxy. Don't attempt to reverse proxy Icecast or the Liquidsoap harbor inputs.

You can secure the Icecast output streams by adding an additional Icecast socket and reusing the TLS certificates used to secure LibreTime.

Modern protocols such as HLS and SRT will be implement in the future to fix those limitations.

:::

Prerequisites

:::info

In this documentation, we will use libretime.example.org as domain name pointing to your server, and localhost:8080 as location for the LibreTime web server.

:::

Be sure that your firewall and network allows communications from the reverse proxy to the services. You can use ping, telnet and curl to check that communication is working.

Install a reverse proxy

Pick one of the reverse proxies below.

:::info

LibreTime already uses Nginx as web server, so unless you have an advanced setup, we recommend that you use Nginx as reverse proxy.

:::

Nginx

Paste the following configuration in /etc/nginx/sites-available/libretime.example.org.conf and be sure to replace:

  • libretime.example.org with your own station url,
  • localhost:8080 with the location of your LibreTime web server;
server {
    listen 80;
    server_name libretime.example.org;

    client_max_body_size 512M;
    client_body_timeout 300s;

    location / {
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host  $host;
        proxy_set_header X-Forwarded-Port  $server_port;

        proxy_pass http://localhost:8080/;
    }
}

Ensure the default nginx server configuration is not enabled:

sudo rm -f /etc/nginx/sites-enabled/default

Enable the nginx configuration:

sudo ln -s /etc/nginx/sites-available/libretime.example.org.conf /etc/nginx/sites-enabled/

Test the nginx configuration:

sudo nginx -t

Restart nginx:

sudo systemctl restart nginx

You can now follow this guide to configure Nginx with a Let's Encrypt certificate.

You should end up with a nginx configuration similar to:

server {
    listen 80;
    server_name libretime.example.org;

    client_max_body_size 512M;
    client_body_timeout 300s;

    if ($host = libretime.example.org) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    return 404; # managed by Certbot
}

server {
    listen 443 ssl; # managed by Certbot
    server_name libretime.example.org;

    client_max_body_size 512M;
    client_body_timeout 300s;

    ssl_certificate /etc/letsencrypt/live/libretime.example.org/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/libretime.example.org/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    location / {
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host  $host;
        proxy_set_header X-Forwarded-Port  $server_port;

        proxy_pass http://localhost:8080/;
    }
}

Apache

Paste the following configuration in /etc/apache2/sites-available/libretime.example.org.conf and be sure to replace:

  • libretime.example.org with your own station url,
  • localhost:8080 with the location of your LibreTime web server;
<VirtualHost *:80>
    ServerName libretime.example.org

    <Location />
        ProxyPass           http://localhost:8080/
        ProxyPassReverse    http://localhost:8080/
    </Location>
</VirtualHost>

Ensure the default apache vhost configuration is not enabled:

sudo rm -f /etc/apache2/sites-enabled/000-default.conf

Enable the Apache2 proxy modules:

sudo a2enmod proxy proxy_http

Enable the Apache2 vhost configuration:

sudo a2ensite libretime.example.org

Test the Apache2 configuration:

sudo apache2ctl configtest

Restart Apache2:

sudo systemctl restart apache2

You can now follow this guide to configure Apache2 with a Let's Encrypt certificate.

You should end up with 2 Apache2 configurations similar to:

<VirtualHost *:80>
    ServerName libretime.example.org

    RewriteEngine on
    RewriteCond %{SERVER_NAME} =libretime.example.org
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

    <Location />
        ProxyPass           http://localhost:8080/
        ProxyPassReverse    http://localhost:8080/
    </Location>
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName libretime.example.org

    SSLCertificateFile /etc/letsencrypt/live/libretime.example.org/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/libretime.example.org/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf

    <Location />
        ProxyPass           http://localhost:8080/
        ProxyPassReverse    http://localhost:8080/
    </Location>
</VirtualHost>
</IfModule>

Icecast

If you attempt to listen an insecure Icecast stream on a secure website, a mixed content error will be raised by your browser and should prevent your player from listening to the stream.

Securing the Icecast output streams

:::caution

Before you start, make sure to have a working and secured LibreTime server, and that the TLS certificates generated by Cerbot are on the same host as Icecast.

:::

Create a Icecast specific SSL certificate bundle based on the TLS certificates generated by Certbot:

sudo bash -c "install \
  --group=icecast \
  --mode=640 \
  <(cat /etc/letsencrypt/live/libretime.example.org/{fullchain,privkey}.pem) \
  /etc/icecast2/bundle.pem"

Enable the secure socket and set the SSL certificate bundle path in the Icecast configuration file:

     <!-- You may have multiple <listen-socket> elements -->
     <listen-socket>
         <port>8000</port>
         <!-- <bind-address>127.0.0.1</bind-address> -->
         <!-- <shoutcast-mount>/stream</shoutcast-mount> -->
     </listen-socket>
     <!--
     <listen-socket>
         <port>8080</port>
     </listen-socket>
     -->
-    <!--
     <listen-socket>
         <port>8443</port>
         <ssl>1</ssl>
     </listen-socket>
-    -->
         <!-- Aliases: can also be used for simple redirections as well,
              this example will redirect all requests for http://server:port/ to
              the status page
         -->
         <alias source="/" destination="/status.xsl"/>
         <!-- The certificate file needs to contain both public and private part.
              Both should be PEM encoded.
         <ssl-certificate>/usr/share/icecast2/icecast.pem</ssl-certificate>
         -->
+        <ssl-certificate>/etc/icecast2/bundle.pem</ssl-certificate>
     </paths>

:::warning

Don't forget to open the new Icecast secure port 8443 in your firewall.

:::

Restart Icecast to apply the changes:

sudo systemctl restart icecast2

Next, you need to change the LibreTime stream.outputs.icecast.*.public_url configuration to use the newly enabled Icecast secure port, for example:

     # Icecast output streams.
     # > max items is 3
     icecast:
       - <<: *default_icecast_output
         enabled: true
-        public_url:
+        public_url: https://libretime.example.org:8443/main.ogg
         mount: main.ogg
         audio:
           format: ogg
           bitrate: 256

       - <<: *default_icecast_output
         enabled: true
-        public_url:
+        public_url: https://libretime.example.org:8443/main.mp3
         mount: main.mp3
         audio:
           format: mp3
           bitrate: 320

Restart LibreTime to apply the changes:

sudo systemctl restart libretime.target

Finally, you need to configure the Certbot renewal to bundle a Icecast specific SSL certificate and restart the Icecast service:

 # Options used in the renewal process
 [renewalparams]
 account = d76ce6a241c7c74f79e5443216ee420e
 authenticator = nginx
 installer = nginx
 server = https://acme-v02.api.letsencrypt.org/directory
+
+deploy_hook = 'bash -c "install --group=icecast --mode=640 <(cat $RENEWED_LINEAGE/{fullchain,privkey}.pem) /etc/icecast2/bundle.pem && systemctl restart icecast2"'

Check that the renewal configuration is valid:

sudo certbot renew --dry-run