Shadowsocks через Cloudflare CDN - повышаем безопасность в Сети

для раздела Блоги
Начислено вознаграждение
Этот материал написан посетителем сайта, и за него начислено вознаграждение.

реклама

Данный материал является продолжением моей предыдущей статьи про Wireguard, использовать для работы мы будем тот же дроплет на Hetzner, поэтому кто еще не научился поднимать и настраивать свой VPS, прошу ознакомиться с предыдущим материалом.

Так как нашим соседям из Поднебесной гораздо дольше приходится бороться с государственной цензурой в лице Великого Китайского Файервола (т.н. Золотой щит), ими был разработан и успешно применяется для прохождения сквозь Золотой щит шифрующий socks5-proxy под названием Shadowsocks.

реклама

Основные преимущества Shadowsocks:

  • Легкость настройки сервера (конфиг занимает 5 строк в формате json);
  • Проходит почти через любые NAT и корпоративные файерволы (пробивал до недавнего времени даже GFW, теперь только с обфускацией);
  • Легко настраивать доступ на уровне отдельных программ. В браузере, с помощью дополнений типа FoxyProxy/OmegaSwitchy  — на уровне отдельных адресов по сложным правилам;
  • Нет надобности поддерживать постоянный канал, что положительно сказывается на трафике и расходе аккумулятора;
  • Очень высокая скорость на мобильных клиентах, вплоть до полной полосы канала.

К недостаткам можно отнести:

  • Нет управления пользователями. Фактически все пользователи подключаются под одним конфигом, к одному порту, по одному паролю (но какая разница, если все пользователи - доверенные);
  • Документацию писали китайцы, на китайском английском, с кучей пропущенных пунктов и взаимных противоречий;
  • Не проходил официального аудита, т.к. код простой, его смотрела куча народу, но официально нет.

реклама

Последние два преимущества определили направление материала этой статьи: рассказывать я буду в основном про мобильный клиент, т.к. текущая реализация для маршрутизаторов под OpenWRT оставляет желать лучшего, но клиент под OpenWRT тоже есть.

Но самое главное: из этой статьи вы узнаете не только, как поднять сервер и подключить клиент, но и научитесь обфусцировать трафик и пускать его через CDN от Cloudflare так, что для DPI будет казаться, что вы подключаетесь по https к обычному сайту, и сайт этот будет не абы какой, а Конституция Российской Федерации! Для чего это нужно? Чтобы избежать атаки сравнений, когда товарищ-майор, имея пакет Яровой и данные о трафике, а так же данные с серверов  (что пока актуально только для ОРИ, поэтому не пользуйтесь российскими сервисами), для того, чтобы найти злобного цифровой сопротивленец, пишущего "Сказочный д...б"  через VPN, сравнивает, с какого ip пользователь это писал и кто в этот момент времени подключался к ip-адресу, с которого это писали. При использовании данного метода весь трафик уходит на один адрес, а приходит с другого.  Cloudflare CDN с 2014 года бесплатно проксирует websocket трафик. Это позволяет скрыть VPS IP от блокировки Роскомнадзором, трафик идет через Cloudflare CDN, но Cloudflare тоже не видит трафик, он только его транзитит между клиентом и прокси сервером.

реклама

Вот так это будет выглядеть на схеме:

Настройка сервера

реклама


Итак, имеется наш VPS за 3€ в месяц на Hetzner, OS Debian 10, настроенный ssh, Unbound, firewall. Запускаем Putty, вводим:

~# apt update && apt upgrade -y && apt install -y shadowsocks-libev

В отличии от прокси, к которому может подключиться любой желающий, в shadowsocks-libev можно и нужно поставить пароль. Также метод шифрования по умолчанию не оптимален. Поэтому обязательно отредактируйте файл конфигурации по адресу /etc/shadowsocks-libev/config.json:

{
"server": "localhost",
"server_port": 8008,
"password": "пишешь_сюда_какой_нибудь_длинный_пароль",
"timeout": 300,
"method": "xchacha20-ietf-poly1305",
"no_delay": true,
"fast_open": true,
"reuse_port": true,
"workers": 1,
"plugin": "v2ray-plugin",
"ipv6_first": true,
"nameserver": "127.0.0.1",
"plugin_opts": "server;tls;fast-open;path=/v2ray;host=domain.me;cert=/pass/to/certificate.pem;key=/pass/to/certificate.key;loglevel=none",
"mode": "tcp_only"
}

Как видите, параметры не сложно понять:

  • В поле «server» вписываем localhost, т.к. перед сервером shadowsocks у нас будет висеть web-сервер.
  • В качестве «server_port» нужно указать порт 8008.
  • «password» — конечно же, делайте пароль подлиннее и рандомнее (используйте генератор паролей).
  • «timeout» — время, после которого закрывается соединение, если не поступило никаких данных. На сервере лучше поставить это значение побольше, но не более 600.
  • «method» — алгоритм шифрования,  «xchacha20-ietf-poly1305» очень надёжен, такой трафик никакой злоумышленник не расшифрует, он работает быстро даже на утюге, не поддерживающем аппаратное ускорение шифрования.
  • «fast_open» — быстрое открытие соединений, работает на ядрах старше 3.16.
  • «reuse_port» — в много поточном приложении позволяет каждому потоку напрямую привязаться к tcp socket’y (адрес:порт). Это позволяет быстрее принимать пакеты.
  • «wokers» — количество ядер, доступных серверу.
  • «nameserver» — будем использовать свой сервер имен: "127.0.0.1" (это наш Unbound, если не устанавливали, укажите 1.1.1.1. Как установить и настроить Unbound я рассказывал здесь).
  • «plugin» — здесь мы указываем используемый в сервере плагин, в нашем случае v2ray-plugin.
  • «plugin_opts» — опции плагина. В поле host= нужно вписать имя домена, которым вы управляете (сюрприз: мы будем регистрировать собственный домен). Поле cert= содержит путь до файла сертификата нашего домена, а поле key= путь до ключа сертификата (сертификат и ключ нам выдаст Cloudflare). Данные файлы разместите по адресу /etc/ssl/. Поле path=/ отвечает за секрет на web-сервере nginx, по которому он будет перенаправлять наш трафик на плагин v2ray, данное поле может быть сложным и длинным как пароль.
  • «mode»:«tcp_only» включает передачу данных только по TCP, так как будем работать по websocket-tls. 

Теперь немного отвлечемся от настройки сервера и пойдем зарегистрируем себе доменное имя. Можно воспользоваться бесплатным сервисом freenom.com

который выдаст вам домен на год с последующим продлением, но у меня не получилось, т.к. работающая в автоматическом режиме capcha не хотела признавать во мне человека. Я воспользовался dynadot.com:

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

Когда зарегистрировали домен, идете на Cloudflare.com, создаете бесплатный аккаунт, и вписываете туда ваш новенький домен.

Ждете некоторое время, прежде чем Cloudflare опросит авторитативные DNS-серверы и найдет регистратора вашего домена (может потребоваться несколько минут). После этого откроется следующее окно с выбором тарифного плана - берем бесплатную версию и заполняем две A записи для нашего домена - в них указываем ipv4 адрес нашего сервера Shadowsocks: одна просто domain.me, вторая www.domain.me, плюс еще можно добавить AAAA запись для ipv6 адресации.

После этого Cloudflare выдаст нам неймсерверы, которые необходимо скопировать и вставить в панель управления у регистратора домена. Для этого в dynadot вам надо пройти в Управление доменами, щелкнуть на свой зарегистрированный домен, перейти в настройки DNS, нажать Управление и в выпадающем списке выбрать Серверы имен (Nameservers):

Таким же способом вы можете сформировать подпись DNSSEC для своего домена. После этого возвращаемся в панель управления Cloudflare и заходим во вкладку SSL/TLS:

В Overview выбираем режим Full (Strict). В разделе Edge Certificates включаем все настройки безопасности: Always Use HTTPS, Minimum TLS Version выбираете 1.3 (и тут можно попасть в ловушку, потому что, как оказывается, не все сети поддерживают обмен по TLS1.3, поэтому будьте внимательны), Opportunistic Encryption, Onion Routing, TLS 1.3, Automatic HTTPS Rewrites (для работы под TLS1.3 нужен клиент Android версии не ниже 8-й). Идете в раздел Origin Certificates нужно выпустить себе сертификат, по которому наш web-сервер будет взаимодействовать с Cloudflare.

Преимущество данного способа в том, что полученный сертификат будет работать только с бэк-ендом Cloudflare: если вы или кто-то другой захочет напрямую подключиться к вашему серверу, он получит ошибку сертификата, т.к. данный сертификат опознается только Cloudflare. Вам также не нужно связываться с Let's Encrypt и перевыпускать себе сертификат каждые 90 дней.

В следующем окне у вас будет два поля: сам сертификат и ключ к нему. Их надо скопировать в два файла: domain.me.pem и domain.me.key.

Файлы необходимо разместить на сервере в папке /etc/ssl/ и установить права на чтение (убрать права на запись и обязательно указывайте имя с .tld). Пути к этим файлам нужно вписать в наш файл конфигурации shadowsocks в раздел «plugin_opts»: поле cert= и поле key=.  После завершения возни с сертификатом перейдите во вкладку Firewall консоли Cloudflare, раздел Settings и отключите все функции:

Теперь вернитесь в консоль вашего сервера.

Отредактируйте файл /etc/sysctl.conf, вписав в конец следующую информацию:

# tcp bbr

net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
net.ipv4.tcp_notsent_lowat = 16384
net.ipv6.icmp.echo_ignore_all=1
net.ipv4.icmp_echo_ignore_all=1
kernel.sysrq=0
kernel.core_uses_pid=1
net.ipv4.tcp_syncookies=1
kernel.msgmnb=65536
kernel.msgmax=65536
kernel.shmmax=68719476736
kernel.shmall=4294967296
net.ipv4.conf.all.accept_source_route=0
net.ipv4.conf.default.accept_source_route=0
net.ipv4.conf.all.log_martians=1
net.ipv4.conf.default.log_martians=1
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.default.send_redirects=0
net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.default.rp_filter=0
net.ipv4.icmp_echo_ignore_broadcasts=1
net.ipv4.icmp_ignore_bogus_error_responses=1
net.ipv4.conf.all.secure_redirects=0
net.ipv4.conf.default.secure_redirects=0
kernel.randomize_va_space=1
net.ipv4.tcp_fastopen=3

#options for ss

fs.file-max = 51200
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.core.netdev_max_backlog = 250000
net.core.somaxconn = 4096
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.ip_local_port_range = 10000 65000
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.tcp_fastopen = 3
net.ipv4.tcp_mem = 25600 51200 102400
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
net.ipv4.tcp_mtu_probing = 1

Не забудьте применить изменения без перезагрузки командой

~# sysctl -p

Проверяем результат, команда:

~# sysctl net.ipv4.tcp_available_congestion_control

должна показывать net.ipv4.tcp_available_congestion_control = reno cubic bbr.

Также нам надо установить плагин v2ray, который, собственно, и будет обфусцировать трафик shadowsocks под https. Выполняем следующие команды:

~# cd /usr/local/bin

~# wget https://github.com/shadowsocks/v2ray-plugin/releases/download/v1.2.0/v2ray-plugin-linux-amd64-v1.2.0.tar.gz && tar xf v2ray-plugin-linux-amd64-v1.2.0.tar.gz

~# mv v2ray-plugin_linux_amd64 v2ray-plugin

~# setcap 'cap_net_bind_service=+eip' v2ray-plugin

После этого у вас в папке /usr/local/bin будет лежать файл v2ray-plugin. Его трогать не надо. Сам плагин мы скачиваем вручную из папки релизов https://github.com/shadowsocks/v2ray-plugin/releases. Отсюда же вы можете потом обновлять плагин по мере выхода новых стабильных версий, либо можете скачивать отсюда https://circleci.com/gh/shadowsocks/v2ray-plugin промежуточные (нужно только входить в каждый релиз и в конце адресной строки приписывать #artifacts, чтобы это выглядело вот так: https://circleci.com/gh/shadowsocks/v2ray-plugin/55#artifacts).

Устанавливаем nginx:

~# apt install nginx && systemctl status nginx

если inactive, значит 80 порт чем-то занят. Для чего нам web-сервер? Для того, чтобы, если кто захочет проверить, что это за сайт такой и "постучит" по нашему адресу, дверь ему бы открыл дворецкий и вежливо  направил на замечательный сайт с Конституцией.

Открываем файл /etc/nginx/sites-available/default в редакторе, удаляем содержимое и вставляем:

server {

    listen 80;

    listen [::]:80;

    server_name <домен>;

    return 301 https://$host$request_uri;

    root /usr/share/nginx/html/<домен>;

    index index.html;

server {

        listen       443 ssl http2;

        listen       [::]:443 ssl http2;

        server_name  <домен>;

        root         /usr/share/nginx/html/<домен>;

        index index.html;

        ssl_certificate /etc/ssl/<домен>.pem;

        ssl_certificate_key /etc/ssl/<домен>.key;

        ssl_session_cache shared:SSL:1m;

        ssl_session_timeout  10m;

        ssl_ciphers HIGH:!aNULL:!MD5;

        ssl_prefer_server_ciphers on;

        location / {

                proxy_pass http://constitution.ru/;

 proxy_redirect off;
        }

        location /v2ray {

            proxy_redirect off;

            proxy_http_version 1.1;

            proxy_pass https://localhost:8008;

            proxy_set_header Host $http_host;

            proxy_set_header Upgrade $http_upgrade;

            proxy_set_header Connection "upgrade";

        }

}

Здесь на месте <домен> вам надо вписать свой зарегистрированный домен. В месте proxy_pass http://constitution.ru/; мы вписываем любой http сайт для редиректа.

Также откройте файл /etc/nginx/nginx.conf и раздел events приведите к следующему виду:

events {
worker_connections 65536;
multi_accept on;
accept_mutex off;
}

Рестартуем nginx:

~# systemctl restart nginx && systemctl status nginx

Запускаем наш сервер:

~# systemctl enable shadowsocks-libev.service && systemctl restart shadowsocks-libev && systemctl status shadowsocks-libev

Смотрите /var/log/syslog на наличие ошибок. Не забудьте открыть порты 80 и 443 в Firewall.

Настройка Android-клиента

Андроид-клиент скачиваем отсюда, а отсюда скачиваем плагин v2ray (для iOS используйте Shadowrocket). Настраивается клиент достаточно просто:

Задаем имя профиля, в раздел Сервер вписываем наш домен, который привязан к нашему VPS через Cloudflare (резолвится он соответственно будет также ip-адресом, принадлежащим CDN). Удаленный порт 443, пароль - как на сервере, метод шифрования как на сервере.

В поле Удаленный DNS указываем ссылку на поднятый на нашем сервере Unbound, просто прописывая 127.0.0.1 (как альтернатива - можете использовать резолвер от провайдера VPS, это будет самый быстрый вариант, но не самый безопасный). Плагин выставляем v2ray и тыкаем на его настройки:

Транспортный режим выбираем websocket-tls, Hostname - наш домен, Path - вписываем /v2ray, Concurrent connections можно оставить 1, разницы нет, если увеличивать. И поле сертификат оставляем пустым. Все сохраняем, жмем на кнопку самолетика, если подключились, должны обновляться данные скачивания/загрузки. Если выдало ошибку, перепроверяйте, все ли вы сделали правильно.

Важный момент по поводу клиента для Андроид. В настройках профиля есть пункт "Режим VPN для выбранных приложений", советую ее включить и выбрать в ней третью опцию "В обход прокси". Туда следует отправить приложения, которые вас идентифицируют, например, мобильный банкинг, Госуслуги и пр.

По поводу скорости:

Просадка есть, но она не критичная. Гораздо сильнее вырастает ping (у меня где-то в 4 раза). К сожалению, Cloudflare не располагает собственной сетью на территории РФ, из-за этого маршрут трафика может значительно увеличиться, но возможно, что мы придем к такой ситуации, когда другого выхода получить свободный Интернет у нас не останется.

Пробуем скрестить Shadowsocks, v2ray и OpenWRT

Почему пробуем? Потому что нормального материала на русском языке по данному вопросу мне найти не удалось, все приходится делать по китайским гайдам. Итак, сначала подготовим роутер к установке shadowsocks:

~# opkg update

~# opkg install ip-full ipset iptables-mod-tproxy libpthread ca-bundle ca-certificates wget

Добавим ключ подписи gpg автора пакета shadowsocks:

~# wget -qO /tmp/openwrt-dist.pub http://openwrt-dist.sourceforge.net/openwrt-dist.pub

~# opkg-key add /tmp/openwrt-dist.pub

~# rm /tmp/openwrt-dist.pub

Нужно открыть Luci, зайти Sysytem -> Software -> Configuration и в раздел "Пользовательские источники" добавить два канала:

src/gz openwrt_dist http://openwrt-dist.sourceforge.net/packages/base/arm_cortex-a15_neon-vfpv4

src/gz openwrt_dist_luci http://openwrt-dist.sourceforge.net/packages/luci

Вместо arm_cortex-a15_neon-vfpv4 в первой строке вам надо вписать свою архитектуру роутера, посмотрев ее в ссылках системных каналов выше. Обновляемся и устанавливаем пакеты:

~# opkg update

~# opkg install shadowsocks-libev luci-app-shadowsocks

Пакет v2ray тоже будем ставить руками из гита, присутствуют не все архитектуры, если своей не нашли, значит вам не повезло.

~#  cd /tmp

~# wget https://github.com/honwen/openwrt-v2ray-plugin/releases/download/v1.1.0/v2ray-plugin_1.1.0-20190219_arm_cortex-a15_neon-vfpv4.ipk

~# mv v2ray-plugin_1.1.0-20190219_arm_cortex-a15_neon-vfpv4.ipk v2ray-plugin.ipk

~# opkg install v2ray-plugin.ipk

Затем в Luci мы получаем отдельный сервис в разделе Services: Shadowsocks-libev.

Раздел Servers Manage заполняется также как и остальные клиенты, если бы не одно большое НО: мне так и не удалось заставить клиент Shadowsocks-libev работать вместе с v2ray плагином. Точнее запустить получилось, но трафика никакого пропустить не смог.

Неприятная особенность также в том, что в разделе Адрес сервера нельзя указать доменное имя, принимает только ipv4. Но даже подставив ipv4-адрес Cloudflare, в который резолвится мой домен, мне не удалось подключиться.

Оставлю это для более пытливых умов. Но кое-что на маршрутизаторе стоит сделать: установить шифрующий в DNS-over-TLS резолвер Stubby. Дело в том, что для использования shadowsocks нам постоянно нужно будет разрешать наше доменное имя в системном резолвере. Если у вас стоит маршрутизатор на OpenWRT, по-умолчанию он берет вышестоящие резолверы от провайдера. Так делать небезопасно. Но системный резолвер мало заменить на, к примеру, 1.1.1.1. Ведь в этом случае DNS-запросы все равно будут ходить открытым текстом. Необходимо их шифровать, и для этого-то нам и понадобится Stubby (я уверен, что рано или поздно мы все придем к использованию eSNI, и плагин v2ray реализует его поддержку - таким образом мы зашифруем все оставшиеся данные, и провайдер будет видеть только ip-адрес назначения в сети Cloudflare).

~# opkg update

~# opkg install getdns stubby

Теперь надо настроить Stubby: в WinSCP открываете файл /etc/config/stubby. Установите option manual '0' в option manual '1', сохраните изменения. После этого в WinSCP открываете файл /etc/stubby/stubby.yml
Удаляете все содержимое файла и вставляете следующий конфиг.

Вносим изменения в /etc/config/dhcp:

option noresolv '1'
list server '127.0.0.1#5453'
list server '/pool.ntp.org/84.200.69.80'

Далее через графический интерфейс (Luci) идем в Network->Interface->Wan, Edit->Advanced Settings->Убираем галочку из поля "Use DNS servers advertised by peer" и вписываем в качестве сервера DNS 127.0.0.1. После этого перезагружаем роутер.

Что ж, если не удалось настроить OpenWRT (он и без обфускации показывал не более 70 Мбит/сек), займемся клиентом для Windows.

Клиент Windows

Сам клиент можно скачать отсюда, не забывайте сюда заглядывать и обновлять. Сам архив надо обязательно распаковать в отдельную папку. Туда же надо положить файл плагина v2ray, предварительно скачав его отсюда (выбирайте windows-amd64). Переименовывать файл не надо, оставляйте как есть.

Запустите исполняемый файл Shadowsocks.exe. Раз это первый запуск, появится окно добавления сервера, где нужно ввести доменное имя, порт, пароль и алгоритм шифрования:

В разделе Plugin Program указывайте имя исполняемого файла плагина v2ray (без расширения, перепроверяйте операционную систему), в опциях плагина прописываете:

tls;fast-open;path=/v2ray;host=domain.me

Сертификат здесь нигде указывать не нужно (domain.me везде заменяйте на свой домен). 

После нажатия ОК сервер добавится в список слева и окно скроется. При необходимости его можно вызвать нажатием правой кнопкой мыши по значку Windows-клиента Shadowsocks в трее — Servers — Edit Servers.

Чтобы инициировать подключение к настроенному серверу, нужно переключить системный прокси: в меню System-Proxy -> Global - это включит системный прокси вашей системы. Пункт Disable выключает проксирование, а PAC - это специальный набор правил, который может формироваться автоматически на основании подсетей китайского Интернета. Также советую, чтобы не запускать программу каждый раз при включении ПК, отметить галкой пункт Start on Boot.

Вот такая скорость получается при пропуске трафика через CDN:

Как можно нивелировать потерю пинга? Можно установить программу Proxifier (скачать ее можно отсюда или отсюда). Программа позволяет вместо использования глобального системного прокси более гибко управлять подключением программ к нашему удаленному серверу. Т.е. как и с использованием VPN-Policy-Routing на маршрутизаторе, мы выборочно отправляем браузер, месенджер, голосовой чат через Shadowsocks, либо же наоборот: отправляем весь трафик на Shadowsocks, а избранные программы отправляем напрямую через нашего провайдера.

На этом пока все. Если захотите что-то исправить или уточнить, добро пожаловать в комментарии.

Подпишитесь на наш канал в Яндекс.Дзен или telegram-канал @overclockers_news - это удобные способы следить за новыми материалами на сайте. С картинками, расширенными описаниями и без рекламы.
Оценитe материал
рейтинг: 4.7 из 5
голосов: 24

Комментарии Правила

Возможно вас заинтересует

Популярные новости

Сейчас обсуждают