分享到朋友圈 1. 点击导航栏右侧按钮。
2. 选择 发送给朋友 或 分享到朋友圈。
收起 捐款给作者

Cherysun’s Tech Cafe

在 Raspberry Pi 上运行 Clash 作为透明代理

家里闲置着一个 Raspberry Pi 3 Model B+,决定简单部署一下 Clash 为局域网中的设备“科学”访问网络提供方便。由于路由器用着 Linksys Veloop 和 AirPort Time Capsule,OpenWrt 不适用,我对于更改路由器固件后的稳定性一直表示怀疑,所以就选择在 Pi 上部署 Clash,然后通过修改 iptables 用作透明代理,这样只需要将接入局域网设备的网关和 DNS 手动设置为 Pi 的 IP 地址即可实现同样的功能。

Raspberry Pi Imager 在今年 3 月发布,这使得 Raspbian 的安装更为简单。只需要在 Mac 上下载 Raspberry Pi Imager 的 DMG 并安装,就可以可视化地将 Pi 的镜像写入 microSD 卡。这里我选择了安装 Raspbian Lite,即仅有 CLI 的版本,毕竟只需要命令行就足够了,没有桌面还能提高一些运行效率。

Raspberry Pi Imager

摘要 TL;DR

Raspberry Pi 的准备配置

启动全新的 Raspbian 后需要做的自然是配置 SSH 相关的信息。这里,为了方便,我选择删除默认的 pi 用户,直接使用 root 用户进行后续的管理。

如果你不希望删除 pi 用户,那么可以忽略接下来的配置。

首先使用 pi 用户的默认密码 raspberry 登录,然后通过 sudo supasswd 命令为 root 用户设置密码。接着通过 sudo raspi-config 访问 Pi 的软件配置工具,选择 3 Boot Options > B1 Desktop / CLI > B1 Console 然后重新启动从而禁用自动登录,否则 Raspbian 将自动登录到 pi 用户,会导致其无法删除。

重新启动后,登录到 root 用户,通过 deluser --remove-home --remove-all-files pi 命令将 pi 用户及其相关文件删除。

接着,配置网络连接。我的 Pi 使用 Wi-Fi 连接到网络,因而需要在 raspi-config 中选择 2 Network Options > N2 Wi-Fi,然后分别输入 SSID 名称和密码,使 Pi 连接 Wi-Fi。当然,需要在路由器中为 Pi 分配一个静态的 IP 地址而非由 DHCP 服务器动态分配,以便于其他设备可以通过固定的 IP 地址访问到 Pi,例如这里,我将 Pi 的 IP 地址配置为 10.0.1.11。

安装和配置 Clash

访问 https://github.com/Dreamacro/clash 查看有关 Clash 的信息。

关于 Clash,Dreamacro/clash

可以使用 Go 直接 build,这里我直接使用 Premium release 的二进制文件,截至文章发布,最新版本为 Premium 2020.05.08。Raspberry Pi 3 Model B+ 为 ARMv7 架构(可以通过 arch 命令查看),因此选择 clash-linux-armv7-2020.05.08.gz。

wget https://github.com/Dreamacro/clash/releases/download/premium/clash-linux-armv7-2020.05.08.gz
gunzip clash-linux-armv7-2020.05.08.gz
mv clash-linux-armv7-2020.05.08.gz /usr/local/bin/clash
chmod +x /usr/local/bin/clash

这样,将 Clash 的二进制文件下载并放置于 /usr/local/bin/ 路径中,增加 execute 权限。

执行一次 clash 命令,Clash 会自动创建 $HOME/.config/clash/ 配置目录,并新建默认配置文件 config.yaml 和名为 Country.mmdb 的 GeoIP 数据库。接着修改 config,yaml 配置文件,如下是一个示例配置供参考。

port: 8888
socks-port: 8889
redir-port: 8890
allow-lan: true
mode: Rule
log-level: info

# external-controller: 0.0.0.0:6300
# external-ui: clash-dashboard
# secret: "your-secret-passphrase"

experimental:
  ignore-resolve-fail: false

dns:
  enable: true
  ipv6: false
  listen: 0.0.0.0:53
  enhanced-mode: redir-host
  nameserver:
    - https://dns.alidns.com/dns-query # DNS-over-HTTPS

hosts:
  "dns.alidns.com": 223.5.5.5

proxies:
  ...

proxy-groups:
  ...

rules:
  ...
  GEOIP,DIRECT
  MATCH,Proxy

需要注意以下的一些配置。

  • allow-lan: true 允许 Clash 处理来自局域网内其他设备的流量。
  • redir-port: 8890 意味着 Clash 将会监听 8890 端口以处理局域网内其他设备所转发的流量。而 port: 8888socks-port: 8889 分别声明了用作 HTTP / HTTPS 和 SOCKS5 代理的端口。
  • dns 中需要配置 enable: true 允许 Clash 用作 DNS 服务器,配置 enhanced-mode: redir-host 以用于透明代理,并声明 listen: 0.0.0.0:53 以监听 53 端口。如果要绑定例如 53 等低位端口,就必须要使用 root 用户;如果使用 pi 等普通用户运行 Clash 将会出现端口绑定的权限错误。
  • 关于 dns 中的 nameserver 配置,可以使用常用的公共 DNS 如 114.114.114.114、8.8.8.8 等,也可以配置 DNS-over-HTTPS。这里我使用 https://dns.alidns.com/dns-query 即阿里 DNS 的 DoH,并且增加了一条 hosts 配置 "dns.alidns.com": 223.5.5.5,这样就不需要再对 dns.alidns.com 进行解析了。

至于 proxiesproxy-groups 以及 rules 的配置,则可以根据需要自行编辑。更多 Clash 示例配置及说明可以参考 https://github.com/Dreamacro/clash#config 中的内容。

如果需要通过浏览器可视化地查看 Clash 运行情况,可以下载 clash-dashboard

cd $HOME/.config/clash/
git clone https://github.com/Dreamacro/clash-dashboard.git
git checkout -b gh-pages origin/gh-pages

取消注释 external-controllerexternal-uisecret,并配置 secret 作为访问 dashboard 的口令。

在终端中通过 clash 命令启动 Clash。如果配置了 dashboard,可以在局域网内的其他设备上开启浏览器,访问 http://10.0.1.11:6300/ui/,其中 10.0.1.11 即此前配置的 Pi 的 IP 地址,端口 6300 即 Clash 监听的外部控制器端口。然后输入如下信息:

  • Host 为 10.0.1.11,即 Pi 的 IP 地址。
  • 端口为 6300,即 external-controller: 0.0.0.0:6300 所配置的端口。
  • 密钥即 secret 所配置的口令,上述示例中为 your-secret-passphrase

至于 clash-dashboard 的后续用法应该非常简单明了,这里就不再介绍。

在浏览器中通过 clash-dashboard 控制 Clash

以守护进程运行 Clash

显然,直接在终端中运行 clash 会使 Clash 随着终端的退出而关闭。这时就需要将其作为守护进程运行,这里选择使用 PM2

运行 wget -qO- https://getpm2.com/install.sh | bash 安装 PM2。有关 PM2 的一些基本使用方法,可以 查阅其文档。如下是一些简要的 PM2 的用法。

# Start, restart, stop and delete Clash instance
pm2 start|restart|stop|delete clash

# 查看所有 PM2 实例
pm2 list

# 删除所有 PM2 示例
pm2 kill

# 查看 Clash 日志
pm2 logs clash

# 清空 Clash 日志
pm2 flush clash

通过 pm2 list 查看 Clash 实例的状态为 online 并且 pm2 logs clash 的日志中没有错误输出,这表明 Clash 已经作为守护进程正确运行了。

为终端配置代理服务器

尽管我们的目的是为局域网内的其他设备配置代理服务器,但我们也经常需要在终端通过代理服务器访问一些资源。由于在 Clash 配置文件中声明了 port: 8888,所以我们可以在 .zshrc、.bashrc 或 .bash_profile 中增加以下内容。

# Define `setproxy` command to enable proxy configuration
setproxy() {
  export http_proxy="http://localhost:8888"
  export https_proxy="http://localhost:8888"
}

# Define `unsetproxy` command to disable proxy configuration
unsetproxy() {
  unset http_proxy
  unset https_proxy
}

# By default, enable proxy configuration for terminal login
setproxy

这样,就可以在终端中使用 setproxyunsetproxy 命令分别配置或取消配置代理服务器了,并且默认地为终端启用代理服务器。

为 Raspberry Pi 启用 IP 转发

编辑 /etc/sysctl.conf 文件,将 net.ipv4.ip_forward=0 修改为 net.ipv4.ip_forward=1,然后执行 sysctl -p 以使配置生效。

配置 iptables 并使其持久化

在启用 IP 转发后,我们需要增加 iptables 规则对流量进行处理。通过以下命令,创建名为 CLASH 的链,将 TCP 流量转发到 8890 端口并将访问专有网络 IP 地址的流量排除其外。

# Create CLASH chain
iptables -t nat -N CLASH

# Bypass private IP address ranges
iptables -t nat -A CLASH -d 10.0.0.0/8 -j RETURN
iptables -t nat -A CLASH -d 127.0.0.0/8 -j RETURN
iptables -t nat -A CLASH -d 169.254.0.0/16 -j RETURN
iptables -t nat -A CLASH -d 172.16.0.0/12 -j RETURN
iptables -t nat -A CLASH -d 192.168.0.0/16 -j RETURN
iptables -t nat -A CLASH -d 224.0.0.0/4 -j RETURN
iptables -t nat -A CLASH -d 240.0.0.0/4 -j RETURN

# Redirect all TCP traffic to 8890 port, where Clash listens
iptables -t nat -A CLASH -p tcp -j REDIRECT --to-ports 8890
iptables -t nat -A PREROUTING -p tcp -j CLASH

不过,iptables 规则会在 Pi 重新启动后清空,因而需要借助 iptables-persistent 实现持久化。

apt install iptables-persistent netfilter-persistent
netfilter-persistent save

运行 netfilter-persistent save 会将刚才配置的 iptables 规则保存在 /etc/iptables/rules.v4 文件中,并会在 Pi 重新启动后自动加载,也可以使用 netfilter-persistent reload 命令手动加载到 iptables。

已保存的 /etc/iptables/rules.v4 文件

为局域网内的其他设备配置网关和 DNS

最后,将局域网内其他设备的网关和 DNS 均配置为 Pi 的 IP 地址 10.0.1.11 即可,下图以 iOS 设备为例。在浏览器中访问 http://10.0.1.11:6300/ui/,可以查看到经由 Clash 处理的所有当前连接。

使用微信扫描下方二维码,然后 发送给朋友分享到朋友圈

感谢您的支持与贡献

您的捐款将使您阅读到的内容变得更好。

支持微信支付和支付宝。

在微信中扫描二维码 在支付宝中扫描二维码

感谢您的支持与贡献

您的捐款将使您阅读到的内容变得更好。

触摸并按住二维码,选择识别图中二维码

触摸并按住二维码