Skip to content

常见问题

zfl9 edited this page May 26, 2023 · 25 revisions

非标准的内网地址段

标准内网地址段如:10.0.0.0/8172.16.0.0/12192.168.0.0/16,如果你将其它 IP 段作为内网使用,强烈建议你纠正这个错误,这不仅会导致透明代理出问题,也会引发其它 bug,因为很多软件设计者并没有考虑到你使用的是一个非标准内网地址段。如果因为各种原因无法更改,比如公司内部,请将相关网段加入 ignlist.ext

内网主机无法访问白名单

ss-tproxy 主机上都正常,但其他主机上,黑名单正常,白名单不正常(如百度无法访问)。请将 ipts_set_snat(IPv4)、ipts_set_snat6(IPv6)设为 true。并检查 ss-tproxy 主机的 iptables 规则,有些系统会将 FORWARD 链的默认策略设为 DROP,如果有这种情况,请进行合理的调整,如果不知道怎么设置,可以参照下面的步骤,配置 pre_start 钩子函数。

代理异常时,应留意系统是否预设了某些 iptables 规则、是否与 ss-tproxy 冲突

比如,你可以通过 pre_start 钩子函数,在 start 之前,将已有的 iptables 规则清空,并将默认策略设为 ACCEPT。编辑 ss-tproxy.conf,添加如下内容(这些命令会在 ss-tproxy start 之前执行):

reset_ipt() {
    local table_chains=(
        raw 'PREROUTING OUTPUT'
        mangle 'PREROUTING INPUT FORWARD OUTPUT POSTROUTING'
        nat 'PREROUTING INPUT OUTPUT POSTROUTING'
        filter 'INPUT FORWARD OUTPUT'
    )
    for ((i = 0; i < ${#table_chains[@]}; i += 2)); do
        local table="${table_chains[i]}"
        local chains="${table_chains[i + 1]}"
        $1 -t $table -F
        $1 -t $table -X
        for chain in $chains; do
            $1 -t $table -P $chain ACCEPT
        done
    done
}

pre_start() {
    is_true "$ipv4" && reset_ipt iptables
    is_true "$ipv6" && reset_ipt ip6tables
}

ss-tproxy status 显示不准确(已运行却显示 stopped)

如果 start/restart 时某些服务显示 stopped,稍后执行 status 时又变为 running;可以不用管,这只是因为进程 从启动到监听端口 需要一个时间过程;比如,某些代理进程在启动时可能需要解析节点域名,这个过程可能比较慢。

另外,ss-tproxy 需要使用 root 权限执行,如果使用非 root 权限执行 ss-tproxy status,会因为权限不足,导致检测失败,显示 stopped 状态。

如果不是上面这些情况,请检查 ss-tproxy.conf 配置,看看是不是端口冲突了,另外就是检查代理进程、dns进程的日志,检查是否有报错,具体请见:故障排查

ss-tproxy 现在是否支持 ipv6 的透明代理(v4.x 版本已支持)

ipv6 已经在 ss-tproxy v4.x 中实现,欢迎大家进行测试,我目前并没有 ipv6 环境,测试是在某位热心网友协助下进行的,在此表示感谢。虽然 ss-tproxy v4.6 版本的 ipv6 透明代理不需要任何额外的配置,直接使用 gua 地址即可实现透明代理,但是仍然有个比较烦的地方,那就是 gua 地址随时会变化;如果无法忍受这种情况,可以给我们的设备分配一个 ula 地址段,ula 地址就如同 192.168.0.0/16 这样的 ipv4 私有地址,我们仅需给 ss-tproxy 主机固定一个 ula 地址,然后将其它主机的 ipv6 默认网关设为 ss-tproxy 主机的 ula 地址即可,因为 ula 地址是我们自己内部管理和分配的,不会随时变动,这样就不用被 gua 地址牵着鼻子走了。不过要注意,如果使用 ula 地址实现 ipv6 透明代理,那么请打开 ss-tproxy.conf 的 ipts_set_snat6 选项,因为 ula 地址不可以在公网上被路由。

如果 udp 代理不可用,建议使用 tcponly 模式(v4.6+)

对于 ss/ssr 来说,ss-redir/ssr-redir 需要开启 udp relay 功能,然后 ss-server/ssr-server 也需要开启 udp relay 功能,如果服务器还有防火墙规则,请注意放行对应的 udp 端口,此外还请确认你当地的 ISP 没有对 udp 流量进行恶意丢包。对于 v2ray(vmess),因为它的 udp 是通过 tcp 转发出去的(即 udp over tcp),所以不需要放行服务器的防火墙端口,也不需要担心 ISP 对 udp 流量的恶意干扰,因为走的是 tcp 而不是 udp。

如何只对指定的 host/addr 进行代理,其它的通通走直连

其实非常简单,使用 gfwlist 模式即可;gfwlist 模式会读取 gfwlist.txt、gfwlist.ext 两个黑名单文件,如果你只想代理某些域名、IP、网段,其它的都不想代理,可以直接将 gfwlist.txt 文件清空(执行命令 true >/etc/ss-tproxy/gfwlist.txt),然后编辑 gfwlist.ext 文件,填写要代理的域名、IP、网段即可(文件中有格式说明)。注意,在这种模式下就不要执行 update-gfwlist 命令了,因为它们会操作 gfwlist.txt 文件。

iptables: No chain/target/match by that name

如果是 iptables -j TPROXY 这条命令报的错(使用 ss-tproxy start -x 可查看调试信息),那就是没有 TPROXY 模块。

ss-tproxy.conf 中的函数不可重复定义

特别注意,因为 ss-tproxy 和 ss-tproxy.conf 都是一个 bash 脚本,所以这两个文件的内容也必须符合 bash 的语法规则,比如你不能在里面重复定义一个函数,虽然这不会报错,但是只有最后一个函数才会生效,这可能会坑死你,如果你定义了多个同名的 bash 函数,请将它们合并为一个!

切换为 gfwlist 模式后不能正常代理了

从其它模式切换到 gfwlist 模式时可能会出现此问题,原因是因为内网主机的 DNS 缓存。在访问被墙网站时,比如 www.google.com,客户机首先会进行 DNS 解析,因为之前解析过这个域名,因此客户机实际上并没有向外部网络发送 dns 解析请求,而是直接取出缓存中的 IP 地址,然后访问它;因为解析请求没有经过 ss-tproxy 主机的 dnsmasq 处理,所以对应 IP 也没有添加到 ipset-gfwlist 集合中,导致客户机发给该 IP 的数据包不会被 ss-tproxy 处理,也就是走直连出去了,GFW 当然不会让它通过了,也就出现了连接被重置等问题。解决方法也很简单,对于 Windows,请先关闭浏览器,然后打开 cmd.exe,执行 ipconfig /flushdns 来清空 DNS 缓存,然后重新打开浏览器,应该正常了;其它系统也差不多,清理 DNS 缓存即可。

有时会无法访问代理服务器

如果你在 ss-tproxy 中使用自己的 VPS 代理服务,且出现这么一个现象:访问其它地址都没问题,唯独不能正常访问自己的 VPS,比如 ssh 连不上,那么请检查你是否修改了这两个内核参数:net.ipv4.tcp_tw_reusenet.ipv4.tcp_tw_recycle,请确认它们的值都为 0(也就是禁用),vps 端和本地主机都检查一下,这两个内核参数其实默认都是为 0 的,也就是说,只要你没动过内核参数,基本不会出现这种诡异的问题。

ss-tproxy 支持什么发行版

一般都支持,没有限制。如果是路由器的那种系统或者其它的精简版系统,可能会有点问题,比如 TPROXY 模块缺失,不过都有相应的解决办法,不难移植。测试过的系统有:ArchLinux、RHEL、CentOS、Debian、Alpine、OpenWrt。

ss-tproxy 是否可以运行在虚拟机中

可以。以 VMware 为例,只需将网络设为 桥接模式 即可,这样这台虚拟机就接入了当前网络,与物理机基本没有区别。

与 UFW 一起使用的问题

如果使用了UFW,会出现局域网代理流量无法转发的问题,修复方法https://github.com/zfl9/ss-tproxy/issues/199: 打开/etc/ufw/before.rules,在-A ufw-before-input -j ufw-not-local这行下面加入以下内容:

# if TPROXY, RETURN
-A ufw-not-local -m mark --mark 0x2333 -j RETURN

如果fwmark不是0x2333,请修改为对应的fwmark。

请使用 root 权限执行 ss-tproxy 脚本

因为脚本涉及到iptables规则的修改,/etc/resolv.conf系统文件的修改等;所以,若无特殊说明,请用root权限执行脚本。

Clone this wiki locally