Shadowsocks + Cloak
1. Введение
Shadowsocks был одним из первых протоколов для обхода блокировок в Китае, но со временем DPI системы научились его распознавать и блокировать. Не исключается такой вариант событий и в нашей стране, так что для сокрытия трафика Shadowsocks предлагается множество вариантов обфускаторов в виде плагинов. Одним из таких плагинов является Cloak. Для шифрования между серверной и клиентской частью Cloak используется асимметричное шифрование на базе открытого и закрытого ключа, закрытая часть всегда остается на сервере, открытая передается клиенту. С помощью ключевой пары клиент и сервер согласуют сеансовый симметричный ключ для дальнейшей передачи данных между клиентом и сервером. Аналогичная схема PFS применяется в HTTPS сеансах с использованием x.509 сертификатов или SSH. Варианты шифрования поддерживаемые Cloak:
Так как Shadowsocks на своем уровне уже использует различные типы шифрования, в конфигурации Cloak можно использовать plain. Если вдруг перестанет работать, включить шифрование на уровне Cloak не составляет большого труда, оно настраивается на стороне клиента, дополнительная настройка на сервере не требуется. Так например трафик OpenVPN разработчики Cloak рекомендуют дополнительно шифровать, так как DPI системы научились распознавать его по отпечаткам.
2. Настройка Shadowsocks
Установку Shadowsocks я описывал ранее в статье https://teletype.in/@yachmenev/shadowsocks-rust, приведу только конфиг Shadowsocks
cat >/etc/shadowsocks/server.json <<HEREDOC { "udp_timeout": 300, "udp_max_associations": 512, "mode": "tcp_and_udp", "fast_open": true, "timeout": 300, "servers": [ { "server": "0.0.0.0", "server_port": 11443, "method": "aes-256-gcm", "password": "zZyWP+OBQWG5YmL0flJyNTZdeUORlZw1urCbIlhZHmA=" }, { "server": "0.0.0.0", "server_port": 12443, "method": "2022-blake3-aes-256-gcm", "password": "zZyWP+OBQWG5YmL0flJyNTZdeUORlZw1urCbIlhZHmA=", "users": [ { "name": "user1", "password": "XtXtAUk3wUWjvJ336HD69uTSTgRzVwBpon1ACj03py8=" }, { "name": "user2", "password": "2tP/krYV6RNBqM0xwXKwYi0af1Rs6lk23wpBHWYYoNo=" } ] } ] } HEREDOC
cat >/etc/shadowsocks/client.json <<HEREDOC { "udp_timeout": 300, "udp_max_associations": 512, "mode": "tcp_and_udp", "fast_open": true, "timeout": 300, "servers": [ { "server": "shadowsocks.example.com", "server_port": 11443, "method": "aes-256-gcm", "password": "zZyWP+OBQWG5YmL0flJyNTZdeUORlZw1urCbIlhZHmA=" }, { "disabled": true, "server": "shadowsocks.example.com", "server_port": 12443, "method": "2022-blake3-aes-256-gcm", "password": "zZyWP+OBQWG5YmL0flJyNTZdeUORlZw1urCbIlhZHmA=:XtXtAUk3wUWjvJ336HD69uTSTgRzVwBpon1ACj03py8=", } ] "locals": [ { "protocol": "socks", "local_address": "127.0.0.1", "local_port": 1080 }, { "protocol": "http", "local_address": "127.0.0.1", "local_port": 3128 }, ] } HEREDOC
Проверяем конфиги с помощью jq
ssservice server -c /etc/shadowsocks/server.json
ssservice local -c /etc/shadowsocks/client.json
Проверяем работу сервера и клиента shadowsocks
curl https://checkip.groupit.team curl --proxy socks5://127.0.0.1:1080 https://checkip.groupit.team
После того как убедились что у нас все работает, можно активировать и запустить службы:
systemctl enable --now shadowsocks-server
systemctl enable --now shadowsocks-client
3. Настройка Cloak
Установка Cloak как самостоятельных сервисов описана в статье https://teletype.in/@yachmenev/cloak
cat >/etc/cloak/server.json <<HEREDOC { "ProxyBook": { "ss11443": [ "tcp", "127.0.0.1:11443" ], "ss12443": [ "tcp", "127.0.0.1:12443" ] }, "BindAddr": [ ":443" ], "BypassUID": [ "yR5UJjyZ+JSWW239AUbscQ==" ], "RedirAddr": "mail.google.com", "PrivateKey": "oNbxJyE1JpQbmyc8QXZsbw2KUMpGrypsiG6eH7gQV3o=" } HEREDOC
cat >/etc/cloak/cloak-client-ss-aes-256-gcm <<HEREDOC { "Transport": "direct", "ProxyMethod": "ss11443", "EncryptionMethod": "plain", "UID": "yR5UJjyZ+JSWW239AUbscQ==", "PublicKey": "5SQ90GPAUWcYZbJM1NnLzhk2f8gtRlXLcCPaUUYcjU8=", "ServerName": "mail.google.com", "NumConn": 4, "BrowserSig": "chrome", "StreamTimeout": 300 } HEREDOC
cat >/etc/default/cloak-client-ss-aes-256-gcm <<HEREDOC LISTENIP=127.0.0.1 LISTENPORT=11443 REMOTESERVER="shadowsocks.example.com" REMOTEPORT=443 HEREDOC
cat >/etc/cloak/cloak-client-ss-2022-blake3-aes-256-gcm.json <<HEREDOC { "Transport": "direct", "ProxyMethod": "ss12443", "EncryptionMethod": "plain", "UID": "yR5UJjyZ+JSWW239AUbscQ==", "PublicKey": "5SQ90GPAUWcYZbJM1NnLzhk2f8gtRlXLcCPaUUYcjU8=", "ServerName": "mail.google.com", "NumConn": 4, "BrowserSig": "chrome", "StreamTimeout": 300 } HEREDOC
cat >/etc/default/cloak-client-ss-2022-blake3-aes-256-gcm <<HEREDOC LISTENIP=127.0.0.1 LISTENPORT=12443 REMOTESERVER="shadowsocks.example.com" REMOTEPORT=443 HEREDOC
systemctl enable --now cloak-client@ss-aes-256-gcm systemctl enable --now cloak-client@ss-2022-blake3-aes-256-gcm
Есть ограничение на количество символов в конфиге Cloak клиента: параметр "ProxyMethod" не должен превышать 12 символов. Не знаю по какой причине такие ограничения, баг это или фича, но это недокументированный момент и я не меньше часа потратил разбираясь почему не работает туннель.
4. Перенастройка клиента Shadowsocks на использование Cloak
Вариантов настройки связки Shadowsocks+Cloak рассмотрим два. Первым будет вариант самостоятельной службы cloak-client. Данный вариант позволяет подключить несколько клиентов shadowsocks с локального компьютера или из сети. Второй вариант - использование Сloak в качестве плагина Shadowsocks, такой вариант применения описан в SIP003 (Shadowsocks Improvement Proposal) https://shadowsocks.org/doc/sip003.html
4.1 Cloak как самостоятельная служба
Конфигурация службы cloak-client приведена в пункте 3, в текущем разделе настроим Shadowsocks на подключение к ней.
Перенастраиваем клиент Shadowsocks на порты прослушиваемые нашим Cloak клиентом 11443 и 12443 на адресе 127.0.0.1
Итоговый конфиг клиента Shadowsocks будет выглядеть следующим образом:
cat >/etc/shadowsocks/client.json <<HEREDOC { "udp_timeout": 300, "udp_max_associations": 512, "mode": "tcp_and_udp", "fast_open": true, "timeout": 300, "servers": [ { "server": "127.0.0.1", "server_port": 11443, "method": "aes-256-gcm", "password": "zZyWP+OBQWG5YmL0flJyNTZdeUORlZw1urCbIlhZHmA=" }, { "disabled": true, "server": "127.0.0.1", "server_port": 12443, "method": "2022-blake3-aes-256-gcm", "password": "zZyWP+OBQWG5YmL0flJyNTZdeUORlZw1urCbIlhZHmA=:XtXtAUk3wUWjvJ336HD69uTSTgRzVwBpon1ACj03py8=", } ] "locals": [ { "protocol": "socks", "local_address": "127.0.0.1", "local_port": 1080 }, { "protocol": "http", "local_address": "127.0.0.1", "local_port": 3128 }, ] } HEREDOC
То есть во всем конфиге меняется только адрес сервера для подключения shadowsocks-client
Перезапускаем службу клиента Shadowsocks:
systemctl restart shadowsocks-client
Проверяем что проксирование работает:
curl https://checkip.groupit.team curl --proxy socks5://127.0.0.1:1080 https://checkip.groupit.team
4.2 Cloak как плагин Shadowsocks
В данной конфигурации клиента Shadowsocks адрес сервера остается прежний, но порт подключения меняется на 443 (на сервере данный порт прослушивается службой cloak-server). Так же добавляется два новых параметра "plugin" и "plugin_opts" отвечающие за то какое приложение необходимо использовать в качестве плагина и какие опции ему передавать на вход. Данный способ все так же требует конфигурирования cloak-client, но не требует настройки службы, плагин подключается динамически по мере необходимости. Недостатком же является запуск только одним экземпляром клиента Shadowsocks на локальном компьютере без возможности предоставления сервиса для компьютеров локальной сети.
cat >/etc/shadowsocks/client.json <<HEREDOC { "udp_timeout": 300, "udp_max_associations": 512, "mode": "tcp_and_udp", "fast_open": true, "timeout": 300, "servers": [ { "server": "shadowsocks.example.com", "server_port": 443, "method": "aes-256-gcm", "password": "zZyWP+OBQWG5YmL0flJyNTZdeUORlZw1urCbIlhZHmA=", "plugin": "cloak-client", "plugin_opts": "/etc/cloak/cloak-client-ss-aes-256-gcm.json" }, { "disabled": true, "server": "shadowsocks.example.com", "server_port": 443, "method": "2022-blake3-aes-256-gcm", "password": "zZyWP+OBQWG5YmL0flJyNTZdeUORlZw1urCbIlhZHmA=:XtXtAUk3wUWjvJ336HD69uTSTgRzVwBpon1ACj03py8=", "plugin": "cloak-client", "plugin_opts": "/etc/cloak/cloak-client-ss-2022-blake3-aes-256-gcm.json" } ] "locals": [ { "protocol": "socks", "local_address": "127.0.0.1", "local_port": 1080 }, { "protocol": "http", "local_address": "127.0.0.1", "local_port": 3128 }, ] } HEREDOC
Серверная часть cloak-server подключается к Shadowsocks через loopback интерфейс с адресом 127.0.0.1 так что можем без проблем скрыть наличие Shadowsocks на нашем сервере.
sed -i 's/0.0.0.0/127.0.0.1/g' /etc/shadowsocks/server.json systemctl restart shadowsocks-server