0%

Shadowsocks-libev的Server和Client(for Linux)配置

文献综述

VPN, VPS, Shadowsocks(ss), Shadowsocks-R(ssr)

浅谈vpn、vps、Proxy以及shadowsocks之间的联系和区别 - Thomas Xu - Medium
各种加密代理协议的简单对比 - Yachen Liu - Medium
Vpn与ss/ssr的区别 | DeepOnion Forum

VPS推介

在路上on the way - 走别人没走过的路,让别人有路可走
flyzy小站 - Learning on the way
flyzy小站 | flyzy小站,GitHub Pages分部
逗比根据地 - 世界那么逗,我想出去看看

Shadowsocks项目

时间最近的一篇教程: 自己搭建服务器 · 科学上网相关知识总结
官网: Shadowsocks - A secure socks5 proxy
项目合集: shadowsocks, 有多个发行版, 用C/C++写就的有

(后两者共同指向同一个网站: librehat/shadowsocks Copr.) 2015年, clowwindy因喝茶事件被迫停止了shadowsocks的维护, 并删除了其开源在GitHub上的代码, Python版就此停滞. 但其它版本仍处于维护更新中. 其中, 更新最频繁, 新技术跟进最快的是由@madeye维护的shadowsocks-libev版本.

Server

Install

server & client(for linux) 都要做的:

1
2
3
4
5
6
git clone https://github.com/shadowsocks/shadowsocks-libev.git
cd shadowsocks-libev
mkdir -p ~/build-area/
cp ./scripts/build_deb.sh ~/build-area/
cd ~/build-area
./build_deb.sh

Configuration Files

各版本的默认配置文件如下

1
2
3
4
vim /etc/shadowsocks-python/config.json  #Shadowsocks-Python
vim /etc/shadowsocks-r/config.json #ShadowsocksR
vim /etc/shadowsocks-go/config.json #Shadowsocks-Go
vim /etc/shadowsocks-libev/config.json #Shadowsocks-libev

内容无外乎

1
2
3
4
5
6
7
8
9
10
{
"server": "134.209.239.83", //["::1", "127.0.0.1"],
"server_port": 8388,
//"local_address": "127.0.0.1",
//"local_port": 1080,
"password": "1a2b3c4d5e6f7g",
"timeout": 60,
"method": "chacha20-ietf-poly1305", //以前常见的是aes-256-cfb
"mode": "tcp_and_udp"
}

Remarks: 端口的取值一般要>1024, <=65535=2^16-1. 这一说法来自于(自己搭建服务器 · 科学上网相关知识总结), 像默认端口22肯定是不能被Shadowsocks登录的, 但必须保留22端口用于本地shell的ssh登录.

除了/etc/shadowsocks-libev/config.json, Shadowsocks-libev还有三个文件是很关键的:

1
2
3
4
5
6
7
8
9
vim /etc/default/shadowsocks-libev
CONFFILE="/etc/shadowsocks-libev/config.json" #line15

vim /lib/systemd/system/shadowsocks-libev.service
EnvironmentFile=/etc/default/shadowsocks-libev #line20
ExecStart=/usr/bin/ss-server -c $CONFFILE $DAEMON_ARGS #line24

vim /lib/systemd/system/'shadowsocks-libev-local@.service'
ExecStart=/usr/bin/ss-local -c /etc/shadowsocks-libev/%i.json #line21

最后一个跟本地客户端有关.

开启服务 & Multi-User Management

Ref:
Shadowsocks-libev 多端口配置方式 | Nonu’s Lab
搬瓦工Shadowsocks安装及配置多用户(服务端) | HuiHut(这里有用port_password这个格式来管理多用户, 然而, 亲测该配置不能用)

博客上常见的有两种启动方式:

  1. ss-server /path/to/config.json
  2. systemctl restart shadowsocks-libev

初看, 方法2跟nginx的很像. 然而, 它只能管理一个config.json, 即只能管理一个用户. $CONFFILE/etc/default/shadowsocks-libevline24里面的一个变量. 可以在这上面下功夫吗? 一次失败的尝试是给/etc/default/shadowsocks-libev加上CONFFILE1, CONFFILE2, …, 并在/lib/systemd/system/shadowsocks-libev.service第24行加上ExecStart … $CONFFILE1, … 执行systemctl restart shadowsocks-libev后没有报错, 但/lib/systemd/system/shadowsocks-libev.serviceExecStart只会读取最后一行的$CONFFILE, 前面的CONFFILE都跳过的. 这都说明systemctl restart shadowsocks-libev只能管理一个config.json. (或者对那几个关键文件适当修改是能够做到多用户启动的, 但这要 非常熟悉shell命令 才行.)

实际上, 开发团队早就造出了shadowsocks-manager. 不过这家伙似乎是图形化界面, 在服务端上并不好用(似乎服务器对应要装gnome-shell), 所以这里仅举出如何调用相关的包, 并不详解怎么做.

1
2
npm i -g shadowsocks-manager
ss-manager -c /etc/shadowsocks-libev/config.json

shadowsocks/shadowsocks-manager: A shadowsocks manager tool for multi user and traffic control.
Shadowsocks-Manager

总之, 在我的服务器配置里我采用如下管理方案:

命令 被管理的文件 Port 用途
systemctl restart shadowsocks-libev config.json 8388 自用自测
./shadowsocks-libev-run.sh config_1.json, config_2.json, … 1024-65536 多用户管理, 积德

shadowsocks-libev-run.sh的写法为

1
2
ss-server -c /etc/shadowsocks-libev/config_1.json &
ss-server -c /etc/shadowsocks-libev/config_2.json &

别忘了chmod 755 shadowsocks-libev-run.sh.

执行如下命令就能够打开并监控所有shadowsocks-libev的配置了

1
2
3
4
5
6
7
8
systemctl restart shadowsocks-libev               #启动config.json
systemctl enable shadowsocks-libev #开机启动
systemctl status shadowsocks-libev #查看状态
/etc/shadowsocks-libev/shadowsocks-libev-run.sh #一键启动config_1.json, config_2.json, ...
netstat -anptuo | grep 8388 #p: 显示PID进程号; tu: 指明显示TCP端口和UDP端口. anp参数必须有
lsof -i:8388 #功能同上
netstat -anptuo | grep ss-server
ps -ef | grep ss-server

最后一条是检测网络端口的监听状况. You can see that ports 8388, 1234, 5678 are listened. However, 他们还暂时不能连上: 因为服务器的防火墙还没开通对应端口.
虽然写shell script的方法看上去有点笨, 如果服务器重启, 得自己再执行一遍; 但由于服务器不出意外从不关机, 这种笨方法是能用的.

Remarks: 如果启动时报出一个很物理的错:

1
This system doesn't provide enough entropy to quickly generate high-quality random numbers

原因也正如提示中所说, 系统没有足够的熵, 这时候可以通过安装rng-tools来解决这个问题. 如果不安装rng-tools, 等待一定的时间后, 服务也可以正常运行, 至于用还是不用, 请自行取舍.

1
2
3
apt-get install rng-tools
vim /etc/default/rng-tools
HRNGDEVICE=/dev/urandom

Refs: 安装rng-tools使Shadowsocks-libev有足够的熵可用 - 刘洋同学的博客

最后一步: GFW 开通端口

Note: 在这之前我做了ufw enableufw default deny.

1
2
3
ufw allow 8388            #Shadowsocks自用端口
ufw delete allow 8388 #删除Shadowsocks端口
ufw status #查看服务器防火墙状态

可以看到输出中应该包含端口8388.

性能优化(Optional)

Ref: 搬瓦工Shadowsocks安装及配置多用户(服务端) | HuiHut
编辑vim /etc/sysctl.d/local.conf:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# max open files
fs.file-max = 1024000
# max read buffer
net.core.rmem_max = 67108864
# max write buffer
net.core.wmem_max = 67108864
# default read buffer
net.core.rmem_default = 65536
# default write buffer
net.core.wmem_default = 65536
# max processor input queue
net.core.netdev_max_backlog = 4096
# 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 = 4096
# max timewait sockets held by system simultaneously
net.ipv4.tcp_max_tw_buckets = 5000
# 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
# forward ivp4
net.ipv4.ip_forward = 1

使配置生效: sysctl --system

Server-HyperRef

1
2
3
4
5
6
7
8
9
vim /etc/shadowsocks-libev/config.json
systemctl restart shadowsocks-libev #启动config.json
systemctl status shadowsocks-libev #查看状态
/etc/shadowsocks-libev/shadowsocks-libev-run.sh #一键启动config_1.json, config_2.json, ...
ufw allow 8388 #增加端口
ufw delete allow 8388 #删除端口
ufw status #查看服务器防火墙状态
netstat -anptuo | grep 8388 #p: 显示PID进程号; tu: 指明显示TCP端口和UDP端口. anp参数必须有
netstat -anptuo | grep ss-server

Client (Linux)

Configure and Start

按照老方法安装好shadowsocks-libev之后

1
sudo vim /etc/shadowsocks-libev/config.json

作如下修改:

1
2
3
4
5
6
7
8
9
10
{
"server": "134.209.239.83",
"server_port": 8388,
"local_address": "127.0.0.1",
"local_port": 1080
"password": "1a2b3c4d5e6f7g",
"timeout": 60,
"method": "chacha20-ietf-poly1305", //以前常见的是aes-256-cfb
"mode": "tcp_and_udp"
}

然后重启并监测状态

1
2
3
4
5
6
7
8
sudo systemctl restart shadowsocks-libev-local@config  #本地启动Shadowsocks
sudo service shadowsocks-libev-local@config restart #功能同上
sudo systemctl enable shadowsocks-libev-local@config #配置开机自启
sudo systemctl status shadowsocks-libev-local@config #查看状态
sudo netstat -anptuo | grep 8388 #p: 显示PID进程号; tu: 指明显示TCP端口和UDP端口. anp参数必须有
lsof -i:8388 #功能同上
sudo netstat -anp | grep ss-local
sudo ps -ef | grep ss-server

Remarks: 以下三条命令等价:

1
2
3
sudo systemctl start shadowsocks-libev-local@config
sudo ss-local -c /etc/shadowsocks-libev/config.json &
sudo ss-local -s 134.209.239.83 -p 8388 -l 1080 -ki 1a2b3c4d5e6f7g -m chacha20-ietf-poly1305 &

参见/lib/systemd/system/'shadowsocks-libev-local@.service'第21行.

代理

配置好前面的东西之后还并不能帆樯, 因为Linux依旧默认走http和https流量. 要把这些流量用Socks5代理, 才可以实现帆樯.

使用系统图形界面无脑全局设置

ubuntu18.04配置shadowsocks客户端
Linux安装配置Shadowsocks客户端及开机自动启动 | HuiHut
打开ubuntu系统的设置 -> Network -> Network Proxy -> Manual -> 在socks Host 一栏输入 127.0.0.1, 端口1080即可. 浏览器 输入ifconfig.me可以查看自己是否在墙外.
这个只对图形界面有效, 不过能够驾驭绝大部分使用场景了, 譬如Telegram和WhatsApp.

使用polipo实现在terminal的全局代理

Linux 下 shadowsocks 客户端全局代理 | Fang
Ubuntu server命令行配置shadowsocks全局代理 - jingsam

  1. 安装并启动

    1
    2
    sudo apt-get install polipo
    sudo systemctl start polipo
  2. 编辑配置文件: sudo vim /etc/polipo/config

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    # This file only needs to list configuration variables that deviate
    # from the default values. See /usr/share/doc/polipo/examples/config.sample
    # and "polipo -v" for variables you can tweak and further information.

    logSyslog = true
    logFile = /var/log/polipo/polipo.log

    proxyAddress = "0.0.0.0"

    socksParentProxy = "127.0.0.1:1080"
    socksProxyType = socks5

    chunkHighMark = 50331648
    objectHighMark = 16384

    serverMaxSlots = 64
    serverSlots = 16
    serverSlots1 = 32
  3. 重启服务

    1
    2
    sudo systemctl restart polipo
    sudo systemctl status polipo
  4. 设置环境变量

    1
    2
    export http_proxy="http://127.0.0.1:8123/"
    export https_proxy="http://127.0.0.1:8123/"

测试一下此时的IP

1
curl ifconfig.me

若是VPS的IP, 说明帆樯成功. 以上最关键的一步是设置环境变量, 使得http和https的流量都用socks5代理.

不过polipo仅仅是在当前terminal下成立, 在别的terminal要再设置一回环境变量. 这看起来有点弱智因为并没有做到每个terminal都默认代理又不能用到Chrome浏览器; 不过也有两个好处:

  1. 服务器配置其实往往并没有自己的电脑强, 什么都拿去挂服务器运行后果可想而知.
  2. Terminal无非是用来装packages, 虽然说绝大部分包的寄托站点在墙内都能访问但下载速度奇慢, 所以不妨使用代理来下载.

Remarks: Linux export命令 | 菜鸟教程, 有讲如何查看和删除环境变量:

1
2
3
export -p
export -n http_proxy
export -n https_proxy

使用genpac智能代理

Ref:
ubuntu 16.04 下 shadowsocks 配置,安装与自动启动 - idealclover
Ubuntu配置ss-local客户端 | Claude’s Blog
安装genpac并在/home/ochicken/目录下生成autoproxy.pac

1
2
sudo pip install genpac
genpac --pac-proxy "SOCKS5 127.0.0.1:1080" --gfwlist-proxy="SOCKS5 127.0.0.1:1080" --output="~/autoproxy.pac"

打开ubuntu的settings - Network - Network proxy, 选择方法为自动 (Automatic), URL为file:///{pac文件路径}, 如

1
file:///home/ochicken/autoproxy.pac

不过由于该智能代理列表都是被GFW封禁的网页, 现在我自己在墙外, 没法亲测.

使用proxychains

Ref: 在Linux上使用ss客户端并设置代理 - Kong’s Blog
这个方案不好的地方在于, terminal执行命令前都要加个proxychains.

1
2
3
sudo apt-get install proxychains
sudo vim /etc/proxychains.conf
socks5 127.0.0.1 1080 //修改最后一行

然后就可以用proxychains+commands的方式来代理. 例如

1
2
3
proxychains curl xxxx
proxychains wget xxxx
sudo proxychains apt-get xxxx

使用privoxy

Refs:
Ubuntu配置Shadowsocks全局代理 | 悬崖边上的日与夜
Linux 安装 Shadowsocks 客户端 并全局代理 – LIUGUOFENG
Privoxy的功能据第一篇Blog来看, 跟polipo是很相近的. 但感觉这个的配置更麻烦, 就放弃了.

Client-HyperRef

1
2
3
4
5
6
7
8
9
10
11
sudo vim /etc/shadowsocks-libev/config.json
sudo systemctl restart shadowsocks-libev-local@config #本地启动Shadowsocks
sudo systemctl status shadowsocks-libev-local@config #查看状态
sudo netstat -anptuo | grep 8388 #p: 显示PID进程号; tu: 指明显示TCP端口和UDP端口. anp参数必须有
sudo netstat -anp | grep ss-local
curl ifconfig.me #查看自己公网IP. 正确答案是VPS的IP
export http_proxy="http://127.0.0.1:8123/"
export https_proxy="http://127.0.0.1:8123/"
export -p
export -n http_proxy
export -n https_proxy

开通名单

1
2
3
4
ss-local -s 134.209.239.83 -p 1234 -l 1080 -ki abcdefg -m chacha20-ietf-poly1305  #config_1.json User1
ss-local -s 134.209.239.83 -p 4321 -l 1080 -ki gfedcba -m chacha20-ietf-poly1305 #config_2.json User2
ss-local -s 134.209.239.83 -p 5678 -l 1080 -ki hijklmn -m chacha20-ietf-poly1305 #config_3.json User3
ss-local -s 134.209.239.83 -p 8765 -l 1080 -ki nmlkjih -m chacha20-ietf-poly1305 #config_4.json User4