tty1 Posted February 17, 2023 · Report post Всем привет! Столкнулся с проблемой, прошу совета (к сожалению сам не являюсь сетевым инженером). Попросили меня товарищи реализовать схему проброса RDP из офиса через два VPS, один из которых выполняет роль OpenVPN сервера (к нему с одной стороны подключаются терминальные серверы из офисов, с другой - "внешний" VPS, на котором входящие соденения фильтруются по белому списку и NATятся внутри туннеля в офис). Все работает, но тормозит просто невероятно! OpenVPN поднят как udp tun, размер буфера выставлен побольше, но адекватно работать невозможно. Стал копаться: выяснилось, что интернет конкретно в этом офисе работает через Wireguard (весь трафик на роутере заворачивается в wg-туннель) - может еще это сказывается, что OpenVPN заворачивается дополнительно в Wireguard? В общем хочется понять, можно ли как то оптимизировать эту неповоротливую схему (думал может заменить OpenVPN на WG тоже - поможет?). И может ли WG на роутере в офисе быть причиной всех бед? К сожалению не знаю, что можно в плане диагностики сюда приложить, если подскажете алгоритм, как вычислить узкое место - был бы признателен. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
YuryD Posted February 17, 2023 · Report post Полную бы схему проброса рдп через что. А так обычно - весится на каждом хопе мелкий демонок проброса с ип-порт на соседний демонок со своей парой ип-порт Пробрасывайте только tcp Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
tty1 Posted February 17, 2023 · Report post Пробовал изначально соединить через 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, правда иногда нет нет, да пакет потеряется. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
jffulcrum Posted February 17, 2023 · Report post Так где на этой схеме Wireguard появляется? В целом рекомендую на VPS2 сделать не OpenVPN сервер, а HAProxy в TCP режиме Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
tty1 Posted February 17, 2023 · Report post Wireguard в самом начале, в офисе, где стоит терминальный сервер весь трафик заворачивается в WG туннель на роутере. То есть этот терминальный сервер соединяется с OpenVPN-сервером (vps1) через wireguard. За наводку с HAProxy благодарю! Попробую. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
rm_ Posted February 17, 2023 · Report post Quote выяснилось, что интернет конкретно в этом офисе работает через Wireguard (весь трафик на роутере заворачивается в wg-туннель) - может еще это сказывается, что OpenVPN заворачивается дополнительно в Wireguard? Именно это сказывается, WG откусывает часть от MTU на свои служебные расходы, если OpenVPN об этом не знает, и пытается слать полноразмерные пакеты в расчёте на стандартный MTU 1500, каждый из них будет разбиваться на тело и маленький хвост. Понизить MTU на OpenVPN-туннеле. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
jffulcrum Posted February 17, 2023 · Report post С высокой вероятностью у вас где-то фрагментация по MTU происходит или потеря пакетов Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
tty1 Posted February 17, 2023 · Report post На фрагментацию думал, но не помогло. Что сделал: пингом с 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 Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Ivan_83 Posted February 17, 2023 · Report post Нормально работать - вряд ли будет, туннели всегда добавляют знатно лагов для TCP соединений. В теории можно попробовать поставить на каждом вашем промежуточном сервере по nginx в режиме проксирования tcp (тогда потеряете инфу кто идёт), и накрутить TCP стёк в линухе, я бы попробовал cc bbr поставить, но hybla и htcp тоже должны хорошо работать. Так же можно даже попробовать такой прокси перед виндовым сервером поставить, в принципе линуксовые CC по лучше будут (те кто я перечислил, а не сраный cubic который дефолтом везде). Смысл тут вот в чём. В случае туннеля у вас растёт rtt и любая потеря/ретрансмит занимают кучу времени. Ставя прокси посредине вы сокращаете rtt и время необходимое на ретрансмит пакета. Ещё у RDP есть всякие гейтвеи, вроде как специально чтобы из инета ходить, я попробовал как то более напрямую ходить, не через туннели. Можно же рядом с туннелями гонять и tcp трафик rdp. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
tty1 Posted February 18, 2023 (edited) · Report post Иван, огромное спасибо!! 🙂 Что сделал: на 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 February 18, 2023 by tty1 Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Ivan_83 Posted February 18, 2023 · Report post 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? Да, смотрите опции конфига. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
tty1 Posted February 19, 2023 (edited) · Report post В общем nginx победить не удалось, но пока искал решение не раз наткнулся на мнение, что nginx это в первую очередь для веб и не надо им проксировать всё подряд 🙂 Реализовал на haproxy - не вылетает при неактивности пользователя. Правда (чисто субъективно) показалось, что чуть медленнее стало через него. Возможно кажется, пусть люди попробуют поработать. UPD: всё равно вылетает. В качестве эскперимента подключился напрямую к vps1 - все ок! То есть содинение рвется на участке vps2 -> vps1 (там где NAT). Объединил vps2->vps1 так же через haproxy - вылетов нет. Но вообще так можно, RDP через два прокси? 🙂 Edited February 19, 2023 by tty1 Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Ivan_83 Posted February 19, 2023 · Report post Можно, чем на больше кусков порежете проксями - тем выше пропускная способность будет на потерях, но инпут лаг может возрасти. Попробуйте keep-alive принудительно в линухе включить для всех tcp соединений, если не можете это сделать средствами nginx/ha - вероятно без трафика NAT считает что соединение умерло и прибивает его. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
jffulcrum Posted February 19, 2023 · Report post keep-alive надо в настройках сервера RDP включить, в групповых политиках: Windows Components - RDS-RDS Host-Connections-Configure keep-alive connection interval Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
tty1 Posted February 20, 2023 (edited) · Report post Quote вероятно без трафика NAT считает что соединение умерло и прибивает его Пришел к аналогичному выводу, но не понял, как для NAT включить keep-alive в netfilter На стороне RDP включал, правда не через групповые политики, а в реестр (добавление параметра KeepAliveEnable=1), не помогло.* В общем где то час люди работают, гневных звонков нет, пока возьму паузу 🙂 А если есть возможность продолжить беседу, очень интересует теоретический аспект - почему TCP трафик внутри UDP туннеля плохо ходит? Ведь сам по себе UDP быстрее - шлет и шлет пакеты, не ждет никаких подтверждений... _______ UPD: * - я же сервер после этого не перезагрузил!!! Побоялся, что после ребута не попаду по каким то другим причинам :))) Семен Семеныч..... Edited February 20, 2023 by tty1 Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...