Skip to main content

第 6 课:加密代理

我们可以使用 ss 构建一条加密代理隧道,

(一)安装服务器端

1. Ubuntu

安装python

sudo apt update
sudo apt install -y python3 python3-pip

安装shadowsocks

sudo apt install -y shadowsocks-libev

编辑配置文件

sudo vim /etc/shadowsocks-libev/config.json
{
    "server":"0.0.0.0",
    "server_port":8388,
    "local_port":1080,
    "password":"yourpassword",  
    "timeout":300,
    "method":"aes-256-gcm",
    "fast_open": true
}

将配置文件指向你的 config.json

sudo vim /etc/default/shadowsocks-libev
DAEMON_ARGS="-c /etc/shadowsocks-libev/config.json"

启动并启用 shadowsocks-libev 服务

sudo systemctl start shadowsocks-libev
sudo systemctl enable shadowsocks-libev

确认 Shadowsocks 是否运行成功:

sudo systemctl status shadowsocks-libev

在 Azure 管理控制台中,开放对应的端口(如 8388)


在你的设备上使用 Shadowsocks 客户端,添加服务器信息:

服务器 IP:你的 Ubuntu 服务器的公网 IP。

端口:8388(或配置文件中的 server_port)。

密码:yourpassword。

加密方式:aes-256-gcm。


重启服务

sudo systemctl restart shadowsocks-libev

停止服务

sudo systemctl stop shadowsocks-libev

2. CentOS

安装EPEL仓库

sudo yum update
sudo yum install epel-release

安装python

sudo yum install python3 python3-pip
python --version
pip --version

安装shadowsocks

sudo pip3 install https://github.com/shadowsocks/shadowsocks/archive/master.zip

安装 libsodium

sudo yum install libsodium

编写配置文件

sudo vi /etc/shadowsocks.json
{
    "server": "你的服务器IP",
    "port_password": {
        "端口号(这里使用 11451)": "密码"
    },
    "timeout": 300,
    "method": "aes-256-gcm",
    "protocol": "auth_chain_a",
    "protocol_param": "",
    "obfs": "tls1.2_ticket_auth",
    "obfs_param": "",
    "redirect": "",
    "fast_open": false,
    "workers": 1
}

也可以使用 IPv6,可以先测试一下:

{
  "server": "2001:19f0:7002:0582:5400:05ff:fe26:939f",
  "server_port": 8388,
  "local_address": "127.0.0.1",
  "local_port": 1080,
  "password": "your_password",
  "timeout": 300,
  "method": "aes-256-cfb"
}

添加系统服务

sudo vi /etc/systemd/system/shadowsocks.service
[Unit]
Description=Shadowsocks
After=network.target

[Service]
ExecStart=/usr/local/bin/ssserver -c /etc/shadowsocks.json
Restart=on-failure

[Install]
WantedBy=multi-user.target

设置开机自启动

sudo systemctl enable shadowsocks

开启防火墙 (比如如果是11451端口,则如下:)

sudo firewall-cmd --zone=public --remove-port=11451/tcp --permanent
sudo firewall-cmd --zone=public --add-port=11451/tcp --permanent
sudo firewall-cmd --reload
sudo firewall-cmd --zone=public --add-port=8388/tcp --permanent --add-rich-rule='rule family=ipv6 source address=你的IPv6地址/128 accept'
sudo firewall-cmd --reload

启动服务

sudo systemctl start shadowsocks

手动启动shadowsocks

sudo python3 -m shadowsocks.server -c /etc/shadowsocks.json -d start

或者

sudo /usr/local/bin/ssserver -c /etc/shadowsocks.json

查看详细日志

journalctl -u shadowsocks.service -b

客户端连接

image-20250920160819932



(二)安装客户端

安装 Shadowsocks 客户端

sudo apt update && sudo apt upgrade -y
sudo apt install shadowsocks-libev -y

Shadowsocks 客户端 默认是以 服务器模式 启动(ss-server),而不是以 客户端模式 启动(ss-local),以下是修复步骤:

打开服务文件,找到

sudo vim /usr/lib/systemd/system/shadowsocks-libev.service

ExecStart=/usr/bin/ss-server -c $CONFFILE $DAEMON_ARGS

修改为

ExecStart=/usr/bin/ss-local -c $CONFFILE $DAEMON_ARGS

重新加载 Systemd 配置

sudo systemctl daemon-reload

创建 Shadowsocks 的配置文件

sudo vim /etc/shadowsocks-libev/config.json
{
"server": "13.64.155.237",
"server_port": 11451,
"local_address": "127.0.0.1",
"local_port": 1081,
"password": "****",
"method": "aes-256-gcm",
"timeout": 300,
"mode": "tcp_and_udp",
"fast_open": true,
"nameserver": "8.8.8.8",
"dns": "8.8.8.8",
"ipv6_first": false
}

启动服务

sudo systemctl start shadowsocks-libev
sudo systemctl restart shadowsocks-libev
sudo systemctl status shadowsocks-libev
sudo systemctl enable shadowsocks-libev


启用 HTTPS 代理工具,将 Shadowsocks 的 SOCKS5 代理转为 HTTP/HTTPS 代理。将 SOCKS5 请求转化为了 HTTP 代理请求。

安装 privoxy

sudo apt install privoxy -y
sudo vim /etc/privoxy/config

添加以下内容,启用 SOCKS5 代理:

forward-socks5t / 127.0.0.1:1081 .

listen-address 127.0.0.1:8118

启动并启用 privoxy 服务

sudo systemctl restart privoxy
sudo systemctl enable privoxy

安装 curl 工具

sudo apt install curl -y

通过代理访问一个网站,如果返回 HTML 内容,说明 Shadowsocks 工作正常。

curl --proxy http://127.0.0.1:8118 https://www.google.com

在python中代码如下:

import requests

url = "https://www.google.com"
proxies = {
    "http": "http://127.0.0.1:8118",
    "https": "http://127.0.0.1:8118",
}

try:
    response = requests.get(url, proxies=proxies, timeout=5)
    if response.status_code == 200:
        print("连接正常!Google.com 访问成功。")
    else:
        print(f"连接异常,状态码:{response.status_code}")



tip

如果本来装的是客户端,要改成服务端,只按照上面的步骤修改是不够的。正确步骤如下:

systemctl status shadowsocks-libev

输出:

Main PID: 1874485 (ss-local)
...
└─1874485 /usr/bin/ss-local -c /etc/shadowsocks-libev/config.json -c /etc/shadowsocks-libev/config.json

说明你当前运行的是 ss-local(本地代理客户端),而不是 ss-server(远程服务端监听 server_port)。

卸载当前 ss-local 服务(不是卸载程序,而是禁用错误的 systemd 服务)

sudo systemctl stop shadowsocks-libev
sudo systemctl disable shadowsocks-libev

然后重新创建或修改一个服务文件 /etc/systemd/system/ss-server.service

sudo nano /etc/systemd/system/ss-server.service

内容如下:

[Unit]
Description=Shadowsocks-libev Server
After=network.target

[Service]
ExecStart=/usr/bin/ss-server -c /etc/shadowsocks-libev/config.json
Restart=on-failure

[Install]
WantedBy=multi-user.target

保存后执行以下命令启动并开机自启:

sudo systemctl daemon-reload
sudo systemctl enable ss-server
sudo systemctl start ss-server

同时确保 /etc/shadowsocks-libev/config.json 配置为服务端用途

{
    "server": "0.0.0.0",
    "server_port": 45117,
    "password": "HandsomeHeihe",
    "timeout": 300,
    "method": "aes-256-gcm",
    "mode": "tcp_and_udp",
    "fast_open": false
}

这一配置用于监听公网 IP(或 0.0.0.0 监听全部网卡)。


再检查

sudo systemctl status ss-server

正确结果应为

Main PID: xxxx (ss-server)
...
└─xxxx /usr/bin/ss-server -c /etc/shadowsocks-libev/config.json


(三)配置全局代理

1. 手动命令

但是到这里还没结束, Shadowsocks 不是 启动就直接接管本地网路的!

要使所有流量通过此代理,可以使用以下方法:

echo 'export http_proxy="http://127.0.0.1:8118"' >> ~/.bashrc
echo 'export https_proxy="http://127.0.0.1:8118"' >> ~/.bashrc
echo 'export all_proxy="socks5://127.0.0.1:1081"' >> ~/.bashrc
source ~/.bashrc

通过环境变量设置全局代理,仅适用于命令行流量(如 curl, wget),Chrome 浏览器 和 ping 并不会自动使用 WSL 的代理设置

  • ping 使用的是 ICMP 协议,而 Shadowsocks 通常只处理 TCP 和 UDP 流量

  • Chrome 不会自动读取 这些 环境变量,需要通过配置参数或工具使其流量通过代理。

如果返回 HTML 内容,说明全局代理设置成功。

curl https://www.google.com

为了让 apt 使用代理,需要额外配置:

sudo vim /etc/apt/apt.conf.d/95proxies

添加

Acquire::http::Proxy " http://127.0.0.1:8118";

Acquire::https::Proxy " http://127.0.0.1:8118";

测试 apt 是否通过代理运行:

sudo apt update

(可选)如果你需要 Git 通过代理运行,可以配置全局代理:

git config --global http.proxy http://127.0.0.1:8118
git config --global https.proxy http://127.0.0.1:8118
git clone https://github.com/example/repo.git

测试 Git 是否工作正常


(可选)让 Python requests 默认使用代理(可选)

在 Python 中,可以通过环境变量让 requests 自动使用代理。

将以下代码添加到你的程序顶部:

import os
os.environ['http_proxy'] = 'http://127.0.0.1:8118'
os.environ['https_proxy'] = 'http://127.0.0.1:8118'

浏览器使用代理

启动 Chrome 时添加命令行参数以设置代理。如果使用 privoxy 提供的 HTTP 代理

google-chrome-stable --proxy-server="http://127.0.0.1:8118"

如果使用 Shadowsocks 的 SOCKS5 代理

google-chrome-stable --proxy-server="socks5://127.0.0.1:1081"

如果使用终端启动 Chrome,可以创建一个别名:

echo 'alias chrome="google-chrome-stable --proxy-server=http://127.0.0.1:8118"' >> ~/.bashrc
source ~/.bashrc

以后只需运行 chrome 即可启动 Chrome 并使用代理。


如果需要暂时关闭全局代理,可以运行以下命令:

unset http_proxy
unset https_proxy
unset all_proxy

2. 快捷开关

先确定当前 shell 的配置文件是哪个

echo $SHELL
  • /bin/zsh 对应的是 ~/.zshrc
  • /bin/bash 对应的是 ~/.bashrc

以mac为例:

vim ~/.zshrc

加入:(当前本地 SS 客户端 socks5端口 7891,HTTP 端口 7890)

# === 快捷命令 ===
alias proxy_on='\
export http_proxy=http://127.0.0.1:7890; \
export https_proxy=http://127.0.0.1:7890; \
export all_proxy=socks5://127.0.0.1:7891; \
export HOMEBREW_HTTP_PROXY=http://127.0.0.1:7890; \
export HOMEBREW_HTTPS_PROXY=http://127.0.0.1:7890; \
git config --global http.proxy http://127.0.0.1:7890; \
git config --global https.proxy http://127.0.0.1:7890'

alias proxy_off='\
unset http_proxy; \
unset https_proxy; \
unset all_proxy; \
unset HOMEBREW_HTTP_PROXY; \
unset HOMEBREW_HTTPS_PROXY; \
git config --global --unset http.proxy; \
git config --global --unset https.proxy'

立即应用修改

source ~/.zshrc

现在就可以一键开启代理了

proxy_on #代理开启
proxy_off #代理关闭

检查是否设置成功

git config --global --get http.proxy
# 应该显示 http://127.0.0.1:7890(proxy_on 后)

env | grep -i proxy
# 应该显示所有 export 的代理变量


(四)PAC 策略

PAC 全称是 Proxy Auto-Configuration,它是一个自动代理配置脚本,能够决定网络流量走默认通道还是代理服务器通道,控制的流量类型包括:HTTP、HTTPS 和 FTP

默认情况下,Shadowsocks 为我们提供了一个基础的 PAC 规则配置文件,里面大致列举了一些主流需要走代理的网站,比如 *.google.com, *.bbc.com 等等。

但是,还有很多网站也被屏蔽了,所以这时候就需要我们手动编辑 PAC 规则文件,以适应这些变化。

image-20250920160925540

PAC 文件是一个 JavaScript 文件,定义了哪些域名需要代理,哪些不需要。找到如下部分代码:

image-20250920160945482

在 FindProxyForURL 函数内,添加以下规则:

image-20250920161004562

然后在文件开头加上:

image-20250920161019414

重启软件即可。参考文章:https://juniway.github.io/Network-Technology/vps-pac-rules/

如果需要自定义规则,可以编辑自己的 PAC 文件。

vim /etc/shadowsocks-libev/ss.pac

PAC 文件的基本格式如下:

function FindProxyForURL(url, host) {

// 直连规则
var direct = "DIRECT";

// 代理规则
var proxy = "SOCKS5 127.0.0.1:1081";

// 如果访问 [www.heihet09.com,直接连接](http://www.heihet09.com,直接连接)
if (dnsDomainIs(host, "[www.heihet09.com](http://www.heihet09.com)")) {
return direct;
}

// 常见网站通过代理
if (dnsDomainIs(host, "google.com") ||
dnsDomainIs(host, "facebook.com") ||
dnsDomainIs(host, "twitter.com") ||
dnsDomainIs(host, "youtube.com") ||
dnsDomainIs(host, "instagram.com")) {
return proxy;

}

// 默认直连
return direct;

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

添加:

  "pac_file": "/etc/shadowsocks-libev/ss.pac"

重启 Shadowsocks 客户端

sudo systemctl restart shadowsocks-libev

之前启动浏览器使用 --proxy-server=http://127.0.0.1:8118

这是全局代理 生效,所有请求都会通过代理转发,无论是否在 PAC 文件中定义。

这就是为什么使用 --proxy-server 时,像 Github 这样的域名也可以通过代理访问。

我们更改了 local_port 为 1081,因此 SOCKS5 代理端口为 1081

google-chrome-stable --proxy-pac-url="http://127.0.0.1:1080/ss.pac"

然而 Shadowsocks 的 PAC 文件默认通过 http://127.0.0.1:1080/ss.pac 提供服务,即使 local_port 是 1081。

curl http://127.0.0.1:1080/ss.pac

如果能成功返回 PAC 文件内容,说明 Shadowsocks 使用 1080 提供 PAC 文件。

附:

一. 解决使用 root 无法打开 Vscode 的问题

在尝试 使用 code [path] 打开文件时,会出现不允许的报错

解决方法如下:

命令: vim ~/.bashrc

添加

alias code-root='DONT_PROMPT_WSL_INSTALL=1 code --no-sandbox --user-data-dir="~/.vscode-root"'

命令:source ~/.bashrc

使用时,只需运行:code-root [path]

二. WSL 中 导致主机1080 端口被占用

如果 Ubuntu 是 WSL,由于主机上也是用了shadowsocks,它们都尝试使用相同的 127.0.0.1:1080 作为 Shadowsocks 的本地监听地址,导致端口冲突。

因此需要将 WSL 中的 Shadowsocks 配置文件中的 local_port 改为一个未被占用的端口,例如 1081

三. 去除会话代理

如果想要解除下面这三个命令

export http_proxy="socks5://127.0.0.1:1081"
export https_proxy="socks5://127.0.0.1:1081"
export all_proxy="socks5://127.0.0.1:1081"

光把他们删掉是没有用的

env | grep -i proxy

检查是否还有代理相关的环境变量

若代理变量仍然存在,需要手动取消

unset http_proxy
unset https_proxy
unset all_proxy

四. PAC 文件实际上是一个白名单策略

它明确指定了哪些域名需要走代理(如 Google、Facebook 等),

默认返回 DIRECT,即不通过代理直接访问。

修改为黑名单策略

将默认返回改为使用代理,仅屏蔽特定网站直连:

function FindProxyForURL(url, host) {
var direct = "DIRECT";
var proxy = "SOCKS5 127.0.0.1:1081";

// 直连规则
if (dnsDomainIs(host, "[www.heihet09.com](http://www.heihet09.com)") ) {
return direct;
}

// 默认走代理
return proxy;
}

修改为严格白名单

将默认返回改为使用无效代理,确保只有白名单网站可以访问:

function FindProxyForURL(url, host) {
var direct = "DIRECT";
var proxy = "SOCKS5 127.0.0.1:1081";

// 代理规则
if (dnsDomainIs(host, "google.com") ||
dnsDomainIs(host, "facebook.com")) {
return proxy;
}

// 默认无效代理
return "PROXY 127.0.0.1:0";

}