Доступ подрядчиков: изолированный шлюз с записью сессий на Apache Guacamole

Подрядчику нужно настроить один сервер. Самый быстрый способ дать доступ — выдать ему VPN: теперь на его ноутбуке, о защищённости которого вы ничего не знаете, живёт туннель в вашу внутреннюю сеть. Если ноутбук заражён, злоумышленник получает те же права. Альтернатива — изолированный шлюз: подрядчик подключается к одной точке в отдельной сети, видит только свои цели и работает через браузер; его сессия записывается, а доступ закрывается по сроку. Ниже схема, установка шлюза на Apache Guacamole, настройка второго фактора, записи сессий, ограничение срока и порядок работы.
Условия предоставления удалённого доступа в целом: регламент удалённого доступа. Контроль привилегированных пользователей внутри компании (команды администраторов, временные права): PAM для небольшой компании. Договор с подрядчиком: оценка рисков подрядчиков.
Схема доступа
Подрядчик подключается по HTTPS к шлюзу, входит с вторым фактором и выбирает из списка свои подключения. Шлюз сам открывает сессию к целевой системе по протоколам RDP или SSH, и подрядчик получает экран, но не сетевой доступ: он не может обратиться к соседним серверам. Всё, что он делает, записывается.
| Свойство | VPN подрядчику | Изолированный шлюз |
|---|---|---|
| Что получает подрядчик | Сетевой доступ к подсетям | Экран конкретной системы |
| Видимость действий | Только сетевые журналы | Запись сессии, видно что именно он делал |
| Риск заражённого ноутбука | Заражение идёт в сеть | Ограничено экраном: копирование отключается |
| Отзыв | Нужно снять ключ и проверить маршруты | Отключить учётную запись |
Шаг 1. Где поставить шлюз
Шлюз — самая выставленная наружу машина, поэтому размещать его нужно как отдельную зону (DMZ или отдельный VLAN): снаружи доступен только порт 443, внутрь шлюз пускают только на согласованные цели. Правила экрана для шлюза (адрес шлюза 192.0.2.70, цели в 198.51.100.0/24):
table inet gateway {
chain forward {
type filter hook forward priority 0; policy drop;
ct state established,related accept
# снаружи только HTTPS на шлюз
iifname "wan0" ip daddr 192.0.2.70 tcp dport 443 accept
# шлюз в цели подрядчика: только нужные адреса и порты
ip saddr 192.0.2.70 ip daddr 198.51.100.20 tcp dport { 22, 3389 } accept comment "srv-app-02 для подрядчика ООО Пример"
log prefix "gw-drop: " limit rate 5/minute drop
}
}
Ожидаемо: шлюз подключается только к перечисленным целям, остальные внутренние адреса недоступны с него. Подробнее об экране: nftables и firewalld.
Шаг 2. Установка Guacamole в Docker
Apache Guacamole — открытый шлюз удалённых рабочих столов с веб-интерфейсом. Состоит из службы guacd (подключается к целям), веб-приложения и базы данных пользователей. Каркас docker-compose.yml (версии образов подставьте актуальные, секреты берите из переменных окружения):
services:
guacd:
image: guacamole/guacd:1.5.5
restart: unless-stopped
volumes:
- ./record:/record
postgres:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_DB: guacamole_db
POSTGRES_USER: guacamole_user
POSTGRES_PASSWORD: ${GUAC_DB_PASSWORD}
volumes:
- ./pgdata:/var/lib/postgresql/data
- ./initdb.sql:/docker-entrypoint-initdb.d/initdb.sql:ro
guacamole:
image: guacamole/guacamole:1.5.5
restart: unless-stopped
depends_on: [guacd, postgres]
environment:
GUACD_HOSTNAME: guacd
POSTGRESQL_HOSTNAME: postgres
POSTGRESQL_DATABASE: guacamole_db
POSTGRESQL_USER: guacamole_user
POSTGRESQL_PASSWORD: ${GUAC_DB_PASSWORD}
EXTENSIONS: auth-totp
volumes:
- ./record:/record
ports:
- "127.0.0.1:8080:8080"
docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgresql > initdb.sql
read -rs -p "Пароль базы: " GUAC_DB_PASSWORD; export GUAC_DB_PASSWORD
docker compose up -d
docker compose ps
Ожидаемо: три контейнера в состоянии running, веб-интерфейс слушает только 127.0.0.1:8080. Наружу выставляйте не его, а обратный прокси (nginx) с TLS-сертификатом на порту 443. Сразу после входа учётной записью по умолчанию (guacadmin) смените пароль и создайте отдельную именную учётную запись администратора; запись по умолчанию отключите. Пароль базы сохраните в сейфе паролей, а не в истории оболочки.
Шаг 3. Второй фактор
Расширение auth-totp, включённое переменной EXTENSIONS выше, просит каждого пользователя при первом входе зарегистрировать приложение для кодов. После этого вход требует пароль и одноразовый код. Для подрядчика это обязательно: без него шлюз остаётся единственной защитой на публичном адресе только пароля.
Шаг 4. Подключения, запись и права
В интерфейсе администратора (Настройки → Соединения) для каждой цели создайте подключение: протокол (RDP или SSH), адрес, порт, учётная запись на цели. Ключевые параметры:
| Параметр | Значение | Зачем |
|---|---|---|
Путь записи (recording-path) |
/record |
Запись сессии сохраняется в каталог, который смонтирован в контейнер |
| Создавать каталог записей | Включить | Для каждой сессии своя запись |
| Копирование и вставка, передача файлов | Отключить, если не нужны | Не позволяет вынести данные на ноутбук подрядчика |
| Только чтение | Для аудитов и обзора | Подрядчик смотрит, но не меняет |
Затем создайте группу пользователей (например, «ООО Пример») и разрешите ей только подключения по этому договору. Для каждого подрядчика отдельная именная учётная запись, не общая на фирму. Записи можно посмотреть в Настройки → История: сессия воспроизводится как видео, а текстовая запись SSH-сессии доступна как вывод терминала. Хранение записей определите заранее (например, 6 месяцев) и очищайте автоматически: они занимают место и содержат всё, что было на экране, включая пароли, которые подрядчик вводил или видел.
Шаг 5. Ограничение срока
В карточке пользователя (Ограничения учётной записи) задайте период действия («Действует с», «Истекает») и, при необходимости, часы работы. После окончания срока вход невозможен. Дата ставится при создании учётной записи и берётся из заявки на доступ. Раз в неделю сверяйте список учётных записей с согласованными заявками, как в регламенте.
Журнал подключений
Guacamole хранит историю подключений в базе. Выборка для отчёта и проверок:
docker compose exec postgres psql -U guacamole_user -d guacamole_db -c \
"SELECT username, remote_host, connection_name, start_date, end_date
FROM guacamole_connection_history ORDER BY start_date DESC LIMIT 20;"
Ожидаемо: список с именем пользователя, адресом, названием подключения и временем сессии. Отправляйте события в SIEM и настройте оповещение на вход вне часов, неудачные попытки и подключение к целям вне списка: журналы сетевых средств в Wazuh, аномалии доступа. Работа с записями касается персональных данных подрядчика: уведомите его о записи сессий в договоре или правилах доступа.
Порядок выдачи и закрытия
- Договор содержит обязательства по информационной безопасности и право компании записывать сессии.
- Заявка на доступ: кто, к каким системам, на какой срок, зачем. Согласуют владелец договора и ИБ.
- Создаются именная учётная запись с ограничением по сроку и подключения только к согласованным целям. Подрядчик получает ссылку и регистрирует второй фактор.
- Во время работ ответственный сотрудник знает, что подрядчик подключён, и может увидеть сессию.
- По окончании работ или срока доступ закрывается; в карточке заявки фиксируется дата закрытия и ссылка на записи.
Какие артефакты хранить
| Что хранить | Что показывает |
|---|---|
| Документация шлюза: схема, правила экрана, порядок выдачи | Изолированный шлюз описан и ограничен |
| Журнал подключений через шлюз за последние месяцы | Доступ подрядчиков идёт через шлюз и контролируется |
| Записи сессий (выборочно) и политика их хранения | Расширенный мониторинг работает |
| Заявки и записи о закрытии доступа подрядчиков | Доступ ограничен по сроку |
Диагностика
| Симптом | Причина и что делать |
|---|---|
| Подрядчик подключается, но экран чёрный | Не открыт порт от шлюза до цели или не совпадают параметры безопасности RDP. Проверьте правило экрана и журнал guacd |
| Записей сессий нет | Не смонтирован каталог в оба контейнера или нет прав. Проверьте recording-path и владельца каталога |
| Подрядчик просит прямой SSH «так проще» | Исключение вернёт всё к VPN. Объясните причину и предложите работу через SSH-подключение шлюза |
| Диск заполняется записями | Нет очистки. Настройте удаление старше установленного срока |
| Шлюз стал единой точкой отказа | Заведите резервный способ входа для аварий (консоль хостера), но не открывайте внутренние порты наружу |
Где это в модели зрелости
Материал относится к направлению «Управление доступом» (хаб: управление доступом, карта: карта зрелости). На третьем уровне реализован изолированный шлюз с расширенными политиками безопасности и мониторинга для доступа подрядчиков и третьих сторон к ИТ-инфраструктуре. Журналы подключений и описание работы шлюза — подтверждения.
Как проверить
- С тестовой учётной записью подрядчика открывается только список согласованных подключений.
- Прямой доступ с шлюза к несогласованному серверу блокируется экраном (запись
gw-drop). - Сессия записана и воспроизводится; запись содержит все действия.
- После даты окончания учётная запись не входит.
- Второй фактор требуется при каждом входе.
Источники
- Apache Guacamole, руководство: guacamole.apache.org/doc/gug.
- Установка Guacamole в Docker: guacamole.apache.org.
- NIST SP 800-53 Rev. 5, управление доступом (AC) и аудит (AU): csrc.nist.gov.


















