Shadowsocks原理和搭建

目前来说虽然Shadowsocks有被检测到的可能性,但是目前来说还算是比较有效的上网方式。所以介绍一下在VPS上搭建Shadowsocks的方法。

原理

前面文章已经介绍过Shadowsocks的基本原理。在我们和目标地址之间有一个代理服务器(我们的VPS)。

  1. 我们首先通过SS Local和VPS进行通信,通过Socks5协议进行通信。
  2. SS Local连接到VPS, 并对Socks5中传输的数据进行对称加密传输,传输的数据格式是SS的协议。
  3. SS Server收到请求后,对数据解密,按照SS协议来解析数据。
  4. SS Server根据协议内容转发请求。
  5. SS Server获取请求结果后回传给SS Local
  6. SS Local获取结果回传给应用程序

所以这个VPS一定是要能访问到,并且可以访问目标网站的,所以一般VPS选择国外的。如果这个VPS IP被封就没有办法翻墙了。

 

协议

Protocol

The shadowsocks protocol is very similar to SOCKS5 but encrypted and simpler.

Below is the structure of a shadowsocks request (sent from client-side), which is identical for both TCP and UDP connections before encrypted (or after decrypted).

+--------------+---------------------+------------------+----------+
| Address Type | Destination Address | Destination Port |   Data   |
+--------------+---------------------+------------------+----------+
|      1       |       Variable      |         2        | Variable |
+--------------+---------------------+------------------+----------+

Possible values of address type are 1 (IPv4), 4 (IPv6), 3 (hostname). For IPv4 address, it’s packed as a 32-bit (4-byte) big-endian integer. For IPv6 address, a compact representation (16-byte array) is used. For hostname, the first byte of destination address indicates the length, which limits the length of hostname to 255. The destination port is also a big-endian integer.

The request is encrypted using the specified cipher with a random IV and the pre-shared key, it then becomes so-called payload.

Shadowsocks基于Socks5,支持TCP和UDP,而且支持远端DNS解析,所以对于Client来说,不需要设置DNS,这样使用SS也能避免DNS污染和劫持。 发送的TCP或UDP数据的格式如上,指定了要访问的地址、端口和数据。整个结构非常简单。

TCP

The first packet of a shadowsocks TCP connection sent either from server-side or client-side must contains the randomly generated IV that used for the encryption.

+-------+----------+
|  IV   | Payload  |
+-------+----------+
| Fixed | Variable |
+-------+----------+

Once this packet is received, payload is decrypted using the specified cipher with the IV in the packet and the pre-shared key. For the server-side, the data is then forwarded to the destination. For client-side, the data is forwarded to the application. And this shadowsocks TCP relay goes into stream stage, in which the data is being encrypted with the same IV and transmitted directly without IV prepended.

+----------+
| Payload  |
+----------+
| Variable |
+----------+

Client和Server第一次建立连接后发送的第一条数据前面带上了IV信息,这个IV是Client加密使用的IV,但是Secret Key 是保存在Client和Server的。所以Server会保存这个IV,用来解密Client的数据。然后从Payload中获取数据进行转发。而后续的请求,就不需要带上IV信息了。

服务端会根据Payload中的Address Type的值来判断请求是否合法,如果不满足要求的3个数字,就会断开连接。

漏洞

因为目前客户端大量使用AES加密方式,所以IV长度是固定的,那么很容易确定Payload中的Address Type的位置,而AES密文和明文的位置有对应关系。所以可以模拟客户端请求,模拟密文数据,并修Address Type的值来枚举256种情况,发送给服务器。如果有3种情况没有断开连接,那么这个服务很可能是Shadowsocks服务。

UDP

When the client-side receives a UDP request from other applications, RSV and FRAG are dropped and a shadowsocks UDP request is made out from it. A random IV is always generated and used for the encryption of shadowsocks UDP request and response. Therefore, all UDP requests and responses have the same structure, no matter whether it’s the first packet or not.

+-------+----------+
|  IV   | Payload  |
+-------+----------+
| Fixed | Variable |
+-------+----------+

UDP和TCP区别在于,每次都要带上IV信息。

 

Server部署

使用Shadowsocks需要在VPS上部署Server,目前有用Python、Go和C编写的Server端程序。我在VPS上部署的是使用Python版本,所以后面介绍的都是基于Python版本

First, make sure you have Python 2.6 or 2.7.

$ python --version
Python 2.6.8

Then install from PIP

$ pip install shadowsocks

如果要了解其他版本的部署方式查看:https://shadowsocks.org/en/download/servers.html

 

Server配置

SS安装以后需要进行配置,SS使用JSON格式文件进行配置,配置文件路径和名字可以自己决定,一般放在:

/etc/shadowsocks.json

格式如下:

{
    "server":"my_server_ip",
    "server_port":8388,
    "local_address": "127.0.0.1",
    "local_port":1080,
    "password":"mypassword",
    "timeout":300,
    "method":"aes-256-cfb",
    "fast_open": false
}

解释如下:

Name Explanation
server 你VPS的IP地址,IPV4,IPV6都可以
server_port 提供SS服务的端口号,写自己想用的端口号
local_address the address your local listens
local_port local port
password 传输数据时用来加密的密钥,和Client相同
timeout 连接超时时间
method 加密方法 推荐使用 “aes-256-cfb”
fast_open use TCP_FASTOPEN, true / false
workers number of workers, available on Unix/Linux

多用户配置

使用port_password,每个用户对应一个端口,然后后面是密码。如果想搭建一个用户管理系统,参见:Manager API.

{
    "server": "0.0.0.0",
    "port_password": {
        "8381": "foobar1",
        "8382": "foobar2",
        "8383": "foobar3",
        "8384": "foobar4"
    },
    "timeout": 300,
    "method": "aes-256-cfb"
}

加密方式

以下是支持的加密方法,table和RC4已经不推荐使用

https://shadowsocks.org/en/spec/cipher.html

Method Name Key Size IV Length
table* 0 0
aes-128-ctr 16 16
aes-192-ctr 24 16
aes-256-ctr 32 16
aes-128-cfb 16 16
aes-192-cfb 24 16
aes-256-cfb 32 16
bf-cfb 16 8
camellia-128-cfb 16 16
camellia-192-cfb 24 16
camellia-256-cfb 32 16
cast5-cfb 16 8
chacha20 32 8
chacha20-ietf 32 12
des-cfb 8 8
idea-cfb 16 8
rc2-cfb 16 8
rc4* 16 0
rc4-md5 16 16
salsa20 32 8
seed-cfb 16 16

安装m2crypto可以加快一点加密速度

apt-get install python-m2crypto

 

启动和停止

前台运行命令:

ssserver -c /etc/shadowsocks.json

后台运行命令:

ssserver -c /etc/shadowsocks.json -d start
ssserver -c /etc/shadowsocks.json -d stop

都需要指定配置文件的路径。启动后可以在系统中查看:

chengchao@189554:~$ ps -aux | grep ssserver
root 5034 0.0 0.9 47676 9340 ? Ss Jan16 2:37 /usr/bin/python /usr/local/bin/ssserver -c /etc/shadowsocks.json -d start

也可以查看Log,检查SS的状态

tail -f /var/log/shadowsocks.log

输出log如下:

2017-01-30 14:52:59 INFO connecting s2.googleusercontent.com:443 from 59.172.28.64:37629
2017-01-30 14:52:59 INFO connecting s2.googleusercontent.com:443 from 59.172.28.64:37627
2017-01-30 14:52:59 INFO connecting s2.googleusercontent.com:443 from 59.172.28.64:37626
2017-01-30 14:52:59 INFO connecting s2.googleusercontent.com:443 from 59.172.28.64:37625
2017-01-30 14:52:59 INFO connecting s2.googleusercontent.com:443 from 59.172.28.64:37630
2017-01-30 14:52:59 INFO connecting s2.googleusercontent.com:443 from 59.172.28.64:37628
2017-01-30 14:57:45 WARNING timed out: shadowsocks.org:443
2017-01-30 14:58:46 INFO connecting clients4.google.com:443 from 59.172.28.64:37979
2017-01-30 14:59:33 INFO connecting clients4.google.com:443 from 59.172.28.64:38113
2017-01-30 14:59:40 INFO connecting mtalk.google.com:5228 from 59.172.28.64:38130

开机启动

在/etc/rc.local中加入

#start the shadowsocks server
sudo ssserver -c /etc/shadowsocks.json -d start

 

Client配置

Server服务启动之后,就可以在客户端安装SS Client使用了。SS目前支持Windows、MAC、 Linux、Android、IOS等众多平台。参考:https://shadowsocks.org/en/download/clients.html

Windows:  Shadowsocks-win 推荐使用这个

MAC: ShadowsocksX-NG 和 shadowsocks-iOS

Android: Shadowsocks 中文名:影梭

IOS:MobileShadowSocks 和收费的土豆丝 (Potatso)

 

下面是在MAC上面使用,设置服务器信息。IP和端口填写服务端的信息,密码和加密选择也是选择服务端配置的信息。

在菜单中有一些选项,通用的设置每个平台基本是一样的。

开关

控制Shadowsocks客户端是否启用。

 

全局代理模式

就是所有访问全部走SS

 

自动代理模式

只有PAC List中的地址才走SS。

 

编辑自动模式的PAC

可以手动把不能访问的页面添加到里面。用文本编辑器打开,然后添加不能访问的网站的域,比如搬瓦匠我这经常访问不了,就添加

“||bandwagonhost.com/”,

从GFWList更新PAC: 可以从网上获取最新的PAC list,不过shadowsocks-iOS的自动更新有问题。Windows上没有问题,Android上没有更新PAC,应该会随版本更新而更新。

 

高级功能配置:

上面是一些最基本,最重要的配置,每个平台都有。有一些高级功能只有特定平台才支持,比如Windows平台还支持多个Server负载均衡,而Android上功能更多,可以开启Fast TCP , KCP, 一次性认证等,这些都需要Server也支持。

 

其他程序中设置:

打开Shaodowsock后,PC上是设置了代理自动设置

代理自动配置英语:Proxy auto-config,简称PAC)是一种网页浏览器技术,用于定义浏览器该如何自动选择适当的代理服务器来访问一个网址。

MAC和Windows中都会自动设置,用来代理网页的访问。 而在Android上类似VPN,针对手机所有应用有效。PC上如果要其他一些程序也能使用,可以进行设置。

比如在Android Studio中,可以设置PAC,这样AS就可以正常下载gradle,sdk了。

 

全局代理:

有一些APP并没有自动代理设置的配置,那么就没有办法走SS了。但是有把SS变为全局代理的方法,就是使用Proxier。

Proxifier是一款功能非常强大的socks5客户端,可以让不支持通过代理服务器工作的网络程序能通过HTTPS或SOCKS代理或代理链。支持 64位系统,支持Xp,Vista,Win7,MAC OS ,支持socks4,socks5,http代理协议,支持TCP,UDP协议,可以指定端口,指定IP,指定域名,指定程序等运行模式,兼容性非常好

Proxier是收费软件,网上很多下载和KEY,搜索一下就有了。

具体配置过程就不介绍了,网上很多,可以看这里:用Shadowsocks和Proxifier自由访问互联

 

优化

完成上面设置,应该就可以正常上网了。但是可能网速并不理想,所以需要进行一些优化。

 

内核修改优化

来自:Optimizing Shadowsocks

对内核进行一些修改,如果你对VPS是OpenVZ不一定能生效。 在Ubuntu上,创建下面的文件,

/etc/sysctl.d/local.conf

内容是:

# max open files
fs.file-max = 51200
# 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
# turn on TCP Fast Open on both client and server side
net.ipv4.tcp_fastopen = 3
# 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

执行命令让配置生效

sysctl --system

如果是老系统使用

sysctl -p /etc/sysctl.d/local.conf

在/etc/rc.local中加入

ulimit -n 51200

#start the shadowsocks server
sudo ssserver -c /etc/shadowsocks.json -d start

按官方WIKI上写的优化效果:

After optimizing, a busy Shadowsocks server that handles thousands of connections, takes about 30MB memory and 10% CPU. Notice that at the same time, Linux kernel usually uses >100MB RAM to hold buffer and cache for those connections. By using the sysctl config above, you are trading off RAM for speed. If you want to use less RAM, reduce the size of rmem and wmem.

只需要30M内存和10%的CPU处理上千个SS请求。Kernel可能会使用大于100M的内存最为缓存。如果你内存很小,要节省内存,可以减少rmen和wmenem的数值(现在设置的是64M+64M)

# max read buffer
net.core.rmem_max = 67108864
# max write buffer
net.core.wmem_max = 67108864

 

 使用锐速优化

锐速(ServerSpeeder)加速软件是一种基于ZETATCP加速引擎的软件,可以起到显著加速效果的TCP 加速技术。原理是通过算法优化TCP的拥塞控制机制,预判并及时重传可能的丢包。

http://www.serverspeeder.com/

这是官网,有免费版本但是限速,可以在网上下载破解版。不过锐速不支持OepnVZ,支持KVM和Xen。所以买VPS时要注意。如果不清楚自己机器那一种虚拟化技术 使用下面命令:

 

检查虚拟化技术是否支持

下载vm.check.sh文件

wget N nocheckcertificate https://raw.githubusercontent.com/91yun/code/master/vm_check.sh
执行, 要root权限
 sudo bash vm_check.sh
会下载virt-what-1.12.tar.gz并解压执行里面的脚本
drwxrwxr-x 4 500 500 4096 Jan 30 08:22 virt-what-1.12
-rw-r–r– 1 root root 147144 Feb 19 2016 virt-what-1.12.tar.gz
-rw-rw-r– 1 chengchao chengchao 290 Jan 30 08:18 vm_check.sh
输出结果:
make[1]: Entering directory `/home/chengchao/software/vm_check/virt-what-1.12′
test -z “/usr/local/libexec” || /bin/mkdir -p “/usr/local/libexec”
/usr/bin/install -c virt-what-cpuid-helper ‘/usr/local/libexec’
test -z “/usr/local/sbin” || /bin/mkdir -p “/usr/local/sbin”
/usr/bin/install -c virt-what ‘/usr/local/sbin’
test -z “/usr/local/share/man/man1” || /bin/mkdir -p “/usr/local/share/man/man1”
/usr/bin/install -c -m 644 virt-what.1 ‘/usr/local/share/man/man1′
make[1]: Leaving directory `/home/chengchao/software/vm_check/virt-what-1.12’
xen
显示我的VPS是XEN,可以支持。

破解版安装和卸载:

锐速需要内核支持,可以在这里查看:https://www.91yun.org/wp-content/plugins/91yun-serverspeeder/systemlist.html

如果内核不在支持范围内,需要更换内核版:

教程:CentOS更换内核,提供锐速可用的内核下载

如果Ubuntu需要更换内核,自己google一下方法就好了。Ubuntu下可以查看自己版本和内核:

chengchao@189554:~$ cat /proc/version
Linux version 3.13.0-24-generic (buildd@panlong) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014

使用脚本安装破解版:

wget N nocheckcertificate https://raw.githubusercontent.com/91yun/serverspeeder/master/serverspeeder-all.sh
bash serverspeeder-all.sh
下载serverspeeder-all.sh并执行,如果内核完全匹配就会自动下载安装。破解版会自动下载授权文件
,自动修改配置文件。配置文件在:
/serverspeeder/etc/config
重启后查看是否在运行:
chengchao@189554:~$ ps -aux | grep speed
root 880 0.0 0.0 1580 72 ? Ss Jan13 0:08 /serverspeeder/bin/acce-3.10.61.0-[Ubuntu_14.04_3.13.0-24-generic] -n 1 -s /serverspeeder/etc/apx-20341231.lic -m -p 256
卸载使用命令:
chattr i /serverspeeder/etc/apx* && /serverspeeder/bin/serverSpeeder.sh uninstall f
更多锐速破解版信息: https://github.com/91yun/serverspeeder

KCP优化

https://github.com/skywind3000/kcp

https://github.com/xtaci/kcptun

KCP是一个快速可靠协议,能以比 TCP浪费10%-20%的带宽的代价,换取平均延迟降低 30%-40%,且最大延迟降低三倍的传输效果。纯算法实现,并不负责底层协议(如UDP)的收发

kcptun能够将 TCP流转换为KCP+UDP流,用于任意tcp网络程序的传输承载(尤其用于udp游戏通信测试),用于优化丢包环境下的网络流畅度.

选择性重传 vs 全部重传:

TCP丢包时会全部重传从丢的那个包开始以后的数据,KCP是选择性重传,只重传真正丢失的数据包。

目前我在Youbutu上看1080也比较流畅,所以目前没有使用KCP。如果想开启请参见:

一步一步教你用Kcptun给Shadowsocks加速!看YouTube1080P一点都不卡!

注意

 

端口问题:

搭建完SS之后,在家里无论PC端还是手机端访问都很正常,但是在公司就经常访问以下就不能访问了。在公司可以连上VPS,而且可以看到SS的log有收到客户端的请求,但是客户端网页就是打不开。换用其他人的SS也是类型情况。
想想SS应该不存在公司去封杀的问题,后来从网上看可能是端口问题,公司可能有封锁端高位的端口流入数据。所以我把SS服务器的端口修改为3389,windows远程桌面使用的端口,用了一会还是不行,联想到在公司MAC远程登录到自己Windows时一直在等待,可能这个也封了。 因为VPS不会搭建HTTPS,所以把端口号改为443,解决!

防止被墙:

网友有建议最好不要在安装有360的机器上使用SS,不知道是水军还是什么。不过确实要注意,确实存在给你上报你SS IP的可能。

另外SS目前是可以被特征检测的,所以尽量不要在一台VPS上安装SS + OPENVPN,因为OPENVPN特征很明显,结合起来和可能判断你是代理。

如果VPS有多IP,尽量把SS的和SSH的分开。

打赏

发表评论

电子邮件地址不会被公开。 必填项已用*标注