Это руководство о том, как настроить noVNC для удалённого доступа к компьютерам на Windows.

Почему noVNC?


— У Windows есть «родное» средство для удалённого доступа — Remote Desktop Connection. Но оно есть не во всех версиях Windows — например нет в Home edition.
— Также существует множество VNC серверов и клиентов для любой версии Windows. Но для их использования нужно ставить VNC клиент. А бывают случаи, когда ставить ничего нельзя (ограничение прав), или нежелательно, чтобы не оставлять следов на чужом компьютере.
— Ещё есть Chrome Remote Desktop, которому на стороне клиента нужно только расширение в браузере. Но у меня был случай, когда протокол Хрома был заблокирован организацией (там почто всё было заблокировано), а noVNC использует обычный HTTP и поэтому работал.

Насколько я знаю, noVNC — единственное средство, которое позволяет подключиться к удалённому компьютеру без установки какого-либо клиента — используется лишь браузер.
Ещё есть SPICE, но для него я не нашёл сервера под Windows.

В результате этого руководства, мы сможем просто открыть линк в браузере, ввести пароль и пользоваться удалённой системой.

Необходимым условием является проброс портов, или белый IP удалённого компьютера. Также можно воспользоваться VNC repeater. Но это уже выходит за рамки этой статьи.

Общая схема


image

Сначала мы поставим обычный VNC сервер на порт 5900.

Затем поставим noVNC и WebSockify на порт 5901.

WebSockify — это своего рода прокси, который с одной стороны умеет разговаривать с VNC, который у нас на порту 5900, а с другой — умеет транслировать это браузеру через вебсокет, который у нас будет на порту 5901.
noVNC — это просто html-приложение, или как сегодня это называют Single Page Application, которое и будет работать в клиентском браузере и «говорить» с WebSockify на сервере.

Вообще-то в природе существуют VNC серверы, которые умееют сразу соединяться через вебсокеты:

MobileVNC, но он платный (10 Евро за устройство)
— Есть библиотека LibVNCServer, которая поддерживает вебсокеты, и теоретически работает под Windows, но я не нашёл ни одного готового сервера под Windows с этой библиотекой.

В этом случае WebSockify уже не будет нужен.

Ставим VNC


Сам VNC протокол стандартизован, поэтому теоретически можно использовать любой VNC сервер.

Сначала я попробовал поставить TightVNC, но у noVNC были с ним какие-то проблемы с аутентификацией. Думаю, что можно было разобраться, но я поставил UltraVNC (осторожно, у них там тонны рекламы, реальные ссылки — внизу страницы) и всё заработало.

Скорее всего будут работать большинство VNC серверов, которые поддерживают Windows.

VNC сервер я поставил на порт 5900. Не забудьте установить пароль на VNC соединение. UltraVNC не даст подсоединиться до тех пор, пока вы не установите пароль.

Проверьте, что VNC сервер работает, подключившись к нему с помощью VNC клиента с другого компьютера или смартфона.

noVNC и WebSockify


Создаём папку в удобном для себя месте, и загружаем туда:

— распаковываем zip архив noVNC
— распаковываем zip архив WebSockify

Цель, чтобы получилось приблизительно вот так:

image

Теперь запускаем command prompt с администраторскими правами:

image

Запускаем WebSockify:

c:\> cd c:\noVNC\websockify
c:\noVNC\websockify> websockify.exe 5901 127.0.0.1:5900 --web c:\noVNC\noVNC-master
WARNING: no 'resource' module, daemonizing support disabled
WebSocket server settings:
  - Listen on :5901
  - Flash security policy server
  - Web server. Web root: c:\noVNC\noVNC-master
  - No SSL/TLS support (no cert file)
  - proxying from :5901 to 127.0.0.1:5900

Первый параметр выше — порт на котором noVNC будет слушать: 5901. Этот порт нужно сделать доступным для клиентов.

Второй параметр — IP и порт, где стоит VNC сервер: 127.0.0.1:5900

Третий параметр --web инструктирует noVNC, чтобы он отдавал содержимое директории c:\noVNC\noVNC-master по HTTP(s). По умолчанию noVNC отдаёт только VNC вебсокет, но этот параметр позволяет иметь и HTTP сервер на этом же порту.

В директории c:\noVNC\noVNC-master переименуйте файл vnc.html в index.html, чтобы он отдавался по умолчанию.

Теперь noVNC клиент должен быть доступен на порту 5901:

image

Попробуйте также открыть noVNC страницу с другого компьютера/смартфона, чтобы удостовериться, что она доступна снаружи. Если нет — то проверьте:

— что у вас Windows Firewall не блокирует внешние подключения на этот порт,
— что ваш роутер правильно перенаправляет запросы на этот порт на нужный компьютер; если надо гуглите «проброс портов».

Соединяемся (Connect), вводим VNC пароль и видим рабочий стол удалённого компьютера!

Если что-то пошло не так, то ошибки должны показаться в нашей консоли.

Остановить noVNC сервер можно нажав Ctrl-C в консоли. Описанная выше конфигурация работает по HTTP (и по WS).

Добавляем SSL с самоподписанным сертификатом


Добавлять SSL — необязательно. Создать самоподписанный сертификат можно вот так:

openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem

Для Windows openssl можно взять здесь.

В результате получаем файл self.pem, на который надо указать при старте noVNC:

c:\noVNC\websockify> websockify.exe 5901 127.0.0.1:5900 --web c:\noVNC\noVNC-master --cert=c:\noVNC\self.pem

Теперь у нас работает HTTPS и WSS (WebSocket Secure). Для WSS в настройках (Settings) нужно указать Encrypt. Интересно, что noVNC использует один и тот же порт для HTTP и HTTPS — он «умеет» различать запросы и правильно отвечать.

Так как сертификат самоподписанный, то в браузере нужно будет принять этот сертификат.

Let's Encrypt


У меня нет инструкций о том, как настроить систему, чтобы Let's Encrypt автоматически генерировал сертификат специально для нашей системы. Для этого потребовалось бы, чтобы noVNC работал на порту 80, что конечно же возможно, но может быть неудобно, и найти способ интегрировать certbot, чтобы эти файлы публиковались в нужную директорию. Думаю, что это возможно, но я этого не сделал. Если вы допилите — поделитесь в комментариях.

В моём случае, у меня уже есть домашний сервачок с NGINX и DDNS именем, который настроен автоматически получать сертификат от Lets Encrypt.

Вы можете запустить что-то похожее у себя. Здесь есть инструкции о настройке Let's Encrypt для Linux и Windows.

Поэтому для noVNC я просто использую уже существующие pem-файлы, сгенерированные для nginx.

Let's Encrypt создаёт следующие файлы:

cert.pem: Your domain's certificate
chain.pem: The Let's Encrypt chain certificate
fullchain.pem: cert.pem and chain.pem combined
privkey.pem: Your certificate's private key

На Ubuntu их можно найте по вот такому пути: /etc/letsencrypt/live/your_domain_name

Нужно скопировать (объединить) fullchain.pem и privkey.pem в один файл, например назовём его encrypt.pem, и этот файл мы будем использовать для noVNC.

Конечно, работать это будет только если nginx сервер и noVNC — на одном домене. Порты могут быть разными.

И нужно не забывать, что сертификаты годны только несколько месяцев, а потом надо копировать обновлённые файлы.

Добавляем noVNC, как Windows-сервис


Загружаем zip-архив, и распаковываем файлы оттуда так, чтобы они лежали в той же папке, где и файл websockify.exe, то есть в нашем случае в c:\noVNC\websockify.

При запуске, сервис будет использовать параметры из файла noVNCConfig.ini. Вот пример моего конфига:

5901 127.0.0.1:5900 --web C:\noVNC\noVNC-master --cert=c:\noVNC\encrypt.pem

В консоли, запущенной с администраторскими привилегиями создаём новый сервис:

sc create "noVNC Websocket Server" binPath= "c:\noVNC\websockify\noVNC Websocket Service.exe" DisplayName= "noVNC Websocket Server"

Если нужно будет удалить сервис, то вот так:

sc delete "noVNC Websocket Server"

Открываем сервисы (Control Panel > Administrative Tools > Services) и запускаем noVNC Websocket Server. Также здесь можно настроить, чтобы сервис стартовал каждый раз вместе с Windows:

image

Известные недоработки


Раскладка клавиатуры


Я обнаружил, что русская раскладка клавиатуры работает довольно необычным образом:
Если у клиента выбран русский язык, то на удалённый компьютер нажатия клавиш не передаются вообще.

Поэтому, чтобы печатать по русски на удалённом компьютере:

— на клиенте должна быть выбрана английская раскладка
— на удалённой системе должна быть выбрана русская раскладка
image

Буфер обмена


Буфер обмена (клипборд) работает через кнопку в браузере (на скриншоте выше), то есть вы можете туда что-то положить и забрать на удалённой системе, или наоборот. И оно (у меня) не умеет работать с русскими буквами.
Поделиться с друзьями
-->

Комментарии (27)


  1. AEP
    12.04.2017 05:49

    Сам VNC протокол стандартизован, поэтому теоретически можно использовать любой VNC сервер.


    Не согласен.

    NoVNC поддерживает только кодировки Tight, Hextile и совсем примитивные. Т.е. единственная, сносно работающая за пределами локальной сети — это Tight. А ее поддерживают не все VNC-сервера. Например, платный RealVNC ее не поддерживает, и будет работать медленно через noVNC (т.к. скатится на Hextile).


    1. SlavikF
      12.04.2017 07:21

      Да, я почитал тут про noVNC performance:

      Пишут, что они не поддерживают tight, но поддерживают tightPNG и это самый быстрый режим для noVNC.

      Теперь надо вот разобраться, какие VNC серверы поддерживают tightPNG.

      В общем, noVNC работает заметно медленней RDP, но вполне терпимо.


  1. EndUser
    12.04.2017 05:54
    -2

    Для таких случаев существует TeamViewer QS (quick support). Чем не годится?


    1. SlavikF
      12.04.2017 06:05

      Думаю, что для многих случаев годится…

      Сам я TeamViewer QS не пробовал, но
      — похоже его надо запускать на удалённом компьютере, тогда как noVNC может работать как сёрвис.
      — да, Team Viewer (не QS) можно поставить, как сёрвис. Вот интересно в этом случае, — нужно ли инсталлировать что-то клиентской стороне? И будет ли это работать в организациях, где заблокировано всё, кроме HTTP?


      1. EndUser
        13.04.2017 03:51

        Я недопонял задачу:
        1) Разовая помощь извне какому-то сотруднику внутри периметра — это слегка против корпоративной политики, но иногда ради сил добра можно так побаловаться ради хорошего человека поперёк тупого внутреннего саппорта. Для этого портативный .exe как раз, а TV QS умеет разные способы связи. Да и то, TV обычно старается не запускаться на компе, который является частью домена.
        2) Постоянный доступ извне внутрь корпоративки вопреки корпоративке — тут я никак не могу придумать для чего такие хитрости.


        1. lobzanoff
          19.04.2017 21:27

          Как админ организации могу сказать, что такое нужно, когда, например, нахожусь в отпуске или на выходных, при этом квалификации других специалистов, остающихся на работе может оказаться недостаточно, потому что мы — бюджетная организация, и не можем себе позволитьболее одного специалиста соответствующего профиля, то есть только один админ-сетевик, один админ баз данных и т.д., и, например, по правилам инфобезопасности, у админа сетевого нет доступа к базам данных, и наоборот.


          В этом случае такие средства как TeamViewer и аналоги выручают как никогда, при этом не нужно пробрасывать доступ извне ко всем компам домена, достаточно доступа к компу админа, а с него по цепочке уже через RDP к любому другому в домене.


          На клиентской стороне можно хоть веб-интерфейс использовать, достаточно знать ID и пароль серверной стороны.


          Для SlavikF: TV может работать и по 80-му порту, если остальное закрыто, заблокировать можно только заблокировав на шлюзе сервера TeamViewer.com


          1. SlavikF
            19.04.2017 21:29

            Согласен — TV вполне себе вариант.

            Вот только бывает случаи, когда блокируются не порты, а протокол. Не знаю, как TV ведёт себя в этом случае. Знаю, что Chrome Remote Desktop «не пролазиет» через наш корпоративный прокси.


            1. yosemity
              19.04.2017 22:40

              А что мешает цепляться напрямую к своему кампу, например через OpenVPN? В критических ситуациях с телефона по RDP так захожу.

              V может работать и по 80-му порту, если остальное закрыто, заблокировать можно только заблокировав на шлюзе сервера TeamViewer.com

              Явная дыра, всё не заблокируешь. А вот SRP просто не дает запускать TV.

              Извиняюсь, ответ адресован выше.


  1. ranebull
    12.04.2017 08:12
    +2

    Использовать RDP Wrapper Library не вариант?
    rdpwrap github


    1. SlavikF
      12.04.2017 08:16

      Очень интересное решение. Думаю, что стоит про него написать отдельную статью.

      Хотя я так понял, что у него другие цели. И работает он через тот же протокол RDP. Верно?


      1. ranebull
        12.04.2017 08:20

        Хотя я так понял, что у него другие цели. И работает он через тот же протокол RDP. Верно?

        RDPWrap восстанавливает функциональность RDP-сервера на редакциях, где он отсутствует.
        Неоднократно заводил его на Windows 7 Home Basic


  1. dklm
    12.04.2017 09:00

    — У Windows есть «родное» средство для удалённого доступа — Remote Desktop Connection. Но оно есть не во всех версиях Windows — например нет в Home edition.

    Я все равно не понял почему не RDP =\

    Home редакция для домашнего использования — или у меня фантазия скудная, но я не смог придумать сценарий чтобы мне на домашний ПК был нужен протокол удаленного доступа, в редких случаях я юзаю TeamViewer…


  1. kvaps
    12.04.2017 11:30
    +1

    Ещё есть SPICE, но для него я не нашёл сервера под Windows.

    И правильно что не нашли, SPICE — это протокол доставки рабочего стола, используется в виртуальной среде и только, т.к. требует наличия виртуальной видеокарты (QXL) на клиенте, и поддержки со стороны Хозяина


    Если ищете адекватную замену VNC, есть еще X2Go — но этот скорее для Linux. Из свободных решений для Windows ничего лучше VNC пока не придумали.


    VNC — медленный, но позволяет подключаться к пользовательской сессии, в RDP это так же поддерживается, но только в серверных версиях Windows — называется shadow sessions. Упомянутый выше патч rdpwrap вроде может вернуть эту функцию и на клиентских Windows, но я не проверял, и кроме того это нарушает клиентскую лицензию.


    В вашем случае думаю что вам будет крайне интересно попробовать проект Guacamole — это свободный RDP(и VNC)-gatevay, который позволит вам настроить список всех клиентов, и подключатся к ним по RDP или VNC прямо из браузера.


    В случае успеха, обязательно пишите еще! — статей про Guacamole на хабрахабре раз-два и обчелся, народ должен знать :)


    1. kernelconf
      12.04.2017 18:37
      +1

      Многих отпугивает что Guacamole требует контейнер servlet'ов (обычно это простой Tomcat). Кроме того, RDP-реализация работает с замечаниями. Я когда-то использовал Guacamole для доступа на работе (где всё закрыто) на виртуалку с биржевым терминалом. С RDP проблем было 2:
      1. Я тогда использовал вируализацию на CentOS7, там идёт старая версия программы, в которой RDP поломан в принципе.
      2. Со свежим Guacamole проблема была интереснее — он частично отваливался и переставал транслировать изменения на рабочем столе, при это Input обрабатывал (т.е. переподключаюсь и вижу результат клика мыши, к примеру). Но происходило это нечасто (скажем, раз в час в среднем) и решалось простым нажатием F5 в браузере.

      Обе проблемы радикально решались переходом на VNC. Но данный переход закончился у меня невесело — письмом от службы безопасности, по гигантскому потреблению трафика.


      1. kvaps
        12.04.2017 21:53

        Не могу не согласиться с вами на счет подобных сложностей при настройке.
        Но есть достаточно безболезненый способ попробовать — это docker:


        https://github.com/glyptodon/guacamole-docker


        Этот образ позволяет развернуть готовое, а главное стабильное, окружение за считанные минуты и всего за пару команд.


    1. StraNNicK
      12.04.2017 18:37

      Честно говоря, x2go тоже медленный. Хотя возможно я просто давно его не видел.


  1. mihmig
    12.04.2017 14:42

    >> когда протокол Хрома был заблокирован организацией (там почто всё было заблокировано), а noVNC использует обычный HTTP и поэтому работал.
    Обычно недоадмины используют блокировку по портам.
    А вы говорите что noVNC работает по нестандартному порту 5901. т.о. вероятность что трафик пройдет очень низка…


  1. slavius
    12.04.2017 15:39

    LiteManagerFree — не встроен в Windows, но есть portable. И с настраиваемым портом. И не скинет, как TeemViewer после какого-то времени или количества подключений. Но, да, тоже требует нормального IP.


    1. slavius
      12.04.2017 16:02
      +1

      Да, для него требуется клиент, через браузер не получится. Клиент, правда, и для Андроида есть.


  1. AstorS1
    12.04.2017 15:47

    >> А бывают случаи, когда ставить ничего нельзя (ограничение прав)...
    входит в противоречие с
    >> Теперь запускаем command prompt с администраторскими правами:

    т.е. без прав администратора этим решением воспользоваться проблематично или я ошибаюсь?


    1. SlavikF
      12.04.2017 18:39

      Противоречия нет:
      — админские права нужны на удалённо компьютере, где мы ставим VNC и noVNC
      — на стороне клиента нужен только браузер. Админские права не нужны


      1. yosemity
        13.04.2017 04:24

        Как защититься? Мне, как админу эта фигня не нужна.


    1. yosemity
      13.04.2017 04:19

      DEL. Не въехал в тему


  1. dmitryredkin
    12.04.2017 22:01

    Ну, во-первых, насколько я помню, VNC viewer applet еще никто не отменял (несмотря на все последние сложности с джавой в браузере).
    Во-вторых, если есть возможность развернуть apache/tomcat в локалке, то guacamole — отличная вещь!


    1. SlavikF
      12.04.2017 22:07

      Мне кажется, что на сегодняшний день, Java в современных браузерах уже отмирает…


  1. SlavikF
    12.04.2017 22:07

    del


  1. Stkn
    13.04.2017 18:41

    С TightVNC не получилось, скорее всего, из-за отсутствия галки на Allow loopback connections. С этой галкой у меня всё заработало.