最近把 Newifi3 D2 的系统折腾安装上了 OpenWrt, 这篇文章记录我在 OpenWrt 上折腾 Clash 全局科学上网的过程。

科学上网思路

在折腾前,我们先想好怎么做。整体思路不外乎利用透明代理,代理海外流量,国内流量直连接。但其中还要解决一个 DNS 污染的问题。找了一些文章,看了一些视频,最后总结思路如下:

  1. 利用 dnsmasq + 国内域名名单 将国内 DNS 解析直接走国内的 DNS 服务器,直接连接,实现加速访问;
  2. 不在国内域名名单的 DNS 解析走 dnscrypt-proxy2 进行解析,结合 iptables 将流量代理到 clash, clash 来判断是否直接连接还是经过代理服务器。

下面是简单的时序图,只画了主要过程。

sequenceDiagram
    客户端->>dnsmasq: 客户端 DNS 解析
    Note right of dnsmasq: 检查域名是否在国内名单中
    dnsmasq->>dnsmasq: 国内的使用国内 DNS 解析 <br/> 并加入 ipset(chinalist)
    dnsmasq->>dnscrypt-proxy2: 非国内名单中 <br/> 交给 dnscrypt-proxy2 解析
    dnscrypt-proxy2 ->> dnsmasq: 返回 IP
    dnsmasq->>客户端: 返回 IP
    客户端->>iptables: 客户端 tcp 请求到达 iptables
    iptables->>iptables: 检查 ip 是否是否在国内名单(chinalist)中  <br/> 国内的直接通过
    iptables->>clash: 不在国内名单的转发

其中我们用到了:

  • dnsmasq-full: 主要就是提供 DNS 和 DHCP 服务,可配置性强,上面我们国内名单就是配置在这里的,而且 DNS 解析后,利用 ipset 将 IP 更新到 chinalist 中;
  • ipset: 一个可以操作 IP 集合的工具,我们国内IP名单就是用它动态生成的;
  • dnscrypt-proxy2: 一个强大的DNS代理工具,支持一些新的 DNS 协议, 如 DNSCrypt v2, DNS-over-HTTPS, Anonymized DNSCryptODoH (Oblivious DoH)。 我们这里用它主要是防止海外域名的 DNS 污染;
  • iptables:linux 上强大的包处理包转发软件,我们用几条规则将国内的节点直连,其他节点走 clash。

准备梯子

要科学上网,你必须有一个梯子,可以自己弄个海外的服务器搭建一个,或者直接购买现场的服务。推荐购买现在的服务,节点多,不怕封==。 可以直接 Google, 有很多推荐的文章,自己比较下,选择合适的购买。给个参考,我买的这个shadowsocks 50刀三年,90多节点,100G流量每月,我17年开始用的,还算比较稳定,除了一些特殊的时期。

安装 & 配置 Clash

下载安装

首先,我们要下载或者自己编译 clash。 直接下载地址。选择路由器对应的版本,Newifi3 D2 选择 clash-linux-mipsle-softfloat 版本。

上传到路由器。

scp clash-linux-mipsle-softfloat-v1.11.4.gz root@192.168.100.1:/tmp/

ssh 到路由器上解压,赋予执行权限。 路由器的 ssh 密码就是页面登录的密码。

ssh root@192.168.100.1

gzip -d /tmp/clash-linux-mipsle-softfloat-v1.11.4.gz
mv /tmp/clash-linux-mipsle-softfloat-v1.11.4 /bin/clash
chmod +x /bin/clash

配置

主要准备三个文件:

  • 配置文件 config.yaml

Github上有完整的配置说明。我这里给出我的配置参考。后面将用到下面两个端口。

# http proxy 端口
port: 7890
# 透明代理端口
redir-port: 7892

放到 /etc/clash/ 目录下。

  • 地理数据库 Country.mmdb [可选]

启动的时候,如果没有这个库 Clash 也会自动去下载,如果你和我一样,从 Github 下载很慢,可以先下载好,上传上去。 这里是下载地址

Clash 依赖 Country.mmdb 数据来判断流量是直达还是走代理。

这个也放到 /etc/clash/ 目录下。

  • service 脚本

我希望 Clash 是以 service 运行的,方便管理。 写了一个服务脚本如下:

#!/bin/sh /etc/rc.common
START=90
USE_PROCD=1

start_service() {
        procd_open_instance
        procd_set_param command /bin/clash -d /etc/clash
        procd_set_param respawn 300 0 5 # threshold, timeout, retry
        procd_set_param file /etc/clash/config.yml
        procd_set_param stdout 1
        procd_set_param stderr 1
        procd_set_param pidfile /var/run/clash.pid
        procd_close_instance
}

这个放到 /etc/init.d/ 目录下。

启动 Clash

配置文件和服务都放好位置后,我们就可以启动 Clash 了。

chmod +x /etc/init.d/clash

# 启动 并设置开机自启动
service clash start
service clash enable

可以用 logread 查看日志, 看看是否正常启动。

logread -e clash -f

这样 Clash 就配置好了,透明代理和HTTP代理都可以使用了。

安装 dnsmasq-full、dnscrypt-proxy2

接下来我们需要 ssh 到路由器上操作了。

# 登陆路由器
ssh root@192.168.1.1

# update 一下
opkg update

# 卸载原来的 dnsmasq 安装 dnsmasq-full
opkg remove dnsmasq && opkg install dnsmasq-full

#  安装 dnscrypt-proxy2 和其他一些基础工具包
opkg install curl ipset dnscrypt-proxy2 ca-certificates coreutils-base64

配置 dnscrypt-proxy2

vim /etc/dnscrypt-proxy2/dnscrypt-proxy.toml

基本上在原来的配置上修改一下就好了。 我这边主要修改了一下监听的地址,以及加了一个 HTTP 代理地址(clash http proxy 地址),因为其中部分配置是需要从 Github 下载的,我这访问 GitHub 不走代理有点抽疯。更多配置参考官方文档。 我的配置如下:

listen_addresses = ['127.0.0.1:5353']
max_clients = 250
ipv4_servers = true
ipv6_servers = false
dnscrypt_servers = true
doh_servers = true
odoh_servers = false
require_dnssec = false
require_nolog = true
require_nofilter = true
disabled_server_names = []
force_tcp = false
# Clash HTTP  代理地址,加速配置下载
http_proxy = 'http://127.0.0.1:7890'
timeout = 5000
keepalive = 30
log_level = 2
cert_refresh_delay = 240
bootstrap_resolvers = ['114.114.114.114:53', '9.9.9.9:53']
ignore_system_dns = true
netprobe_timeout = 60
netprobe_address = '9.9.9.9:53'
log_files_max_size = 10
log_files_max_age = 7
block_ipv6 = false
block_unqualified = true
block_undelegated = true
reject_ttl = 10
cache = true
cache_size = 512
cache_min_ttl = 600
cache_max_ttl = 86400
cache_neg_min_ttl = 60
cache_neg_max_ttl = 600

[sources]
 [sources.'public-resolvers']
   urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md', 'https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md', 'https://ipv6.download.dnscrypt.info/resolvers-list/v3/public-resolvers.md', 'https://download.dnscrypt.net/resolvers-list/v3/public-resolvers.md']
   cache_file = 'public-resolvers.md'
   minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
   refresh_delay = 72
   prefix = ''

 [sources.'relays']
   urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/relays.md', 'https://download.dnscrypt.info/resolvers-list/v3/relays.md', 'https://ipv6.download.dnscrypt.info/resolvers-list/v3/relays.md', 'https://download.dnscrypt.net/resolvers-list/v3/relays.md']
   cache_file = 'relays.md'
   minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
   refresh_delay = 72
   prefix = ''

fragments_blocked = ['cisco', 'cisco-ipv6', 'cisco-familyshield', 'cisco-familyshield-ipv6', 'cleanbrowsing-adult', 'cleanbrowsing-adult-ipv6', 'cleanbrowsing-family', 'cleanbrowsing-family-ipv6', 'cleanbrowsing-security', 'cleanbrowsing-security-ipv6']

skip_incompatible = false

配置好后,把服务重启。

#  重启
service dnscrypt-proxy restart
# 开机自启
service dnscrypt-proxy enable
# 查看日志
logread -e dnscrypt-proxy -f

配置 dnsmasq

配置 dnsmasq 的配置文件夹。

mkdir /etc/dnsmasq.d
uci add_list dhcp.@dnsmasq[0].confdir=/etc/dnsmasq.d
uci add_list dhcp.@dnsmasq[0].cachesize=10000
uci commit dhcp

下载大陆白名单,让大陆的走指定的解析,直接连接,达到加速国内站点的目的。

# 创建一个放脚本的文件夹
mkdir -p /etc/scripts && cd /etc/scripts

# 由于访问 Github 不是很通畅,使用 http 代理
export https_proxy=http://127.0.0.1:7890

# 下载大陆白名单,生成 dnsmasq 配置的脚本
curl -L -o generate_dnsmasq_chinalist.sh https://github.com/cokebar/openwrt-scripts/raw/master/generate_dnsmasq_chinalist.sh

# 赋权
chmod +x generate_dnsmasq_chinalist.sh

# 执行脚本,生成配置
sh generate_dnsmasq_chinalist.sh -d 114.114.114.114 -p 53 -s chinalist -o /etc/dnsmasq.d/accelerated-domains.china.conf

# 重启 dnsmasq 使配置生效
service dnsmasq restart

除了这些,我们还需要登录管理界面,设置 DNS 转发。

Network > DHCP and DNS > General Settings 中,将 DNS 转发到 dnsencrpt-proxy2, 如下图:

同时,忽略解析文件。

保存并应用后,dnsmasq 就配置好了。

配置 iptables

Network > Firewall > Custom Rules 中,添加以下规则并保存。

iptables -t nat -N clash

# 本地白名单部分
iptables -t nat -A clash -d 0.0.0.0/8 -j RETURN
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

# 清空 ipset 集合
ipset destroy
ipset create chinalist hash:net

# 国内白名单
iptables -t nat -A clash -m set --match-set chinalist dst -j RETURN

# 其他流量走透明代理
iptables -t nat -A clash -p tcp -j REDIRECT --to-ports 7892 

iptables -t nat -A PREROUTING -p tcp -j clash

重启防火墙立即生效。

/etc/init.d/firewall restart

到这里,我们就全部配置完成了,可以愉快的上网了。

看看效果。

简单来说,用 Youtube 看 4k 应该是没问题的。

Jietu20220811-062347-HD

参考