openwrt / luci

LuCI - OpenWrt Configuration Interface
Apache License 2.0
6.38k stars 2.53k forks source link

luci-app-ttyd: Nginx reverse proxy #7022

Open alex9434 opened 7 months ago

alex9434 commented 7 months ago

Steps to reproduce:

  1. Connect to Luci with cloudflared or behind firewall with only 80 and 443 open ports
  2. Go to services -> terminal

Actual behavior:

Empty page for terminal

Expected behavior:

Terminal windows

Lucy-app-ttyd uses separate port (default 7681) for ttyd. I would like to use nginx reverse proxy to have ttyd on port 80 (and 443). That requires to change the web interface to use a path for ttyd to use nginx reverse proxy.

ysc3839 commented 7 months ago

This issue has been there for some years. Because there are many different SSL/reverse proxy configurations. It's difficult to detect it automatically. See also #5347.

alex9434 commented 7 months ago

Hi @ysc3839 My suggestion is different than #5347 . I want to use nginx as reverse proxy (could be an option in the config for luci-app-ttyd). The location could be automatically included as ttyd.locations in /etc/nginx/conf.d if the user has chosen to use Luci with nginx.

        location /ttyd {
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Forwarded-Port $server_port;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://localhost:7681;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
        }

However, from my understanding that would require the web-interface to use the path /ttyd to talk to ttyd. Advantage is that nginx automatically would use the existing ssh-setup and only port 443 would be used.

alex9434 commented 7 months ago

Great, will test and report back

alex9434 commented 7 months ago

Hi @ysc3839, I have successfully compiled and installed your commit. Apologies for the delay. I have added the above snipped to /etc/nginx/conf.d/ttyd.locations (and restarted nginx). Will add authentication later when it is working (thanks for pointing that out).

What exactly do I need to put in URL_override in the LuCI config for ttyd? Just putting in /ttyd does not seem to work. Nginx shows the following error:

2024/04/16 10:26:35 [error] 32292#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: ::1, server: _lan, request: "GET /ttyd HTTP/1.1", upstream: "http://127.0.0.1:7681/ttyd", host: "*deleted*", referrer: "https://*deleted*/cgi-bin/luci/admin/services/ttyd/ttyd"
2024/04/16 10:26:35 [warn] 32292#0: *1 upstream server temporarily disabled while connecting to upstream, client: ::1, server: _lan, request: "GET /ttyd HTTP/1.1", upstream: "http://127.0.0.1:7681/ttyd", host: "*deleted*", referrer: "https://*deleted*/cgi-bin/luci/admin/services/ttyd/ttyd"

What other settings are needed to make this work?

ysc3839 commented 7 months ago

Did you start ttyd? The error is Connection refused, which means no program is listening that port. And you should use UNIX socket for localhost reverse proxy, because it has better performance.

alex9434 commented 6 months ago

Hi @ysc3839, ttyd is running but without active instances.

service ttyd status
active with no instances

Which is strange because I have created an instance that is enabled in LuCI. When I create an instance with Unix socket in /var/run/ttyd.sock, the file does not appear. What is going on?

alex9434 commented 6 months ago

Hi @ysc3839 apologies for the late reply. It took some time for me to build OpenWrt again and test the changes. I can confirm that this is now working! For everybody that is interested, here is what I did: nginx: ttyd.locations

location ~ ^/ttyd(.*)$ {
    auth_digest 'Restricted Area'; # set the realm for this location block
    auth_digest_user_file passwd.digest;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_pass http://unix:/var/run/ttyd.sock:/$1;
}

UCI

uci set ttyd.@ttyd[0].interface=' /var/run/ttyd.sock'
uci set ttyd.@ttyd[0].url_override='/ttyd'
uci set ttyd.@ttyd[0].unix_sock='1'
uci commit ttyd

It works perfect on https and cloudfared. Thank you very much for the change. I support merging this.