最近发现树莓派涨价了,所以翻出了吃灰很久的树莓派 3B+,作为可以翻墙的旁路由网关,替代性能孱弱的路由器翻墙。这里记录下步骤。

1. 在树莓派上安装 clash

直接在这里下载clash-linux-armv8 开头的二进制包,解压后放到/usr/local/bin 下

clash 配置文件部分内容:

cat /data/clash/config.yaml

port: 7890
socks-port: 7891
allow-lan: true
tproxy-port: 7893
mode: Rule
log-level: info
external-controller: 0.0.0.0:9090
external-ui: yacd
secret: ""
dns:
  enable: false
  ipv6: false
  nameserver:
    - https://dns.rubyfish.cn/dns-query
    - https://223.5.5.5/dns-query
    - https://dns.pub/dns-query
  fallback:
    - tls://dns.google
proxies:
  -
    name: proxy1
    # 你的节点配置
proxy-groups:
  -
    name: Auto
    type: url-test
    url: http://www.gstatic.com/generate_204
    interval: 300
    proxies:
      - proxy1
  -
    name: Proxy
    type: select
    proxies:
      - Auto
      - proxy1

2. 在树莓派上安装 ss-tproxy

ss-tproxy 是个工具套件,帮你配置透明代理。

这里直接贴出我的配置文件,不介绍安装步骤。

cat /etc/ss-tproxy/ss-tproxy.conf

## mode
#mode='global'  # global 模式 (不分流)
#mode='gfwlist' # gfwlist 模式 (黑名单)
mode='chnroute' # chnroute 模式 (白名单)

## ipv4/6
ipv4='true'     # true:启用 ipv4 透明代理;false:关闭 ipv4 透明代理
ipv6='false'    # true:启用 ipv6 透明代理;false:关闭 ipv6 透明代理

## tproxy
tproxy='true'  # true:TPROXY+TPROXY; false:REDIRECT+TPROXY

## tcponly
tcponly='true' # true:仅代理 TCP 流量;false:代理 TCP 和 UDP 流量

## selfonly
selfonly='false' # true:仅代理本机流量;false:代理本机及"内网"流量

## proxy
# user/group(#1,推荐) vs svraddr+port(#2), user/group 选其中一个填写(允许同时填写)
proxy_procuser='clash'        # 本机代理进程的 user/uid,用来放行本机代理进程传出的流量
proxy_procgroup=''       # 本机代理进程的 group/gid,用来放行本机代理进程传出的流量
proxy_svraddr4=(1.2.3.4) # 服务器的 IPv4 地址或域名,允许填写多个服务器地址,空格隔开
proxy_svraddr6=()        # 服务器的 IPv6 地址或域名,允许填写多个服务器地址,空格隔开
proxy_svrport='80,443'   # 服务器的监听端口,可填多个端口,格式同 ipts_proxy_dst_port
proxy_tcpport='7893'    # ss/ssr/v2ray 等本机进程的 TCP 监听端口,该端口支持透明代理
#proxy_udpport='7893'    # ss/ssr/v2ray 等本机进程的 UDP 监听端口,该端口支持透明代理
proxy_startcmd='sudo -u clash bash -c "/usr/local/bin/clash -d /data/clash -f /data/clash/config.yaml > /var/log/clash.log 2>&1 &"'     # 用于启动本机代理进程的 shell 命令,该命令应该能立即执行完毕
proxy_stopcmd='pkill clash'      # 用于关闭本机代理进程的 shell 命令,该命令应该能立即执行完毕

## dns
dns_direct='123.123.123.123'          # 本地 IPv4 DNS,不能指定端口,也可以填组织、公司内部 DNS
#dns_direct='114.114.114.114'          # 本地 IPv4 DNS,不能指定端口,也可以填组织、公司内部 DNS
dns_direct6='240C::6666'              # 本地 IPv6 DNS,不能指定端口,也可以填组织、公司内部 DNS
dns_remote='8.8.8.8#53'               # 远程 IPv4 DNS,必须指定端口,提示:访问远程 DNS 会走代理
dns_remote6='2001:4860:4860::8888#53' # 远程 IPv6 DNS,必须指定端口,提示:访问远程 DNS 会走代理

## dnsmasq
dnsmasq_bind_port='5353'                  # dnsmasq 服务器监听端口,见 README
dnsmasq_cache_size='4096'               # DNS 缓存大小,大小为 0 表示禁用缓存
dnsmasq_cache_time='3600'               # DNS 缓存时间,单位是秒,最大 3600 秒
dnsmasq_query_maxcnt='1024'             # 设置并发 DNS 查询的最大数量,默认为 150
dnsmasq_log_enable='false'              # 记录详细日志,除非进行调试,否则不建议启用
dnsmasq_log_file='/var/log/dnsmasq.log' # 日志文件,如果不想保存日志可以改为 /dev/null
dnsmasq_conf_dir=()                     # `--conf-dir` 选项的参数,可以填多个,空格隔开
dnsmasq_conf_file=()                    # `--conf-file` 选项的参数,可以填多个,空格隔开
dnsmasq_conf_string=()                  # 自定义配置,一个数组元素就是一行配置,空格隔开

## chinadns
chinadns_bind_port='65353'               # chinadns-ng 服务器监听端口,通常不用改动
chinadns_timeout='5'                     # 等待上游 DNS 返回响应的超时时间,单位为秒
chinadns_repeat='1'                      # 向可信 DNS 发送几次 DNS 查询请求,默认为 1
chinadns_fairmode='false'                # 使用公平模式,具体看 chinadns-ng 的 README
chinadns_gfwlist_mode='false'            # gfwlist 模式,加载 gfwlist.txt/gfwlist.ext
chinadns_noip_as_chnip='false'           # 启用 chinadns-ng 的 `--noip-as-chnip` 选项
chinadns_verbose='false'                 # 记录详细日志,除非进行调试,否则不建议启用
chinadns_logfile='/var/log/chinadns.log' # 日志文件,如果不想保存日志可以改为 /dev/null
chinadns_privaddr4=()                    # IPv4 私有地址段,多个用空格隔开,具体见 README
chinadns_privaddr6=()                    # IPv6 私有地址段,多个用空格隔开,具体见 README

## dns2tcp
dns2tcp_bind_port='65454'               # dns2tcp 转发服务器监听端口,如有冲突请修改
dns2tcp_tcp_syncnt=''                   # dns2tcp 的 `-s` 选项,留空表示不设置此选项
dns2tcp_tcp_quickack='false'            # dns2tcp 的 `-a` 选项,选项取值为 true/false
dns2tcp_tcp_fastopen='false'            # dns2tcp 的 `-f` 选项,选项取值为 true/false
dns2tcp_verbose='false'                 # 记录详细日志,除非进行调试,否则不建议启用
dns2tcp_logfile='/var/log/dns2tcp.log'  # 日志文件,如果不想保存日志可以改为 /dev/null

## ipts
ipts_if_lo='lo'                 # 环回接口的名称,在标准发行版中,通常为 lo,如果不是请修改
ipts_rt_tab='233'               # iproute2 路由表名或表 ID,除非产生冲突,否则不建议改动该选项
ipts_rt_mark='0x2333'           # iproute2 策略路由的防火墙标记,除非产生冲突,否则不建议改动该选项
ipts_set_snat='true'           # 设置 iptables 的 MASQUERADE 规则,布尔值,`true/false`,详见 README
ipts_set_snat6='true'          # 设置 ip6tables 的 MASQUERADE 规则,布尔值,`true/false`,详见 README
ipts_reddns_onstop='true'       # ss-tproxy stop 后,是否将其它主机发至本机的 DNS 重定向至直连 DNS,详见 README
ipts_proxy_dst_port='1:65535'   # 黑名单 IP 的哪些端口走代理,多个用逗号隔开,冒号为端口范围(含边界),详见 README

## opts
opts_ss_netstat='auto'                  # auto/ss/netstat,用哪个端口检测工具,见 README
opts_ping_cmd_to_use='auto'             # auto/standalone/parameter,ping 相关,见 README
opts_hostname_resolver='auto'           # auto/dig/getent/ping,用哪个解析工具,见 README
opts_overwrite_resolv='false'           # true/false/留空,如何操作 resolv.conf,见 README
opts_ip_for_check_net='114.114.114.114' # 检测外网是否可访问的 IP,ping,留空表示跳过此检查

## file
file_gfwlist_txt='/etc/ss-tproxy/gfwlist.txt'      # gfwlist/chnlist 模式预置文件
file_gfwlist_ext='/etc/ss-tproxy/gfwlist.ext'      # gfwlist/chnlist 模式扩展文件
file_ignlist_ext='/etc/ss-tproxy/ignlist.ext'      # global/chnroute 模式扩展文件
file_chnroute_set='/etc/ss-tproxy/chnroute.set'    # chnroute 地址段文件 (iptables)
file_chnroute6_set='/etc/ss-tproxy/chnroute6.set'  # chnroute6 地址段文件 (ip6tables)
file_dnsserver_pid='/etc/ss-tproxy/.dnsserver.pid' # dns 服务器进程的 pid 文件 (shell)

pre_start() {
    iptables -t filter -P FORWARD ACCEPT
}

有热心网友整理了坑点:https://github.com/zfl9/ss-tproxy/issues/188

需要注意的是需要给clash 设置能开启tproxy 的权限:

sudo setcap cap_net_bind_service,cap_net_admin=+ep /usr/local/bin/clash

启动 ss-tproxy

sudo ss-tproxy start

设置开启启动

cp  ss-tproxy.service /etc/systemd/system/ss-tproxy.service
systemctl daemon-reload
systemctl enable ss-tproxy

3. 验证效果

假设你的树莓派 IP 为192.168.1.2

在手机上配置静态 IP,网关和 DNS 都设置成192.168.1.2 看下能否正常上网,翻墙。

4. 配置 DHCP

为了不用在每台设备上配置静态 IP,可以直接修改路由器的 DHCP 配置。

a. 配置路由器的 DHCP,将树莓派的 MAC 地址和 IP 绑定,并将网关和 DNS 都设置成192.168.1.2

b. 配置树莓派为静态 IP

如果树莓派也按照路由器的 DHCP 配置,那它会用自己当网关,ss-tproxy 会一直在等待网络就绪,无法启动,死锁了。

所以需要将树莓派设置成静态 IP,网关和 DNS 都设置成路由器 IP。

我的树莓派装的是 Ubuntu 系统,可以参考这篇:https://cloud.tencent.com/developer/article/1933335

不过这样做有个风险,如果哪天你换路由器了,且 IP 段也变了,那可能连不上树莓派,只能重装树莓派的系统了。

5. 常见问题

1. Chrome 访问 Google 证书错误,Safari 正常

访问 https://www.google.com ,结果出来的是 facebook 的证书。

这是因为 DNS 被污染了,需要调整 Chrome 的 DNS 配置。

chrome://settings/security?search=dns 关闭 Use secure DNS

UDDATE

树莓派 3B 的网口是 100 Mbps 的,如果你的宽带带宽超过 100,就浪费了。