marcelGoerentz / Threadfin

MIT License
3 stars 1 forks source link

QUESTION/FEATURE: Wish for HTTP while m3u streaming + HTTPS for management UI #9

Closed SjoerdV closed 4 months ago

SjoerdV commented 4 months ago

Using 1.2.2 So at the moment I have these settings for the networking stack and run the app with -port=12345 -useHttps. This will now NOT startup an unsecure listener on the same port, this was working in 1.2, I guess. So forceClientHttps is already implied, without the automatic redirect though.

  "listeningIp": "127.0.0.1,192.168.100.15",
  "forceHttps": false,
  "useHttps": true, # must be set through command line, will not be stored when set through settings or manually edited
  "forceClientHttps": false,
  "threadfinDomain": "server01.mydomain.internal",

I would like to have the management side (/web) being accessed through TLS, so useHttps must be true. As a side effect this also makes the m3u file contents have https://server01.mydomain.internal:12345/stream/guid (note the https)

I also have certain clients that can not work with my in-house Certificate Authority, which produces internal certificates for web servers and stuff, so I must have the m3u file contain http addresses.

Did I overlook something? OR

Just brainstorming here Could we have an extra option 'ForceM3uHttps' that can be toggled and when false will set the m3u to use http? To make 'ForceM3uHttps' actually work in combination with the `forceClientHttps` option, `forceClientHttps` should only work for the management UI initially and when 'ForceM3uHttps' is also true it would work for everything Reference: https://stackoverflow.com/a/9036191 In fact, I propose a split in what is TLS and what is unsecured. This would mean deciding what path is used in streaming and which one is used for management: https://github.com/marcelGoerentz/Threadfin/blob/1f68b1a190625b5cb47a189b1c7cf65459f416ea/src/webserver.go#L28C1-L39C50. Reviewing those paths: maybe it is even better to use settings like 'UseHttpsForStreaming', 'UseHttpsForManagement' and 'UseHttpsForApi' to split is all up It would require two listeners, with rewrite rules for the paths. One of the listeners can be disabled when all options have the same value
marcelGoerentz commented 4 months ago

I understand what you are aiming for. This is all possible but I would Never thought that someone is in Need for this. Most of the things can be done via additional software like nginx. And to be honest I would not split up the webservices like this. For in house streaming everything should be fine via http. And if you want to connect from outside to your server I would recommend to use a reverse proxy.

Also doing this split will potentially break other users set up.

So all in all this is doable, but I won‘t do it until enough people need it.

SjoerdV commented 4 months ago

I understand what you are aiming for. This is all possible but I would Never thought that someone is in Need for this. Most of the things can be done via additional software like nginx. And to be honest I would not split up the webservices like this.

For in house streaming everything should be fine via http. And if you want to connect from outside to your server I would recommend to use a reverse proxy.

Also doing this split will potentially break other users set up.

So all in all this is doable, but I won‘t do it until enough people need it.

@marcelGoerentz I understand! I already created an additional nginx reverse proxy (doing the TLS bit). I am having problems with CORS though, especially loading the external images for the channels and it took a while before the socket started working.

Do you by any chance have a conf file you can share?

marcelGoerentz commented 4 months ago

Sure here is the config that I'm using. I have multiple server running on the same machine. And they can be addressed over different subdomains. nginx.zip

marcelGoerentz commented 4 months ago

BTW I've pushed a new beta version, that should fix the behavior with the useHttps setting and the http webserver running when https should run.

SjoerdV commented 4 months ago

BTW I've pushed a new beta version, that should fix the behavior with the useHttps setting and the http webserver running when https should run.

Ah ok so no more http then when useHttps is selected. So the only thing the forceClientHttps setting does is do an automatic redirect. Maybe just put that directly under useHttps functionality and remove the setting all together? https://github.com/marcelGoerentz/Threadfin/blob/1f68b1a190625b5cb47a189b1c7cf65459f416ea/src/data.go#L122C1-L124C6

SjoerdV commented 4 months ago

Sure here is the config that I'm using. I have multiple server running on the same machine. And they can be addressed over different subdomains. nginx.zip

@marcelGoerentz Great thanks, actually I was more interested in the reverse proxy 'server' and 'location' settings for the site under /etc/nginx/sites-enabled/*

marcelGoerentz commented 4 months ago

BTW I've pushed a new beta version, that should fix the behavior with the useHttps setting and the http webserver running when https should run.

Ah ok so no more http then when useHttps is selected. So the only thing the forceClientHttps setting does is do an automatic redirect. Maybe just put that directly under useHttps functionality and remove the setting all together? https://github.com/marcelGoerentz/Threadfin/blob/1f68b1a190625b5cb47a189b1c7cf65459f416ea/src/data.go#L122C1-L124C6

Well the thing is, when you are using a reverse proxy you will probably use https so if the redirect should work you need your urls with the https protocol and that is what the forceClientHttps does. The other option is directly for the web user interface and will also change the urls.

marcelGoerentz commented 4 months ago

Sure here is the config that I'm using. I have multiple server running on the same machine. And they can be addressed over different subdomains. nginx.zip

@marcelGoerentz Great thanks, actually I was more interested in the reverse proxy 'server' and 'location' settings for the site under /etc/nginx/sites-enabled/*

I will send the file probably tonight.

SjoerdV commented 4 months ago

BTW I've pushed a new beta version, that should fix the behavior with the useHttps setting and the http webserver running when https should run.

Ah ok so no more http then when useHttps is selected. So the only thing the forceClientHttps setting does is do an automatic redirect. Maybe just put that directly under useHttps functionality and remove the setting all together? https://github.com/marcelGoerentz/Threadfin/blob/1f68b1a190625b5cb47a189b1c7cf65459f416ea/src/data.go#L122C1-L124C6

Well the thing is, when you are using a reverse proxy you will probably use https so if the redirect should work you need your urls with the https protocol and that is what the forceClientHttps does.

The other option is directly for the web user interface and will also change the urls.

@marcelGoerentz Hmmm, my reverse proxy (on the same box) just passes traffic to the http endpoint now. So I guess I just externalized the whole SSL story. I still am using Threadfin's ipBindings option so that's a great plus.

Still I would like the option of limiting the IPs that can access the /web location, so I can just allow the reverse proxy (coming from 127.0.0.1)

marcelGoerentz commented 4 months ago

@SjoerdV as promised, here is my config for nginx:

server {
    access_log                     /var/log/nginx/access_threadfin.log;
    error_log                      /var/log/nginx/error_threadfin.log;

    listen                          <your external port>;
    server_name                     <your FQDN>;

    location / {
        proxy_pass  http://localhost:8091;
        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_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}
SjoerdV commented 4 months ago

Excellent, got it all working. Thanks for your help!. Closing this one.

marcelGoerentz commented 4 months ago

@SjoerdV Great to here I will release a new version.

SjoerdV commented 4 months ago

@marcelGoerentz Just a heads-up. I managed the initial requirement for this issue in the following way and I thought I'd share:

Prereqs

Standalone Nginx

Nginx security measure

upstream node_backend {
    zone upstreams 128K;
    server media.mydomain.tld:12345 max_fails=1 fail_timeout=10s;
    keepalive 100;
}

# Secure endpoint, used for WebUI management, also secured with machine firewall
server {
    listen              12346 ssl http2;
    server_name         media.mydomain.tld;

    location / {
        proxy_pass              http://node_backend;
        proxy_next_upstream     error timeout           http_500;
    }
}

# Unsecure endpoint, used for direct streaming, with protection of /web location, preventing accidental authentication through WebUI
server {
    listen              10.10.1.100:12345;
    server_name         media.mydomain.tld;

    location / {
        proxy_pass              http://node_backend;
        proxy_next_upstream     error timeout           http_500;
    }

    location ~ /(web) {
        deny all;
    }

    location @proxy {
        proxy_pass              http://node_backend;
        proxy_next_upstream     error timeout           http_500;
    }
}
marcelGoerentz commented 4 months ago

Thanks for sharing your solution, I hope someone else will help it 👍🏼