Home

Awesome

Linux 透明代理

什么是正向代理?

科学上网套件通常分为客户端(client)和服务端(server),server 运行在境外服务器(通常为 Linux 服务器),client 运行在本地主机(如 Windows、Linux、Android、iOS)。本文只关心 client。大多数 client 被实现为一个本地的 http、socks5 代理服务器(如 ss-local),一个程序如果想通过 client 科学上网,必须对它进行特定的设置,使其通过 http、socks5 协议与 client 进行通信,这是大多数人的使用方式。这种代理方式,我们称之为 正向代理

什么是透明代理?

在正向代理中,一个程序要想走代理,必须显式的对其进行一些设置,对该程序来说,有没有走代理是很明确的,大家都“心知肚明”。而透明代理则与之相反,以 Linux 为例,当我们设置好适当的 iptables 规则后,我们将不再需要显式的配置这些程序来让其经过代理或者不经过代理(直连),因为这些程序传出的流量会自动被 iptables 规则处理,那些我们认为需要走代理的流量,会通过合适的方法送往 client,不需要走代理的流量则直接放行(直连)。这个过程对于我们使用的程序来说是完全透明的,程序自身对其一无所知。这就叫做 透明代理。注意,所谓透明是对我们使用的程序(如浏览器)透明,而非对 client、server 或目标网站透明,理解这一点非常重要。

透明代理如何工作?

在透明代理中,那些需要走代理的流量,会通过“合适的方法”送往 client。具体到 iptables,有两种方式:

为方便叙述,本文以 纯 TPROXY 模式 指代 TCP 和 UDP 都使用 TPROXY 来实现,以 REDIRECT + TPROXY 模式 指代 TCP 使用 REDIRECT 实现,而 UDP 使用 TPROXY 来实现,有时候简称 REDIRECT 模式,它们都是一个意思。

除了 iptables 这边的支持,client 这边当然也需要实现相应的“传入协议”:

以常见的科学上网套件为例:

不同科学上网套件,对透明代理传入的支持度并不相同:

另外,是否支持 UDP 还取决于 server 端的配置,某些机场可能未开启 UDP。


如果 client 端只支持 socks5 传入(绝大部分代理套件都支持此协议),不支持透明代理传入,还能实现透明代理吗?当然可以,我们可以运行这样一个程序,该程序支持透明代理传入,socks5 传出(与 client 通信):

ipt2socks 是我编写的一个简单 C 程序,只专注于给科学上网套件添加“透明代理”传入支持,编译和使用方法都非常简单,没有配置文件,指定几个命令行参数即可运行。为了方便,ipt2socks 的 releases 页面提供了预编译好的二进制。

借助 ipt2socks,你可以将 client 程序运行在其他性能更强的内网机器上(因为代理的加解密比较费性能,尤其是你在低端设备上跑 ss-tproxy,体验会比较明显),ipt2socks 专门做了一些优化,尽可能实现零拷贝,降低性能开销。

此脚本的作用及由来

通过上面的介绍,可以知道,在构建透明代理的过程中,需要的仅仅是 iptables、支持透明代理传入的程序,那 ss-tproxy 脚本的作用是什么?如果你尝试搭建过透明代理,那么你就会体会到,这一过程并不容易,你需要设置许多繁琐的 iptables 规则,还要应对国内复杂的 DNS 环境,还要考虑 UDP 透明代理,并且希望实现常见的分流模式,而不是全都走代理。

于是有了 ss-tproxy 脚本,该脚本的目的就是辅助大家快速搭建一个透明代理环境,ss-tproxy 支持 global、gfwlist、chnroute、回国模式 等常见分流模式,以及配套的无污染 DNS 解析/分流服务。你可以在常见 Linux 环境中运行 ss-tproxy,比如路由器、旁路由网关、普通局域网机器、甚至虚拟机(桥接)。可以透明代理 ss-tproxy 本机的 TCP/UDP 流量;同一局域网下的其他机器,也可以随时将 网关和DNS 指向 ss-tproxy 主机,接入 ss-tproxy 的透明代理服务。

为什么叫做 ss-tproxy?因为该脚本最初只支持 ss 透明代理,当然现在并不局限于特定的代理套件。

脚本简介


脚本自带的分流模式,从本质上说,就是 白名单黑名单 的各种组合:

有人可能会疑问,为什么使用 ss-tproxy 后,可以访问谷歌,但无法 ping 谷歌?<br> 因为 ping 走的是 ICMP 协议,几乎没有哪个代理会处理 ICMP,所以 ICMP 走直连。

相关依赖

https://github.com/zfl9/ss-tproxy/wiki/安装依赖

<details><summary><b>依赖项</b></summary><p>

基础依赖:


TPROXY 相关:


默认 DNS 方案:

使用自定义 DNS 方案时,不需要此处的 DNS 依赖。


其他依赖:


如果某些模式基本不用,那对应的依赖也不用管。比如,不打算使用 IPv6 透明代理,则无需关心 ip6tables。脚本会检查当前配置所需的依赖,根据提示安装缺少的依赖即可。

</p></details>

安装和卸载

<details><summary><b>获取</b></summary><p>
git clone https://github.com/zfl9/ss-tproxy
cd ss-tproxy
chmod +x ss-tproxy
</p></details> <details><summary><b>安装</b></summary><p>

请确保当前用户有权限读写以下目录,如没有,请先运行sudo su进入超级用户(root)。

install ss-tproxy /usr/local/bin
install -d /etc/ss-tproxy
install -m 644 *.conf *.txt *.ext /etc/ss-tproxy
install -m 644 ss-tproxy.service /etc/systemd/system # 可选,安装 service 文件
cp -af ss-tproxy /usr/local/bin
mkdir -p /etc/ss-tproxy
cp -af *.conf *.txt *.ext /etc/ss-tproxy
cp -af ss-tproxy.service /etc/systemd/system # 可选,安装 service 文件
</p></details> <details><summary><b>卸载</b></summary><p>
# 停止脚本 (v4.7版本之前)
ss-tproxy stop
ss-tproxy flush-postrule
ss-tproxy delete-gfwlist

# 停止脚本 (v4.7版本开始)
ss-tproxy stop
ss-tproxy flush-stoprule

# 删除文件
rm -fr /usr/local/bin/ss-tproxy # 删除脚本
rm -fr /etc/ss-tproxy # 删除配置(做好备份)
rm -fr /etc/systemd/system/ss-tproxy.service # service文件
</p></details> <details><summary><b>升级</b></summary><p>

脚本目前没有自我更新能力,只能卸载后重新安装,也许后续会支持。

不同版本的配置文件、数据文件,不保证兼容,避免背上不必要的历史包袱。

</p></details>

文件列表

ss-tproxy 只是一个 shell 脚本,并不是常驻后台的服务,因此所有的修改都需要 restart 来生效。

配置说明

注意,配置文件在 /etc/ss-tproxy/ 目录,不是 git clone 下来的目录!

初次接触的,请先跳过这一段,直接看下一节 代理软件配置,按照示例修改配置即可

配置项有点多,但通常只需修改 ss-tproxy.conf 前面的少数配置项(开头至proxy配置段)

<details><summary>注释</summary>

井号开头的行为注释行,配置文件本质上是一个 shell 脚本,对于同名变量或函数,后定义的会覆盖先定义的。

</details> <details><summary>mode</summary>

分流模式,默认为 chnroute 模式,可根据需要修改为 global/gfwlist 模式。

</details> <details><summary>ipv4、ipv6</summary> </details> <details><summary>tproxy</summary>

列举一些常见的代理套件:

此配置非常重要,配置不当将无法透明代理。

</details> <details><summary>tcponly</summary>

某些机场、client、server 不支持 UDP,请注意判别。

</details> <details><summary>selfonly</summary>

内网主机如果想走代理,必须将 网关DNS 都指向 ss-tproxy 主机。

</details> <details><summary>proxy_procgroup</summary> </details> <details><summary>proxy_tcpport、proxy_udpport</summary> </details> <details><summary>proxy_startcmd、proxy_stopcmd</summary>

如果需要切换代理节点,请直接操作相关代理进程,而不是修改 ss-tproxy.conf、ss-tproxy restart,因为这是一个重量级操作,没有必要反复操作 iptables 规则、重启 DNS 服务。

ss-tproxy 提供 proxy_startcmd/proxy_stopcmd 的目的,是为了“帮你”启动/关闭代理进程,并不是要完全接管它;因此,对于那些不涉及 iptables 规则、DNS 服务的操作(比如切换节点),请不要通过 ss-tproxy 进行。

如果觉得切换节点麻烦,可以使用那些支持 自动切换节点 的代理套件,比如 clash,又比如套上 haproxy,或者用脚本封装节点切换操作,总之,请尽情发挥你的想象力。

ss-tproxy 要求代理进程不参与 ip 分流、dns 分流/解析,专心实现 TCP/UDP 全局透明代理即可,脚本已经帮你设置好了 iptables 分流规则,iptables 分流比代理进程的“用户空间”分流更快,性能开销更小,也更加彻底。

</details> <details><summary>dns_custom</summary>

给高级用户用的,用于自定义 DNS 方案,具体见 ss-tproxy.conf、ss-tproxy 脚本、wiki/DNS方案

</details> <details><summary>dns_procgroup</summary> </details> <details><summary>dns_mainport</summary> </details> <details><summary>chinadns_chnlist_first</summary>

该选项只作用于 mode=chnroute,用于设置 chinadns-ng 的 --chnlist-first 选项。该选项只影响那些 同时位于黑白名单 的域名模式,具体解释可以参见 chinadns-ng 的 README 文档。

</details> <details><summary>ipts_set_snat</summary>

selfonly=false 时有效,设置 IPv4 的 MASQUERADE 规则,有两种情况需要将其设置为 true:

此规则在 ss-tproxy stop 后仍然有效,如果你想清空这些规则,请执行 ss-tproxy flush-stoprule

</details> <details><summary>ipts_set_snat6</summary>

selfonly=false 时有效,设置 IPv6 的 MASQUERADE 规则,需要设置的情况同 ipts_set_snat。

v4.6+ 版本的 IPv6 透明代理可以通过 GUA 公网地址进行,不需要额外配置。但如果希望其他主机也使用 ss-tproxy 主机的代理(网关和 DNS 都指向 ss-tproxy 主机),建议给相关主机配置 ULA 静态私有地址,也就是组建一个 IPv6 内网,避免公网 IP 经常变动带来的麻烦。这种情况下,你需要将此配置设为 true。

</details> <details><summary>ipts_reddns_onstop、ipts_reddns6_onstop</summary>

此配置仅在 selfonly=false 时有效;前者用于 IPv4,后者用于 IPv6;必须指定端口号。

ss-tproxy stop 后,是否将内网主机发往 ss-tproxy 主机的 DNS 请求重定向至给定的 DNS,为什么要这么做?因为其它内网主机的 DNS 已经指向了 ss-tproxy 主机,但现在 ss-tproxy 已经关闭了,附带的 DNS 服务自然也被一同关闭,所以这些内网主机会因为无法解析 DNS 而无法上网。

设置该选项后,ss-tproxy 会设置一些 iptables 规则,重定向至指定的 DNS,确保内网主机可以正常上网。这些规则在执行 start 时会被自动移除,如果在 stop 状态下需要手动移除规则,请执行 ss-tproxy flush-stoprule

如果 ss-tproxy 主机上有可用的 DNS 服务,请设置为空串(留空)。

</details> <details><summary>ipts_proxy_dst_port</summary>

要代理 黑名单 的哪些端口,留空表示全部,等价于 1:65535。允许指定多个范围,逗号隔开即可。

如果觉得端口范围太大,可以设置为 1:1023,8080;此时,只有当我们访问黑名单的 1~1023 和 8080 端口时才会走代理,访问其它端口不走代理,因此可以利用此选项来放行 BT、PT 流量,因为这些流量的目的端口通常在 1024 以上。

修改此选项需要足够小心,配置不当会导致某些软件无法走代理,因为它们访问的目标端口可能不在你指定的范围内;因此将此选项留空,可能是最保险的一种做法,防止出现漏网之鱼。

</details> <details><summary>ipts_drop_quic</summary>

丢弃发往 黑名单 的 QUIC 流量(目标端口为 UDP/443),黑名单是指“分流”时,被判定为要走代理的地址。注意:本机代理进程传出的流量,不会受到此配置的影响。目前有如下取值:

比如 YouTube、ChatGPT 就默认启用 QUIC,如果油管测速比较低、ChatGPT 无法使用,可以尝试禁用 QUIC。

</details> <details><summary>opts_ss_netstat</summary>

告诉 ss-tproxy,使用 ss 还是 netstat 命令进行端口检测,目前检测本机代理进程是否正常运行的方式是直接检测其是否已监听对应的端口,虽然这种方式有时并不准确,但似乎也没有其它更好的便携方法来做这个事情。

</details>

代理软件配置

<details><summary><b>ss-libev</b></summary><p>

ss 配置文件 /etc/ss.json,与常规配置相同,无特别之处。

{
    "server": "服务器地址",
    "server_port": 服务器端口,
    "local_address": "127.0.0.1",
    "local_port": 60080,
    "method": "加密方式",
    "password": "用户密码",
    "no_delay": true,
    "fast_open": true,
    "reuse_port": true
}

配置 ss-tproxy.conf,填写启动和停止命令:

# 这里只介绍 v4.7+ 版本的配置

tproxy='false' # ss-libev 默认为 redirect 模式
tcponly='false' # 若节点不支持 udp,请修改为 true

proxy_startcmd='start_ss'
proxy_stopcmd='stop_ss'

start_ss() {
    # 设置 setgid 权限位 (只需执行一次)
    set_proxy_group ss-redir

    (ss-redir -c /etc/ss.json -u </dev/null &>>/var/log/ss-redir.log &)

    # -v 表示记录详细日志
    # (ss-redir -c /etc/ss.json -u -v </dev/null &>>/var/log/ss-redir.log &)
}

stop_ss() {
    kill_by_name ss-redir
}
</p></details> <details><summary><b>ssr-libev</b></summary><p>

ssr 配置文件 /etc/ssr.json,与常规配置相同,无特别之处。

{
    "server": "服务器地址",
    "server_port": 服务器端口,
    "local_address": "127.0.0.1",
    "local_port": 60080,
    "method": "加密方式",
    "password": "用户密码",
    "protocol": "origin",
    "protocol_param": "",
    "obfs": "plain",
    "obfs_param": ""
}

配置 ss-tproxy.conf,填写启动和停止命令:

# 这里只介绍 v4.7+ 版本的配置

tproxy='false' # ssr-libev 只支持 redirect 模式
tcponly='false' # 若节点不支持 udp,请修改为 true

proxy_startcmd='start_ssr'
proxy_stopcmd='stop_ssr'

start_ssr() {
    # 设置 setgid 权限位 (只需执行一次)
    set_proxy_group ssr-redir

    (ssr-redir -c /etc/ssr.json -u </dev/null &>>/var/log/ssr-redir.log &)

    # -v 表示记录详细日志
    # (ssr-redir -c /etc/ssr.json -u -v </dev/null &>>/var/log/ssr-redir.log &)
}

stop_ssr() {
    kill_by_name ssr-redir
}
</p></details> <details><summary><b>v2ray</b></summary><p>

v2ray 配置文件 /etc/v2ray.json,在原有配置上,添加 dokodemo-door 入站协议即可。

{
  "log": {
    "loglevel": "info" // 调试时请改为 debug
  },

  "inbounds": [
    {
      "protocol": "dokodemo-door",
      "listen": "127.0.0.1",
      "port": 60080, // 必须与proxy_tcpport/proxy_udpport保持一致
      "settings": {
        "network": "tcp,udp",
        "followRedirect": true
      },
      "streamSettings": {
        "sockopt": {
          // 若有改动,请同步修改 ss-tproxy.conf 的 tproxy 配置
          // "tproxy": "tproxy" // tproxy + tproxy 模式 (纯tproxy)
          "tproxy": "redirect" // redirect + tproxy 模式 (redirect)
        }
      }
    }
  ],

  "outbounds": [
    {
      "protocol": "shadowsocks",
      "settings": {
        "servers": [
          {
            "address": "服务器地址",
            "port": 服务器端口,
            "method": "加密方式",
            "password": "用户密码"
          }
        ]
      }
    }
  ]
}

配置 ss-tproxy.conf,填写启动和停止命令:

# 这里只介绍 v4.7+ 版本的配置

tproxy='false' # 本例中,使用 redirect 模式
tcponly='false' # 若节点不支持 udp,请修改为 true

proxy_startcmd='start_v2ray'
proxy_stopcmd='stop_v2ray'

start_v2ray() {
    # 设置 setgid 权限位 (只需执行一次)
    set_proxy_group v2ray

    (v2ray run -c /etc/v2ray.json </dev/null &>>/var/log/v2ray.log &)
}

stop_v2ray() {
    kill_by_name v2ray
}
</p></details> <details><summary><b>xray</b></summary><p>

xray 在配置上兼容 v2ray,inbounds 配置照抄 v2ray 的,然后将 v2ray 替换为 xray 即可。

</p></details> <details><summary><b>trojan(socks5)</b></summary><p>
{
    "run_type": "client",
    "local_addr": "127.0.0.1",
    "local_port": 1080,
    "remote_addr": "服务器地址",
    "remote_port": 服务器端口,
    "password": [
        "用户密码"
    ],
    "log_level": 1,
    "ssl": {
        "verify": true,
        "verify_hostname": true,
        "cert": "",
        "cipher": "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA",
        "cipher_tls13": "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384",
        "sni": "",
        "alpn": [
            "h2",
            "http/1.1"
        ],
        "reuse_session": true,
        "session_ticket": false,
        "curves": ""
    },
    "tcp": {
        "no_delay": true,
        "keep_alive": true,
        "reuse_port": false,
        "fast_open": false,
        "fast_open_qlen": 20
    }
}

配置 ss-tproxy.conf,填写启动和停止命令:

# 这里只介绍 v4.7+ 版本的配置

tproxy='true' # ipt2socks 默认使用纯 tproxy 模式
tcponly='false' # 若节点不支持 udp,请修改为 true

proxy_startcmd='start_trojan'
proxy_stopcmd='stop_trojan'

start_trojan() {
    # 设置 setgid 权限位 (只需执行一次)
    set_proxy_group trojan
    set_proxy_group ipt2socks

    (trojan -c /etc/trojan.json </dev/null &>>/var/log/trojan.log &)
    (ipt2socks </dev/null &>>/var/log/ipt2socks.log &)
}

stop_trojan() {
    kill_by_name trojan ipt2socks
}
</p></details> <details><summary><b>hysteria</b></summary><p>

hysteria 配置文件 /etc/hysteria.json,这里使用 纯 TPROXY 模式

{
  "server": "example.com:36712",
  "obfs": "8ZuA2Zpqhuk8yakXvMjDqEXBwY",
  "up_mbps": 10,
  "down_mbps": 50,
  "retry": -1,
  "retry_interval": 1,
  "tproxy_tcp": {
    "listen": ":60080",
    "timeout": 300
  },
  "tproxy_udp": {
    "listen": ":60080",
    "timeout": 300
  }
}

配置 ss-tproxy.conf,填写启动和停止命令:

# 这里只介绍 v4.7+ 版本的配置

tproxy='true' # 本例中,使用纯 tproxy 模式
tcponly='false' # 若节点不支持 udp,请修改为 true

proxy_startcmd='start_hy'
proxy_stopcmd='stop_hy'

start_hy() {
    # 设置 setgid 权限位 (只需执行一次)
    set_proxy_group hysteria

    (hysteria -c /etc/hysteria.json </dev/null &>>/var/log/hysteria.log &)

    # 由于 hy 从启动到监听端口需要一些时间,建议 sleep 一会,避免初次 status 显示异常
    sleep 0.5
}

stop_hy() {
    kill_by_name hysteria
}
</p></details> <details><summary><b>naive</b></summary><p>

naive 配置文件 /etc/naive.json:

{
  "listen": "redir://127.0.0.1:60080",
  "proxy": "https://用户:密码@naive服务器域名"
}

配置 ss-tproxy.conf,填写启动和停止命令:

# 这里只介绍 v4.7+ 版本的配置

tproxy='false' # naive 只支持 REDIRECT
tcponly='true' # naive 不支持 udp 代理

proxy_startcmd='start_naive'
proxy_stopcmd='stop_naive'

start_naive() {
    # 设置 setgid 权限位 (只需执行一次)
    set_proxy_group naive

    (naive /etc/naive.json </dev/null &>>/var/log/naive.log &)
}

stop_naive() {
    kill_by_name naive
}
</p></details> <details><summary><b>clash</b></summary><p>

clash 配置文件 /etc/clash/config.yaml:

mode: rule

# 日志级别
# log-level: info
log-level: warning

# redir-port: 60080 # REDIRECT 模式
tproxy-port: 60080 # 纯 TPROXY 模式

# RESTful API 相关
external-controller: 0.0.0.0:9090 # 监听 0.0.0.0 是为了能在其他设备访问
secret: a934ecd1-9729-4925-bcb3-15a3d7d85e77 # RESTful API 的访问密钥
# external-ui: ui

# 节点列表,节点名可被 proxy-groups 引用
proxies:
  - name: socks5_server # 节点名
    type: socks5 # 以 socks5 节点为例,其他协议请看 clash 文档
    udp: true # 启用 UDP,默认不启用 (请尽量启用,除非节点不支持)
    server: 192.168.1.100 # 填写 socks5 服务器地址
    port: 1080 # 填写 socks5 服务器端口

# 节点分组,分组名可被 rules 引用
proxy-groups:
  - name: PROXY # 分组名
    type: select # 如果想自动选择节点,可使用 url-test
    proxies:
      - socks5_server # 引用的节点名

# 如果是机场,也可以使用订阅,具体请看 clash 文档
# proxy-providers:

# 分流由 ss-tproxy 负责,clash 这边只需全部走代理
rules:
  - MATCH,PROXY # 所有流量都走 PROXY 组出去

配置 ss-tproxy.conf,此处使用 systemd 管理 clash 进程:

# 这里只介绍 v4.7+ 版本的配置

tproxy='true' # 本例中,使用纯 tproxy 模式
tcponly='false' # 若节点不支持 udp,请修改为 true

proxy_startcmd='systemctl start clash.service'
proxy_stopcmd='systemctl stop clash.service'

clash 的 systemd 服务文件 /etc/systemd/system/clash.service

[Unit]
Description=A rule based proxy in Go.
After=network-online.target

[Service]
Type=simple
#User=proxy
Group=proxy
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
LimitNOFILE=102400
Restart=on-abort
ExecStart=/usr/local/bin/clash -d /etc/clash

[Install]
WantedBy=multi-user.target

clash.service 在只使用 Group=proxy 的情况下无需特意修改 clash 配置文件目录(即 /etc/clash)的权限;因为未指定 User= 时,clash 进程的 UID 是 root,不存在权限不足的问题。

如果在 Debian/Ubuntu 中运行 ss-tproxy,考虑到 proxy 是 Debian 的 内置用户/组,你可能想在 clash.service 中同时使用 User=proxyGroup=proxy 以进一步限制进程的权限;这种情况下,在启动 clash.service 前,需要将 /etc/clash 目录的属主修改为 proxy:proxy(如 chown -R proxy:proxy /etc/clash),因为 clash 进程在运行时(可能)会往其配置文件目录写入一些文件,比如 Country.mmdb

</p></details>
<details><summary><b>若使用 systemctl 启动代理进程,请进行一次下面的操作</b></summary><p>

这些操作执行过一次就行,除非代理程序重新安装或 service 文件更新了

1、执行systemctl edit <服务名>,它会打开一个文件,让你编辑

systemctl edit xray # 以xray为例

2、在光标默认位置(第4行),新增两行,然后保存退出。具体如下:

### Editing /etc/systemd/system/xray.service.d/override.conf
### Anything between here and the comment below will become the contents of the drop-in file

# 下面两行就是要新加的,含义是:让代理进程以proxy组的身份来运行
[Service]
Group=proxy

### Edits below this comment will be discarded

3、重启代理进程的服务,让刚刚的修改生效:systemctl restart <服务名>

systemctl restart xray # 以xray为例
</p></details>
<details><summary><b>无论是什么方式启动的代理进程,请务必检查下gid是否正确</b></summary><p>
# 先查看proxy组的gid是多少
grep proxy /etc/group

# 检查进程的gid是否为proxy组
for pid in $(pidof xray); do # 以xray为例
  grep Gid /proc/$pid/status
done

# 如果gid不对,说明配置或姿势不对,请发issue寻求帮助,我尽量解决
# 也可以看下这个: https://github.com/zfl9/ss-tproxy/discussions/233
</p></details>

注意,如果只是切换代理节点,请不要通过 “修改 ss-tproxy.conf、重启 ss-tproxy” 的方式进行,请直接操作“代理进程”。举个例子,对于 ss-redir,就是先把原来的 ss-redir 进程关闭,然后启动新的 ss-redir 进程。当然,你可以用脚本或者你喜欢的任意方式,来封装节点切换操作,或者使用类似 clash 这种支持 自动切换/选择节点 的代理客户端。

脚本命令行选项


可以在命令行的任意位置,指定以下选项:


如果要修改以下配置,请先 stop,再修改 ss-tproxy.conf,再 start。

对于 proxy_stopcmd,如果忘记遵循 先 stop,后修改 的顺序,也可以补救,那就是自己手动 kill 之前的代理进程。当然,你也可以在 proxy_stopcmd 中预先填写好所有可能要 kill 的代理进程,这样后续就不需要再修改了。

其他 ss-tproxy.conf 配置无需遵循上述约定,改完 restart 即可。


内置 DNS 方案的缓存

从 ss-tproxy v4.8.2 开始,内置 DNS 方案(chinadns-ng)支持 缓存持久化

“缓存持久化” 是指 chinadns-ng 进程重启后,其缓存数据将被保留,不会丢失。

如果更改了 分流模式(mode)、gfwlist/chnlist/ignlist 等域名列表(比如一个域名从“代理”域名变成了“直连”域名),除了需要 ss-tproxy restart,还需要清空 chinadns-ng 的持久化缓存,操作如下:

verdict 缓存仅存在于 mode=chnroute 模式,其他模式下该缓存是空的。


ss-tproxy restart 后,客户机可能由于 DNS 缓存而无法正常代理,请尝试:

脚本开机自启

对于 SysVinit 发行版,直接在 /etc/rc.d/rc.local 开机脚本中加上 ss-tproxy 的启动命令即可:

/usr/local/bin/ss-tproxy start

对于 Systemd 发行版,将 ss-tproxy.service 文件放到 /etc/systemd/system/ss-tproxy.service,执行:

systemctl daemon-reload
systemctl enable ss-tproxy

不建议使用 systemctl start|stop|restart ss-tproxy 来操作 ss-tproxy,此服务文件应仅作开机自启用。

如果遇到开机自启失败的问题,可以看下这个 wiki:https://github.com/zfl9/ss-tproxy/wiki/开机自启

IPv6 透明代理

对于 v4.6+ 版本,设置 ipv6 选项即可使用 IPv6 透明代理,使用方法同 IPv4 透明代理。但如果想让其他主机也接入 ss-tproxy 的透明代理,建议给相关主机配置 ULA 静态私有地址,也就是组建一个局域网,这样在给他们设置网关和 DNS 时,就不怕公网 IP 经常变动了。在这种情况下,你需要启用 ss-tproxy.conf 的 ipts_set_snat6 选项。

更多信息请参见 wiki