Рассказываю о своём опыте использования Xray (с протоколом VLESS-Reality) - одного из лучших решений для преодоления интернет-цензуры на сегодняшний день. Я потратил много времени на то, чтобы разобраться с ним - теперь вам достаточно одного вечера, чтобы поднять свой сервер на несколько десятков пользователей, c xray на борту!
скрипт
ex.sh
для простой настройки и установки; есть поддержка Dockerлегко добавлять пользователей; клиентские конфиги в форме url-ссылок
правильные конфиги: скрытность + удобство
трафик популярных российских сайтов идёт напрямую, a не через сервер
для xray есть приложения под все популярные ОС - делюсь инструкциями
только https, нет udp; торренты через сервер блокируются по возможности
мой проект на гитхабе: easy-xray
Интересны детали? Добро пожаловать под кат.
Роскомнадзор
Многие коммерческие VPN заблокированы, их приложения бесполезны. Любимый бесплатный VPN в очередной раз не работал. А shadowsocks-клиент ещё одного коммерческого VPN просто не ставился на мой домашний компьютер. Достало. Так я решил поднимать свой VPN-сервер. Из статей @MiraclePtr на Хабре я знал про xray и протокол VLESS-Reality (статей очень много!). Идея VLESS-Reality простая: берём https-пакеты, и пускаем их через наш заграничный сервер (VPS), как через прокси. Однако к серверу обращаемся, как будто к какому-нибудь популярному сайту, например www.microsoft.com, но в стандартной процедуре хендшейка делаем скрытую авторизацию - и сервер понимает, что мы его клиент. Если кто-то другой (читай РКН) попробует обратиться к нашему "сайту" без авторизации (такая атака называется active probing, смысл её в поиске нестандартных ответов от серверов заграницей, с которыми соединяются пользователи), он получит копию www.microsoft.com со всеми необходимыми сертификатами. РКН подумает, что наш сервер - это просто сервер Microsoft, a никакой не VPN, и ничего блокировать не будет. Кроме того, поскольку https-пакеты, которые мы гоним через прокси, уже зашифрованы, дополнительных ресурсов на шифрование не нужно, и никакой глубокий анализ пакетов (deep package inspection, DPI) тоже не увидит ничего подозрительного. Поэтому было решено - ставим xray. (Другие хорошие варианты - AmneziaWG или Shadowsocks-2022 через Outline VPN, например - но они могут быть заблокированы во время масштабных блокировок, когда под нож идёт всё, что не https).
Урок географии: список customgeo.dat
Установить xray оказалось делом довольно простым, к тому же его можно использовать не только на сервере, но и в качестве клиента - если у вас Linux или MacOS, например. Но вот настройка... Xray может использовать разные протоколы и может быть сконфигурирован сотней способов, а доступные в сети примеры, хотя и работают иногда, дают конфигурацию, далёкую от идеальной.
Что такое идеальная конфигурация? Во-первых, наш сервер должен крякать выглядеть максимально похоже на обычный сайт. Значит, у нас должны быть открыты порты 80 (http) и 443 (https), и по ним в случае обращения не со стороны клиента должна выдаваться копия того сайта, под который мы маскируемся. Во-вторых, в идеале наш сервер никак не должен взаимодействовать с российскими, китайскими и другими потенциально опасными сайтами, которые могут попытаться понять, что их открыли через VPN (например, сопоставляя часовой пояс, в котором находится загрузивший их ip-адрес, то есть vpn-сервер, с часовым поясом вашего компьютера). Про удобство тоже не хочется забывать: сейчас многие российские сайты просто не открываются заграницей, поэтому неплохо было бы пустить их трафик напрямую. Xray даёт такую возможность, но не всё так просто. Страницы сайтов часто тянут себя по кусочкам из разных источников, и далеко не все российские сайты, а тем более их "кусочки" находятся в зоне ".ru". "В комплекте" с xray идёт некоторый список российских сайтов, но он оставляет желать лучшего. Так что пришлось повозиться и обогатить этот список, чтобы большинство популярных российских сайтов наконец-то стали работать корректно и в то же время не вызывали трафика через сервер.
Дополнительный список сайтов для прямого доступа в специальном формате хранится в файле customgeo.dat
, который нужен не только на сервере, но и на клиентах (в несколько ином виде). На самом деле это два списка: список потенциально опасных сайтов, трафик до которых блокируется сервером, и список сайтов, которые стоит открывать напрямую с клиента. Второй список шире первого и содержит, например, Хабр - по какой-то причине он лучше работает напрямую, и конечно, его не нужно блокировать на сервере. Ещё во втором списке есть, например, googleapis.com - чтобы ваш браузер определял геолокацию по вашему ip-адресу, а не по адресу сервера, и вызванное вами такси не пыталось ехать куда-нибудь в Польшу.
Что ещё нужно пользователям? Владелец xray сервера при желании может видеть, какие сайты открывают клиенты. И хотя сам трафик к сайтам зашифрован, клиенты могут не доверять владельцу сервера и имеют полное право скрывать даже сам факт своего контакта с любыми сайтами. Это нормально. Поэтому нужно настроить сервер так, чтобы Tor Browser мог работать с ним вместе. Тогда при использовании Tor с сервера будет видно только то, что пользователь подключился к какому-то узлу в интернете (на самом деле узлу сети Tor, через которую и пойдёт вся дальнейшая маршрутизация). Tor Browser работает (ещё бы!) немного хитрее, чем обычные браузеры - например, он вставляет в запросы фейковые server name indications (SNI) - поэтому часто не работает через xray "из коробки". "Починить" удалось благодаря китайскому телеграм-чату проекта xray (всё просто, "routeOnly": true в sniffing object и на клиенте, и на сервере + obfs4 bridge на клиенте, но кто же знал).
Ещё пользователям нужны торренты, но они совершенно не нужны VPS-провайдеру - значит, не нужны вам. За время тестирования один раз прилетела жалоба от правообладателя какого-то сериала - кто-то из пользователей качал его на торрентах через xray, и ip-адрес сервера попал в список пиров. Ответы на жалобу, переписка - всё это отнимает время. Поэтому пришлось провести разъяснительную работу ревизию конфигов и по возможности заблокировать популярные порты торрент-трекеров и торрент-клиентов. Кроме того, Xray как-то умеет выявлять протокол bittorrent, и можно пытаться блокировать трафик по протоколу, но торренты всю жизнь борются с блокировками - и побеждают, подобно тому, как xray побеждает китайский файервол. Но всё равно разработчикам xray за подобный полезный оксюморон отдельное спасибо - в ряде случаев bittorrent действительно не проходит.
Хотя мне пришлось менять конфигурацию сервера, уже имея с десяток пользователей на борту, мне не пришлось выпускать новые конфиги для них, а им не пришлось перенастраивать свои клиентские программы: при переустановке xray можно задать прежние ключи, и есть возможность импорта старых пользователей в новый серверный конфиг. Но давайте перейдём от слов к делу и шаг за шагом рассмотрим, как установить xray, как добавлять пользователей, делиться конфигами и т. п.
Инструкция
Для начала вам нужно арендовать сервер заграницей. Лучше всего это делать через друга, который живёт там - это упрощает оплату и снижает вероятность атаки - не только на ваш сервер, но и на вас. Если серьёзно - пока за VPN не сажают и ничего похожего, кроме дела Дмитрия Богатова за выходной узел сети Tor, мне не приходит на ум (дело развалилось, Дмитрий уехал из страны). Да и навряд ли РКН сможет выпытать у заграничного хостера имя владельца сервера, даже если каким-то образом узнает его IP. Для любителей крипты отмечу, что хотя оплата хостинга заграницей иногда возможна через криптовалюту, но, как правило, этой криптовалютой оказывается безальтернативный биткоин, для которого даже минимальная комиссия за перевод уже перевалила за стоимость месячной аренды сервера. Надеюсь, в комментариях меня поправят и накидают нормальных вариантов хостеров для криптоэнтузиастов? Если же друг всё таки есть (внимание, воображаемый друг не подходит!), или есть заграничная карточка, то аренда сервера - дело пяти минут. В качестве референса можно посмотреть собранный проектом Amnezia список дешевых хостеров. (Из интересного - в этом списке есть молдавский PQhosting, который принимает российские карточки и даёт сервера по всему миру. Они пишут, что раскрывают информацию о пользователях только по официальным запросам российских правоохранительных органов.) Потребляемые ресурсы - минимальны, так что 1-2 GB памяти (в зависимости от прожорливости выбранной ОС, сомневаетесь - берите 2) и 1 ядро - это всё, что нужно; сеть - в зависимости от ваших планов/потребностей, вполне можно начать с того лимита, который предлагают на старте. Дальше заходим на сервер, и понеслось.
Сервер, Linux
В целом вся установка-настройка-администрирование сводится к выполнению пары команд
# копируем с гитхаба
curl -L https://codeload.github.com/EvgenyNerush/easy-xray/tar.gz/main | tar -xz
# переходим в директорию
cd easy-xray-main
# ставим
sudo ./ex.sh install
# добавляем пользователей
sudo ./ex.sh add alice bob
# генерируем пользовательские конфиги в url форме
./ex.sh link conf/config_client_alice.json
но давайте рассмотрим весь процесс чуточку поподробнее.
шпаргалка по настройке сервера
# на сервере, от рута
useradd -m username # создаём пользователя
passwd username # придумываем ему пароль
visudo # проверяем, что группе wheel или sudoers разрешено выполнять "рутовые" команды
usermod -aG wheel username # добавляем пользователя в группу wheel или sudoers
# на домашнем компьютере
ssh-keygen # генерируем пару ключей
ssh-copy-id username@server_ip_address # и копируем открытый ключ на сервер
# eval `ssh-agent` # может понадобиться
# ssh-add your_new_key # если ssh всё ещё просит пароль
ssh username@server_ip_address
# снова сервер, от пользователя
# настраиваем фаервол на примере RedHat-based дистрибутива
sudo firewall-cmd --state
sudo firewall-cmd --list-all
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --reload
Обновляем систему, ставим зависимости - пакеты jq и openssl, которые есть в репозиториях большинства популярных дистрибутивов. Затем копируем целиком директорию моего проекта easy-xray с github и заходим в неё:
curl -L https://codeload.github.com/EvgenyNerush/easy-xray/tar.gz/main | tar -xz
cd easy-xray-main
Гитхаб добавляет имя ветки к названию директории, поэтому директория будет называться easy-xray-main. Затем запускаем интерактивный скрипт ex.sh
, который проведёт установку и настройку xray. Вам нужно будет сообщить ему ip-адрес арендуемого сервера, имена создаваемых пользователей (более-менее любые последовательности символов, подходящие под требования к имени пользователя в email, их можно добавить позже) а также сайт, под который ваш сервер будет маскироваться. Здесь спокойно можно выбрать один из предлагаемых скриптом вариантов - РКН, кажется, отстаёт от китайских коллег лет на десять и не умеет (а ещё хорошо, что он не знает, что именно он не умеет). Нам нужны права суперпользователя, так как xray работает с сетью, а также предполагает использование systemd. Если sudo для незнакомого скрипта вас не устраивает, или на вашем сервере уже что-то крутится и вы не хотите ничего случайно сломать - можно поставить xray в контейнер Docker (читайте об этом на два раздела ниже), а пока хардкор:
chmod +x ex.sh
./ex.sh help
sudo ./ex.sh install
Дальше, при необходимости, можно добавить пользователей (при этом скрипт снова предложит скопировать обновлённый серверный конфиг в специальную директорию, где его ищет xray, и перезапустить xray - поэтому снова sudo), ещё можно удалить пользователя, или посмотреть статистику трафика по пользователям (к сожалению, статистика сбрасывается каждый раз, когда перезапускается xray - а его приходится перезапускать при каждом добавлении пользователя, если вы не сделали конфиги заранее):
sudo ./ex.sh add charlie dave eve
./ex.sh stats
В результате всех этих манипуляций у вас появится директория conf
, содержащая серверный конфиг config_server.json
, "референсный" клиентский конфиг config_client.json
и конфиги других пользователей config_client_username.json
. Осталось забэкапить эту директорию куда-нибудь в надёжное место - и раздавать конфиги! Один конфиг можно использовать с нескольких устройств, и сами пользователи могут делиться своими конфигами со своими друзьями. То есть для друзей друзей можно не выпускать отдельные конфиги, что облегчает вам жизнь.
Важно, что многие клиенты позволяют вставлять из буфера обмена конфиг в упрощённом виде, похожем на url-ссылку. Пользователю не нужно ничего прописывать руками, пользователь доволен. Чтобы сгенерировать конфиг-ссылку, выполните
./ex.sh link conf/config_client_username.json
И последнее. Чтобы быть совсем похожим на сервер обычного сайта, неплохо выбрать далёкий порт для ssh вместо 22-го. Дважды проверьте, что по выбранному вами порту ssh вы можете зайти на сервер - только после этого закрывайте порт 22. (Возможно, вам придётся также открыть этот порт в фаерволе, см. пример с firewall-cmd выше в шпаргалке).
# кусочек /etc/ssh/sshd_config
#Port 22
Port 43210
Клиенты для пользовательских устройств
Для xray есть с десяток клиентов под все популярные операционные системы - Linux, Windows, MacOS, Android, iOS. Список можно посмотреть на страничке xray. Я не буду здесь писать подробные инструкции для них всех, тем более многие клиенты похожи как близнецы-братья. Вместо этого давайте рассмотрим подробно один клиент - Hiddify NG, под Android. Тем не менее, общие советы и краткие гайды для некоторых ОС и приложений можно найти на Хабре или на страничке моего проекта:
Linux
macOS
Windows (Nekoray)
Android (V2RayNG)
iOS (Straisand)
Вообще под Android обычно ставят V2RayNG, но пусть здесь будет немного разнообразия. Hiddify NG - иранское приложение, очень похожее на китайский V2RayNG. Есть более новый Hiddify Next - "морду" переписали на Flutter, а приложение стало мультиплатформенным (помимо Android, заявлены Windows, Linux и macOS), но пока оно не поддерживает пользовательские правила маршрутизации - то, что нужно нам для потенциально опасных сайтов. Если российские сайты вам не нужны, или вы готовы включать/выключать приложение для доступа к ним, то Hiddify Next вполне подойдёт. Вообще приложения Hiddify рассчитаны на страны с ещё более жесткой цензурой, и оперирует "профилями" или "группами", включающими в себя сервера с разными протоколами и ip-адресами, соединение с частью которых может периодически обрываться. Но и с одним сервером всё прекрасно работает, просто выглядит немного запутанно.
Итак, устанавливаем HiddifyNG, например из Google Play, потом копируем в буфер конфиг-ссылку вида vless://...#easy-xray+%F0%9F%97%BD
, сгенерированную командой ./ex.sh link
. Запускаем Hiddify NG, идём во вкладку конфигов внизу по центру ("Configs"), жмём плюсик справа вверху и выбираем вставку конфига из буфера обмена ("Import config from Clipboard"), после чего конфиг с названием easy-xray должен появиться в списке в центре экрана. Выбираем наш конфиг easy-xray и жмём Start справа внизу для подключения. По-умолчанию приложение работает как общесистемный прокси, поэтому сразу можно проверить его работоспособность, зайдя через браузер, например, на whatismyip.com (вы должны увидеть страну и ip-адрес вашего сервера). Осталось настроить список сайтов для прямого доступа. Идём в настройки в левом верхнем углу (Settings), проматываем до раздела Маршрутизация ("Routing"), выбираем Пользовательские правила ("Custom rules"), и в среднюю секцию (прямые, "direct URL or IP") вставляем список сайтов из customgeo4hiddify.txt, жмём еле заметную галочку справа вверху. Всё, настройка закончена, можно вернуться на вкладку Дом ("Home") или Конфиги ("Configs"), переподключиться (иногда кроме этого приходится перезапустить приложение) и проверить, что российские сайты, например 2ip.ru, показывают ваш айпишник и страну, а не айпи-адрес сервера. Если HiddifyNG подключается, но браузер работает с перебоями или вообще не загружает сайты, попробуйте удалить в настройках Hiddify поле VPN DNS (Настройки -> Настройки VPN -> VPN DNS (только IPv4/v6), оставить поле пустым, нажать Ok).
Последнее замечание по поводу клиентов. Tor Browser, скорее всего, не заработает без указания моста - связующего звена между вами и сетью Tor (дело не в блокировках, просто Tor и xray не очень дружат). Чтобы включить мост, перейдите в тор-браузере в Настройки -> Соединение, и выберите один из встроенных obfs4-мостов.
Docker
Установка и настройка xray в Docker уже не уложится в пять минут, как установка в саму систему. Xray обычно предполагает использование systemd, что противоречит физиологии идеологии Docker, да и с портами придётся повозиться. Так что замените пять на десять, и продолжим.
Для начала скачайте директорию easy-xray
и соберите образ Docker, используя файл Dockerfile
; ключ -t задаёт тег/имя образа, например ximage
:
curl -L https://codeload.github.com/EvgenyNerush/easy-xray/tar.gz/main | tar -xz
cd easy-xray-main
docker build -t ximage ./
Обычно пользовательские приложения не могут использовать порты ниже 1024. В то же время, для того, чтобы замаскировать xray сервер под обычный вебсайт, мы должны использовать порты 80 и 443. Самый простой выход - разрешить на хосте "пользовательское использование" портов, начиная с 80-го:
sudo sysctl -w net.ipv4.ip_unprivileged_port_start=80
Также нужно разрешить не-залогиненному пользователю выполнять долгоживущие сервисы. Иначе после выхода пользователя с сервера контейнер может перестать работать:
sudo loginctl enable-linger your_username
Теперь можно запустить docker контейнер в интерактивном режиме (флаги -i -t
), пробрасывая порты 80 и 443 от хоста к контейнеру:
docker run -it --name xcontainer -p 80:80 -p 443:443 ximage
В интерактивном режиме можно установить и сконфигурировать xray так же, как и в обычной системе, но копировать серверный конфиг в директорию xray и перезапускать xray через systemctl нет смысла. Сообщения об отсутствии systemd можно просто проигнорировать. Xray можно запустить с серверным конфигом вручную (и нужно будет перезапускать вручную при каждом изменении конфигов):
./ex.sh install
xray -c conf/config_server.json
После запуска xray можно отсоединиться от контейнера, используя Ctrl+p затем Ctrl+q. Если нужно снова присоединиться к контейнеру, можно использовать
docker attach xcontainer
(после этого нужно нажать Ctrl+c, чтобы завершить работающий xray), или можно воспользоваться командой
docker exec -it xcontainer bash
для запуска ещё одной сессии. Для того, чтобы скопировать конфиг-файлы из контейнера на хост, сначала нужно узнать Id контейнера:
docker ps -a
docker cp 123abc456def:/easy-xray/conf ./
Команду ./ex.sh link user_config_file
можно использовать не обязательно в контейнере или на хосте - на любом компьютере с Linux, если на нём хранятся конфиг-файлы. Работающий xray для этой команды не нужен.
Опыты на людях
В теории всё хорошо, а на практике? Для тестирования был куплен VPS с одним ядром и 2 ГБ памяти за 650 рублей в месяц, с квотой на загрузку 4 ТБ при канале 100 Мб/с. В результате тестирования получилось, что двадцать активных пользователей загружают вместе всего около 300 ГБ в месяц, в сумме с системой потребляется около 1 ГБ памяти, загрузка процессора не превышает 10%, а трафик, как правило, не превышает 10 Мб/с. Сервер был успешно протестирован из Китая, а вот "потыкать" российские блокировки не получилось - к началу тестирования волнения в Дагестане уже прошли, и пользователей из Башкортостана или Якутии в январе не нашлось. Но РКН отстаёт от китайских "коллег", поэтому скорее всего, с ним не будет проблем.
Как оказалось, пользователи - народ нетребовательный. Большинство даже не настраивало правила для доступа к российским и т. п. потенциально опасным сайтам, а просто вешали на этот прокси одно-два приложения с квадратными картинками, либо включали/выключали общесистемный прокси вручную, при необходимости. Обе эти модели поведения явно не делают сервер более подозрительным с точки зрения РКН (всё равно трафик до "опасных" сайтов блокируется сервером), а может быть даже способны запутать какую-нибудь (потенциальную воображаемую) эвристику обнаружения впн.
Но постойте... Не может же быть всё настолько хорошо (впн работающий как часы за 30 руб/месяц/человека, без учёта разработки и поддержки, естественно)? Да, проблемы есть. Например, в Туркменистане заблокировано больше половины всех ip-адресов, и тестовый сервер просто оказался в этом чёрном диапазоне. В РФ - пара сайтов просто не открывается - потому что недоступна ни из РФ, ни из страны, где расположен тестовый сервер. Другая проблема - сервер пропускает только http/https трафик, и если вам нужен udp - извините (SIP телефония в пролёте, но zoom и googleMeet не используют udp, как иногда думают, и прекрасно работают). Что касается минусов самой программы xray - после изменения конфигов нужен её рестарт, а каждый раз при рестарте xray сбрасывает статистику потреблённого трафика. Это может быть неудобно, если (вдруг) вы собрались делать коммерческое решение с ограничением по "гигабайтам".
Однако главная (и немного неожиданная) проблема - найти пользователей. И дело не в недоверии - из пользовательского браузера трафик идёт уже в шифрованном виде и украсть какие-то данные из потока ни клиентская программа, ни сервер просто не могут. Главная причина в том, что сейчас уже есть множество коммерческих и некоммерческих решений для обхода блокировок, и обычно те, кому они нужны, уже чем-то пользуются, к чему-то привыкли, или просто устали искать и пробовать. Так что прежде, чем поднимать свой сервер, чётко определитесь с вашими потребностями и финансовыми возможностями, и найдите хотя бы минимум пользователей - чтобы потраченные усилия не принесли разочарование. Тем не менее, начать эксперименты с xray лучше уже сегодня - чтобы завтра, когда РКН начнёт вовсю блокировать Wireguard, OpenVPN или Shadowsocks, у вас оставался полноценный доступ в Сеть.
Репозиторий проекта на гитхабе: easy-xray, а здесь readme на русском, и чат проекта в Телеграме.
P.S.
Хочется сказать спасибо всем пользователям тестового сервера 🫶 (отдельное спасибо @Limping), а также спасибо @fadey и @dmserebr за замечания по черновику этой статьи.