Skip to content

SSR推荐配置

zfl9 edited this page Mar 21, 2020 · 3 revisions

ShadowsocksR(简称 SSR)是由 @breakwa11 发起的一个 Shadowsocks 分支,主要特点是增加了协议插件(增强安全性)和混淆插件(降低识别率)。本文主要介绍如何配置 ShadowsocksR,来提高代理的速度以及尽量避免被封锁(其实自从 SSR 项目被 breakwa11 删除后,SSR 已经不再安全了,因为没人维护了,所以不是很建议再使用 SSR,用 AES-GCM 加密的 SS 或许更好一点,或者 V2Ray)。

SSR 安装脚本

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

获取脚本

wget --no-check-certificate -O shadowsocks-all.sh https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks-all.sh
chmod +x shadowsocks-all.sh

安装 SSR

./shadowsocks-all.sh 2>&1 | tee shadowsocks-all.log

# 安装成功后,脚本提示如下:
Congratulations, your_shadowsocks_version install completed!
Your Server IP        :your_server_ip
Your Server Port      :your_server_port
Your Password         :your_password
Your Encryption Method:your_encryption_method

Your QR Code: (For Shadowsocks Windows, OSX, Android and iOS clients)
 ss://your_encryption_method:your_password@your_server_ip:your_server_port
Your QR Code has been saved as a PNG file path:
 your_path.png

Welcome to visit:https://teddysun.com/486.html
Enjoy it!

卸载 SSR

# 若安装了多个版本,请运行多次(每次卸载一个)
./shadowsocks-all.sh uninstall

管理 SSR

# 启动、关闭、重启、状态
## Shadowsocks-Python
/etc/init.d/shadowsocks-python start|stop|restart|status
## ShadowsocksR
/etc/init.d/shadowsocks-r start|stop|restart|status
## Shadowsocks-Go
/etc/init.d/shadowsocks-go start|stop|restart|status
## Shadowsocks-libev
/etc/init.d/shadowsocks-libev start|stop|restart|status

# 各版本默认配置文件
## Shadowsocks-Python
/etc/shadowsocks-python/config.json
## ShadowsocksR
/etc/shadowsocks-r/config.json
## Shadowsocks-Go
/etc/shadowsocks-go/config.json
## Shadowsocks-libev
/etc/shadowsocks-libev/config.json

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(避免被封)的目的(个人理解,如有不对之处请指正)。

要点一:提高速度
因为互联网中 HTTP/HTTPS 流量占比很大,所以 HTTP/HTTPS 流量的 QoS 优先级通常也比较高,所以我觉得将 SSR 流量伪装成 HTTP/HTTPS 流量或许可以减少 QoS 的影响,从而提高它在国际出口上的速度。实现该目的的配置很简单,将混淆插件改为 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 错误,因为 SSR 本身并不能提供 HTTP/HTTPS 服务),这就会加深 GFW 对服务器的怀疑,如果请求比较频繁或流量很大,很有可能就被封了。那如何让 SSR 既能作为正常代理使用,又能作为 HTTP/HTTPS 服务器呢?不要认为这很难做到,其实很简单,只需在 SSR 服务端加个 redirect 参数,以及一个 HTTP(S) 服务器(推荐 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 地址。

{
    "server": "0.0.0.0",
    "server_port": 80,
    "method": "none",
    "password": "password",
    "protocol": "auth_chain_a",
    "protocol_param": "#666:abc123456",
    "obfs": "http_simple",
    "obfs_param": "",
    "redirect": "127.0.0.1:8080",
    "fast_open": true,
    "workers": 1
}

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

server {
    listen      127.0.0.1:8080;
    server_name www.example.com;

    root    /srv/http/www.example.com;
    index   index.html;
}

伪装为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 地址。

{
    "server": "0.0.0.0",
    "server_port": 443,
    "method": "none",
    "password": "password",
    "protocol": "auth_chain_a",
    "protocol_param": "#666:abc123456",
    "obfs": "tls1.2_ticket_auth",
    "obfs_param": "",
    "redirect": "127.0.0.1:8443",
    "fast_open": true,
    "workers": 1
}

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

server {
    ## 监听域名及端口
    listen      127.0.0.1:8443 ssl;
    server_name www.example.com;

    ## 网站根目录、index 文件
    root    /srv/http/www.example.com;
    index   index.html;

    ## SSL/TLS 配置
    ssl                 on;
    ssl_certificate     "/etc/nginx/ssl/www.example.com.crt";
    ssl_certificate_key "/etc/nginx/ssl/www.example.com.key";

    ## 静态资源缓存
    location ~* \.(jpg|jpeg|png|gif|ico|(css|js)(\?v=.*)?)$ {
       expires 60d;
    }
}

HTTP+HTTPS

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

SSR 配置

{
    "server": "0.0.0.0",
    "port_password": {
        "80": {
            "obfs": "http_simple"
        },
        "443": {
            "obfs": "tls1.2_ticket_auth"
        }
    },
    "method": "none",
    "password": "password",
    "protocol": "auth_chain_a",
    "protocol_param": "#666:abc123456,2333:abc123456",
    "obfs_param": "",
    "redirect": ["*:80#127.0.0.1:8080", "*:443#127.0.0.1:8443"],
    "fast_open": true,
    "workers": 2
}

Nginx 配置

# http 站点配置
server {
    listen      127.0.0.1:8080;
    server_name www.example.com;
    return 301 https://www.example.com$request_uri;
}

# https 站点配置
server {
    ## 监听域名及端口
    listen      127.0.0.1:8443 ssl;
    server_name www.example.com;

    ## 网站根目录、index 文件
    root    /srv/http/www.example.com;
    index   index.html;

    ## SSL/TLS 配置
    ssl                 on;
    ssl_certificate     "/etc/nginx/ssl/www.example.com.crt";
    ssl_certificate_key "/etc/nginx/ssl/www.example.com.key";

    ## 静态资源缓存
    location ~* \.(jpg|jpeg|png|gif|ico|(css|js)(\?v=.*)?)$ {
       expires 60d;
    }
}

测试是否成功

  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。