June 14, 2024

Shadowsocks + Cloak

1. Введение

Shadowsocks был одним из первых протоколов для обхода блокировок в Китае, но со временем DPI системы научились его распознавать и блокировать. Не исключается такой вариант событий и в нашей стране, так что для сокрытия трафика Shadowsocks предлагается множество вариантов обфускаторов в виде плагинов. Одним из таких плагинов является Cloak. Для шифрования между серверной и клиентской частью Cloak используется асимметричное шифрование на базе открытого и закрытого ключа, закрытая часть всегда остается на сервере, открытая передается клиенту. С помощью ключевой пары клиент и сервер согласуют сеансовый симметричный ключ для дальнейшей передачи данных между клиентом и сервером. Аналогичная схема PFS применяется в HTTPS сеансах с использованием x.509 сертификатов или SSH. Варианты шифрования поддерживаемые Cloak:

  • plain
  • aes-128-gcm
  • aes-256-gcm (alias aes-gcm)
  • chacha20-poly1305

Так как 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

USDT/TRC20: TW4ZRcrb4qBRb9uSNiu9wJCWveCp4rLoGL

:)