Jump to content
Калькуляторы

Хитрая схема проброса RDP и жуткие тормоза - возможно ли ускорить?

Всем привет!

Столкнулся с проблемой, прошу совета (к сожалению сам не являюсь сетевым инженером).

Попросили меня товарищи реализовать схему проброса RDP из офиса через два VPS, один из которых выполняет роль OpenVPN сервера (к нему с одной стороны подключаются терминальные серверы из офисов, с другой - "внешний" VPS, на котором входящие соденения фильтруются по белому списку и NATятся внутри туннеля в офис).

Все работает, но тормозит просто невероятно! OpenVPN поднят как udp tun, размер буфера выставлен побольше, но адекватно работать невозможно.

Стал копаться: выяснилось, что интернет конкретно в этом офисе работает через Wireguard (весь трафик на роутере заворачивается в wg-туннель) - может еще это сказывается, что OpenVPN заворачивается дополнительно в Wireguard?

В общем хочется понять, можно ли как то оптимизировать эту неповоротливую схему (думал может заменить OpenVPN на WG тоже - поможет?). И может ли WG на роутере в офисе быть причиной всех бед?

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

Share this post


Link to post
Share on other sites

 Полную бы схему проброса рдп через что. А так обычно - весится на каждом хопе мелкий демонок проброса с ип-порт на соседний демонок со своей парой ип-порт Пробрасывайте только tcp

Share this post


Link to post
Share on other sites

Пробовал изначально соединить через stunnel4 - клиент RDP выдал очень информативную ошибку (в духе Майкрософт): "Произошла внутренняя ошибка" :)) (хотя ранее был опыт проброса веб-версии 1С через stunnel, все работало как часы, с RDP что то не пошло).

Схему сейчас попробую, заранее прошу меня извинить, не мастер!)

Терминальный сервер и внешний vps2 подключаются через OpenVPN к связующему их vps1 (10.3.1.1) и получают соответственно адреса 10.3.1.100 и 10.3.1.10 (постоянные, прописаны в ccd).

На vps2 стучится клиент по порту 54181, его IP адрес проверяется по белому списку и перекидывается через tun0 на терминальный сервер.

Включен форвард:

iptables -A FORWARD -i tun0 -o eth0 -j ACCEPT


собственно проброс:

iptables -t nat -A PREROUTING -p tcp -d <extIP2> --dport 54181 -j DNAT --to-destination 10.3.1.100:3389

 

маскарад:

iptables -t NAT -A POSTROUTING -o tun0 -j MASQUERADE

 

И в общем то оно работает, но отрисовка жутко тормозит.

Измерил пинг между "внешним" vps2 и терминальным сервером - 170-180, правда иногда нет нет, да пакет потеряется.

scheme.png

Share this post


Link to post
Share on other sites

Wireguard в самом начале, в офисе, где стоит терминальный сервер весь трафик заворачивается в WG туннель на роутере. То есть этот терминальный сервер соединяется с OpenVPN-сервером (vps1) через wireguard.

За наводку с HAProxy благодарю! Попробую.

Share this post


Link to post
Share on other sites

Quote

выяснилось, что интернет конкретно в этом офисе работает через Wireguard (весь трафик на роутере заворачивается в wg-туннель) - может еще это сказывается, что OpenVPN заворачивается дополнительно в Wireguard?

Именно это сказывается, WG откусывает часть от MTU на свои служебные расходы, если OpenVPN об этом не знает, и пытается слать полноразмерные пакеты в расчёте на стандартный MTU 1500, каждый из них будет разбиваться на тело и маленький хвост. Понизить MTU на OpenVPN-туннеле.

Share this post


Link to post
Share on other sites

На фрагментацию думал, но не помогло.

Что сделал: пингом с OpenVPN сервера определил размер MTU, он оказался 1420.

Добавил в конфиг сервера и обоих клиентов

tun-mtu 1420
mssfix 1360

Все равно жутко картинка виснет.

Может что то еще упускаю в конфигах Ovpn? Под спойлером конфиги (директивы с указанием ключей вырезал)

Spoiler

server.conf (VPS1)

---------------
port 443
proto udp
dev tun

cipher AES-128-GCM
server 10.3.1.0 255.255.255.0
topology subnet
client-config-dir /etc/openvpn/ccd
keepalive 10 120
max-clients 6

tun-mtu 1420
mssfix 1360

sndbuf 524288
rcvbuf 524288
push "sndbuf 524288"
push "rcvbuf 524288"

persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
mute 20
daemon
mode server
tls-server

 

 

vps2.conf (сервер, принимающий снаружи подключения клиентов)

-------------

client
dev tun

proto udp

remote <IP_VPS1> 443

nobind

persist-key
persist-tun

keepalive 10 120
auth-nocache

script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf

tun-mtu 1420
mssfix 1360
verb 4

 

 

RDP.conf (терминальный сервер в офисе)

-------------

client
dev tun
proto udp
remote <IP_VPS1> 443
nobind
auth-nocache

persist-key

persist-tun
keepalive 10 120

tun-mtu 1420
mssfix 1360
verb 3

 

 

Share this post


Link to post
Share on other sites

Нормально работать - вряд ли будет, туннели всегда добавляют знатно лагов для TCP соединений.

 

В теории можно попробовать поставить на каждом вашем промежуточном сервере по nginx в режиме проксирования tcp (тогда потеряете инфу кто идёт), и накрутить TCP стёк в линухе, я бы попробовал cc bbr поставить, но hybla и htcp тоже должны хорошо работать.

Так же можно даже попробовать такой прокси перед виндовым сервером поставить, в принципе линуксовые CC по лучше будут (те кто я перечислил, а не сраный cubic который дефолтом везде).

 

Смысл тут вот в чём.

В случае туннеля у вас растёт rtt и любая потеря/ретрансмит занимают кучу времени.

Ставя прокси посредине вы сокращаете rtt и время необходимое на ретрансмит пакета.

 

Ещё у RDP есть всякие гейтвеи, вроде как специально чтобы из инета ходить, я попробовал как то более напрямую ходить, не через туннели.

Можно же рядом с туннелями гонять и tcp трафик rdp.

Share this post


Link to post
Share on other sites

Иван, огромное спасибо!! 🙂

Что сделал: на vps1 (который OpenVPN сервер) поставил nginx, принимаю соединения на внешний интерфейс (с IP адреса <vps2> - в белом списке), проксирую на RDP внутри туннеля (да, остался последний прыжок через udp openvpn) - но уже стало существенно лучше!! Да, есть небольшие лаги, но работать думаю возможно в принципе. Последний участок связать через TCP пока не соображу как (ибо в офисе же вся внешка завернута в wireguard). Стоит keenetic, возможно ли пробросить порт в такой ситуации не представляю, не приходилось сталкиваться. А удаленно играться с файрволлом - к дороге (согласно старой админской примете) 🙂 Поэтому оставлю до понедельника.

Уточнить еще хочу, насколько такая схема безопасна (в плане перехвата трафика между vps2 и vps1, мало ли какой злоумышленник может оказаться посередине?). И правильно ли я реализовал белый список на "внешнем" vps2 сервере - на каждый разрешенный IP в PREROUTING создал отдельное правило, где в --source прописал IP (глубоко с netfilter не знаком, а хочется грамотно все сделать).

 

UPD: похоже рано радовался. Отваливается по таймауту соединение (когда окно не активно, причем через довольно короткое время):

[13:54:29:323] [5714:5715] [ERROR][com.freerdp.core.transport] - BIO_read returned a system error 110: Connection timed out
[13:54:29:323] [5714:5715] [ERROR][com.freerdp.core] - transport_read_layer:freerdp_set_last_error_ex ERRCONNECT_CONNECT_TRANSPORT_FAILED [0x0002000D]
[13:54:29:323] [5714:5715] [INFO][com.freerdp.client.common] - Network disconnect!

 

Подозреваю нужно смотреть в сторону каких то таймаутов в nginx?

Edited by tty1

Share this post


Link to post
Share on other sites

11 hours ago, tty1 said:

Уточнить еще хочу, насколько такая схема безопасна (в плане перехвата трафика между vps2 и vps1, мало ли какой злоумышленник может оказаться посередине?).

Там TLS внутри, и NLA.

В инете есть подробности про безопасность RDP.

 

11 hours ago, tty1 said:

И правильно ли я реализовал белый список на "внешнем" vps2 сервере - на каждый разрешенный IP в PREROUTING создал отдельное правило, где в --source прописал IP (глубоко с netfilter не знаком, а хочется грамотно все сделать).

Хз, я не юзаю линух, не считая андройда и опенврт.

 

11 hours ago, tty1 said:

Подозреваю нужно смотреть в сторону каких то таймаутов в nginx?

Да, смотрите опции конфига.

Share this post


Link to post
Share on other sites

В общем nginx победить не удалось, но пока искал решение не раз наткнулся на мнение, что nginx это в первую очередь для веб и не надо им проксировать всё подряд 🙂

Реализовал на haproxy - не вылетает при неактивности пользователя. Правда (чисто субъективно) показалось, что чуть медленнее стало через него. Возможно кажется, пусть люди попробуют поработать.

 

UPD: всё равно вылетает. В качестве эскперимента подключился напрямую к vps1 - все ок! То есть содинение рвется на участке vps2 -> vps1 (там где NAT).

Объединил vps2->vps1 так же через haproxy - вылетов нет. Но вообще так можно, RDP через два прокси? 🙂

Edited by tty1

Share this post


Link to post
Share on other sites

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

Попробуйте keep-alive принудительно в линухе включить для всех tcp соединений, если не можете это сделать средствами nginx/ha - вероятно без трафика NAT считает что соединение умерло и прибивает его.

Share this post


Link to post
Share on other sites

Quote

вероятно без трафика NAT считает что соединение умерло и прибивает его

Пришел к аналогичному выводу, но не понял, как для NAT включить keep-alive в netfilter

 

На стороне RDP включал, правда не через групповые политики, а в реестр (добавление параметра KeepAliveEnable=1), не помогло.*

 

В общем где то час люди работают, гневных звонков нет, пока возьму паузу 🙂

А если есть возможность продолжить беседу, очень интересует теоретический аспект - почему TCP трафик внутри UDP туннеля плохо ходит? Ведь сам по себе UDP быстрее - шлет и шлет пакеты, не ждет никаких подтверждений...

 

_______

UPD: * - я же сервер после этого не перезагрузил!!! Побоялся, что после ребута не попаду по каким то другим причинам :))) Семен Семеныч.....

Edited by tty1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.