一直让我不解的是,我的整个博客只有“Linux配置SSR”这一篇博文,质量也不算高,内容也没什么价值,发了这么长时间,都能获得不错的点击量(貌似是博文里点击量最高的)。那篇文章中的工具
electron-ssr
,不能够以系统代理的形式接管流量,ssr
本身支持的功能也不太好。因此就写了这篇文章,作为进阶读者的参考。穷则独善其身,达则兼善天下。本文介绍的方法,不仅可以作为单机流量配置的参考,也能作为路由器(软路由)的配置策略。我目前的上网工具就运行在软路由上,供整个局域网使用。
先决条件
不是OpenWRT,并使用Systemd启动
OpenWRT有诸多的插件,可以快速配置透明代理,如OpenClash,fancy-ssr等。同时,下文的配置因为使用的是Systemd启动的Linux(当今流行的发行版中,绝大多数都采用Systemd),不适用于OpenWRT。
有root权限
此教程中的方法接管系统流量,需要配置路由表和防火墙。如果你没有root权限,可以使用引子里提到的文章,配置用户态的代理工具。
Clash的配置
Clash是比较常见的上网工具,其支持、整合多种协议,且与Linux端的网络栈配合较好。程序文件可以在GitHub上下载,Arch Linux也提供了官方的软件包。
需要注意的是,GitHub上提供两种版本,分为开源版本和闭源的Premium版。Arch Linux只提供开源版本的软件包(闭源版本貌似在AUR中提供),下载时应当注意区分。本文以开源版本示意,如果你需要Premium版提供的特性,也可以对应下载。
配置文件
我们将配置文件放置在/etc/clash
中。你从你的服务提供商处可以获取到config.yaml
配置文件。需要修改的地方有:
1 | allow-lan: true # 局域网的连接 |
allow-lan
: 是否允许局域网连接。dns
: 配置没有污染的DNS。注意:这是必须的[1]。mode
: 按规则匹配。redir-port
: 路由表转发的端口。这和内建http代理、socks5代理端口都不一样。
Clash与Systemd集成
基础服务与开机启动
在/etc/systemd/system/
文件夹下新建clash.service
文件,并写入以下内容:
1 | [Unit] |
使用sudo systemctl enable clash
命令来启用该服务。
自动订阅更新
你需要准备一个订阅更新的脚本,比如用wget下载,用sed调整配置后覆盖原本的/etc/clash/config.yaml
文件。
在/etc/systemd/system/
文件夹下新建clash-subscription.service
文件,并写入以下内容:
1 | [Unit] |
在/etc/systemd/system/
文件夹下新建clash-subscription.timer
文件,并写入以下内容:
1 | [Unit] |
Timer的设定可以参考Arch Wiki-Systemd-Timers。
最后启用该定时器(注意不是启用服务)。
检测到配置文件改动后重启服务
在/etc/systemd/system/
文件夹下新建clash-watcher.service
文件,并写入以下内容:
1 | [Unit] |
在/etc/systemd/system/
文件夹下新建clash-watcher.path
文件,并写入以下内容:
1 | [Path] |
启用该systemd path(注意不是启用服务)。
配置系统转发
要实现无感上网,需要通过内核的网络包netfilter将特定规则的包转发到上面配置的redir-port。如果你不希望这样做,也可以在上面的配置文件中直接添加HTTP proxy的端口,将需要的程序流量进行转发。
netfilter有多种工具提供控制与操作。如果你没有特殊的控制需求,建议使用firewalld而不是iptables或nftables。firewalld可以提供一个更加抽象、便于操作的界面,也能够为网络,尤其是作为网关的网络提供一个更强的、开箱即用的防火墙。
本文提供两种方法,基于nftables的和firewalld的。
基于nftables的转发
在您的/etc/nftables.conf
中添加如下项:
1 | table ip filter { |
上面的内容只是示例。请按照以下的需求对table和chain进行调整:
- 本机:
ip filter
表中的output
- 作为路由转发:
ip nat
表中的prerouting
上述条件不是互斥的,如果你同时需要,则需要同时配置。如果你的设备上还有以虚拟网络形式构成的虚拟机、容器,则也需要配置路由转发。每一张不同的table中都需要配置proxy链。
基于firewalld的转发
在/etc/firewalld/direct.xml
中添加下面的rule
:
1 | <direct> |
具体的table和chain调整如上一章节所示。
本地/特定地址跳过转发
如果你不希望一些特定地址(如私有地址)也通过clash,需要配置跳过的规则。clash本身的规则已经提供了一个可以调节的界面,但netfilter是内核组件,转发效率比clash高。
nftables的配置方法:
先定义私有地址:
1 | define private_route = { |
在proxy链中,redirect语句前加入以下语句:
1 | ip daddr $private_route return |
firewalld的配置方法:
在上述规则前配置以下跳过规则:
1 | <rule ipv="ipv4" table="nat" chain="PREROUTING" priority="-20">-m set --match-set <your private route> dst -j RETURN</rule> |
同时需要在/etc/firewalld/ipsets/<your private route>.xml
中建立你所需要的条目:
1 | <ipset type="hash:net"> |
这里有根据国家分配的IP地址列表,可以供配置时参考。
DNS服务器的配置
你可以使用clash自身提供的DNS服务器污染检测机制,也可以选用DNS-over-TLS/DNSCrypt/DNS-over-HTTPS来作为无污染的DNS源。笔者使用的是dnscrypt-proxy
这一程序。鉴于篇幅此处就不详细介绍。
Clash域名匹配的原理,是在客户端DNS查询时构建域名-IP的对应表,并以此将请求的IP与域名联系起来,作为域名匹配的目标域名。如果关闭Clash内建的DNS,基于域名的匹配规则就是无效的。enhanced-mode中还有其他的选项(fake-ip),可以确保这一匹配的正确性,但因为影响用户获取的IP地址,且需要配置其他的选项,此文不使用该方法,感兴趣的读者可以进一步探究。 ↩︎