Ubuntu 18.04 安装shadowsocks

本文将简要介绍 shadowsocks 的基本原理,并详细说明如何在 Ubuntu 18.04 下安装使用 shadowsocks 客户端,同时提供了让系统使用 PAC 模式或全局模式的配置方法。

Ubuntu 18.04 安装 shadowsocks

本文使用的是 shadowsocks 的 python 实现版本,没有 GUI,此外只涉及客户端配置,服务端可参考 官方文档

Github 主页:shadowsocks

官网:https://shadowsocks.org/en/index.html

使用 shadowsocks 的前提

  • 一台在防火墙之外的服务器
  • 墙内主机需要安装 shadowsocks 本地端
  • 墙外服务器需要安装 shadowsocks 服务端

shadowsocks 基本原理

Shadowsocks 是一个基于 SOCKS5 的安全拆分代理,由两部分组成,客户端和服务端。

1
client <---> ss-local <--[encrypted]--> ss-remote <---> target

Shadowsocks 本地组件(ss-local)就像传统的 SOCKS5 服务器,为客户端提供代理服务。它将数据流和数据包从客户端加密并转发到 Shadowsocks 远程组件(ss-remote),后者解密并转发到目标。来自目标的回复同样被加密并由 ss-remote 中继回 ss-local,后者解密并最终返回到原始客户端。

安装 shadowsocks

使用的是阿里的镜像源,执行安装命令

1
sudo apt install shadowsocks

查看版本号

执行以下命令查看 shadowsocks 的版本

1
sslocal --version

sslocal-version

配置 shadowsocks 客户端

Configuration via Config File 通过配置文件进行配置

修改 /etc/shadowsocks/config.json 配置(客户端配置),例如:

1
2
3
4
5
6
7
8
9
10
{
"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 the address your server listens 服务端IP
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", see Encryption 加密算法, 与服务端保持一致
fast_open use TCP_FASTOPEN, true / false
workers number of workers, available on Unix/Linux

运行

前台运行

1
sslocal -c /etc/shadowsocks.json

后台运行

1
2
sslocal -c /etc/shadowsocks.json -d start
sslocal -c /etc/shadowsocks.json -d stop

是否使用 sudo 权限根据具体情况而定

run-ss

shadowsocks 代理模式

启动后还不能直接翻墙,因为上面只是启动了代理服务器,但是网络请求并没有经过代理服务器,所以还需要配置代理服务,代理服务可分为部分代理和全局代理。

特别说明:这里所说的是 shadowsocks 的 PAC 模式和全局模式,另外 shadowsocks 的全局模式并不是整个系统所有软件都进行代理,而只是针对所有浏览器进行的全局代理。

  • PAC 模式

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

    PAC-mode

    PAC 模式会在连接网站的时候读取 PAC 文件的规则,来确定所访问的网站有没有被墙,如果被墙了或者符合规则,那就会使用代理服务器连接网站,而 PAC 列表一般都是从 GFWList 更新的。GFWList 定期会更新被墙的网站,不过一般比较慢。

  • 全局模式

    Shadowsocks 的全局模式,是设置系统的代理服务器,使所有的 Http Proxy/Socks5 请求都由代理服务器转发。

  • 区别

    简单地说,在全局模式下,所有网站默认走代理。而 PAC 模式是只有被墙的才会走代理,推荐使用 PAC 模式,如果 PAC 模式无法访问一些网站,就换全局模式试试,一般是因为 PAC 更新不及时(也就是 GFWList 更新不及时)导致的。

配置 Ubuntu 使用 PAC 模式

配置 PAC 模式需要 pac 文件,这个 pac 文件可以自己编写也可以用工具生成,这里直接使用工具 GenPAC 来生成。

Github 主页: GenPAC

GenPAC:基于 gfwlist 的多种代理软件配置文件生成工具,支持自定义规则,目前可生成的格式有 pac, dnsmasq, wingy

  1. 安装 GenPAC
1
2
sudo pip install genpac
sudo pip install --upgrade genpac
  1. 生成 autoproxy.pac

进入终端,cd 到你希望存放配置文件的目录,例如:

1
cd /home/wylu/.config/GenPAC

执行以下命令生成 pac 配置文件:

1
sudo genpac --pac-proxy="SOCKS5 127.0.0.1:1080" -o autoproxy.pac --gfwlist-url="https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt"

关于命令参数说明,详见官方文档 GenPAC

  1. 设置系统网络代理

进入设置:Settings –> Network –> Network Proxy

方法选择 Automatic

Configuration URL 填写刚刚生成的 pac 文件路径 /home/wylu/.config/GenPAC/autoproxy.pac

  1. 测试

浏览器访问 Google 验证代理是否配置成功

一般的浏览器都是默认使用系统代理,所以这里只配置了系统代理,如果浏览器没有走 Socks5 代理服务器,需要自行设置浏览器的代理

  1. 关于 privoxy

以上只是针对浏览器的代理,而使用 privoxy 代理能把电脑上所有 http 请求都转发给 ss,这意味着在终端下也能使用 wget、curl 等命令访问墙外资源。

关于 privoxy 的安装和使用可以参考:

https://www.jianshu.com/p/41378f4e14bc

https://www.jianshu.com/p/e0b05cb7cd50

配置手动代理可以参考:

https://www.serverlab.ca/tutorials/linux/administration-linux/how-to-configure-proxy-on-ubuntu-18-04/

shell 终端里执行的命令,发起的网络请求现在还不支持 socks5 代理,只支持 http/https 代理。使用 privoxy 代理,可以将 shell 发起的网络请求转发给 shadowsocks

autoproxy.pac 文件分析

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
var proxy = 'SOCKS5 127.0.0.1:1080';
var rules = [
/*
用于添加自定义规则
分析以下的js代码,可以知道rules元素,越靠前的优先级越高;
即如果在rules[0]中匹配成功,则不再匹配,直接返回选择"直连"或者"走代理"
*/
[
[],
[]
],
[
/*
以rules[1]为例进行分析,其它类似;
同样,在rules[1]中的元素也是越靠前的优先级越高;
如果在rules[1][0]中匹配成功,则不再匹配,直接返回;
分析代码可知,当匹配成功时:
--如果该元素的索引为偶数,则返回字面值'DIRECT',即选择直连
--如果该元素的索引为奇数,则返回proxy变量的值,即选择使用代理
*/
[],
[]
]
/*
以上规则如果没有一个匹配成功,根据代码分析,最终将返回字面值'DIRECT',
也就是选择直连;这也意味着如果某些URL被墙,而又没有加入到pac规则中,
最终会以直连的方式访问,因为被墙所以肯定是访问不到的, 这时应该使用全局模式,
或者在pac中添加规则。
*/
]

var lastRule = '';

function FindProxyForURL(url, host) {
/*
个人认为,如果这里直接返回proxy,应该就等同于全局模式了,
此时,不管是什么URL,都会走代理
*/
for (var i = 0; i < rules.length; i++) {
ret = testHost(host, i);
if (ret != undefined)
return ret;
}
return 'DIRECT';
}

function testHost(host, index) {
for (var i = 0; i < rules[index].length; i++) {
for (var j = 0; j < rules[index][i].length; j++) {
lastRule = rules[index][i][j];
if (host == lastRule || host.endsWith('.' + lastRule))
return i % 2 == 0 ? 'DIRECT' : proxy;
}
}
lastRule = '';
}

// REF: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
if (!String.prototype.endsWith) {
String.prototype.endsWith = function(searchString, position) {
var subjectString = this.toString();
if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
position = subjectString.length;
}
position -= searchString.length;
var lastIndex = subjectString.indexOf(searchString, position);
return lastIndex !== -1 && lastIndex === position;
};
}

理解 pac 文件 rules 的含义后,就可以自行添加一些规则了。比如 PAC 模式下访问不了 Jetbrains 的插件网址 https://plugins.jetbrains.com,因为在该 pac 文件中并没有与此 URL 匹配的规则,所以最后会以直连的方式访问,但是该网址已被墙,最终是无法访问的,我们可以把该域名添加到 pac 文件的规则列表中,该规则列表应是一个使用代理的列表,在添加规则后会以走代理的方式访问 Jetbrains 的插件网址。

pac-file-rules

配置 Ubuntu 使用 Global 模式

要实现 Global 模式,需要使用 privoxy,并且配置系统网络代理使用手动模式。

privoxy 能够实现不同代理之间的切换,使用它可以作为 SOCKS 代理和 HTTP、HTTPS 代理连接的桥梁,它能把所有的 http 请求(包括终端执行的命令,浏览器)转发给 shadowsocks,它就像是一个适配器,将 SOCKS 代理转为 HTTP 代理。

安装配置 privoxy

  1. 安装 privoxy
1
sudo apt install privoxy
  1. 配置 privoxy
1
sudo vim /etc/privoxy/config

找到 #listen-address 127.0.0.1:8118,取消注释,表示 privoxy 监听本机 8118 端口

privoxy-listen-address

找到 #forward-socks5t / 127.0.0.1:9050 .,在下方添加一行 forward-socks5t / 127.0.0.1:1080 .,表示转发请求到本地 1080 端口,而 1080 端口是 shadowsocks 监听的端口

privoxy-forward-socks5t

  1. 修改完后,重启 privoxy
1
systemctl restart privoxy
  1. 配置请求转发

~/.bashrc 中添加如下内容,如果使用的是 zsh,则在 ~/.zshrc 中添加

1
2
3
4
# set proxy
export http_proxy="127.0.0.1:8118"
export https_proxy="127.0.0.1:8118"
export ftp_proxy="127.0.0.1:8118"

不建议在 shell 的配置文件下设置代理,这种方式下所有的 shell 命令都会走代理,如果你突然不想终端命令走代理,那么又需要修改配置文件,注释掉代理相关配置,反复修改配置文件是一件挺麻烦的事。推荐使用下面"配置系统网络代理"的方式,该配置手动模式下就能使终端命令走代理,不需要配置 .bashrc.zshrc,当禁用系统网络代理时,终端命令就不会走代理了。

  1. 测试

Global-mode-shell-test

配置系统网络代理

配置完 privoxy 后,终端发起的网络请求也能走 SOCKS5 代理了,但浏览器要使用全局模式还需要配置系统网络代理。

默认浏览器默认使用系统代理,所以只需配置系统网络代理即可,具体配置过程如下:

  1. 进入设置:Settings –> Network –> Network Proxy

  2. 方法选择 Manual

  3. 设置 HTTP、HTTPS 请求由 privoxy 来代理

manual-mode-setting

  1. Pac 和 Global 模式切换

系统网络代理的自动 (Automatic) 模式和手动 (Manual) 模式都配置完成后,当选用 Automatic 则使用 Pac 模式,当选用 Manual 则使用 Global 模式。

References

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

https://github.com/shadowsocks/shadowsocks

https://github.com/JinnLynn/GenPAC

https://segmentfault.com/a/1190000011862912

https://www.jianshu.com/p/e0b05cb7cd50

https://www.cnblogs.com/edward2013/p/5560836.html

https://lollogit.gitbooks.io/help/

https://www.serverlab.ca/tutorials/linux/administration-linux/how-to-configure-proxy-on-ubuntu-18-04/