I used to have some code interactive with vncwebsocket via the following procedure. It's used to connect VM serial directly to the user terminal.
1. generate a PVEVNC ticket via
2. Submit Ticket and user to
When switching to API Token. I found that you can still generate PVEVNC Ticket from step1, but Unable to connect the websocket endpoint.
During further diagnosing, I find the following log from pvedaemon:
what's the correct way using vncwebsocket endpoint via api token ?
A small reproduce script is attached below.
1. generate a PVEVNC ticket via
/api2/json/nodes/{node}/qemu/{vmid}/termproxy
2. Submit Ticket and user to
wss://<host>:8006/api2/json/nodes/{node}/qemu/{vmid}/vncwebsocket
When switching to API Token. I found that you can still generate PVEVNC Ticket from step1, but Unable to connect the websocket endpoint.
During further diagnosing, I find the following log from pvedaemon:
Code:
authentication failure; rhost=127.0.0.1 user=root@pam!<redacted> msg=value 'root@pam!<redacted>' does not look like a valid user name
command '/usr/bin/termproxy 5900 --path /vms/10020 --perm VM.Console -- /usr/sbin/qm terminal 10020 -escape 0 -iface serial0' failed: exit code 1
what's the correct way using vncwebsocket endpoint via api token ?
A small reproduce script is attached below.
Python:
"""
Install dependency by pip install proxmoxer websocket-client
"""
import proxmoxer
import websocket
import ssl
import sys
from urllib.parse import urlencode
endpoint = '<replace>'
vmid = 10020
serial='<replace>'
node = '<replace>'
opts = {"cert_reqs": ssl.CERT_NONE, "check_hostname": False}
p = proxmoxer.ProxmoxAPI(endpoint, user='<replace>', token_name="<replace>", token_value="<replace>", verify_ssl=False)
# p = proxmoxer.ProxmoxAPI(endpoint, user='<replace>', password='<replace>', verify_ssl=False)
data = p.nodes(node).qemu(vmid).termproxy.post(serial=serial)
query = {'vncticket': data['ticket'], 'port': data['port']}
extra_opts = {}
handshake = ''
if hasattr(p._backend.auth, 'token_name'):
extra_opts['header'] = {'Authorization': f'PVEAPIToken={p._backend.auth.username}!{p._backend.auth.token_name}={p._backend.auth.token_value}'}
# handshake = f'{p._backend.auth.username}:{data["ticket"]}\n'
handshake = f'{p._backend.auth.username}!{p._backend.auth.token_name}:{data["ticket"]}\n'
else:
extra_opts['cookie'] = '; '.join(['='.join(i) for i in p._backend.auth.get_cookies().items()])
handshake = f'{p._backend.auth.username}:{data["ticket"]}\n'
ws = websocket.create_connection(f"wss://{endpoint}/api2/json/nodes/{node}/qemu/{vmid}/vncwebsocket?{urlencode(query)}", sslopt=opts, **extra_opts)
ws.send(handshake)
print(ws.recv())
# should be 'OK'
ws.close()