[SOLVED] Cannot Proxy XTerm.js Traffic

JWToken

New Member
Dec 8, 2023
3
2
3
I'm creating a proxy for Proxmox's terminals here https://github.com/ConvoyPanel/coterm for my project called Convoy at https://convoypanel.com

Convoy is a server management platform for hosting companies to lease out computing resources. Some hosts may want to hide the origin IP address of their Proxmox node, so that where Coterm comes in.

I have successfully created a proxy for noVNC, but I'm struggling to proxy Xterm.js.


This is my code for proxying Xterm.js traffic: https://github.com/ConvoyPanel/coterm/blob/develop/src-rust/src/util/terminals/xtermjs.rs
This is Proxmox's frontend code for working with Xterm.js: https://github.com/proxmox/pve-xtermjs/blob/master/xterm.js/src/main.js

The issue I'm facing is authenticating my Xterm.js session. Proxmox authenticates Xterm.js sessions twice for some reason (go figure), and I'm stuck at trying to authenticate at the second time.


The first authentication is the initial GET request to the "/nodes/{node}/qemu/{vmid}/vncwebsocket" endpoint. Where I pass in the credentials. I know it's working because if I change the
Code:
ticket = encode(&credentials.ticket)
to something like "hello world" I get HTTP 401 error. After I completed the first authentication successfully, the GET request gets upgraded to a websocket connection.


Now this is where the issue begins, the second authentication process begins in the websocket connection. The first packet sent must contain the credentials like in the picture below (which is a screenshot from Proxmox's implementation of Xterm.js)
image.png



and I've sent it here. I know that it was at least sent because the "sent credentials" message gets emitted in the console. HOWEVER, Proxmox is dead silent. I don't get any response in return. I don't even get an OK message like in the screenshot below of Proxmox's implementation.

image.png



I have tried sending the credentials as both text and binary, but it doesn't make a difference.
I also checked that there's no encoding needed before sending the credentials in the websocket, and only URL encoding is needed for making the initial GET request.


Here is the console output for my application:
image.png




I hope somebody can help me out with figuring out the authentication process of Xterm.js. Thanks!
 
The POST request to the /termproxy route is getting sent. It's housed in another repository.

Coterm calls on a route on a Convoy deployed server: https://github.com/ConvoyPanel/coterm/blob/develop/src-rust/src/util/api/xtermjs.rs#L31

In Convoy:
This request hits this route: https://github.com/ConvoyPanel/panel/blob/develop/routes/api-coterm.php#L7
Which calls on this controller method and group of logic: https://github.com/ConvoyPanel/pane...trollers/Coterm/SessionController.php#L30-L37
Which calls on the /termproxy endpoint: https://github.com/ConvoyPanel/pane...x/Server/ProxmoxConsoleRepository.php#L44-L74


CSRF prevention token is not needed since the connection gets upgraded regardless of it being included or not.
 
The POST request to the /termproxy route is getting sent. It's housed in another repository.

Coterm calls on a route on a Convoy deployed server: https://github.com/ConvoyPanel/coterm/blob/develop/src-rust/src/util/api/xtermjs.rs#L31

In Convoy:
This request hits this route: https://github.com/ConvoyPanel/panel/blob/develop/routes/api-coterm.php#L7
Which calls on this controller method and group of logic: https://github.com/ConvoyPanel/pane...trollers/Coterm/SessionController.php#L30-L37
Which calls on the /termproxy endpoint: https://github.com/ConvoyPanel/pane...x/Server/ProxmoxConsoleRepository.php#L44-L74


CSRF prevention token is not needed since the connection gets upgraded regardless of it being included or not.

Sorry for late reply, I got a bit lost in this now briefly looking and would need to have a second look. Bumping it up for now and maybe someone from staff also would have a better readily available answer (maybe @fabian ?;)).
 
I know that it was at least sent because the "sent credentials" message gets emitted in the console. HOWEVER, Proxmox is dead silent. I don't get any response in return. I don't even get an OK message like in the screenshot below of Proxmox's implementation.
can it be that you missed sending a \n at the end of the message? since websockets are 'streaming' we have to terminate this message with something (and chose a newline for simplicity)

EDIT: we don't have to terminate 'each' message, only this first one, since the other types of messages are either a single byte, or contain the length of the payload like it's described here:
https://git.proxmox.com/?p=pve-xter...5e36c1a45d3889f9f3d74e75;hb=refs/heads/master
 
Last edited:
  • Like
Reactions: esi_y
can it be that you missed sending a \n at the end of the message? since websockets are 'streaming' we have to terminate this message with something (and chose a newline for simplicity)

EDIT: we don't have to terminate 'each' message, only this first one, since the other types of messages are either a single byte, or contain the length of the payload like it's described here:
https://git.proxmox.com/?p=pve-xter...5e36c1a45d3889f9f3d74e75;hb=refs/heads/master
WOW! Adding "\n" worked! I can't believe I missed that detail! That was all I needed to get it working!

Thank you so much man!

I can't leave you hanging, so here's a picture.

1702412671250.png
 
  • Like
Reactions: dcsapak and esi_y

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get yours easily in our online shop.

Buy now!