Когда я перехожу с удаленного рабочего стола Windows на Linux, это всегда вызывает у меня некоторое потрясение. Дело в том, что протокол удаленного рабочего стола (RDP) является родным для Microsoft, а в Linux он выглядит скорее импровизированным. Удаленный доступ к моим Linux-машинам часто сопровождался сбоями сеансов, плохим масштабированием и задержками в работе. Кроме того, приходилось держать открытым SSH-сеанс только для того, чтобы перезапустить службу Xrdp, когда она неизбежно вылетала.
Я решил попробовать шлюз удаленного доступа с открытым исходным кодом Apache Guacamole, а точнее, автономную установку на новом сервере, где я мог бы добавлять свои существующие Linux-машины и получать к ним доступ. Я выбрал Guacamole, потому что он позволял мне управлять сессией RDP через браузер по HTTPS. Он также решил большинство моих проблем с производительностью и стабильностью RDP, с которыми все пользователи удаленного Linux сталкивались хотя бы несколько раз.
В моей домашней лаборатории довольно много компьютеров под управлением Linux. У всех них есть свои индивидуальные назначения, но удаленное управление ими всеми представляет значительный риск для безопасности, учитывая множество открытых портов служб удаленного доступа. Конечно, я мог бы просто поместить их за сетью Mesh VPN, такой как Tailscale, но это не решает проблему задержек в производительности и постоянных сбоев службы Xrdp. Кроме того, это не так интересно и увлекательно.
На самом деле я хотел получить централизованный доступ ко всем своим рабочим столам Linux и решить проблему задержек Xrdp в одном месте. Apache Guacamole позволяет мне сделать именно это. Он позволяет мне добавлять удаленные подключения и запускать их из вкладки браузера, а также в фоновом режиме регулирует размер окна и настройки производительности. И самое лучшее в Guacamole — это то, что больше не нужно открывать службы удаленного рабочего стола для интернета.
Моя новая конфигурация Guacamole выглядела так:
Браузер → HTTPS на порту 443 → Сервер Guacamole → частный RDP → машины Linux
Браузер — это единственный клиент, который мне нужен на любом ноутбуке или настольном компьютере. HTTPS на порту 443 — это правило перенаправления портов в моей сети, позволяющее получить доступ к шлюзу, при этом все остальные порты удаленного доступа закрыты.
Сервер Guacamole выступает в роли шлюза, храня профили подключений и предоставляя доступ к моим частным машинам под управлением Linux, на которых работает RDP (протокол удаленного рабочего стола).
Сначала я установил Apache Guacamole на новый сервер
Сам шлюз был прост, но настройка Docker оказалась сопряжена с одной серьезной сложностью

Guacamole устанавливается в виде небольшого стека из трех сервисов: веб-приложение Guacamole, guacd и PostgreSQL. Веб-приложение предоставляет интерфейс браузера, guacd обрабатывает все удаленные подключения, а база данных PostgreSQL — учетные данные пользователей и настройки подключения.
Я установил Guacamole на новой виртуальной машине и присвоил ей IP-адрес 192.168.100.10. Сам по себе шлюз Guacamole не требует больших ресурсов, но я остановился на следующих характеристиках сервера:
- Ubuntu 24.04 LTS
- 4 ГБ оперативной памяти
- 20 ГБ дискового пространства с 1,5 ГБ swap
- 2 виртуальных процессора
Далее следовала установка Docker, и именно здесь у меня возникли некоторые проблемы. Простые маршруты пакетов Ubuntu не предоставили мне нужный плагин compose, поэтому я вместо этого использовал официальный репозиторий Docker. После установки ca-certificates и curl я создал хранилище ключей и загрузил официальный ключ GPG-подписи Docker:
sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
Затем я добавил репозиторий Docker:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable"| \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Наконец, я установил следующие компоненты Docker:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
Используя команду:
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Моя идеальная конфигурация заключалась в том, чтобы Guacamole оставался частным на сервере, а Nginx обрабатывал публичный HTTPS:
Я не сильно отклонялся от файла Docker Compose по умолчанию. В основном я определил эти три контейнера:
- PostgreSQL, в котором хранятся пользователи Guacamole, учетные данные и настройки подключения.
- guacd, обрабатывающий подключения RDP, SSH и VNC для приложения.
- Guacamole, который предоставляет веб-интерфейс для браузерной части приложения.
Я также привязал Guacamole только к localhost:
127.0.0.1:8080:8080
Перед запуском я сгенерировал скрипт инициализации PostgreSQL:
docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgresql > initdb.sql
После этого я запустил стек Guacamole с помощью:
docker compose up -d
Автономный docker-compose (v1) устарел; теперь Docker рекомендует использовать интегрированный docker compose плагин (Compose V2).
Как только контейнеры запустились, я развернул Nginx в качестве обратного прокси перед Guacamole. Поскольку Guacamole прослушивал только локально на 127.0.0.1:8080, Nginx стал шлюзом для доступа к веб-приложению.
Затем я включил сайт Nginx и проверил, чтобы убедиться, что он работает:
sudo ln -s /etc/nginx/sites-available/guacamole /etc/nginx/sites-enabled/guacamole sudo nginx -t sudo systemctl reload nginx
Наконец, я сделал все легальным с помощью TLS-сертификата для HTTPS:
sudo certbot --nginx -d remote.ggcontentlabs.com
Это позволило сохранить порты Docker закрытыми и предоставило мне публичный URL для доступа к странице входа в Guacamole по адресу https://remote.ggcontentlabs.com/guacamole.
Далее мне нужно было внести некоторые изменения в мою домашнюю сеть
Установка Guacamole означает, что HTTPS становится доступным, но не все Linux-сервисы, расположенные за ним

Целью этого проекта было централизовать удаленный доступ и одновременно предотвратить доступ к моим Linux-компьютерам из Интернета. По сути, Guacamole стал входной дверью, а все остальное было скрыто за ней.
Публичная сторона моего сервера Apache Guacamole была достаточно проста. Nginx использовался в качестве обратного прокси и обрабатывал HTTPS на порту 443. Для создания бесплатного TLS-сертификата использовались Lets Encrypt и Certbot, а Guacamole находился за всем этим. К машинам под управлением Linux, расположенным за Guacamole, по-прежнему можно было получить доступ локально в моей локальной сети, но доступ к каждой машине был заблокирован путем закрытия портов удаленного доступа на моем маршрутизаторе.
Правила брандмауэра публичной части сервера Guacamole выглядели следующим образом:
| Открытый порт на Guacamole | Роль |
| 22 | SSH для доступа администратора |
| 80 | Lets Encrypt требует HTTP для проверки |
| 443 | Guacamole через HTTPS |
Мой сервер Guacamole работает в Docker, поэтому мне также нужно было добавить его локальную подсеть в правила брандмауэра. Сначала я проверил подсеть Docker:
docker network inspect guacamole_default | grep Subnet
Затем я разрешил доступ этой подсети через брандмауэр UFW:
sudo ufw allow from 172.18.0.0/16 to any port 3389 proto tcp
Для каждого из моих рабочих столов Linux я также добавил эти входящие правила, чтобы разрешить серверу Guacamole доступ к соответствующим удаленным службам:
sudo ufw allow from 192.168.100.10 to any port 22 proto tcp sudo ufw allow from 192.168.100.10 to any port 3389 proto tcp sudo ufw allow from 192.168.100.10 to any port 5900 proto tcp
Следующим и заключительным шагом было добавление машин Linux в Guacamole.
Добавление моих машин Linux позволило все собрать воедино
Настройки подключения — это то, где Guacamole начинает ощущаться как полноценный удаленный хаб

После того как я создал новые правила брандмауэра, добавление машин в Guacamole оказалось очень простым. Первым делом я сбросил пароль guacadmin по умолчанию и создал несколько новых подключений. В панели администратора я перешел в Настройки > Подключения > Новое подключение. Я присвоил каждому компьютеру удобное имя, ввел имя хоста/IP-адрес, выбрал нужный протокол и назначил набор учетных данных для доступа.




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