【Network】Shadowsocks 总结

Posted by 西维蜀黍 on 2019-06-19, Last Modified on 2024-08-28

Shadowsocks Server

Shadowsocks Server 的实现

  • shadowsocks: The original Python implementation.

  • shadowsocks-libev: Lightweight C implementation for embedded devices and low end boxes. Very small footprint (several megabytes) for thousands of connections.

  • go-shadowsocks2: Another Go implementation focusing on core features and code reusability.

  • shadowsocks-rust: A rust port of shadowsocks.

  • shadowsocks-libev

    • shadowsocks-libev,是一个基于 libev 库开发的 shadowsocks 代理套件。包含ss-local,ss-redir,ss-tunnel,ss-server四部分。
    • ss-server是shadowsocks 的服务端程序。
    • ss-local是shadowsocks 客户端程序。
    • ss-redir是透明代理工具。
    • ss-tunnel是本地端口转发工具,通常用于解决 dns 污染问题。
  • go-shadowsocks2

  • shadowsocks-rust

Shadowsocks Server 的运行

shadowsocks-libev

前台运行

ssserver -p 443 -k password -m rc4-md5
# 使用配置文件
ssserver -c /etc/shadowsocks.json

后台运行

sudo ssserver -p 443 -k password -m rc4-md5 --user nobody -d start

如果要停止:

sudo ssserver -d stop

如果要检查日志:

sudo less /var/log/shadowsocks.log

shadowsocks-rust

Docker for shadowsocks-rust

docker run --name ssserver-rust \
  --restart always \
  -p 28388:28388/tcp \
  -p 28388:28388/udp \
  -v /home/sw/shadowsocks-rust/config.json:/etc/shadowsocks-rust/config.json \
  -dit ghcr.io/shadowsocks/ssserver-rust:latest
{
    "server": "192.168.18.10",
    "server_port": 28388,
    "password": "NmTVR^UlAK3&",
    "method": "chacha20-ietf-poly1305",
}

macOS

$ brew install shadowsocks-rust

$ ssserver -s "[::]:28390" -m "aes-256-gcm" -k "NmTVR^UlAK3&"

Linux

$ curl -LO https://github.com/shadowsocks/shadowsocks-rust/releases/download/v1.20.4/shadowsocks-v1.20.4.x86_64-unknown-linux-gnu.tar.xz; tar -xf shadowsocks-v1.20.4.x86_64-unknown-linux-gnu.tar.xz

$ vim server.conf
{
    "server": "192.168.18.120",
    "server_port": 8388,
    "password": "rwQc8qPXVsRpGx3uW+Y3Lj4Y42yF9Bs0xg1pmx8/+bo=",
    "method": "aes-256-gcm",
}

$ ./ssserver -c server.conf
via snap
sudo snap install shadowsocks-rust
# List services
snap services shadowsocks-rust

systemctl edit snap.shadowsocks-rust.ss



 sudo systemctl edit snap.shadowsocks-rust.ssserver-daemon.service
 
 


# Enable and start shadowsocks-rust.sslocal-daemon snap service
snap start --enable shadowsocks-rust.sslocal-daemon

# Show generated systemd service status
systemctl status snap.shadowsocks-rust.sslocal-daemon.service

# Override generated systemd service (configure startup options)
systemctl edit snap.shadowsocks-rust.sslocal-daemon.service

配置文件

You can use a configuration file instead of command line arguments.

Create a config file /etc/shadowsocks.json. Example:

{
    "server":"my_server_ip",
    "server_port":8388,
    "password":"mypassword",
    "method":"chacha20-ietf-poly1305",
    "fast_open": true
}

Explanation of the fields:

Name Explanation
server the address your server listens, specify 0.0.0.0 to bind to all IPs
server_port server port
local_address the address your local listens
local_port local port
password password used for encryption
timeout in seconds
method default: “aes-256-cfb”
fast_open use TCP_FASTOPEN, true / false
workers number of workers, available on Unix/Linux

加密方式

The strongest option is an AEAD cipher. The recommended choice is “chacha20-ietf-poly1305” or “aes-256-gcm”. Other stream ciphers are implemented but do not provide integrity and authenticity. Unless otherwise specified the encryption method defaults to “table”, which is not secure.

salsa20 and chacha20 are fast stream ciphers. Optimized salsa20 implementation on x86_64 is even 2x faster than rc4 (but slightly slower on ARM).

These legacy ciphers are either slow or not safe. Do not use them:

  • rc4
  • des-cfb
  • table
  • salsa20-ctr

参数

For a detailed and complete list of all supported arguments, you may refer to the man pages of the applications, respectively.

ss-[local|redir|server|tunnel|manager]

   -s <server_host>           Host name or IP address of your remote server.

   -p <server_port>           Port number of your remote server.

   -l <local_port>            Port number of your local server.

   -k <password>              Password of your remote server.

   -m <encrypt_method>        Encrypt method: rc4-md5,
                              aes-128-gcm, aes-192-gcm, aes-256-gcm,
                              aes-128-cfb, aes-192-cfb, aes-256-cfb,
                              aes-128-ctr, aes-192-ctr, aes-256-ctr,
                              camellia-128-cfb, camellia-192-cfb,
                              camellia-256-cfb, bf-cfb,
                              chacha20-ietf-poly1305,
                              xchacha20-ietf-poly1305,
                              salsa20, chacha20 and chacha20-ietf.
                              The default cipher is chacha20-ietf-poly1305.

   [-a <user>]                Run as another user.

   [-f <pid_file>]            The file path to store pid.

   [-t <timeout>]             Socket timeout in seconds.

   [-c <config_file>]         The path to config file.

   [-n <number>]              Max number of open files.

   [-i <interface>]           Network interface to bind.
                              (not available in redir mode)

   [-b <local_address>]       Local address to bind.
                              For servers: Specify the local address to use 
                              while this server is making outbound 
                              connections to remote servers on behalf of the
                              clients.
                              For clients: Specify the local address to use 
                              while this client is making outbound 
                              connections to the server.

   [-u]                       Enable UDP relay.
                              (TPROXY is required in redir mode)

   [-U]                       Enable UDP relay and disable TCP relay.
                              (not available in local mode)

   [-L <addr>:<port>]         Destination server address and port
                              for local port forwarding.
                              (only available in tunnel mode)

   [-6]                       Resolve hostname to IPv6 address first.

   [-d <addr>]                Name servers for internal DNS resolver.
                              (only available in server mode)

   [--reuse-port]             Enable port reuse.

   [--fast-open]              Enable TCP fast open.
                              with Linux kernel > 3.7.0.
                              (only available in local and server mode)

   [--acl <acl_file>]         Path to ACL (Access Control List).
                              (only available in local and server mode)

   [--manager-address <addr>] UNIX domain socket address.
                              (only available in server and manager mode)

   [--mtu <MTU>]              MTU of your network interface.

   [--mptcp]                  Enable Multipath TCP on MPTCP Kernel.

   [--no-delay]               Enable TCP_NODELAY.

   [--executable <path>]      Path to the executable of ss-server.
                              (only available in manager mode)

   [-D <path>]                Path to the working directory of ss-manager.
                              (only available in manager mode)

   [--key <key_in_base64>]    Key of your remote server.

   [--plugin <name>]          Enable SIP003 plugin. (Experimental)

   [--plugin-opts <options>]  Set SIP003 plugin options. (Experimental)

   [-v]                       Verbose mode.

Shadowsocks Server的优化

Ref

Optimize the shadowsocks server on Linux

First of all, upgrade your Linux kernel to 3.5 or later.

Step 1, increase the maximum number of open file descriptors

To handle thousands of concurrent TCP connections, we should increase the limit of file descriptors opened.

Edit the limits.conf

bash

sudo vi /etc/security/limits.conf

Add these two lines

* soft nofile 51200
* hard nofile 51200

# for server running in root:
root soft nofile 51200
root hard nofile 51200

Then, before you start the shadowsocks server, set the ulimit first

bash

ulimit -n 51200

Step 2, Tune the kernel parameters

The priciples of tuning parameters for shadowsocks are

  1. Reuse ports and conections as soon as possible.
  2. Enlarge the queues and buffers as large as possible.
  3. Choose the TCP congestion algorithm for large latency and high throughput.

Here is an example /etc/sysctl.conf of our production servers:

# max open files
fs.file-max = 51200

# max read buffer
net.core.rmem_max = 67108864
# max write buffer
net.core.wmem_max = 67108864
# max processor input queue
net.core.netdev_max_backlog = 250000
# max backlog
net.core.somaxconn = 4096

# resist SYN flood attacks
net.ipv4.tcp_syncookies = 1
# reuse timewait sockets when safe
net.ipv4.tcp_tw_reuse = 1
# turn off fast timewait sockets recycling
net.ipv4.tcp_tw_recycle = 0
# short FIN timeout
net.ipv4.tcp_fin_timeout = 30
# short keepalive time
net.ipv4.tcp_keepalive_time = 1200
# outbound port range
net.ipv4.ip_local_port_range = 10000 65000
 max SYN backlog
net.ipv4.tcp_max_syn_backlog = 8192
# max timewait sockets held by system simultaneously
net.ipv4.tcp_max_tw_buckets = 5000
# turn on TCP Fast Open on both client and server side
net.ipv4.tcp_fastopen = 3
net.ipv4.tcp_mem = 25600 51200 102400
# TCP receive buffer
net.ipv4.tcp_rmem = 4096 87380 67108864
# TCP write buffer
net.ipv4.tcp_wmem = 4096 65536 67108864
# turn on path MTU discovery
net.ipv4.tcp_mtu_probing = 1

# for high-latency network
net.ipv4.tcp_congestion_control = hybla

# for low-latency network, use cubic instead
# net.ipv4.tcp_congestion_control = cubic

Of course, remember to execute sysctl -p to reload the config at runtime.

TCP Fast Open

If both of your server and client are deployed on Linux 3.7.1 or higher, you can turn on fast_open for lower latency.

First set fast_open to true in your config.json.

Then turn on fast open on your OS temporarily:

echo 3 > /proc/sys/net/ipv4/tcp_fastopen

To turn on fast open permanently, add net.ipv4.tcp_fastopen = 3 into /etc/sysctl.conf

BBR(一种TCP拥塞控制算法)

使用BBR加速需要服务器端主机完整的内核版本为4.9+的支持,下面一Linode主机为例进行设置。

首先Linode主机提供的内核版本虽然大于4.9,但是内核却不完整,并不包含BBR组件,无法直接开启。所以我们要先安装完整内核(64位)。

升级Linux内核

BBR在Linux kernel 4.9引入。首先检查服务器kernel版本:

Bash

uname -r

如果其显示版本在4.9.0之下,则需要升级Linux内核,否则请忽略下文。

更新包管理器:

Bash

sudo apt update

查看可用的Linux内核版本:

Bash

sudo apt-cache showpkg linux-image

找到一个你想要升级的Linux内核版本,如“linux-image-4.10.0-22-generic”:

Bash

sudo apt install linux-image-4.10.0-22-generic

等待安装完成后重启服务器:

Bash

sudo reboot

删除老的Linux内核:

Bash

sudo purge-old-kernels

开启BBR

运行lsmod | grep bbr,如果结果中没有tcp_bbr,则先运行:

Bash

modprobe tcp_bbr
echo "tcp_bbr" >> /etc/modules-load.d/modules.conf

运行:

Bash

echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf

运行:

Bash

sysctl -p

保存生效。运行:

Bash

sysctl net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_congestion_control

若均有bbr,则开启BBR成功。

其他

Shadowsocks 中继(relay)

If you want your client connected to a Japan VPS, but you want a US IP.

Client <--> Japan VPS <--> US VPS

Shadowsocks Client

Shadowsocks Client的实现

  • shadowsocks-android: Android client.
  • shadowsocks-windows: Windows client.
  • shadowsocksX-NG: MacOS client.
  • shadowsocks-qt5: Cross-platform client for Windows/MacOS/Linux.

注意,shadowsocks-libev既包含了Shadowsocks Server(称为shadowsocks-libev-server),也包含了Shadowsocks Client(称为shadowsocks-libev)。

shadowsocksX-NG - macOS

https://github.com/shadowsocks/ShadowsocksX-NG

Reference