Привет, просто пытаемся разобраться с этим после двух дней работы.
**Обновление:** Мы смогли исправить мелкие недочеты. Но все равно выдает 401 No Ticket, хотя есть VNC-билет от vncproxy, который передается в vncwebsocket noVNC (через путь), и, кажется, установлен cookie с PVE-билетом.
**Обновление:** Ошибка No Ticket связана с Access Ticket для самого PVE. Это потребовало тонкой настройки для решения.
```php
function pvewhmcs_noVNC($params) {
$serverip = $params["serverip"];
$serverusername = 'vnc';
$serverpassword = Capsule::table('mod_pvewhmcs')->where('id', '1')->value('vnc_secret');
$proxmox=new PVE2_API($serverip, $serverusername, "pve", $serverpassword);
if ($proxmox->login()) {
# Get first node name.
$nodes = $proxmox->get_node_list();
$first_node = $nodes[0];
unset($nodes);
$guest=Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$vm_vncproxy=$proxmox->post('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/vncproxy', array( 'websocket' => '1' )) ;
// Get both tickets prepared
$pveticket = $proxmox->getTicket();
$vncticket = $vm_vncproxy['ticket'];
// $path should only contain the actual path without any query parameters
$path = 'api2/json/nodes/' . $first_node . '/' . $guest->vtype . '/' . $params['serviceid'] . '/vncwebsocket?port=' . $vm_vncproxy['port'] . '&vncticket=' . urlencode($vncticket);
$url = '/modules/servers/pvewhmcs/novnc_router.php?host=' . $serverip . '&pveticket=' . urlencode($pveticket) . '&path=' . urlencode($path) . '&vncticket=' . urlencode($vncticket);
$vncreply='<center><strong>Console (noVNC) prepared for usage. to open the noVNC window.</strong></center>' ;
return $vncreply;
} else {
$vncreply='Failed to prepare noVNC. Please contact Technical Support.';
return $vncreply;
}
}
```
Затем есть novnc\_router.php, который добавляет cookie локально для пользователя 'vnc' с ограниченными правами доступа на PVE, а затем перенаправляет на файл noVNC HTML для подключения. В файл передается PVE-билет, VNC-билет, IP-адрес сервера и путь запроса. Мы были вынуждены изменить наш подход, чтобы он работал только для одного домена из-за anti-CSRF (cookie могут распространяться только на поддомены), обновить DNS, чтобы это отразилось, а затем исправить кодирование VNC-билета, чтобы он выдерживал proxmox-api-daemon.
```php
<?php
// FILE: novnc_router.php
// TASK: Take WHMCS request, add browser cookie, then redirect to noVNC
if (isset($_GET['pveticket']) && isset($_GET['host']) && isset($_GET['path']) && isset($_GET['vncticket'])) {
$pveticket = $_GET['pveticket'];
$vncticket = $_GET['vncticket'];
$host = $_GET['host'];
$path = $_GET['path'];
// Get the requesting hostname/domain from request
$whmcsdomain = parse_url($_SERVER['HTTP_HOST']);
$domainonly = preg_replace("/^(.*?)\.(.*)$/","$2",$whmcsdomain['path']);
setrawcookie('PVEAuthCookie', $pveticket, 0, '/', $domainonly);
// Create the final noVNC URL with the re-encoded vncticket
$hostname = gethostbyaddr($host);
$redirect_url = '/modules/servers/pvewhmcs/novnc/vnc.html?autoconnect=true&encrypt=true&host=' . $hostname . '&port=8006&password=' . urlencode($vncticket) . '&path=' . urlencode($path);
header('Location: ' . $redirect_url);
exit;
} else {
echo 'Error: Missing required info to route your request. Please try again.';
}
?>
```
noVNC затем правильно настроен с Web Socket config с 1.2.3.4, порт 8006 и путь: api2/json/nodes/syd-pvetest/qemu/103/vncwebsocket?port=5900&vncticket=PVEVNC%3A648F1097%3A%3ALF3XL%2FdXR%2FDhf XJMCPSduSCYkKEQn6m4lTkdnfQe9bSvCBQUFxaehjdyhhCd0EavucnmcTRZn dnQPaLKSlWzSaTpb4yEhL%2B8rvuw%2Fec%2BNLPMh7JOin7vSiQJR2nJ%2B GtO%2BYPMXV9aD4Ib0vzRwmcrjx21u387nnQTX%2Bof0Ap8L0u3xN1XCcabK IMRDwvMMt9Xd5hX7dwg%2BHVufzMarCr2surgkJk7pRDIXB5VzHDBd6%2FQD oD7t29uhsbboY94vVwNA0n4cn2wF0gqqnKE01eUQOm0OdGPE%2BvPpjSxIRk NzSnNeI2PoJ1vLZX%2BOluNUC9KGW2J27LszC78KEKzrvZcqQ%3D%3D
Firefox не может установить соединение с сервером по адресу wss://1.2.3.4:8006/api2/json/nodes/syd-pvetest/qemu/103/vncwebsocket?port=5900&vncticket=PVEVNC%3A648F10... из-за 401 No Ticket.
WHMCS и Proxmox находятся на разных "доменах" (Proxmox только по IP), но ошибка cookie была такой же без добавления 5-го параметра в setrawcookie().
**Обновление 1:** Мы изменили способ установки cookie, чтобы это работало. И, конечно же, anti-CSRF означает только один домен.
**Обновление 2:** Затем мы получили ответ "Invalid VNC Ticket" от PVE. Оказалось, что для этого нужно было дважды закодировать VNC-билет.
**Обновление 3:** Мы изменили параметры запроса noVNC, чтобы включить autoconnect=true и encrypted=true, и передать пароль.
[Ссылка на форум]()
[Ссылка на issue GitHub]()
[Ссылка на форум]()
[Ссылка на форум]()
Многие онлайн просто откатываются к использованию iframe GUI Proxmox VE, и я понимаю почему.
Наконец-то у нас получилось!
**Обновление:** Мы смогли исправить мелкие недочеты. Но все равно выдает 401 No Ticket, хотя есть VNC-билет от vncproxy, который передается в vncwebsocket noVNC (через путь), и, кажется, установлен cookie с PVE-билетом.
**Обновление:** Ошибка No Ticket связана с Access Ticket для самого PVE. Это потребовало тонкой настройки для решения.
```php
function pvewhmcs_noVNC($params) {
$serverip = $params["serverip"];
$serverusername = 'vnc';
$serverpassword = Capsule::table('mod_pvewhmcs')->where('id', '1')->value('vnc_secret');
$proxmox=new PVE2_API($serverip, $serverusername, "pve", $serverpassword);
if ($proxmox->login()) {
# Get first node name.
$nodes = $proxmox->get_node_list();
$first_node = $nodes[0];
unset($nodes);
$guest=Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$vm_vncproxy=$proxmox->post('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/vncproxy', array( 'websocket' => '1' )) ;
// Get both tickets prepared
$pveticket = $proxmox->getTicket();
$vncticket = $vm_vncproxy['ticket'];
// $path should only contain the actual path without any query parameters
$path = 'api2/json/nodes/' . $first_node . '/' . $guest->vtype . '/' . $params['serviceid'] . '/vncwebsocket?port=' . $vm_vncproxy['port'] . '&vncticket=' . urlencode($vncticket);
$url = '/modules/servers/pvewhmcs/novnc_router.php?host=' . $serverip . '&pveticket=' . urlencode($pveticket) . '&path=' . urlencode($path) . '&vncticket=' . urlencode($vncticket);
$vncreply='<center><strong>Console (noVNC) prepared for usage. to open the noVNC window.</strong></center>' ;
return $vncreply;
} else {
$vncreply='Failed to prepare noVNC. Please contact Technical Support.';
return $vncreply;
}
}
```
Затем есть novnc\_router.php, который добавляет cookie локально для пользователя 'vnc' с ограниченными правами доступа на PVE, а затем перенаправляет на файл noVNC HTML для подключения. В файл передается PVE-билет, VNC-билет, IP-адрес сервера и путь запроса. Мы были вынуждены изменить наш подход, чтобы он работал только для одного домена из-за anti-CSRF (cookie могут распространяться только на поддомены), обновить DNS, чтобы это отразилось, а затем исправить кодирование VNC-билета, чтобы он выдерживал proxmox-api-daemon.
```php
<?php
// FILE: novnc_router.php
// TASK: Take WHMCS request, add browser cookie, then redirect to noVNC
if (isset($_GET['pveticket']) && isset($_GET['host']) && isset($_GET['path']) && isset($_GET['vncticket'])) {
$pveticket = $_GET['pveticket'];
$vncticket = $_GET['vncticket'];
$host = $_GET['host'];
$path = $_GET['path'];
// Get the requesting hostname/domain from request
$whmcsdomain = parse_url($_SERVER['HTTP_HOST']);
$domainonly = preg_replace("/^(.*?)\.(.*)$/","$2",$whmcsdomain['path']);
setrawcookie('PVEAuthCookie', $pveticket, 0, '/', $domainonly);
// Create the final noVNC URL with the re-encoded vncticket
$hostname = gethostbyaddr($host);
$redirect_url = '/modules/servers/pvewhmcs/novnc/vnc.html?autoconnect=true&encrypt=true&host=' . $hostname . '&port=8006&password=' . urlencode($vncticket) . '&path=' . urlencode($path);
header('Location: ' . $redirect_url);
exit;
} else {
echo 'Error: Missing required info to route your request. Please try again.';
}
?>
```
noVNC затем правильно настроен с Web Socket config с 1.2.3.4, порт 8006 и путь: api2/json/nodes/syd-pvetest/qemu/103/vncwebsocket?port=5900&vncticket=PVEVNC%3A648F1097%3A%3ALF3XL%2FdXR%2FDhf
Firefox не может установить соединение с сервером по адресу wss://1.2.3.4:8006/api2/json/nodes/syd-pvetest/qemu/103/vncwebsocket?port=5900&vncticket=PVEVNC%3A648F10... из-за 401 No Ticket.
WHMCS и Proxmox находятся на разных "доменах" (Proxmox только по IP), но ошибка cookie была такой же без добавления 5-го параметра в setrawcookie().
**Обновление 1:** Мы изменили способ установки cookie, чтобы это работало. И, конечно же, anti-CSRF означает только один домен.
**Обновление 2:** Затем мы получили ответ "Invalid VNC Ticket" от PVE. Оказалось, что для этого нужно было дважды закодировать VNC-билет.
**Обновление 3:** Мы изменили параметры запроса noVNC, чтобы включить autoconnect=true и encrypted=true, и передать пароль.
[Ссылка на форум]()
[Ссылка на issue GitHub]()
[Ссылка на форум]()
[Ссылка на форум]()
Многие онлайн просто откатываются к использованию iframe GUI Proxmox VE, и я понимаю почему.
Наконец-то у нас получилось!
