配置透明代理,实现无感上网

一直让我不解的是,我的整个博客只有“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
2
3
4
5
6
7
8
9
allow-lan: true             # 局域网的连接
dns: # DNS接管
enable: true
enhanced-mode: redir-host
listen: 0.0.0.0:53
nameserver:
- <your name server>
mode: Rule
redir-port: 7892
  • allow-lan: 是否允许局域网连接。
  • dns: 配置没有污染的DNS。注意:这是必须的[1]
  • mode: 按规则匹配。
  • redir-port: 路由表转发的端口。这和内建http代理、socks5代理端口都不一样。

Clash与Systemd集成

基础服务与开机启动

/etc/systemd/system/文件夹下新建clash.service文件,并写入以下内容:

1
2
3
4
5
6
7
8
9
10
11
[Unit]
Description=A rule based proxy in Go.
After=network-online.target

[Service]
Type=simple
Restart=on-abort
ExecStart=/usr/bin/clash -d /etc/clash

[Install]
WantedBy=multi-user.target

使用sudo systemctl enable clash命令来启用该服务。

自动订阅更新

你需要准备一个订阅更新的脚本,比如用wget下载,用sed调整配置后覆盖原本的/etc/clash/config.yaml文件。

/etc/systemd/system/文件夹下新建clash-subscription.service文件,并写入以下内容:

1
2
3
4
5
6
7
[Unit]
Description=Clash subscription update
After=clash.service

[Service]
Type=oneshot
ExecStart=/usr/bin/bash "你的脚本文件"

/etc/systemd/system/文件夹下新建clash-subscription.timer文件,并写入以下内容:

1
2
3
4
5
6
7
8
9
10
[Unit]
Description=Clash subscription update

[Timer]
OnCalendar=<your timer>
RandomizedDelaySec=5m
RemainAfterElapse=no

[Install]
WantedBy=timers.target

Timer的设定可以参考Arch Wiki-Systemd-Timers

最后启用该定时器(注意不是启用服务)。

检测到配置文件改动后重启服务

/etc/systemd/system/文件夹下新建clash-watcher.service文件,并写入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
[Unit]
Description=clash watcher
After=network.target
StartLimitIntervalSec=10
StartLimitBurst=5

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl restart clash.service

[Install]
WantedBy=multi-user.target

/etc/systemd/system/文件夹下新建clash-watcher.path文件,并写入以下内容:

1
2
3
4
5
6
[Path]
Unit=clash-watcher.service
PathChanged=/etc/clash

[Install]
WantedBy=multi-user.target

启用该systemd path(注意不是启用服务)。

配置系统转发

要实现无感上网,需要通过内核的网络包netfilter将特定规则的包转发到上面配置的redir-port。如果你不希望这样做,也可以在上面的配置文件中直接添加HTTP proxy的端口,将需要的程序流量进行转发。

netfilter有多种工具提供控制与操作。如果你没有特殊的控制需求,建议使用firewalld而不是iptables或nftables。firewalld可以提供一个更加抽象、便于操作的界面,也能够为网络,尤其是作为网关的网络提供一个更强的、开箱即用的防火墙。

本文提供两种方法,基于nftables的和firewalld的。

基于nftables的转发

在您的/etc/nftables.conf中添加如下项:

1
2
3
4
5
6
7
8
9
table ip filter {
chain proxy {
ip protocol tcp redirect to :7892
}
chain output {
type filter hook output priority 0; policy accept;
goto proxy
}
}

上面的内容只是示例。请按照以下的需求对table和chain进行调整:

  • 本机:ip filter表中的output
  • 作为路由转发:ip nat表中的prerouting

上述条件不是互斥的,如果你同时需要,则需要同时配置。如果你的设备上还有以虚拟网络形式构成的虚拟机、容器,则也需要配置路由转发。每一张不同的table中都需要配置proxy链。

基于firewalld的转发

/etc/firewalld/direct.xml中添加下面的rule

1
2
3
<direct>
<rule ipv="ipv4" table="nat" chain="PREROUTING" priority="-20">-p tcp -j REDIRECT --to-ports 7892</rule>
</direct>

具体的table和chain调整如上一章节所示。

本地/特定地址跳过转发

如果你不希望一些特定地址(如私有地址)也通过clash,需要配置跳过的规则。clash本身的规则已经提供了一个可以调节的界面,但netfilter是内核组件,转发效率比clash高。

nftables的配置方法:

先定义私有地址:

1
2
3
4
define private_route = {
172.16.0.0/12,
192.168.0.0/16
}

在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
2
3
4
<ipset type="hash:net">
<entry>192.168.0.0/16</entry>
<entry>172.16.0.0/24</entry>
</ipset>

这里有根据国家分配的IP地址列表,可以供配置时参考。

DNS服务器的配置

你可以使用clash自身提供的DNS服务器污染检测机制,也可以选用DNS-over-TLS/DNSCrypt/DNS-over-HTTPS来作为无污染的DNS源。笔者使用的是dnscrypt-proxy这一程序。鉴于篇幅此处就不详细介绍。


  1. Clash域名匹配的原理,是在客户端DNS查询时构建域名-IP的对应表,并以此将请求的IP与域名联系起来,作为域名匹配的目标域名。如果关闭Clash内建的DNS,基于域名的匹配规则就是无效的。enhanced-mode中还有其他的选项(fake-ip),可以确保这一匹配的正确性,但因为影响用户获取的IP地址,且需要配置其他的选项,此文不使用该方法,感兴趣的读者可以进一步探究。 ↩︎

Ads by Google

Read our privacy policy on how these personalized advertisements are delivered to you.

For your reading experience, we provide full-text RSS feeds. Although math formulas cannot be displayed well, the interface can be adjusted as you like and there are no ads.