MAATRIX / Блог / Apache Guacamole в Docker Compose: готовый файл

Apache Guacamole в Docker Compose: готовый файл

MAATRIX

Если у вас есть парк из десятка серверов на RDP, VNC и SSH, а под рукой то и дело нет нужного клиента — RDP-файла, PuTTY, VNC Viewer с правильной версией, — рано или поздно захочется одну точку входа, которая открывается в обычной вкладке браузера. Apache Guacamole именно это и делает: клиентless-шлюз, который проксирует протоколы удалённого доступа в HTML5, так что зайти на любой из ваших серверов можно с телефона, чужого ноутбука или планшета, не устанавливая ничего локально. Ниже — рабочий docker-compose.yml, который поднимает связку за 10–15 минут, и разбор мест, где новички обычно спотыкаются.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что такое Guacamole и зачем он нужен

Apache Guacamole — не VPN и не туннель, а брокер протоколов. Он состоит из трёх частей:

  • guacd — демон, который непосредственно говорит по RDP/VNC/SSH/Telnet с целевыми машинами и превращает картинку в поток, понятный браузеру (по сути — видео поверх WebSocket);
  • guacamole (веб-приложение на Tomcat) — фронтенд с логином, списком подключений, правами доступа;
  • база данных (MySQL/MariaDB или PostgreSQL) — хранит пользователей, подключения и права.

Практический смысл: у вас есть, скажем, пять Windows-серверов с RDP и три Linux-машины с SSH-доступом только по IP из белого списка. Вместо того чтобы держать RDP-клиент и SSH-агент на каждом рабочем месте, вы даёте команде URL вида https://remote.example.com, логин/пароль (плюс, если настроите, 2FA) — и человек сразу видит рабочий стол в браузере. Это удобно для поддержки, для доступа подрядчиков без выдачи VPN, для work-from-anywhere сценариев и для того, чтобы не публиковать RDP-порт (3389) наружу вообще — он остаётся закрытым для интернета, доступным только с сервера, где стоит guacd.

Для этого нужен отдельный сервер — держать шлюз на той же машине, к которой подключаетесь, бессмысленно. Обычно берут небольшой VPS (2 vCPU / 2–4 ГБ RAM с запасом хватает на 5–10 одновременных сессий) в удобной локации — если основная аудитория в России, разумно смотреть на аренду VPS в США или UK с оплатой картой РФ или криптой, чтобы не зависеть от блокировок и заодно получить понятный биллинг.

Готовый docker-compose.yml

Официальный образ Guacamole не тянет базу автоматически — нужно инициализировать схему отдельным шагом (об этом ниже). Сама связка из трёх контейнеров:

version: "3.8"

services:
  guacd:
    image: guacamole/guacd:1.5.5
    container_name: guacd
    restart: unless-stopped
    networks:
      - guac-net
    volumes:
      - guacd_drive:/drive
      - guacd_record:/record

  guac-db:
    image: mysql:8.0
    container_name: guac-db
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: "ЗАМЕНИТЕ_НА_СЛОЖНЫЙ_ПАРОЛЬ_ROOT"
      MYSQL_DATABASE: guacamole_db
      MYSQL_USER: guacamole_user
      MYSQL_PASSWORD: "ЗАМЕНИТЕ_НА_СЛОЖНЫЙ_ПАРОЛЬ_USER"
    volumes:
      - guac_db_data:/var/lib/mysql
      - ./initdb:/docker-entrypoint-initdb.d
    networks:
      - guac-net

  guacamole:
    image: guacamole/guacamole:1.5.5
    container_name: guacamole
    restart: unless-stopped
    depends_on:
      - guacd
      - guac-db
    environment:
      GUACD_HOSTNAME: guacd
      MYSQL_HOSTNAME: guac-db
      MYSQL_DATABASE: guacamole_db
      MYSQL_USER: guacamole_user
      MYSQL_PASSWORD: "ЗАМЕНИТЕ_НА_СЛОЖНЫЙ_ПАРОЛЬ_USER"
    ports:
      - "127.0.0.1:8080:8080"
    networks:
      - guac-net

networks:
  guac-net:
    driver: bridge

volumes:
  guac_db_data:
  guacd_drive:
  guacd_record:

Порт веб-интерфейса намеренно привязан к 127.0.0.1 — наружу его отдаёт реверс-прокси с TLS (раздел ниже), а не голый Tomcat на 8080.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Инициализация базы данных

Официальный образ guacamole/guacamole умеет сгенерировать SQL-схему под вашу СУБД — этим и нужно воспользоваться перед первым запуском:

mkdir -p initdb

docker run --rm guacamole/guacamole:1.5.5 /opt/guacamole/bin/initdb.sh --mysql > initdb/01-initdb.sql

Файл initdb/01-initdb.sql подхватится MySQL-контейнером автоматически при первом старте (это стандартный механизм docker-entrypoint-initdb.d — он выполняется, только если том с данными пуст). Дальше поднимаем стек:

docker compose up -d

Проверяем, что схема реально накатилась:

docker exec -it guac-db mysql -u guacamole_user -p guacamole_db -e "SHOW TABLES;"

Если список таблиц пуст — том guac_db_data уже был инициализирован раньше (например, вы перезапускали стек с чистым SQL-файлом, но старым volume). В этом случае проще всего снести именно volume базы и поднять заново: docker compose down && docker volume rm <project>_guac_db_data && docker compose up -d. Это стандартная грабля — SQL-скрипты инициализации в docker-entrypoint-initdb.d выполняются ровно один раз, при первом создании тома.

Заходим на http://127.0.0.1:8080/guacamole/ (пока локально, через SSH-туннель ssh -L 8080:127.0.0.1:8080 user@server) с дефолтными учётными данными guacadmin / guacadmin — и сразу меняем пароль в разделе Settings → Users. Оставлять дефолтный пароль даже на пару минут не стоит: боты сканируют путь /guacamole/ целенаправленно.

Reverse proxy и TLS: WebSocket — не мелочь

Guacamole передаёт экран через WebSocket-соединение, и если прокси его не пробрасывает, интерфейс открывается, но при попытке подключения к серверу зависает на чёрном экране или сразу рвётся. Для nginx нужны явные заголовки апгрейда:

server {
    listen 443 ssl http2;
    server_name remote.example.com;

    ssl_certificate     /etc/letsencrypt/live/remote.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/remote.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080/guacamole/;
        proxy_buffering off;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_cookie_path /guacamole/ /;
    }
}

Директиву map $http_upgrade $connection_upgrade нужно объявить один раз в http {} блоке nginx.conf:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

Если вместо nginx у вас Traefik, добавьте лейблы на сервис guacamole вместо публикации порта — сравнение подходов и когда что выбрать разбирали в статье Traefik или Nginx Proxy Manager: что выбрать для сервера. TLS в любом случае обязателен: логин и пароль от Guacamole без HTTPS уходят в открытом виде, а через сам Guacamole фактически проходит управление вашей инфраструктурой.

Добавление RDP- и VNC-подключений

В интерфейсе: Settings → Connections → New Connection. Для RDP:

ПолеЗначениеКомментарий
ProtocolRDP
Hostnameвнутренний IP или домен целевой машиныдоступный именно с сервера guacd
Port3389стандартный порт RDP
Username / Passwordучётка Windowsможно оставить пустыми и вводить при каждом входе
Security modeNLAпочти всегда нужен для Windows 10/11 и Server 2019+
Ignore server certificateвключено (на старте)иначе самоподписанный сертификат RDP оборвёт подключение
Enable drive / Enable audioпо необходимостипроброс файлов и звука через браузер

Для VNC достаточно протокола, адреса, порта (обычно 5900+N) и пароля VNC-сервера. Для SSH — протокола, адреса, порта 22 и либо пароля, либо приватного ключа, который можно вставить прямо в поле Private key (формат PEM, без passphrase, если Guacamole используется для конечных пользователей — с passphrase, если только для админов, которые её знают).

Ключевой момент: guacd должен дотянуться до целевой машины по сети. Если RDP-сервер в другом дата-центре, откройте порт 3389 не всему интернету, а только с IP вашего Guacamole-сервера — правило iptables/security group с конкретным source IP вместо 0.0.0.0/0. Тогда единственная точка, откуда вообще можно достучаться до RDP, — сам шлюз, а он уже закрыт TLS и логином.

Права доступа и группы подключений

На проекте из десятка серверов плоский список подключений быстро превращается в кашу. Используйте:

  • Connection Groups — папки для подключений (например, «Продакшен», «Стейджинг», «Клиент А»);
  • User Groups — группы пользователей с наследуемыми правами;
  • разграничение READ / CHANGE PERMISSIONS / ADMINISTER на уровне отдельного подключения, а не только на уровне пользователя.

Практика, которая экономит нервы: заводите техническую учётку для каждого подрядчика или временного сотрудника, привязывайте её к конкретной Connection Group с доступом только к нужным серверам, и не выдавайте прав ADMINISTER никому, кроме себя. Отдельно посмотрите на встроенный History (Settings → History → Connection History) — там видно, кто, когда и на что заходил, это встроенный аудит без дополнительных инструментов.

Если нужна запись сессий целиком (не только лог факта подключения, а видеозапись экрана), в параметрах подключения включите Enable recording и укажите путь — в docker-compose выше под это уже выделен volume guacd_record. Файлы копятся в формате Guacamole (.guac), их можно проиграть встроенным плеером в интерфейсе или конвертировать в MP4 утилитой guacenc, которая идёт в комплекте с образом guacd.

Двухфакторная аутентификация

Guacamole поддерживает TOTP через официальное расширение guacamole-auth-totp — его нужно скачать отдельно (не входит в базовый образ) и подложить в /etc/guacamole/extensions/ через volume:

  guacamole:
    # ...
    volumes:
      - ./extensions:/etc/guacamole/extensions

Скачиваете .jar расширения с сайта проекта под вашу версию Guacamole, кладёте в ./extensions/, перезапускаете контейнер — при следующем логине пользователю предложат привязать TOTP-приложение (Google Authenticator, Aegis и подобные). Для доступа с чувствительными правами (ADMINISTER, доступ к продакшену) 2FA стоит делать обязательным — это отдельная настройка в самом расширении. Общие принципы двухфакторки для панелей управления, применимые и здесь, разобраны в статье Двухфакторная аутентификация для панелей управления.

Обновление образов (guacamole, guacd, база) и самого сервера тоже стоит держать по расписанию, а не «когда вспомню» — практики для регулярного продакшен-обслуживания Docker-стеков собраны в статье про docker-compose для продакшена: частые ошибки и решения.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Почему после логина сразу чёрный экран при подключении к RDP?

Чаще всего это Security mode. Поставьте NLA и включите «Ignore server certificate» — самоподписанный сертификат RDP без этой галки рвёт handshake молча, без внятной ошибки в интерфейсе.

Можно ли обойтись без отдельной базы данных?

Формально да — есть режим с XML-файлом конфигурации подключений (user-mapping.xml), но там нет ни истории, ни групп, ни веб-управления пользователями. Для чего-то серьёзнее одного-двух подключений это не вариант, MySQL/PostgreSQL в docker-compose поднимается за пару минут и того стоит.

Guacamole может работать без reverse proxy, напрямую на 8080?

Технически да, но тогда вы либо отдаёте трафик без TLS, либо городите TLS в самом Tomcat вручную — прокси с Let's Encrypt проще и стандартнее для продакшена.

Как ограничить количество параллельных сессий на одного пользователя?

В расширении guacamole-auth-jdbc (то, что уже используется для MySQL/PostgreSQL) есть параметр max active connections на уровне подключения и на уровне пользователя — задаётся в веб-интерфейсе при редактировании подключения, поле «Concurrent connection limit».

Нужна ли Guacamole своя лицензия?

Нет, это проект Apache Software Foundation, распространяется под Apache License 2.0, бесплатен для любого использования, включая коммерческое.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →