shadowsocks
June 9, 2024

Установка и настройка Shadowsocks-rust

1. Установка сервера Shadowsocks-rust

1.1 Используемая документация

1.2 Дополнительное ПО

Для проверки корректности файлов JSON нам понадобится утилита jq. Установить ее можно из репозиториев или напрямую из git:

_URL="https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-amd64"
_APP="/usr/bin/jq"

wget -q -O ${_APP} ${_URL}
chmod a+x ${_APP}
chown 0:0 ${_APP}

unset _URL _APP

Проверку можно выполнить командой:

jq '.' <path_to_file>

1.3 Предварительная настройка системы

На странице Advanced configurations рекомендуют изменить ограничения на количество открытых файловых дескрипторов, но в файле /etc/security/limits.conf прямо сказано что для служб это не работает и применяется только для пользователей вошедших в систему через PAM. Чтобы изменить количество открытых файловых дескрипторов для службы, необходимо в файле конфигурации службы добавить строку:

LimitNOFILE=51200

Установим рекомендуемые системные переменные:

cat >/etc/sysctl.d/00-shadowsocks.conf <<HEREDOC
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_syncookies = 1
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
net.ipv4.tcp_congestion_control = hybla
HEREDOC

sysctl -p /etc/sysctl.d/00-shadowsocks.conf

1.4 Установка сервера Shadowsocks-rust

Настроим переменные для процесса установки:

URL="https://github.com/shadowsocks/shadowsocks-rust/releases/download/v1.19.2/shadowsocks-v1.19.2.x86_64-unknown-linux-musl.tar.xz"
CONF="/etc/shadowsocks-rust/server.json"
SERVICE="/etc/systemd/system/shadowsocks-rust.service"

Загружаем и устанавливаем Shadowsocks-rust из git:

wget -q -O - ${URL} | tar --xz --extract
install --mode=0755 --owner=root --group=root --preserve-timestamps -D --target-directory=/usr/bin ssmanager ssserver sslocal ssservice ssurl
rm ssmanager ssserver sslocal ssservice ssurl

ssserver - серверная часть Shadowsocks-rust
sslocal - клиентская часть Shadowsocks-rust
ssservice - серверная/клиентская часть Shadowsocks-rust
ssurl - утилита для генерации qr-code и/или ссылки на подключение к нашему серверу

Для нашего конфига будем использовать ssservice, хотя ни кто не запрещает заменить его на ssserver. Все приложения независимы друг от друга.

В данном примере будут использоваться алгоритмы шифрования использующие длину ключа 32 байта:

  • aes-256-gcm
  • 2022-blake3-aes-256-gcm

Алгоритм шифрования aes-256-gcm поддерживается всеми клиентами в отличие от более нового 2022-blake3-aes-256-gcm. В списке поддерживаемых алгоритмов актуальными числятся AEAD Ciphers и AEAD 2022 Ciphers, все остальные помечены как Deprecated.

AEAD Ciphers

  • aes-128-gcm
  • aes-256-gcm
  • chacha20-ietf-poly1305

AEAD 2022 Ciphers

  • 2022-blake3-aes-128-gcm
  • 2022-blake3-aes-256-gcm
  • 2022-blake3-chacha20-poly1305
  • 2022-blake3-chacha8-poly1305

Сгенерировать ключ можно через ssservice или openssl:

ssservice genkey --encrypt-method aes-256-gcm
openssl rand -base64 32

Можем сгенерировать один пароль для всех алгоритмов или под каждый алгоритм свой ключ. Для упрощения данного примера сделаем один ключ для всех алгоритмов поддерживаемых нашим сервером:

PASS=$(ssservice genkey --encrypt-method aes-256-gcm)

Создадим каталог для нашего будущего конфига:

mkdir -p $(dirname ${CONF})

И сам конфиг:

cat >${CONF} <<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": "${PASS}"
    },
    {
      "server": "0.0.0.0",
      "server_port": 12443,
      "method": "2022-blake3-aes-256-gcm",
      "password": "${PASS}"
    },
    {
      "disabled": true,
      "server": "0.0.0.0",
      "server_port": 13443,
      "method": "2022-blake3-aes-256-gcm",
      "password": "${PASS}",
      "users": [
        {
          "name": "user1",
          "password": "$(ssservice genkey --encrypt-method aes-256-gcm)"
        },
        {
          "name": "user2",
          "password": "$(ssservice genkey --encrypt-method aes-256-gcm)"
        }
      ]
    }
  ]
}
HEREDOC

Если мы хотим разграничить доступ по пользователям, с применением шифрования aes-256-gcm для этого придется использовать отдельный порт для каждого пользователя. В версии 2022-blake3-aes-256-gcm это поправили, стало возможным создавать дополнительные пользовательские пароли. Так же за счет этого стала возможна работа через relay (поддерживается в некоторых реализациях shadowsocks серверов). Формат пароля для пользователя указывается в виде пароля сервера и пароля пользователя разделенных двоеточием. Поддержка пользователей реализована не для всех алгоритмов AEAD 2022 Ciphers, только для 2022-blake3-aes-256-gcm. Если необходимо временно отключить какой-то из конфигов сервера, можно добавить строку "disabled": true, в начало соответствующей секции и перезапустить сервис shadowsocks-rust:

systemctl restart shadowsocks-rust.service

Пример конфигурации сервера и клиентов с разделением по пользователям:

server.json

{
      "server": "0.0.0.0",
      "server_port": 13443,
      "method": "2022-blake3-aes-256-gcm",
      "password": "zZyWP+OBQWG5YmL0flJyNTZdeUORlZw1urCbIlhZHmA=",
      "users": [
        {
          "name": "user1",
          "password": "XtXtAUk3wUWjvJ336HD69uTSTgRzVwBpon1ACj03py8="
        },
        {
          "name": "user2",
          "password": "2tP/krYV6RNBqM0xwXKwYi0af1Rs6lk23wpBHWYYoNo="
        }
      ]
}

user1.json

{
      "server": "shadowsocks.example.com",
      "server_port": 13443,
      "method": "2022-blake3-aes-256-gcm",
      "password": "zZyWP+OBQWG5YmL0flJyNTZdeUORlZw1urCbIlhZHmA=:XtXtAUk3wUWjvJ336HD69uTSTgRzVwBpon1ACj03py8="
	  "local_address": "127.0.0.1",
      "local_port": 1080
}

user2.json

{
      "server": "shadowsocks.example.com",
      "server_port": 13443,
      "method": "2022-blake3-aes-256-gcm",
      "password": "zZyWP+OBQWG5YmL0flJyNTZdeUORlZw1urCbIlhZHmA=:2tP/krYV6RNBqM0xwXKwYi0af1Rs6lk23wpBHWYYoNo="
	  "local_address": "127.0.0.1",
      "local_port": 1080
}

Создадим для запуска службы отдельного пользователя:

useradd --system --home-dir /nonexistent --no-create-home --shell /usr/sbin/nologin shadowsocks

В целом этого можно и не делать, тогда в конфиге службы можно не указывать параметры User и Group, но в целях безопасности лучше запускать службу от непривилегированного пользователя.

Теперь создадим Unit файл для нашей службы:

cat >${SERVICE} <<HEREDOC
[Unit]
Description=Shadowsocks-rust Server
Documentation=https://github.com/shadowsocks/shadowsocks-rust
Documentation=https://shadowsocks.org/doc/configs.html
After=network-online.target

[Service]
Type=simple
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
User=shadowsocks
Group=shadowsocks
LimitNOFILE=51200
ExecStart=/usr/bin/ssservice server -c ${CONF}

[Install]
WantedBy=multi-user.target
HEREDOC

Выполним reload для systemctl, чтобы наш файл службы появился в списке сервисов:

systemctl daemon-reload

Включим автозапуск службы и запустим её:

systemctl enable --now $(basename ${SERVICE})

Проверим что в процессе запуска нет ошибок и служба запустилась:

systemctl status $(basename ${SERVICE})

Удаляем наши переменные или закрываем консоль:

unset URL
unset CONF
unset SERVICE
unset PASS

2. Обновление сервера Shadowsocks-rust

URL="https://github.com/shadowsocks/shadowsocks-rust/releases/download/v1.19.2/shadowsocks-v1.19.2.x86_64-unknown-linux-musl.tar.xz"

systemctl stop shadowsocks-rust

wget -q -O - ${URL} | tar --xz --extract
install --mode=0755 --owner=root --group=root --preserve-timestamps -D --target-directory=/usr/bin ssmanager ssserver sslocal ssservice ssurl
rm ssmanager ssserver sslocal ssservice ssurl

systemctl start shadowsocks-rust
systemctl status shadowsocks-rust

unset URL

3. Удаление сервера Shadowsocks-rust

CONF="/etc/shadowsocks-rust/server.json"
SERVICE="/etc/systemd/system/shadowsocks-rust.service"

systemctl disable --now shadowsocks-rust
rm ${SERVICE}
rm -rf $(dirname ${CONF})
rm /usr/bin/{ssmanager,ssserver,sslocal,ssservice,ssurl}

userdel shadowsocks

unset CONF
unset SERVICE

4. Установка клиента Shadowsocks-rust Linux

Установка клиентской части Shadowsocks-rust выполняется точно таким же образом как и серверной, разница будет только в конфигурации:

URL="https://github.com/shadowsocks/shadowsocks-rust/releases/download/v1.19.2/shadowsocks-v1.19.2.x86_64-unknown-linux-musl.tar.xz"
CONF="/etc/shadowsocks-rust/client.json"
SERVICE="/etc/systemd/system/shadowsocks-rust.service"

wget -q -O - ${URL} | tar --xz --extract
install --mode=0755 --owner=root --group=root --preserve-timestamps -D --target-directory=/usr/bin ssmanager ssserver sslocal ssservice ssurl
rm ssmanager ssserver sslocal ssservice ssurl

mkdir -p $(dirname ${CONF})

cat >${CONF} <<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="
    },
    {
      "server": "shadowsocks.example.com",
      "server_port": 12443,
      "method": "2022-blake3-aes-256-gcm",
      "password": "zZyWP+OBQWG5YmL0flJyNTZdeUORlZw1urCbIlhZHmA="
    },
    {
      "disabled": true,
      "server": "shadowsocks.example.com",
      "server_port": 13443,
      "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

useradd --system --home-dir /nonexistent --no-create-home --shell /usr/sbin/nologin shadowsocks

cat >${SERVICE} <<HEREDOC
[Unit]
Description=Shadowsocks-rust Client
Documentation=https://github.com/shadowsocks/shadowsocks-rust
Documentation=https://shadowsocks.org/doc/configs.html
After=network-online.target

[Service]
Type=simple
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
User=shadowsocks
Group=shadowsocks
LimitNOFILE=51200
ExecStart=/usr/bin/ssservice local -c ${CONF}

[Install]
WantedBy=multi-user.target
HEREDOC

systemctl daemon-reload

systemctl enable --now $(basename ${SERVICE})

systemctl status $(basename ${SERVICE})

unset URL
unset CONF
unset SERVICE

Не забываем что параметры "server_port", "method", "password" в параметрах клиента должны совпадать с аналогичными параметрами в конфиге сервера.

Параметр "local_address": "127.0.0.1" в конфиге клиента задает адрес на котором служба прослушивает подключения. Если мы поднимаем сервер внутри локальной сети и хотим чтобы через него могли подключаться другие пользователи локальной сети по протоколам HTTP и SOCKS5, прослушиваемый адрес нужно заменить на 0.0.0.0

Пример конфигурации сервера соответствующего вышеприведённому конфигу клиента:

CONF="/etc/shadowsocks-rust/server.json"
SERVICE="/etc/systemd/system/shadowsocks-rust.service"

mkdir -p $(dirname ${CONF})

cat >${CONF} <<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="
    },
    {
      "disabled": true,
      "server": "0.0.0.0",
      "server_port": 13443,
      "method": "2022-blake3-aes-256-gcm",
      "password": "zZyWP+OBQWG5YmL0flJyNTZdeUORlZw1urCbIlhZHmA=",
      "users": [
        {
          "name": "user1",
          "password": "XtXtAUk3wUWjvJ336HD69uTSTgRzVwBpon1ACj03py8="
        },
        {
          "name": "user2",
          "password": "2tP/krYV6RNBqM0xwXKwYi0af1Rs6lk23wpBHWYYoNo="
        }
      ]
    }
  ]
}
HEREDOC

cat >${SERVICE} <<HEREDOC
[Unit]
Description=Shadowsocks-rust Server
Documentation=https://github.com/shadowsocks/shadowsocks-rust
Documentation=https://shadowsocks.org/doc/configs.html
After=network-online.target

[Service]
Type=simple
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
User=shadowsocks
Group=shadowsocks
LimitNOFILE=51200
ExecStart=/usr/bin/ssservice server -c ${CONF}

[Install]
WantedBy=multi-user.target
HEREDOC

systemctl daemon-reload

systemctl enable --now $(basename ${SERVICE})

systemctl status $(basename ${SERVICE})

unset URL
unset CONF
unset SERVICE

В браузере, где у нас установлена клиентская служба, прописываем адрес прокси 127.0.0.1 и порт HTTP прокси сервера 3128 или SOCKS5 прокси 1080. Если клиент подключается по сети вместо 127.0.0.1 указываем адрес сервера в локальной сети где установлена клиентская часть Shadowsocks-rust.

5. Установка клиента Shadowsocks-rust Windows

Скачиваем архив https://github.com/shadowsocks/shadowsocks-rust/releases/download/v1.19.2/shadowsocks-v1.19.2.x86_64-pc-windows-msvc.zip

Распаковываем и копируем файл sswinservice.exe в %WINDIR%\System32\

Открываем Блокнот или любой другой текстовый редактор под админом, вставляем из буфера конфиг:

{
  "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="
    },
    {
      "server": "shadowsocks.example.com",
      "server_port": 12443,
      "method": "2022-blake3-aes-256-gcm",
      "password": "zZyWP+OBQWG5YmL0flJyNTZdeUORlZw1urCbIlhZHmA="
    },
    {
      "disabled": true,
      "server": "shadowsocks.example.com",
      "server_port": 13443,
      "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
    },
  ]
}

Сохраняем файл %WINDIR%\System32\ssclient.json

Устанавливаем и запускаем службу:

New-Service -Name 'ShadowsocksClient' -DisplayName 'Shadowsocks Client' -Description 'Shadowsocks-rust Client Service' -BinaryPathName '%WINDIR%\System32\sswinservice.exe local -c "ssclient.json"'
Start-Service "ShadowsocksClient"

Проверяем что служба запустилась:

Get-Service "ShadowsocksClient" | fl *

Управление службой:

Start-Service "ShadowsocksClient"
Restart-Service "ShadowsocksClient"
Stop-Service "ShadowsocksClient"

Удаление службы:

Remove-Service "ShadowsocksClient"

USDT/TRC20: TW4ZRcrb4qBRb9uSNiu9wJCWveCp4rLoGL