Хабрахабр

Туннели и VPN, устойчивые к DPI

Мы живем в интересное время. Я бы даже сказал, в удивительное. Кто-то из журналистов недавно назвал происходящее «цифровой гражданской войной». По одну сторону баррикад мы видим государство в лице госструктур, которое очень хочет знать, о чем между собой разговаривают его граждане, и очень хочет указывать им, что можно читать, а что нельзя, и в целях реализации своих желаний принимает различные законы и акты под надуманными предлогами. С другой стороны баррикад рядовые граждане, которые хотят отстоять свои права тайны личной переписки и свободного получения информации, и не хотят, чтобы факты этой самой переписки и получения этой самой информации были использованы против них. Бонусом проблемы огребает различный бизнес и IT-отрасль в целом.

Но нет, эта статья не о политике, а о технологиях.

Если раньше слова «VPN» и «прокси» были знакомы только IT-специалистам, то теперь даже домохозяйки их знают, и более того — используют то, что эти слова означают. image
Техническая грамотность людей, благодаря всему происходящему, тоже растет.

Новости приходят весьма занятные. Должностные лица, правда, тоже не дремлют. А не так давно РКН начал применять анализ пакетов для блокировки протокола MTProxy. Например, предоставление услуг VPN и аналогичных для шифрования трафика и обхода блокировок ныне наказуемо, а в Китае так за это вообще сажают в тюрьму. В Венесуэле, например, вполне конкретно блокируют прямые подключения к Tor и обфусцированный трафик к мостам. Можно также обратиться к опыту наших стран-собратьев, которые наиболее преуспели в таких делах: Китая, Ирана, Казахстана, Венесуэлы. Исходя из всего этого, можно предположить, что будущее ждет нас тоже очень интересное, особенно, если РКН перестанет устраивать тупые факапы раз за разом, а будет действовать умнее и изощреннее.

Анализируя озвученные мысли и посмотрев на свидетельства из других стран, я попробовал предположить, в какую сторону могут дальше двинуться меры по ограничению связи. На Хабре неоднократно в комментариях озвучивали прогнозы как дальше государство может бороться с технологиями шифрования для обычных граждан. DistortNeo и shifttstas подкинули еще несколько интересных идей, и в итоге я пообещал el777 все-таки дописать эту статью.

Они действуют уже сейчас, и с ними с переменным успехом получается и не получается бороться (хотя существуют вполне себе пессимистические прогнозы). С фильтрами по ACL всё в целом ясно. С DPI все интереснее.

Способы «определения» типа трафика у DPI можно разбить на две группы:

  • Сигнатурный анализ. А именно, разбирание пакета «по косточкам», сопоставляя заголовки и структуру с образцами, и таким образом определение его предназначения. Таким образом детектируются многие туннели, например OpenVPN, L2TP/IPSec, SOCKS, и др.
  • Предварительный анализ паттернов обмена трафиком, например, соотношения входящего/исходящего потока, периодичность запросов-ответов и другие критерии позволят отделить «настоящий трафик» какого-то протокола и туннель, лишь маскирующийся под него.

image

Можно разбить трафик на несколько групп и предположить, что будут делать с каждой из них.

  1. «Явные» VPN, туннели и прокси (OpenVPN, L2TP/IPSec, SOCKS, и др.) Вполне могут блокироваться автоматически, как, например, это происходит в Китае и Венесуэле. Если каким-то организациям или компаниям оно нужно для работы — пусть регистрируются и сертифицируются, о чем вполне конкретно говорит российский закон, упомянутый выше.
  2. Технологии «двойного назначения», например, SSH. Через небольшое время после установления сессии, скорость режется до черепашьей, так, что в консоли работать еще хоть как-то можно, а вот серфить и качать что-либо уже нет. То, что это создает проблемы при обычной работе, никого не волнует (что не раз нам демонстрировал РКН за недавнее время).
  3. Узкоспецифические протоколы, типа месседжеров, игровых клиентов, и т.д.
  4. Соединения, тип которых определить не удается.

Для пунктов 3 и 4 вполне возможны «белые списки» (в которые, например, заносятся подсети официальных игровых серверов или «правильных» месседжеров, и всего того, что владельцы серверов пожелают задекларировать и оформить как надо, чтобы их не трогали, по аналогии с теми, что уже сейчас есть у РКН для доменов и IP-адресов). А тех, кого в этих списках нет, ждет та же участь, что и п.1 или п.2, правда вполне возможна не тупая блокировка или обрезание скорости, а предварительно упомянутый выше анализ паттернов обмена в целях определения, является ли трафик «чистым» или «подозрительным».

Пока что подобных разработок мне на глаза не попадалось. То есть, при желании маскироваться под специальные протоколы, или же обфусцировать соединения, чтобы было невозможно определить их тип, придется так же позаботиться о создании «шума», препятствующего выявлению реально паттернов обмена.

Про разные ICMP и DNS туннели можно даже не вспоминать — большой объем трафика «куда не надо» по ним тоже автоматически вызывает подозрения.

TLS и SSL, HTTPS. 5. Анализ паттернов не имеет смысла, поскольку веб-серфинг — как раз-таки и есть основное предназначение использование HTTPS. Резать подчистую невозможно, поскольку это автоматически означает блокировку всего Интернета. Следовательно, давайте и попробуем замаскироваться под него. Из всего вышеперечисленного, SSL/TLS на 443 порту выглядит самым «не подозрительным» и надежным вариантом.

image

Маскируемся

Для рассмотрения было решено выбрать решения Streisand и SoftEther.

Все это ставится в автоматическом или полуавтоматическом режиме «под ключ», и на выходе пользователь получает сконфигурированный сервер, а также файлы и подробную документацию по настройке клиентов. Streisand — целый набор различных сервисов: OpenConnect/AnyConnect, OpenVPN, stunnel, Shadowsocks, WireGuard.

SoftEther — VPN-сервер, который может поднимать L2TP/IPsec, OpenVPN, SSTP, и другие протоколы, а также имеет свой собственный протокол «SSL-VPN», который, по заявлениям авторов, неотличим от обычного HTTPS-трафика.

Итак…

При установлении соединения видны не только пакеты TLS (TCP), но и DTLS (UDP). OpenConnect/AnyConnect. Опенсорсная реализация протокола AnyConnect SSL от Cisco. DTLS в принципе тоже много где используется «в мирных целях», но это уже совсем не похоже на «обычный HTTPS».

Шифрованный SOCKS-прокси. Shadowsocks. Судя по всему, при желании может быть детектирован, однако существуют плагины, маскирующие его под «чистый HTTPS».

Судя по описанию, имеет хорошо закрученное шифрование и механизм установки сессии, но весь обмен происходит по UDP. WireGuard. Wireshark определяет тип пакетов как нечто совсем невнятное, а какое мнение обо всем происходящем сложится у стороннего DPI — очень и очень большой вопрос.

Обфуцируют пакеты так, что со стороны они выглядят абсолютно случайным набором значений. obfs3, obfs4. 4 из списка выше. То есть попадают под п.

Выглядит как HTTPS, но с одним подвохом. SoftEther. Как удалось выяснить в документации, UDP может использоваться для ускорения передачи данных в том случае, когда он не зарезан на фаерволе. Кроме непосредственно TLS over TCP активно шлет пачками UDP-пакеты. Данный функционал отключается в конфигурации, и после его отключения все становится как надо.

VPN-прокотол от компании Microsoft. SSTP. Со стороны выглядит как HTTPS, и Wireshark это вполне подтверждает. Нативно поддерживается в Windows, вспомогательным софтом в GNU/Linux.

Но это еще не все

Предположим, вы установили на хост VPN-сервер или конец туннеля и сконфигурировали, чтобы он слушал 443 порт. Казалось бы, все прекрасно, но есть одно НО: если мы маскируемся под HTTPS, проверить, что по факту висит на 443 порту можно просто попробовав уткнуться в этот порт простым браузером или CURL'ом, или еще каким угодно способом. В некоторых статьях подобный метод называется «опережающим подключением», и, как упоминается, уже вполне используется в Китае.

И вот тут встает интересная проблема. Следовательно, нам необходимо чтобы по 443 порту у нас отвечал самый обычный и порядочный веб-сервер.

Вариант с SSLH не подходит, хотя бы потому, что sslh не способен разделить трафик между HTTPS и вышеуказанными сервисами. Ни у одного из вышеперечисленных сервисов в основной документации не нашлось описания рабочего механизма port sharing'а. Как минимум, потому что если тип трафика без полной расшифровки смог отличить sslh — то сможет и DPI.

Проблема в том, что указанное при использовании SNI имя хоста передается plain text'ом, то есть в незашифрованном виде, и, следовательно, тоже может быть подсмотрено и использовано в дальнейшем. Большинство манов, наподобие этого, предлагают использовать Server Name Indication (SNI) — расширение TLS, позволяющее указывать имя хоста, и потом с помощью HAProxy, sniproxy и других тулов раскидывать подключения по сервисам.

Поэтому, будем импровизировать, и тут мне на ум пришли два варианта.

Port knocking

image

В классическом варианте (см. Port knocking как раз предназначен для активации «скрытых сервисов» на сервере. например реализацию демона knockd) под нокингом обычно понимают попытки установки соединения или посылку пакетов на определенные порты хоста в определенной последовательности, в результате чего демон вас «опознает» как своего, и активирует правило фаерволла, открывающее доступ на определенный порт только с вашего IP.

Во-первых, сами «нестандартные» порты могут быть заблокированы где-то по пути, а во-вторых, сама процедура при анализе со стороны может выглядеть подозрительно. В нашем же случае, этот вариант не совсем приемлем. Раз уж мы маскируемся под HTTPS, то и «стучаться» нужно по HTTPS.

Как ни удивительно, но HTTP/HTTPS нокеров с требуемой функциональностью я не нашел, и поэтому на свет родился нокер с романтичным названием Labean (гусары, молчать!), который я набросал за пару обеденных перерывов в кафешке неподалеку от офиса.

Дано: наш сервер, на котором на 443 порту крутится Nginx c корректно настроенными сертификатами и выдает какой-нибудь вполне безобидный контент, например, GIF'ки с котиками, ISO-образы дистрибутивов GNU/Linux, или зеркало Википедии и библиотеки Мошкова.

При этом в конфиге Nginx затаились строки вида

location ~ ^/somesecret/(.*)

Когда мы хотим подключиться к скрытому сервису, мы переходим браузером или делаем запрос CURL'ом по адресу вида
https://ourserver.org/somesecret/vpn/on
проходим стандартную авторизацию, после чего нокер, получив и обработав наш запрос, выполнит команду на открытие доступа к скрытому сервису для нашего IP-адреса, например что-то вроде
iptables -t nat -A PREROUTING -p tcp -s {clientIP} --dport 443 -j REDIRECT --to-port 4443
после чего мы поднимаем туннель.

Далее через N секунд (да, поддерживается автоматический таймаут) выполняется команда, отменяющая вышеуказанное правило фаервола, и таким образом наше установленное подключение остается висеть, но подключиться к сервису снова даже с нашего IP без повторного дерганья нокера уже не выйдет.

Либо можно не использовать автоматический таймаут, а вручную деактивировать сервис, запросив URL наподобие указанного выше, только с /off в конце.

Таким образом можно сконфигурировать даже несколько разных сервисов, в том числе используя IPv6 (v6-адреса в заголовке типа X-Real-IP также поддерживаются).

Исходники, подробное описание и примеры конфига nginx и init-скриптов можно найти на Gihub:
https://github.com/uprt/labean
Буду признателен за багрепорты, пулл-реквесты, гитхаб-звездочки и вообще любые хорошие идеи и предложения. Нокер написан на Go, не требует внешних зависимостей, прост как топор, и вполне себе работает.

Websockets

image

Современные Web-технологии давно уже содержат решение для установления связи поверх TCP между браузером и сервером, и имя ему Websocket (RFC 6455). Вторая идея озарила еще более неожиданно: лучшее средство замаскировать туннель внутри HTTPS — использовать общепринятые стандартные инструменты. Со стороны, соответственно, все выглядит в точности как обычный HTTPS и не требуется установки никаких дополнительных соединений. Клиент формирует особый HTTP-запрос, на который сервер отвечает определенным образом, и после небольшого хендшейка мы можем начинать передачу данных по этому же TCP-соединению.

Реализаций WS-туннелей существует несколько (есть даже вариант на Haskell), я для теста взял wstunnel, сделанный на nodejs и не прогадал, все завелось легко и с первого раза.

Для запуска клиента предлагается указывать просто wss://-адрес, типа Лишь один нюанс был не прояснен в документации.

wstunnel -t 33 wss://server:443

В нашем же случае, необходимо «отделить» ws-подключения к серверу туннелирования от запросов «обычного» сайта. Изучив исходники wstunnel, я пришел к выводу, что ничего не помешает удлинить URI после имени хоста каким-нибудь уникальным идентификатором:

wstunnel -t 33 wss://ourserver.org:443/hiddenws/

и оказался прав: все заработало с первого раза

Снова рассмотрим наш сервер, на котором на 443 порту запущен Nginx c каким-нибудь безобидным сайтом.

В конфиг нужно добавить proxy-проброс для нашего Websockets-туннеля:

location /hiddenws { proxy_pass http://127.0.0.1:8081; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; }

После чего мы можем тайным образом поднимать наш websockets-туннель. Поверх туннеля можно пустить подключение к обычному SOCKS-прокси (например, Dante), или OpenVPN, хотя, как по мне, это уже будет избыточно.

Единственный минус такого подхода — кроме непосредственно SOCKS- или VPN-клиента на устройстве также нужно иметь клиент wstunnel, что может быть сложным в случае использования смартфона или другого «недесктопного» устройства.

Вместо заключения

image

Воплотятся ли в жизнь предположения, изложенные в статье, не воплотятся — узнаем со временем, как и о том, что будет дальше. Как на самом деле будет развиваться социально-техническое противостояние, мы знать не можем — только предполагать. Да, маскировка под HTTPS тоже не панацея от всего — например, делать это может быть опасно, если на будет введено административное или уголовное наказание за «использование несертифицированных средств шифрования»/ознакомление с запрещенными ресурсами/etc., или бесполезно, если на государственном уровне всех обяжут устанавливать «национальный сертификат безопасности», как это некоторое время назад хотели сделать в Казахстане.

Пока еще, к счастью, ни до того, ни до другого не дошло ни одно из известных нам государств, и если оно случится — это знак, что пора эвакуироваться, причем не из страны, а с планеты.
Берегите себя.

Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»