Ubuntu 安装shadowsocks

主要跟大家说下如何在Ubuntu18.04上安装shadowsocks,实现科学上网

并详细说明如何在 Ubuntu 18.04 下安装使用 shadowsocks 客户端

同时给大家提供了让系统使用 PAC 模式或全局模式的配置方法。

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

Github 主页:shadowsocks

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

使用 shadowsocks 的前提

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

shadowsocks 基本原理

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

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

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

安装 shadowsocks

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

sudo apt install shadowsocks

查看版本号

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

sslocal --version

sslocal-version

配置 shadowsocks 客户端

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

修改 /etc/shadowsocks/config.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 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

运行

前台运行

sslocal -c /etc/shadowsocks.json

后台运行

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-modePAC 模式会在连接网站的时候读取 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
sudo pip install genpac
sudo pip install --upgrade genpac
  1. 生成 autoproxy.pac

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

cd /home/wylu/.config/GenPAC

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

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 等命令访问墙外资源。

配置手动代理可以参考:

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 文件分析

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
sudo apt install privoxy
  1. 配置 privoxy
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
systemctl restart privoxy
  1. 配置请求转发

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

# 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 模式。