171

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

 2 years ago
source link: https://victrid.dev/2021/pei-zhi-tou-ming-dai-li-shi-xian-wu-gan-shang-wang/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Victrid's Personal Site
This website uses cookies to provide better contents. Check our privacy policy.

一直让我不解的是,我的整个博客只有“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配置文件。需要修改的地方有:

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文件,并写入以下内容:

[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文件,并写入以下内容:

[Unit]
Description=Clash subscription update
After=clash.service

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

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

[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文件,并写入以下内容:

[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文件,并写入以下内容:

[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中添加如下项:

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

<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的配置方法:

先定义私有地址:

define private_route = {
172.16.0.0/12,
192.168.0.0/16
}

在proxy链中,redirect语句前加入以下语句:

ip daddr $private_route return

firewalld的配置方法:

在上述规则配置以下跳过规则:

<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中建立你所需要的条目:

<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地址,且需要配置其他的选项,此文不使用该方法,感兴趣的读者可以进一步探究。 ↩︎


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK