ShadowsocksR 配置

ShadowsocksR(简称 SSR)是由 @breakwa11 发起的一个 Shadowsocks 分支,主要特点是增加了协议插件(增强安全性)和混淆插件(降低识别率),虽然 breakwa11 早在 2017 年 7 月就已经删除了 SSR 相关源码,但我目前仍然使用的 SSR(V2Ray 速度不行,我的树莓派 3B 完全带不起),因为原版 SS 被 QoS(Quality of Service,服务质量)影响严重(SS + simple-obfs 也能像 SSR 那样混淆),如果不将流量伪装为 HTTP/HTTPS 数据,那么代理的速度很难提上来(即使装了锐速、BBR 魔改)。为什么呢,因为 HTTP/HTTPS 流量的优先级相对来说是比较高的(标准端口,HTTP/80、HTTPS/443),优先级高的包在国际出口上就会先发送,尽量不滞留,路顺畅了速度自然就上来了。

SSR 安装脚本

首先感谢 秋水逸冰 提供的 Shadowsocks 一键安装脚本(四合一)

获取脚本

安装 SSR

卸载 SSR

管理 SSR

SSR 配置详解


## 基本配置
{
    "server": "0.0.0.0",
    "server_port": 8989,
    "password": "password",
    "method": "chacha20",
    "protocol": "origin",
    "protocol_param": "",
    "obfs": "plain",
    "obfs_param": "",
    "timeout": 120,
    "udp_timeout": 60,
    "fast_open": false,
    "workers": 2
}

## 参数说明
{
    "server": "0.0.0.0",    # 监听地址
    "server_port": 8989,    # 监听端口
    "password": "password", # 端口密码
    "method": "chacha20",   # 加密方式
    "protocol": "origin",   # 协议插件, origin: 原版协议
    "protocol_param": "",   # 协议插件参数
    "obfs": "plain",        # 混淆插件, plain: 不混淆
    "obfs_param": "",       # 混淆插件参数
    "timeout": 120,         # tcp超时
    "udp_timeout": 60,      # udp超时
    "fast_open": false,     # 需内核支持(3.7+), 在tcp握手的同时交换数据
    "workers": 2            # worker进程数量
}

## 多用户配置
{
    "server": "0.0.0.0",
    "port_password": {
        "8080": "password1",
        "8181": "password2",
        "8282": "password3"
    },
    "method": "chacha20",
    "protocol": "origin",
    "protocol_param": "",
    "obfs": "plain",
    "obfs_param": "",
    "timeout": 120,
    "udp_timeout": 60,
    "fast_open": false,
    "workers": 2
}

## 多用户 + 不同参数
{
    "server": "0.0.0.0",
    "port_password": {
        "8080": {
            "method": "aes-128-cfb",
            "protocol": "auth_sha1_v4",
            "protocol_param": "",
            "obfs": "tls1.2_ticket_auth",
            "obfs_param": "",
            "password": "password1"
        },
        "8181": {
            "method": "aes-256-cfb",
            "protocol": "auth_aes128_md5",
            "protocol_param": "",
            "obfs": "http_simple",
            "obfs_param": "",
            "password": "password2"
        },
        "8282": {
            "password": "password3"
        }
    },
    "method": "chacha20",
    "protocol": "origin",
    "protocol_param": "",
    "obfs": "plain",
    "obfs_param": "",
    "timeout": 120,
    "udp_timeout": 60,
    "fast_open": false,
    "workers": 2
}

SSR 混淆说明

ShadowsocksR 协议/混淆插件文档ShadowsocksR 协议/混淆插件说明

## Client -> Server 方向
客户端请求 -> ss-local -> 协议插件 -> 加密 -> 混淆插件
======================== GFW =======================
混淆插件 -> 解密 -> 协议插件 -> ss-server -> 目标服务器

## 协议插件与混淆插件的作用
"协议插件": 主要用于增加数据完整性校验,增强安全性,进行包长度混淆等
"混淆插件": 主要用于伪装为其它协议(如 HTTP、HTTPS),扰乱 GFW 的检测

## 推荐的协议插件与混淆插件
协议插件: "auth_sha1_v4"、"auth_aes128_md5"、"auth_aes128_sha1"、"auth_chain_a"
混淆插件: "plain"(即:不混淆)、"http_simple"、"http_post"、"tls1.2_ticket_auth"
# 为什么推荐 plain,因为混淆不总是有效果的,有时候不混淆让其看起来像随机数据会更好一些

SSR 推荐配置

简要分析

推荐配置是指:如何配置 SSR 来达到既骗过 QoS(提高速度)又骗过 GFW(避免被封)的目的(个人理解,如有不对之处请指正)。

要点一:提高速度
其实文章开头已经提到了,只要将 SSR 流量伪装成 HTTP/80、HTTPS/443 流量就行了。放到 SSR 中,也就是将混淆插件改为 http_simpletls1.2_ticket_auth,并将 SSR 监听端口改为 80、443。

要点二:避免被封
上面的配置在一定程度上其实也达到了欺骗 GFW 的目的,但这还远远不够。从抓包上看,http_simple 像是在访问一个 HTTP 服务器,而 tls1.2_ticket_auth 则像是在访问一个 HTTPS 服务器。如果 GFW 进行主动探测,即装作一个浏览器,去访问这台 SSR 服务器,看看是不是真的是 HTTP/HTTPS 服务器,结果显而易见,肯定是请求错误(如 curl 会返回 Empty reply from server 错误),这就会加深 GFW 对这个 IP 的怀疑,如果请求比较频繁或流量很大,很有可能这个 IP 就会被封了。那如何让 SSR 既能作为正常代理使用,又能作为 HTTP/HTTPS 服务器呢?不要认为这很难做到,其实很简单,只需在 SSR 服务端加个 redirect 参数,以及一个 HTTP 服务器(推荐 Nginx)就行了。这里的关键是 redirect 参数(重定向),参数值默认是空的,它的作用很简单:如果 SSR 服务端接收到的是正常 SSR 请求,那么就进行正常的代理操作;如果 SSR 服务端接收到的不是正常 SSR 请求,那么就将该请求反代到 redirect 指定的地址。我们只需将 Nginx 监听在 127.0.0.1 的某个端口(监听地址不冲突就行),假设为 127.0.0.1:8080,然后将 SSR 的 redirect 参数设为 127.0.0.1:8080 就能到达我们的目的:让 SSR 服务器正常回应 HTTP/HTTPS 请求。另外,建议给 SSR 服务器分配一个独立的域名,同时客户端的混淆参数设为空。为什么呢?因为默认情况下 SSR 客户端会将 SSR 服务器地址(也就是这个域名)作为 HTTP/HTTPS 的虚拟主机字段,GFW 在进行网站访问时,提取的网站其实就是这个虚拟主机,如果不这样做(比如很多人喜欢将混淆参数设为 www.bing.com 等国外大型网站),那么 GFW 提取到的网站其实是 www.bing.com,而 www.bing.com 解析出来的 IP 列表中根本没有一个与你当前连接的 IP 相对应的,多次请求后可能会增加 IP 或端口被封锁的可能。

http_simple还是tls1.2_ticket_auth
http_simple 是伪装为 HTTP 协议,tls1.2_ticket_auth 是伪装为 HTTPS 协议。但是 http_simple 并非 HTTP/1.1 协议的完整实现,它仅仅做了一个头部的 GET 请求和一个简单的回应,之后依然为原协议流。所以如果检测更严格一些就不太安全了。但是 http_simple 混淆优点还是有的,那就是延迟明显比 tls1.2_ticket_auth 更低(大概 20% 左右),如果你对延迟比较敏感(比如玩游戏),那么可以选择 http_simple,如果对这一点延迟不是很敏感,那么就选 tls1.2_ticket_auth 吧,毕竟它是 TLS 1.2 协议的完整模拟实现,不容易被 GFW 探测到。

伪装为HTTP

SSR 配置
监听端口必须为 80(HTTP 协议标准端口);协议插件推荐使用 auth_chain_*,这里使用 auth_chain_a(注意加密为 none,因为 auth_chain_a 自带 rc4 加密);协议参数其实是一个 单端口多用户 的应用例子,即使只有一个用户,也请这么做,方便以后进行扩展。参数解释:# 前面可以设置一个数字,它表示每个用户允许的最大客户端数,如果省略则表示无限制,但是 # 必须保留;而后面的 uid:pwd 则表示用户 ID(范围:1 ~ 2147483647)和用户密码,多个请使用 , 英文逗号隔开;客户端连接时只需将 uid:pwd 填到协议参数中就可以了。然后就是 redirect 参数了,假设 Nginx 运行在 127.0.0.1:8080 地址。

Nginx 配置
注意将 www.example.com 替换为对应的域名,然后随便下载个网页模板放到网站根目录。

伪装为HTTPS

SSR 配置
监听端口必须为 443(HTTPS 协议标准端口);协议插件推荐使用 auth_chain_*,这里使用 auth_chain_a(注意加密为 none,因为 auth_chain_a 自带 rc4 加密);协议参数其实是一个 单端口多用户 的应用例子,即使只有一个用户,也请这么做,方便以后进行扩展。参数解释:# 前面可以设置一个数字,它表示每个用户允许的最大客户端数,如果省略则表示无限制,但是 # 必须保留;而后面的 uid:pwd 则表示用户 ID(范围:1 ~ 2147483647)和用户密码,多个请使用 , 英文逗号隔开;客户端连接时只需将 uid:pwd 填到协议参数中就可以了。然后就是 redirect 参数了,假设 Nginx 运行在 127.0.0.1:8443 地址。

Nginx 配置
注意将 www.example.com 替换为对应的域名,然后随便下载个网页模板放到网站根目录,准备好该域名的 SSL 证书放到 /etc/nginx/ssl 目录下。

HTTP+HTTPS

如果同时启用 http_simpletls1.2_ticket_auth 混淆,则 SSR 监听 0.0.0.0:80/443,Nginx 监听 127.0.0.1:8080/8443。

SSR 配置

Nginx 配置

测试是否成功

  1. 浏览器访问 http://www.example.comhttps://www.example.com,正常打开网页。
  2. SSR 客户端连接 www.example.com:80www.example.com:443,正常进行 SSR 代理。

注意,如果你的 vps 上本来就有网站,那么最好不要让 Nginx 监听 8080、8443 等非标准端口,否则 Nginx 的 rewrite 操作会附带上 8080、8443 端口,而又因为监听的地址为 127.0.0.1,所以会导致客户端的 Connection refused 连接错误。那么怎么解决呢?比较简单的方法是不要让 SSR 监听 0.0.0.0 地址,而是只监听外网网卡(如 eth0)的地址,然后将 Nginx 的监听地址和端口改为 127.0.0.1:80、127.0.0.1:443,然后重启 SSR、Nginx。