Sockets代理 之 Shadowsocks

ShadowSocks – http://shadowsocks.org

实现一个Socks代理,很多语言都提供有内置支持或扩展包可用,需要编写的代码也不会太多。ShadowSocks这个工具提供了多种语言的实现,从http://shadowsocks.org/en/download/servers.html可以看到,有Python、Go、C with libev、C++ with Qt, 这些实现版本中,都应该包含服务端和客户端工具,不过也有一些专门的客户端(主要提供图形操作界面),比如
Windows客户端(https://github.com/shadowsocks/shadowsocks-windows/releases)
Linux下的客户端(https://github.com/shadowsocks/shadowsocks-qt5/releases)
Mac OS X下的客户端(https://github.com/shadowsocks/ShadowsocksX-NG/releases),Android下的客户端(https://github.com/shadowsocks/shadowsocks-android,在Android下可打开https://play.google.com/store/apps/details?id=com.github.shadowsocks进行安装)。这个代理软件与一般的Socks5代理稍不一样的是:它不是一个纯粹的代理,它加入了加密的功能。 这个工具开启的代理功能和SSH开启的代理有本质不一样,SSH开启的代理会在本地和服务端之间建立一条持久的TCP链接,而shadowsocks只是在服务器开启了监听端口,客户端的链接随到随链。所以,对于需要HOLD大量链接的情况,C with libev是一个很好的选择。

注:
由于shadowsock不是一个纯的Sockets代理,所以必须搭配客户端使用。

服务端,这里关注C实现的版本:https://github.com/shadowsocks/shadowsocks-libev,它提供了比较完整的功能。客户端关注Windows下的版本,它是.NET软件,可能需要升级你的.NET版本。

在CentOS 7.x上,可以使用了一个yum源来安装(参考https://copr.fedorainfracloud.org/coprs/librehat/shadowsocks/):

#https://copr.fedorainfracloud.org/coprs/librehat/shadowsocks/repo/epel-7/librehat-shadowsocks-epel-7.repo
#vi /etc/yum.repos.d/librehat-shadowsocks.repo

[librehat-shadowsocks]
name=Copr repo for shadowsocks owned by librehat
baseurl=https://copr-be.cloud.fedoraproject.org/results/librehat/shadowsocks/epel-7-$basearch/
type=rpm-md
skip_if_unavailable=True
gpgcheck=1
gpgkey=https://copr-be.cloud.fedoraproject.org/results/librehat/shadowsocks/pubkey.gpg
repo_gpgcheck=0
enabled=1
enabled_metadata=1

安装:

yum install shadowsocks

rpm -qa | grep shadowsocks
shadowsocks-libev-2.5.5-1.el7.centos.x86_64

rpm -ql shadowsocks-libev-2.5.5-1.el7.centos.x86_64
/etc/default/shadowsocks-libev
/etc/shadowsocks-libev/config.json
/usr/bin/ss-local
/usr/bin/ss-manager
/usr/bin/ss-nat
/usr/bin/ss-redir
/usr/bin/ss-server
/usr/bin/ss-tunnel
/usr/lib/systemd/system/shadowsocks-libev.service
/usr/lib64/libshadowsocks-libev.so

编译安装(新版本可能有问题)

# Ubuntu
apt-get install --no-install-recommends build-essential automake autoconf libtool libssl-dev libpcre3-dev asciidoc xmlto
# CentOS
yum install gcc autoconf libtool automake make zlib-devel openssl-devel asciidoc xmlto

#克隆源码,或直接下载压缩包
git clone https://github.com/shadowsocks/shadowsocks-libev.git
cd shadowsocks-libev
./configure --prefix=/usr/local/ss
make
make install

#######################################
# CentOS下编译安装新版本参考:https://shadowsocks.be/4.html,以下是从脚本中提取的安装步骤
#安装必须的软件包
yum install epel-release
yum install -y unzip openssl openssl-devel gettext gcc autoconf libtool automake make asciidoc xmlto udns-devel libev-devel pcre pcre-devel git c-ares-devel

#下载安装
wget https://github.com/jedisct1/libsodium/releases/download/1.0.13/libsodium-1.0.13.tar.gz
tar zxf libsodium-1.0.13.tar.gz
cd libsodium-1.0.13
./configure —prefix=/usr && make && make install

wget http://dl.teddysun.com/files/mbedtls-2.6.0-gpl.tgz
tar xf mbedtls-2.6.0-gpl.tgz
cd mbedtls-2.6.0-gpl
make SHARED=1 CFLAGS=-fPIC
make DESTDIR=/usr install

wget https://c-ares.haxx.se/download/c-ares-1.12.0.tar.gz
tar zxvf c-ares-1.12.0.tar.gz
cd c-ares-1.12.0
./configure
make && make install

ldconfig

wget https://github.com/shadowsocks/shadowsocks-libev/releases/download/v3.1.0/shadowsocks-libev-3.1.0.tar.gz
tar zxf shadowsocks-libev-3.1.0.tar.gz
cd shadowsocks-libev-3.1.0
./configure --disable-documentation
make && make install

默认配置在/etc/default/shadowsocks-libev,配置文件/etc/shadowsocks-libev/config.json,服务启动脚本/usr/lib/systemd/system/shadowsocks-libev.service。默认实际使用到的就是/usr/bin/ss-server(如果要启动客户端,修改为ss-local即可),查看配置文件:

{
    "server":"120.xx.xx.28",
    "server_port":8388,
    "local_port":1080,
    "password":"xxxxxxxx",
    "timeout":60,
    "method":"aes-256-cfb"
}

不管是使用ss-local和ss-server,这几个参数都一样,注意:作为服务端,local_port应该是没有用的。客户端和服务端,都预置了密码和对称加密使用的算法,简单来说,它们通过密码认证,然后使用预置的算法产生一个秘钥,用这个秘钥来加解密传输的数据。不难看出,它跟传统的CA不同,秘钥的交换不是通过加密隧道来交换的。如果需要安全,不要使用这个工具。

这个包也包括了其它工具:

/usr/bin/ss-local	客户端,和服务端的配置一样
/usr/bin/ss-manager	用来管理服务端,比如在服务端开启多个端口(动态拉起ss-server)
/usr/bin/ss-nat		管理NAT映射
/usr/bin/ss-redir	客户端工具,用来实现透明代理
/usr/bin/ss-server	服务端
/usr/bin/ss-tunnel	用来实现本地端口转发,比如目的地址符合条件时,转发到本地某个端口

对于客户端,最典型的应用,就是在内网架设一个服务器,上面安装ShadowSocks-livev,然后启动客户端(也可以把参数写入配置,用c指定读取的配置文件):

ss-local -s 120.xx.xx.x -p 8388 -b 192.168.1.250 -l 1080 -k xxxxx -m aes-256-cfb

需要代理的机器,指定为192.168.1.250即可,这样就可以避免在每个终端上安装客户端。不过,如果需要连接多个代理服务器,就需要启动多个ss-local进程,并且指定不同的端口。

注:可以在服务器上设置多用户(实际是启动多个ss-server,用端口区分),客户端可以配置多个远程服务器,但是需要指定默认,需要更换时,需要切换一下默认远程服务器,从这里可知,一个客户端要对应哪个远程是随意的,目前看起来缺少的是在客户端管理远程服务器的工具(比如只启动一个客户端,动态或安装一定规则对应到不同远程服务器)

Window下的客户端(https://github.com/shadowsocks/shadowsocks-windows/releases):
ss

当然,这个客户端还提供了 系统代理模式(就是直接修改系统代理) 系统代理模式(全局与PAC) 切换服务器等功能。

Linux下的客户端不支持配置多个端口(不同端口对应不同的服务端),所以可以启动多个客户端来解决,比如分别对应建立配置文件,然后写一段简单粗暴的定时脚本,就可以Hold它:

#!/bin/bash

live=`ps -efH | grep '/etc/shadowsocks-libev/config_4441.json' | grep -v 'grep' | wc -l`
if [ $live -eq 0 ]; then
    /usr/bin/ss-local -a root -c /etc/shadowsocks-libev/config_4441.json -u 2>&1 > /dev/null &
fi

live=`ps -efH | grep '/etc/shadowsocks-libev/config_4442.json' | grep -v 'grep' | wc -l`
if [ $live -eq 0 ]; then
    /usr/bin/ss-local -a root -c /etc/shadowsocks-libev/config_4442.json -u 2>&1 >> /dev/null &
fi
 
live=`ps -efH | grep '/etc/shadowsocks-libev/config_4443.json' | grep -v 'grep' | wc -l`
if [ $live -eq 0 ]; then
    /usr/bin/ss-local -a root -c /etc/shadowsocks-libev/config_4443.json -u 2>&1 >> /dev/null &
fi

live=`ps -efH | grep '/etc/shadowsocks-libev/config_4444.json' | grep -v 'grep' | wc -l`
if [ $live -eq 0 ]; then
    /usr/bin/ss-local -a root -c /etc/shadowsocks-libev/config_4444.json -u 2>&1 >> /dev/null &
fi

exit 0

需要说明的是shadowsocks-qt5是一个跨平台的客户端(https://github.com/shadowsocks/shadowsocks-qt5/releases),以下链接是安装和使用说明:https://github.com/shadowsocks/shadowsocks-qt5/wiki:

Ubuntu通过PPA方式安装:

sudo add-apt-repository ppa:hzwhuang/ss-qt5
sudo apt-get update
sudo apt-get install shadowsocks-qt5

这个ppa对应的链接是:https://launchpad.net/~hzwhuang/+archive/ubuntu/ss-qt5
ss-ubuntu

而对应的Window版本长这个样子:
ss-window

最后:
作为服务端,如果使用的是Linux(CentOS或Ubuntu),最好的选择是shadowsocks-libev,而对于Windows,看起来只有一个选择(https://github.com/shadowsocks/libQtShadowsocks/releases,提供一个叫libQtShadowsocks的工具,既可做服务端,也可以做客户端); 作为客户端,在Windows和Ubuntu下https://github.com/shadowsocks/shadowsocks-qt5/releases这个较好。

这是一个百花齐放的开源产品。