T.me Многие из вас используют VPN или прокси в повседневной жизни. Кто-то использует его постоянно, получая доступ к заблокированным на государственном или корпоративном уровне ресурсам, многие используют его изредка, для обхода ограничений по географическому положению. Как вы можете знать, крупные интернет-игроки в сфере стриминга видео, музыки и продажи игр никогда не любили пользователей, которые легко обходят географические ограничения, разблокируя недоступный в их стране контент, или совершая покупки заметно дешевле. За примерами не нужно далеко ходить: Netflix изменил свое соглашение об использовании, добавив пункт о блокировке VPN, всего 2 месяца назад; Hulu тоже грешил блокировкой пользователей, а Steam вообще подозрительно смотрит на не-русскоязычных пользователей из России. В последнее время, компании пытаются блокировать уже не конкретных пользователей, а сами IP-адреса VPN-сервисов, создавая определенные неудобства уже самому VPN-сервису и его пользователям. Похоже, они не используют никаких спецсредств, а блокируют выборочно и вручную. Хоть я и не поддерживаю какие-либо блокировки вообще, меня заинтересовала техническая часть вопроса: можно ли как-то определить использование прокси-серверов и VPN со стороны сервера, не прикладывая особых усилий?
Можно, при определенных условиях. И достаточно точно.
MSS и MTU
MTU, или Maximum Transmission Unit — максимальное количество данных, которые могут быть переданы в одном пакете. MTU установлен у каждого сетевого адаптера, даже у тех маршрутизаторов, через которые трафик от вас до удаленного сервера идет транзитом. В подавляющем большинстве случаев, в интернете используют MTU 1500, однако бывают заметные исключения, которые, к слову, зачастую подчиняются некоторым правилам.
Когда ваш браузер или любое другое ПО, работающее с сетью, создает TCP-соединение к удаленному серверу, в заголовки пакета помещается значение Maximum Segment Size (MSS), которое сообщает серверу, какого максимального размера сегменты он может передавать в одном пакете. Это значение очень близко́ к MTU, оно сразу дает понять серверу о возможностях вашего интернет-соединения, исключая излишнюю фрагментацию и позволяя утилизировать ваш канал по полной.
Когда вы отправляете пакет, будучи подключенным к VPN по какому-то протоколу (PPTP, L2TP(±IPsec), IPsec IKE), он помещается (инкапсулируется) в еще один пакет, что вносит свои накладные расходы, и большие пакеты, которые были бы отправлены без фрагментации без VPN, теперь придется фрагментировать. Чтобы избежать такой фрагментации, ОС устанавливает на сетевом интерфейсе MTU меньше, чем MTU реального сетевого интерфейса, из-за чего ОС не пытается создавать большие пакеты, которые требовали бы фрагментации.
В случае с PPTP, L2TP(±IPsec), IPsec, как я понимаю, нет каких-то стандартов на MTU туннеля, все устанавливают такие значения, чтобы работало в большинстве случаев, и устанавливаются они на глаз. Как правило, это 1400, что позволяет использовать, скажем, PPTP на каналах с MTU до 1440 без фрагментации (например, когда для доступа в интернет требуется еще один туннель, как часто бывает у российских провайдеров). OpenVPN — пожалуй, самый популярный вариант VPN — напротив, пошел другим путем.
OpenVPN
В целях совместимости со старым или просто кривым софтом, OpenVPN по умолчанию не устанавливает меньшее значение MTU на VPN-интерфейсе, а изменяет значение MSS внутри инкапсулированного TCP-пакета. За это отвечает параметр mssfix, установленный по умолчанию в значение 1450. Он изменяет MSS таким образом, чтобы он полностью утилизировал канал с MTU 1450, т.е. высчитывает свои накладные расходы таким образом, чтобы они проходили через канал с MTU 1450 и более без фрагментации. Вследствие этого, у нас появляется возможность не просто определить пользователей OpenVPN со стандартным mssfix 1450, но и определить их протокол подключения (IPv4, IPv6), протокол транспортного уровня (TCP, UDP), параметры шифрования, сжатия и MAC, т.к. они вносят свои уникальные накладные расходы и отражаются в MSS.
Давайте посмотрим на типичные значения MSS:
Протокол | Размер блока | MAC | Сжатие | MSS |
---|---|---|---|---|
UDP | 64 | SHA1 | — | 1369 |
UDP | 64 | SHA1 | + | 1368 |
TCP | 64 | SHA1 | — | 1367 |
TCP | 64 | SHA1 | + | 1366 |
UDP | 128 | SHA1 | — | 1353 |
UDP | 128 | SHA1 | + | 1352 |
TCP | 128 | SHA1 | — | 1351 |
TCP | 128 | SHA1 | + | 1350 |
UDP | 128 | SHA256 | — | 1341 |
UDP | 128 | SHA256 | + | 1340 |
TCP | 128 | SHA256 | — | 1339 |
TCP | 128 | SHA256 | + | 1338 |
Если используется шифр с размером блока в 64 бита, это, вероятно, Blowfish, если 128 — вероятно, AES.
Для пущей проверки теории было протестировано 2 VPN-сервиса: VyprVPN и ibVPN. Оба сервиса подвержены определению настроек описанным методом.
Если вы не хотите, чтобы вас обнаруживали таким способом, вы можете либо отключить mssfix, установив его в 0 и на сервере, и на клиентах, получив таким образом MSS 1460 (в случае с IPv4), что соответствует MTU 1500 — типичному MTU для обычного проводного соединения, которое есть у подавляющего большинства пользователей. Однако, в этом случае вы получите излишнюю фрагментацию, что ведет к повышению задержек и уменьшению пропускной способности, поэтому может иметь смысл установить MTU в 1400, 1380 или похожее (должно быть кратно 2, а лучше 10), т.к. такие значения часто используются провайдерами, например, мобильного интернета.
Прокси
Способов определения прокси-сервера, если он не добавляет никаких заголовков (вроде X-Forwarded-For), не так-то много. Чем же технически отличается прокси от VPN? В случае с VPN, удаленный сервер получает от вас пакет, которая создала ваша ОС, в неизменном (зачастую) виде. Прокси же, напротив, получает только всю информацию об удаленном сервере (IP, порт, прочие параметры) и данные, создавая пакет на стороне самого прокси, и отправляет его. Разные ОС по-разному создают пакеты, различия можно встретить даже от версии к версии. Мы с большой точностью можем определить ОС создателя пакета, версия нас не слишком интересует.
Как мне кажется, прокси чаще всего запускают на Linux и BSD, а используют чаще под Windows. Пользователи часто не думают о смене User-Agent, который включает используемую ОС, в браузере, а это нам на руку.
p0f
Существует замечательный проект p0f, который отлично впишется под наши нужды. Пассивно прослушивая трафик, он может определить ОС, MTU и браузер, оповестить о несовпадении ОС создателя пакетов и ОС в User-Agent. К тому же, он имеет API. Немного модифицировав его, добавив экспорт MTU через API и обновив сигнатуры, мы можем с определенной точностью детектировать пользователей популярных VPN-протоколов, пользователей прокси и тех пользователей, которые подделывают User-Agent.
WITCH?
Немного подумав, я решил сделать небольшой веб-сервис для реализации своих идей, т.к., по какой-то причине, я не смог найти ничего похожего.
Из этого получился WITCH?, который с легкостью расскажет вам о настройках вашего OpenVPN-соединения (если вы не трогали mssfix, конечно же), попытается определить вашу ОС и сравнить ее с ОС в User-Agent, получит PTR-запись для вашего IP и сравнит ее с набором правил, определяя, используете ли вы интернет-канал, рассчитанный на домашних или серверных пользователей.
First seen = 2015/07/24 17:19:29
Last update = 2015/07/24 18:39:37
Total flows = 7
Detected OS = Linux 3.11 and newer
HTTP software = Firefox 10.x or newer (ID seems legit)
MTU = 1409
Network link = OpenVPN UDP bs64 SHA1
Language = Russian
Distance = 15
Uptime = 1 days 19 hrs 39 min (modulo 165 days)
PTR test = Probably home user
Fingerprint and OS match. No proxy detected.
OpenVPN detected. Block size is 64 bytes long (probably Blowfish), MAC is SHA1.
WITCH? также без проблем определяет пользователей Tor Browser, т.к. он использует одинаковый статичный User-Agent (с Windows) на всех ОС, а exit nodes запущены под Linux и FreeBSD.
В ходе тестов выяснилось много интересных подробностей:
- Мобильный интернет от Beeline пропускает все соединения через прокси под Linux. Обнаружилось это, когда человек с Beeline зашел с iPhone на WITCH?, и ОС определилась как Linux. Вероятно, именно через него они меняют HTML-теги, добавляют тулбар с поиском mail.ru и изменяют дизайн сайтов.
- MTU у мобильных устройств может быть буквально какой угодно, но, как правило, заканчивается на 0. Исключение — Yota с 1358. От чего это зависит — непонятно, подозреваю, что и от настроек на стороне оператора, и от телефонного модуля. Одна и та же SIM в разных телефонах использует разные MTU.
- Код, который отвечает за mssfix в OpenVPN, очень медленный. Если у вас есть знания в сетях, C, желание и время, пожалуйста, посмотрите, можно ли его оптимизировать.