KASM has the Docker Images of the GUI services they use with their "Work Space". I am interested only in one of them: Desktop but i suppose they all function more ore less the same. I made this Docker Compose to try and spin it up:
services:
kasmweb:
image: kasmweb/desktop:1.15.0-rolling-weekly
container_name: kasmweb
ports:
- 6901:6901
stdin_open: true
tty: true
shm_size: '2gb'
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
devices:
- /dev/dri:/dev/dri
env_file: /dockerfiles/kasmweb.env
networks:
- public
networks:
public:
external: true
It does run with errors related to being in Stand Alone and not connected to KASM Workspace. One Environment variable they mention in the documentation is VNC_PW=password
which in turn is used in Basic HTTP Authentication i assume. Values were not changed from default:
User : kasm_user
Password: password
Going to https://server-host:6901 will get you to the Desktop GUI in your browser and it will work smoothly:
Because I like to secure my services I disabled the ports so the service is accessed only through NPM and enable Websockets for the Proxy Host. You will get again to the HTTP Authentication but even with correct cridentials it will error out:
2024-10-17 10:41:04,174 [INFO] websocket 8: got client connection from 172.19.0.15
2024-10-17 10:41:04,186 [DEBUG] websocket 8: using SSL socket
2024-10-17 10:41:04,195 [DEBUG] websocket 8: X-Forwarded-For ip '192.168.20.59'
2024-10-17 10:41:04,195 [INFO] websocket 8: Authentication attempt failed, BasicAuth required, but client didn't send any
2024-10-17 10:41:04,195 [INFO] websocket 8: 172.19.0.15 192.168.20.59 - "GET / HTTP/1.1" 401 158
2024-10-17 10:41:04,195 [DEBUG] websocket 8: No connection after handshake
2024-10-17 10:41:04,195 [DEBUG] websocket 8: handler exit
For some reason NPM is not forwarding the cridentials to the KASM Host. So i added this to NPM custom configurations:
location / {
proxy_pass https://kasmweb:6901;
proxy_set_header Authorization "Basic a2FzbV91c2VyOnBhc3N3b3Jk";
proxy_pass_header Authorization;
}
The error on KASM container is as following:
2024-10-17 13:44:45,623 [INFO] websocket 56: got client connection from 172.19.0.15
2024-10-17 13:44:45,634 [DEBUG] websocket 56: using SSL socket
2024-10-17 13:44:45,634 [DEBUG] websocket 56: X-Forwarded-For ip '192.168.20.59'
2024-10-17 13:44:45,639 [DEBUG] websocket 56: BasicAuth matched
2024-10-17 13:44:45,639 [DEBUG] websocket 56: Invalid WS request, maybe a HTTP one
2024-10-17 13:44:45,639 [DEBUG] websocket 56: Requested file '/index.html'
2024-10-17 13:44:45,640 [INFO] websocket 56: 172.19.0.15 192.168.20.59 kasm_user "GET /index.html HTTP/1.1" 200 24135
2024-10-17 13:44:45,640 [DEBUG] websocket 56: No connection after handshake
2024-10-17 13:44:45,640 [DEBUG] websocket 56: handler exit
So Authentication is working but Websockets still not working. Websockets function is enabled in NPM. Additionally I did try the following which gave the same error:
location / {
proxy_pass https://kasmweb:6901;
proxy_set_header Authorization "Basic a2FzbV91c2VyOnBhc3N3b3Jk";
proxy_pass_header Authorization;
proxy_set_header X-Real-IP $remote_addr;
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_http_version 1.1;
}
My Goal is to run Linux Desktop Web GUI with Authentik Reverse Proxy Authentication as sand box.
How can I resolve this WS error and access KASM service with NPM?
location / {
proxy_pass https://kasmweb:6901;
proxy_set_header Authorization "Basic a2FzbV91c2VyOnBhc3N3b3Jk";
proxy_pass_header Authorization;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;
}
Thanks to this discussion, this worked for Nginx proxy Manager and it connects imediatly. Authentik changed their configurations to include websockets and that broke the whole thing! reverting back to older configuration style and including the headers from above fixed the connection:
The issue with Authentik is with their new NGINX Websocket configurations. removing them and adding ones from the previus comment fixed it:
# Increase buffer size for large headers
# This is needed only if you get 'upstream sent too big header while reading response
# header from upstream' error when trying to access an application protected by goauthentik
proxy_buffers 8 16k;
proxy_buffer_size 32k;
# Make sure not to redirect traffic to a port 4443
port_in_redirect off;
location / {
# Put your proxy_pass to your application here
proxy_pass $forward_scheme://$server:$port;
# Set any other headers your application might need
# proxy_set_header Host $host;
# proxy_set_header ...
#proxy_pass https://kasmweb:6901;
proxy_set_header Authorization "Basic a2FzbV91c2VyOnBhc3N3b3Jk";
proxy_pass_header Authorization;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;
##############################
# authentik-specific config
##############################
auth_request /outpost.goauthentik.io/auth/nginx;
error_page 401 = u/goauthentik_proxy_signin;
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
# translate headers from the outposts back to the actual upstream
auth_request_set $authentik_username $upstream_http_x_authentik_username;
auth_request_set $authentik_groups $upstream_http_x_authentik_groups;
auth_request_set $authentik_email $upstream_http_x_authentik_email;
auth_request_set $authentik_name $upstream_http_x_authentik_name;
auth_request_set $authentik_uid $upstream_http_x_authentik_uid;
proxy_set_header X-authentik-username $authentik_username;
proxy_set_header X-authentik-groups $authentik_groups;
proxy_set_header X-authentik-email $authentik_email;
proxy_set_header X-authentik-name $authentik_name;
proxy_set_header X-authentik-uid $authentik_uid;
#add_header X-calibre-web-user "CloudAdmin" always;
}
# all requests to /outpost.goauthentik.io must be accessible without authentication
location /outpost.goauthentik.io {
proxy_pass https://authentik-server:9443/outpost.goauthentik.io;
# ensure the host of this vserver matches your external URL you've configured
# in authentik
proxy_set_header Host $host;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
add_header Set-Cookie $auth_cookie;
auth_request_set $auth_cookie $upstream_http_set_cookie;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
# Special location for when the /auth endpoint returns a 401,
# redirect to the /start URL which initiates SSO
location u/goauthentik_proxy_signin {
internal;
add_header Set-Cookie $auth_cookie;
return 302 /outpost.goauthentik.io/start?rd=$request_uri;
# For domain level, use the below error_page to redirect to your authentik server with the full redirect path
# return 302 https://authentik.company/outpost.goauthentik.io/start?rd=$scheme://$http_host$request_uri;
}