Разворачивание HAproxy и настройка единой точки входа для RDP на основе ACL
Данная статья в кратце рассказывает как реолизовать единую точку входа используя HAproxy и ACL для RDP серверов.
Все делалось на базе Ubuntu Server. И на других дистрибутивах Linux могут требовать дополнительные шаги по установки.
Данная страница служит напоминием автору, как это реализованно для быстрого разворачивание подобного на другом железе и отладке работы уже существующих вариантов.
Установка HAproxy
Для быстрой установки HAproxy переходим на этот сайт. И выбираем, какая у нас ОСь и какой версии HAproxy нас интересует.

Получаем готовый набор команд для установки.
Конфигурация HAproxy
После установки идем в конфиг HAproxy для настройки. Он находиться по пути /etc/haproxy/haproxy.cfg
Пример конфига для единой точки входа:
Замените #IPrds* на IP своего RDS
global log 127.0.0.1 local0 log 127.0.0.1 local1 notice maxconn 1000 user haproxy group haproxy daemon stats socket /tmp/haproxy.sock ssl-server-verify none defaults mode tcp option tcplog option tcp-smart-accept option tcp-smart-connect frontend ft_rdp mode tcp bind *:3389 name rdp #timeout client 1h persist rdp-cookie log global option tcplog tcp-request inspect-delay 2s tcp-request content accept if RDP_COOKIE acl remoteRDSH01_ACL req.rdp_cookie(mstshash),bytes(0,19) -m str -i -f /etc/haproxy/remoteRDSH01 acl remoteRDSH02_ACL req.rdp_cookie(mstshash),bytes(0,19) -m str -i -f /etc/haproxy/remoteRDSH02 acl remoteRDSH03_ACL req.rdp_cookie(mstshash),bytes(0,19) -m str -i -f /etc/haproxy/remoteRDSH03 acl remoteRDSH04_ACL req.rdp_cookie(mstshash),bytes(0,19) -m str -i -f /etc/haproxy/remoteRDSH04 acl remoteRDS01_ACL req.rdp_cookie(mstshash),bytes(0,19) -m str -i -f /etc/haproxy/remoteRDS01 acl remoteRDS02_ACL req.rdp_cookie(mstshash),bytes(0,19) -m str -i -f /etc/haproxy/remoteRDS02 acl remoteRDS03_ACL req.rdp_cookie(mstshash),bytes(0,19) -m str -i -f /etc/haproxy/remoteRDS03 acl remoteRDS04_ACL req.rdp_cookie(mstshash),bytes(0,19) -m str -i -f /etc/haproxy/remoteRDS04 acl remoteRDS05_ACL req.rdp_cookie(mstshash),bytes(0,19) -m str -i -f /etc/haproxy/remoteRDS05 acl remoteRDS06_ACL req.rdp_cookie(mstshash),bytes(0,19) -m str -i -f /etc/haproxy/remoteRDS06 use_backend remoteRDSH01_BK if remoteRDSH01_ACL use_backend remoteRDSH02_BK if remoteRDSH02_ACL use_backend remoteRDSH03_BK if remoteRDSH03_ACL use_backend remoteRDSH04_BK if remoteRDSH04_ACL use_backend remoteRDS01_BK if remoteRDS01_ACL use_backend remoteRDS02_BK if remoteRDS02_ACL use_backend remoteRDS03_BK if remoteRDS03_ACL use_backend remoteRDS04_BK if remoteRDS04_ACL use_backend remoteRDS05_BK if remoteRDS05_ACL use_backend remoteRDS06_BK if remoteRDS06_ACL default_backend DF_RDP backend remoteRDSH01_BK mode tcp balance leastconn log global stick-table type string len 32 size 10k expire 8h stick on req.rdp_cookie(mstshash),bytes(0,19) option tcplog tcp-check connect port 3389 default-server inter 3s rise 2 fall 3 server TS02 #IPrds1:3389 weight 10 check backend remoteRDSH02_BK mode tcp balance leastconn log global stick-table type string len 32 size 10k expire 8h stick on req.rdp_cookie(mstshash),bytes(0,19) option tcplog tcp-check connect port 3389 default-server inter 3s rise 2 fall 3 server TS03 #IPrds2:3389 weight 10 check backend remoteRDSH03_BK mode tcp balance leastconn log global stick-table type string len 32 size 10k expire 8h stick on req.rdp_cookie(mstshash),bytes(0,19) option tcplog tcp-check connect port 3389 default-server inter 3s rise 2 fall 3 server TS04 #IPrds3:3389 weight 10 check backend remoteRDSH04_BK mode tcp balance leastconn log global stick-table type string len 32 size 10k expire 8h stick on req.rdp_cookie(mstshash),bytes(0,19) option tcplog tcp-check connect port 3389 default-server inter 3s rise 2 fall 3 server TS05 #IPrds4:3389 weight 10 check backend remoteRDS01_BK mode tcp balance leastconn log global stick-table type string len 32 size 10k expire 8h stick on req.rdp_cookie(mstshash),bytes(0,19) option tcplog tcp-check connect port 3389 default-server inter 3s rise 2 fall 3 server TS06 #IPrds5:3389 weight 10 check backend remoteRDS02_BK mode tcp balance leastconn log global stick-table type string len 32 size 10k expire 8h stick on req.rdp_cookie(mstshash),bytes(0,19) option tcplog tcp-check connect port 3389 default-server inter 3s rise 2 fall 3 server TS07 #IPrds6:3389 weight 10 check backend remoteRDS03_BK mode tcp balance leastconn log global stick-table type string len 32 size 10k expire 8h stick on req.rdp_cookie(mstshash),bytes(0,19) option tcplog tcp-check connect port 3389 default-server inter 3s rise 2 fall 3 server TS08 #IPrds7:3389 weight 10 check backend remoteRDS04_BK mode tcp balance leastconn log global stick-table type string len 32 size 10k expire 8h stick on req.rdp_cookie(mstshash),bytes(0,19) option tcplog tcp-check connect port 3389 default-server inter 3s rise 2 fall 3 server TS09 #IPrds8:3389 weight 10 check backend remoteRDS05_BK mode tcp balance leastconn log global stick-table type string len 32 size 10k expire 8h stick on req.rdp_cookie(mstshash),bytes(0,19) option tcplog tcp-check connect port 3389 default-server inter 3s rise 2 fall 3 server TS10 #IPrds9:3389 weight 10 check backend remoteRDS06_BK mode tcp balance leastconn log global stick-table type string len 32 size 10k expire 8h stick on req.rdp_cookie(mstshash),bytes(0,19) option tcplog tcp-check connect port 3389 default-server inter 3s rise 2 fall 3 server TS11 #IPrds10:3389 weight 10 check backend DF_RDP mode tcp balance leastconn log global option tcplog stick-table type string len 32 size 10k expire 8h stick on rdp_cookie(mstshash),bytes(0,6) option tcp-check tcp-check connect port 3389 default-server inter 3s rise 2 fall 3 server TS01 #IPrds11:3389 weight 10 check listen stats bind *:9000 mode http stats enable #stats hide-version stats show-node stats realm Haproxy\ Statistics stats uri /
Теперь давайте объясню главные моменты, что написано в этом файле.
acl remoteRDSH##_ACL req.rdp_cookie(mstshash),bytes(0,19) -m str -i -f /etc/haproxy/remoteRDSHxx
Данная команда обозначает, что для для RDS## требуется RDP куки и смотрят первые 20 байтов и сравнивает их с файлом ACL
use_backend remoteRDSHxx_BK if remoteRDSHxx_ACL
Обозначает, что если RDP куки нашлась в ACL, то перенаправить на нужный RDS.
Создание ACL для HAproxy
Стоит учесть, что файлы ACL /etc/haproxy/remoteRDSHxx
ДОЛЖНЫ быть созданы ЗАРАНЕЕ. Иначе HAproxy откажется запускаться. Файлы могут быть полностью пустыми. Так что для простоты просто используйте команду:
touch remoteRDSHxx
В RDP куки НЕ передается имя пользователя ЕСЛИ ОНО НА РУССКОМ. Создаем пользователей ТОЛЬКО на Английском.
Редактировать ACL на горячую нельзя. Изменения вступят в силу лишь ПОСЛЕ перезапуска HAproxy.
Заполнение ACL и как это делать правильно. Стоит сразу определить, что используют пользователи:
- Windows с стандартным RDP-клиентом / Толстый клиент
- Linux и его зоопарк RDP-клиентов / Тонкий клиент
Windows
Если у нас ПК не в домене. И подключение происходит просто по имени пользователя то проблем у нас нет. Можем спокойно открывать файлы с ACL и пишем всех пользователей с новой строчки. Как тут:
admin 1060Admin 960Admin
Если же у нас ПК в домене. То стоит учесть, стандартный RDP клиент Windows брезгует и при подключение к HAproxy не передает ИМЯ пользователя, а первые 9 СИМВОЛОВ. Если же проварчивать такое на прямую то клиент будет передавать имя пользователя.
Есть два решения данной проблемы:
- Использовать АЛЬТЕРАНТИВНЫЙ клиент RDP под виндус (как пример mRemoteNG)
- Сделать костыль со стороны ACL. (Быстрое решение проблемы)
С первым вариантом как бы все понятно. А второй требует внимания. В ACL мы будем писать не просто имя пользователя, а по вот такой форме:
Имя_Пользователя@Домен
Но мы должны оставить ТОЛЬКО 9 символов. Это лишь быстрое решение проблемы, стоит рассмотреть вариант смены RDP клиента.
Linux
Если же у нас Linux машина и/или тонкий клиент, то мы можем спокойно писать имя пользователя, не важно в домене ли ПК или нет. Клиента под Linux передают столько символов сколько напишут и ТОЛЬКО имя пользователя даже если пользователь писал домен.
