Информация
Услуги
  • Внедрение
  • Настройка
  • Поддержка
  • Ремонт
Контакты
Оплата
Новости
Доставка
Загрузки
Форум
Настройка
    info@proxmox.su
    +7 (495) 320-70-49
    Заказать звонок
    Аспро: ЛайтШоп
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Аспро: ЛайтШоп
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Аспро: ЛайтШоп
    Телефоны
    +7 (495) 320-70-49
    Заказать звонок
    0
    0
    0
    Аспро: ЛайтШоп
    • +7 (495) 320-70-49
      • Назад
      • Телефоны
      • +7 (495) 320-70-49
      • Заказать звонок
    • info@proxmox.su
    • Москва, Бакунинская улица, 69с1
    • Пн-Пт: 09-00 до 18-00
      Сб-Вс: выходной
    • 0 Сравнение
    • 0 Избранное
    • 0 Корзина
    Главная
    Форум
    Proxmox Виртуальная Среда
    [РЕШЕНО] noVNC через API: PVEAuthCookie (PVE Ticket) и Tunnel Auth (VNC Ticket) — как это сделать? :-)

    Форумы: Proxmox Виртуальная Среда, Proxmox Backup Server, Proxmox Mail Gateway, Proxmox Datacenter Manager
    Поиск  Пользователи  Правила  Войти
    Страницы: 1
    RSS
    [РЕШЕНО] noVNC через API: PVEAuthCookie (PVE Ticket) и Tunnel Auth (VNC Ticket) — как это сделать? :-), Proxmox Виртуальная Среда
     
    linux
    Guest
    #1
    0
    18.06.2023 16:17:00
    Привет, просто пытаемся разобраться с этим после двух дней работы.

    **Обновление:** Мы смогли исправить мелкие недочеты. Но все равно выдает 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. Click here 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, и передать пароль.

    [Ссылка на форум](https://forum.proxmox.com/threads/401permission-denied-invalid-pvevnc-ticket.34144/)

    [Ссылка на issue GitHub](https://github.com/ZzAntares/ProxmoxVE/issues/17#issuecomment-688937674)

    [Ссылка на форум](https://forum.proxmox.com/threads/401permission-denied-invalid-pvevnc-ticket.110961/)

    [Ссылка на форум](https://forum.proxmox.com/threads/working-with-api-getting-401-no-ticket.75108/)

    Многие онлайн просто откатываются к использованию iframe GUI Proxmox VE, и я понимаю почему.

    Наконец-то у нас получилось!
     
     
     
    xianzhi0520
    Guest
    #2
    0
    06.07.2023 12:34:00
    Я не понимаю.
     
     
     
    xianzhi0520
    Guest
    #3
    0
    14.07.2023 05:22:00
    Можешь, пожалуйста, откликнись мне насчёт Cookie?
     
     
     
    xianzhi0520
    Guest
    #4
    0
    17.07.2023 14:26:00
    Наконец-то использую Nginx в качестве прокси, и JS устанавливает одинаковую Origin cookie — теперь работает!

    Код:
    ```
    server {
       listen 80 default_server;
       rewrite ^(.*) https://$host$1 permanent;
    }

    server {
       listen 443 ssl;
       server_name _;
       #ssl on;
       ssl_certificate /etc/Nginx1.15.11/conf/proxmox/pve-ssl.pem;
       ssl_certificate_key /etc/Nginx1.15.11/conf/proxmox/pve-ssl.key;
       proxy_redirect off;
       location ~ /pve {
           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection "upgrade";
           add_header 'Access-Control-Allow-Origin' '*' always;
           add_header 'Access-Control-Allow-Methods' '*' always;
           add_header 'Access-Control-Allow-Headers' '*' always;
           add_header 'Access-Control-Allow-Credentials' true always;
           #my php webapp
           proxy_pass http://127.0.0.1:8989;
           proxy_buffering off;
           client_max_body_size 0;
           proxy_connect_timeout  3600s;
           proxy_read_timeout  3600s;
           proxy_send_timeout  3600s;
           send_timeout  3600s;
      }
       location /api2/json {
           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection "upgrade";
           add_header 'Access-Control-Allow-Origin' '*' always;
           add_header 'Access-Control-Allow-Methods' '*' always;
           add_header 'Access-Control-Allow-Headers' '*' always;
           add_header 'Access-Control-Allow-Credentials' true always;
           #my pve server
           proxy_pass https://192.168.99.230:8006;
           proxy_buffering off;
           client_max_body_size 0;
           proxy_connect_timeout  3600s;
           proxy_read_timeout  3600s;
           proxy_send_timeout  3600s;
           send_timeout  3600s;
      }
    ```
     
     
     
    dklinux7
    Guest
    #5
    0
    21.11.2023 15:02:00
    Можешь объяснить, как ты это сделал? Весь процесс?
     
     
     
    xianzhi0520
    Guest
    #6
    0
    21.11.2023 15:14:00
    Я использую nginx proxy, чтобы PVE и мой PHP-проект работали по одному домену. Поэтому они оба могут использовать одни и те же куки. xterm или novnc websocket подключились.
     
     
     
    dklinux7
    Guest
    #7
    0
    15.12.2023 20:18:00
    Можешь поделиться кодом или ссылкой на GitHub?
     
     
     
    xianzhi0520
    Guest
    #8
    0
    27.12.2023 04:40:00
    PHP: use Corsinvest\ProxmoxVE\Api\PveClient;
    public function createCookie()
       {

           $client = new PveClient("192.168.99.230", 8006);
           if ($client->login('root', 'rootroot', 'pam')) {
               //
               $csr = $client->ticketCSRFPreventionToken;
               $ticket = $client->ticketPVEAuthCookie;
               $res['data'] = array('username' => 'root@pam', 'CSRFPreventionToken' => $csr, 'ticket' => $ticket);
               return json($res);
           }
    //another file
       <?php

    /*
    * SPDX-FileCopyrightText: Copyright Corsinvest Srl
    * SPDX-License-Identifier: GPL-3.0-only
    */

    namespace Corsinvest\ProxmoxVE\Api;

    /**
    * Class ClientBase
    * @package Corsinvest\ProxmoxVE\Api
    *
    * Proxmox VE Client Base
    */
    class PveClientBase
    {

       /**
        * @ignore
        */
       //private->public
       public $ticketCSRFPreventionToken;

       /**
        * @ignore
        */
       //private->public
       public $ticketPVEAuthCookie;
       } if you use get createCookie function can get a json array, JavaScript: var xhr = new XMLHttpRequest();
           xhr.open('GET', '/admin/pve.lxc/createCookie', true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
           xhr.withCredentials=true
    xhr.onload = function() {
             if (xhr.status === 200) {
               
               var res = JSON.parse(xhr.responseText);
               console.log(res);
               PVE.UserName = res.data.username;
               PVE.CSRFPreventionToken = res.data.CSRFPreventionToken
               
               setCookie('PVEAuthCookie',res.data.ticket,8600)
               createTerminal();
             } else {
             
               console.error('faild' + xhr.status);
             }
           };
           var params = [];
           xhr.send(params); nginx proxy the pve server make sure in the same area https://127.0.0.1 ,same cookies
     
     
     
    Страницы: 1
    Читают тему
    +7 (495) 320-70-49
    info@proxmox.su

    Конфиденциальность Оферта
    © 2026 Proxmox.su
    Главная Каталог 0 Корзина 0 Избранные Кабинет 0 Сравнение Акции Контакты Услуги Бренды Отзывы Компания Лицензии Документы Реквизиты Поиск Блог Обзоры