作者:Chancel Yang, 创建:2024-04-21, 字数:26990, 已阅:642, 最后更新:2024-07-28
R2S 是一台优秀的 Arm 服务器,功耗低、双千兆以及价格低的优势,让这个设备非常流行
不少R2S的教程都是以刷入 openwrt 为主,而除了 openwrt 外,R2S 还支持许多第三方系统,例如原生的 Linux 系统 Armbian
Armbian 可以完美地实现透明代理网关,设置起来不像 openwrt 一样,在Web界面上左点右按再保存设置等待生效
使用 R2S + Armbian 来实现完全可以实现一个简洁的透明网关,其网络拓补图如下:
在上图中,省略了光猫的部分,R2S 取代了原路由器,2个千兆接口分别接入路由器的 WAN口 和光猫 LAN口
R2S 将负责宽带拨号以及网络转发、网络分流的功能,这一点与openwrt版的R2S是一模一样的
下面将一步一步地实现拨号、DNS解析以及针对不同IP分别处理直连与科学代理
Armbian 是一个基于 Linux 的操作系统发行版,专门为ARM架构的单板计算机(如树莓派、Orange Pi等)设计和优化
这当中也包括了 R2S ,可以从 Armbian 的官网上下载得到属于 R2S 的 Armbian 系统镜像
R2S 的官方镜像地址
下载后的系统镜像是一个 .xz
文件,无需解压 .xz
,直接将镜像写入到内存卡上插入 R2S 即可开机
写入内存卡后,将内存卡插入R2S中,从路由器的 LAN口 连接网线到 R2S 的 LAN口
再接入电源和网线,并观察 LAN 灯是否亮起
如亮起,说明已连接到路由器下,登录到路由器后台,查看R2S被分配到的IP,之后使用SSH远程登录
登录后会提示你进行初始化设置,包括ROOT账户密码以及一个具备管理员权限的账户
如果访问外网不畅通,可以将 Armbian 的源更换到清华源
安装要用的一些必要软件以及我的一些常用软件
# 更新软件包
apt update -y
# 更新系统
apt upgrade -y
# 安装必要软件
apt install -y supervisor gcc make iproute2 ipset pppoeconf vim wget git curl unzip dnsutils net-tools tree
# 安装我常用的软件(可选)
apt install -y btop proxychains openssl
以下操作默认采用 ROOT 用户进行操作
编辑:/etc/netplan/armbian-default.yaml
network:
version: 2
renderer: NetworkManager
ethernets:
lan0: # 请确保你的LAN口名称是lan0
dhcp4: no
addresses: [192.168.1.1/24]
eth0: # 请确保你的WAN口名称是eth0
dhcp4: yes
编辑完成后,拔除网线,将路由器的 WAN口 接入 R2S 的 LAN口 ,将R2S的 WAN口 接入光猫的拨号口,将路由器设置为:
接着使用ssh会话连接到 192.168.1.1 ,即你的R2S,再进行宽带拨号
pppoeconf
根据提示填入宽带帐号密码即可
允许IPV4转发,编辑: /etc/sysctl.conf
...
# 允许IPV4的流量转发
net.ipv4.ip_forward=1
并更新支持IP转发的设置
sysctl -p
然后添加临时转发规则进行测试
iptables -t nat -I POSTROUTING -j MASQUERADE
连接路由器Wifi,通过 ping 114.114.114.114
确认网络转发设置是否成功
以上实现了 R2S 拨号并转发网络数据
网络透明代理(Transparent Proxy)是一种网络代理的方式,在代理服务器和用户之间进行中间层的数据传输
对用户来说,它是透明的,用户无需进行任何额外的配置,这种代理不用在每一个设备上安装代理软件
对于一些游戏机、特定系统的设备来说很友好
代理我使用的是 gost ,服务端的部分可以使用商业代理或自建服务,这里假设代理协议是普通的 ss
下载gost:
下载到 /root/gost/
中,解压后目录如下
$ tree
.
├── gost
├── gost_3.0.0-rc8_linux_arm64.tar.gz
├── LICENSE
├── README_en.md
└── README.md
0 directories, 5 files
编辑:/root/gost/config.yaml
services:
# 1080 端口开启流量中继服务,走的是Chain-0的代理路线
- name: "1080-red"
addr: :1080
handler:
chain: chain-0
type: red
listener:
type: red
# 1080 端口开启UDP的DNS代理查询,走的是Chain-0的代理路线
- name: "1080-dns"
addr: :1080
handler:
chain: chain-0
type: dns
listener:
type: dns
metadata:
mode: udp
forwarder:
nodes:
- name: Google-1
addr: tls://8.8.8.8:853
- name: Google-2
addr: tls://8.8.4.4:853
chains:
- name: chain-0
hops:
- name: hop-0
nodes:
# SS协议的信息
- name: "1.2.3.4"
addr: "1.2.3.4:48888"
connector:
type: ss
auth:
username: chacha20-ietf-poly1305
password: my-passwd
请自行修改 ss 的地址、端口、加密方式、密码,然后运行 gost 服务进行测试
/root/gost/gost -C /root/gost/config.yml
运行后检查输出无错误,然后使用 supervisor 配置为后台进程
编辑:/etc/supervisor/conf.d/gost.conf
[program:gost]
command=/root/gost/gost -C /root/gost/config.yaml
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
stdout_logfile_maxbytes=32MB
user=root
更新 supervisor 运行,并检查运行状态
supervisorctl update
supervisorctl status
Overture 是一个开源的 DNS 加速器和广告过滤器,它旨在提供更快的 DNS 查询响应速度,并屏蔽广告和恶意网站
稍加配置 Overture 也可以解决 DNS 污染
overture仓库地址:
由于 R2S 的 Armbian 自带DNS服务 systemd-resolved.service
,需要先将其禁用
systemctl stop systemd-resolved.service
systemctl disable systemd-resolved.service
在禁用掉自带的DNS服务后,下载后(V1.8版本)到 /root/overture
中解压,目录输出如下:
$ tree
.
├── config.yml
├── domain_alternative_sample
├── domain_primary_sample
├── domain_ttl_sample
├── hosts_sample
├── ip_network_alternative_sample
├── ip_network_primary_sample
├── overture-linux-arm64
└── overture-linux-arm64.zip
0 directories, 9 files
在运行 Overture 之前,先查找运营商指定的DNS服务地址
cat /etc/ppp/resolv.conf
通常来说,宽带服务商的 DNS 服务提供更本地化的 CDN 加速效果,而公共 DNS 由于查询距离较远所以不如宽带运营商的 DNS 服务
编辑:/root/overture/config.yml
bindAddress: :53
debugHTTPAddress: :55555
dohEnabled: false
primaryDNS:
# 服务商的DNS服务地址,这里填的是 114.114.114.114 的公共DNS服务
- name: domestic_dns
address: 114.114.114.114:53
protocol: udp
socks5Address:
timeout: 3
ednsClientSubnet:
policy: disable
externalIP:
noCookie: true
onlyPrimaryDNS: false
alternativeDNS:
# 国外DNS服务(在Gost中配置为Google)
- name: foreign_dns
address: 127.0.0.1:1080
# 此处UDP对应GOST中的`mode`参数值,可选`tcp`、`udp`
protocol: udp
socks5Address:
timeout: 6
ednsClientSubnet:
policy: disable
externalIP:
noCookie: true
ipv6UseAlternativeDNS: false
alternativeDNSConcurrent: false
whenPrimaryDNSAnswerNoneUse: primaryDNS
# 通过文件中的 IP 网络段来决定哪些 IP 地址的请求应该被定向到特定的 DNS 服务器
ipNetworkFile:
# 符合 `china_ip_list.txt` 中的IP则优先使用 `primary` DNS服务的结果
primary: /root/china_ip_list.txt
alternative: /root/overture/ip_network_alternative_sample
# 通过文件中的域名决定哪些 IP 地址的请求应该被定向到特定的 DNS 服务器
domainFile:
primary: /root/overture/domain_primary_sample
# 符合 `gfw_all_domain.txt` 中的域名则优先使用 `alternative` DNS服务的结果
alternative: /root/gfw_all_domain.txt
matcher: full-map
hostsFile:
hostsFile: /root/overture/hosts
finder: full-map
minimumTTL: 3600
domainTTLFile: /root/overture/domain_ttl_sample
# 缓存的结果数量
cacheSize: 10240
cacheRedisUrl:
cacheRedisConnectionPoolSize:
rejectQType:
- 255
配置中重要的部分已添加了注释,在配置中使用到的1个国内 IP 文件与国外 GFW 域名名单:
2个文件的来源:
由于这两个文件都是需要定期更新,所以写一个脚本来实现
编辑: /root/generate.sh
#/bin/bash
#author:Chancel.Yang
#date:2023/09/21
wget https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt
curl https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt | base64 -d | sort -u | sed '/^$\|@@/d'| sed 's#!.\+##; s#|##g; s#@##g; s#http:\/\/##; s#https:\/\/##;' | sed '/\*/d; /apple\.com/d; /sina\.cn/d; /sina\.com\.cn/d; /baidu\.com/d; /qq\.com/d' | sed '/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/d' | grep '^[0-9a-zA-Z\.-]\+$' | grep '\.' | sed 's#^\.\+##' | sort -u > temp_gfwlist.txt
curl https://raw.githubusercontent.com/hq450/fancyss/master/rules/gfwlist.conf | sed 's/ipset=\/\.//g; s/\/gfwlist//g; /^server/d' > temp_koolshare.txt
cat temp_gfwlist.txt temp_koolshare.txt | sort -u > gfw_all_domain.txt
rm -f temp_gfwlist.txt temp_koolshare.txt
在 /root
下执行该脚本会产生 china_ip_list.txt
和 gfw_all_domain.txt
2个文件,如下:
$ tree -L 1
.
├── china_ip_list.txt
├── gfw_all_domain.txt
├── update_china_and_gfw.sh
├── iptables.sh
└── overture
1 directory, 4 files
运行overture
overture-linux-arm64 -c config.yml
使用 dig 程序来验证是否能够顺利进行DNS解析,分别对 127.0.0.1:53 和 127.0.0.1:1080 发起 google.com
域名查询,确保结果一致,如下:
$ dig google.com @127.0.0.1
; <<>> DiG 9.18.24-1-Debian <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64070
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 3600 IN A 142.250.68.110
;; Query time: 648 msec
;; SERVER: ::1#53(::1) (UDP)
;; WHEN: Sat Jul 27 22:59:49 CST 2024
;; MSG SIZE rcvd: 65
root@nanopi-r2s ~$ dig google.com @127.0.0.1 -p 1080
; <<>> DiG 9.18.24-1-Debian <<>> google.com @127.0.0.1 -p 1080
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51110
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 291 IN A 142.250.68.110
;; Query time: 0 msec
;; SERVER: 127.0.0.1#1080(127.0.0.1) (UDP)
;; WHEN: Sat Jul 27 22:59:58 CST 2024
;; MSG SIZE rcvd: 65
使用 supervisor 配置为后台进程
编辑:/etc/supervisor.d/overture.conf
[program:overture]
command=/root/overture/overture-linux-arm64 -c /root/overture/config.yml
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
stdout_logfile_maxbytes=32MB
user=root
更新 supervisor 运行,并检查状态
supervisorctl update
supervisorctl status
在完成 gost 与 overture 设置后,需要将流量进行国内外分流
分流规则为:
编辑:/root/iptables.sh
#/bin/bash
#date:2023/09/21
/usr/sbin/ipset -N china hash:net
# china_ip_list.txt文件在overture中已经下载
for i in $(cat /root/china_ip_list.txt );
do
/usr/sbin/ipset -A china $i;
done
# 创建一个NAT规则集`SSNAT`
/sbin/iptables -t nat -N SSNAT
# 忽略国内IP
/sbin/iptables -t nat -A SSNAT -p all -m set --match-set china dst -j RETURN
# 忽略局域网IP
/sbin/iptables -t nat -A SSNAT -d 0.0.0.0/8 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 10.0.0.0/8 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 127.0.0.0/8 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 169.254.0.0/16 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 172.16.0.0/12 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 192.168.0.0/16 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 224.0.0.0/4 -j RETURN
# 将剩下IP段(国外)的流量全部转发到gost的透明代理网口1080中
/sbin/iptables -t nat -A SSNAT -p tcp -j REDIRECT --to-port 1080
# 最后将所有进入R2S的数据包转入`SSNAT`规则集合中
/sbin/iptables -t nat -A PREROUTING -p tcp -j SSNAT
# 将出站数据包的源地址进行NAT避免被防火墙拦截
/sbin/iptables -t nat -I POSTROUTING -j MASQUERADE
请再次检查你的 /root
目录,文件应如下:
$ tree -L 1
.
├── update_china_and_gfw.sh
├── china_ip_list.txt
├── gfw_all_domain.txt
├── iptables.sh
└── overture
├── gost
2 directory, 4 files
然后借助 crontab 设置脚本开机自动执行
crontab -e
# 在crontab界面中添加开机运行iptables.sh脚本
...
@reboot /bin/sh /root/iptables.sh
设置完毕后重启系统
在重启后,打开R2S的SSH会话,查看iptables的nat表,参考如下:
$ iptables -L -n -v -t nat
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
5371 341K SSNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
10260 1026K MASQUERADE all -- * * 0.0.0.0/0 0.0.0.0/0
Chain SSNAT (1 references)
pkts bytes target prot opt in out source destination
2530 171K RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 match-set china dst
0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/8
3 120 RETURN all -- * * 0.0.0.0/0 10.0.0.0/8
0 0 RETURN all -- * * 0.0.0.0/0 127.0.0.0/8
0 0 RETURN all -- * * 0.0.0.0/0 169.254.0.0/16
0 0 RETURN all -- * * 0.0.0.0/0 172.16.0.0/12
234 14040 RETURN all -- * * 0.0.0.0/0 192.168.0.0/16
0 0 RETURN all -- * * 0.0.0.0/0 224.0.0.0/4
2604 156K REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 redir ports 1080
再检查 gost 与 overture 的运行日志正常:
最后,使用任意连入 WI-FI 的任意设备访问如下两个网站,测速并确认IP分别为直连IP和代理IP:
如果路由器支持有线中继,那么也可以让 R2S 充当 DHCP 服务器,从而实现更强的控制效果,例如:
网络拓补图如下:
以下是实现步骤
安装 DHCP 分配服务
apt update
apt install isc-dhcp-server
编辑:/etc/dhcp/dhcpd.conf
...
# 默认的租约时间12小时
default-lease-time 43200;
# 允许的最大租约时间7天
max-lease-time 604800;
...
# 局域网设备将自动分配 192.168.1.128 到 192.168.1.254 的IP段
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.128 192.168.1.254;
option routers 192.168.1.1;
option domain-name-servers 192.168.1.1;
}
编辑: /etc/default/isc-dhcp-server
...
# 限定 DHCP 服务作用的接口为 `lan0`
INTERFACESv4="lan0"
启动和开机自启 isc-dhcp-server
服务
systemctl enable --now isc-dhcp-server
最后开启路由器的有线中继模式,开启成功后,可以在 R2S 中查看当前已分配的IP列表:
$ dhcp-lease-list
Reading leases from /var/lib/dhcp/dhcpd.leases
MAC IP hostname valid until manufacturer
===============================================================================================
40:31:3c:d9:ef:65 192.168.1.171 chunmi-cooker- 2024-07-09 08:43:22 XIAOMI Electronics,CO.,LTD
64:82:14:b4:f6:6c 192.168.1.165 NarwalRobotics 2024-07-09 08:43:49 FN-LINK TECHNOLOGY Ltd.
78:8b:2a:9d:e9:a1 192.168.1.166 chuangmi.camer 2024-07-09 08:44:09 Zhen Shi Information Technology (Shanghai) Co., Ltd.
7c:c2:94:23:e0:5b 192.168.1.168 zhimi-airpurif 2024-07-09 08:40:16 Beijing Xiaomi Mobile Software Co., Ltd
94:f8:27:b0:63:b1 192.168.1.157 chuangmi_camer 2024-07-09 08:44:05 Shanghai Imilab Technology Co.Ltd
cc:b5:d1:7c:26:cb 192.168.1.164 midjd6-fridge- 2024-07-09 08:42:18 Beijing Xiaomi Mobile Software Co., Ltd
d4:f0:ea:69:a2:0c 192.168.1.167 philips-light- 2024-07-09 08:42:36 Beijing Xiaomi Mobile Software Co., Ltd
d4:f0:ea:6a:ae:7d 192.168.1.160 yeelink-light- 2024-07-09 08:42:09 Beijing Xiaomi Mobile Software Co., Ltd
d4:f0:ea:85:10:5a 192.168.1.162 yeelink-light- 2024-07-09 08:42:08 Beijing Xiaomi Mobile Software Co., Ltd
d4:f0:ea:85:19:30 192.168.1.163 yeelink-light- 2024-07-09 08:42:13 Beijing Xiaomi Mobile Software Co., Ltd
dc:ed:83:61:9b:fd 192.168.1.172 lumi-acpartner 2024-07-09 08:43:34 Beijing Xiaomi Mobile Software Co., Ltd
dc:ed:83:ec:17:3c 192.168.1.170 lumi-acpartner 2024-07-09 08:43:52 Beijing Xiaomi Mobile Software Co., Ltd
如果分配IP出现问题,可以通过 journalctl
来查看 DHCP 服务日志排查问题:
journalctl -xeu isc-dhcp-server.service -f
在晚餐配置 DHCP 的 IP 分配后,局域网内的设备将默认被分配到 192.168.1.128 到 192.168.1.254 之间
结合之前 iptables 脚本就可以实现对动态IP不进行透明代理的效果
重新编辑:/root/iptables.sh
#/bin/bash
#date:2023/09/21
/usr/sbin/ipset -N china hash:net
# china_ip_list.txt文件在overture中已经下载
for i in $(cat /root/china_ip_list.txt );
do
/usr/sbin/ipset -A china $i;
done
# 创建一个NAT规则集`SSNAT`
/sbin/iptables -t nat -N SSNAT
# 国内IP
/sbin/iptables -t nat -A SSNAT -p all -m set --match-set china dst -j RETURN
# 忽略局域网IP
/sbin/iptables -t nat -A SSNAT -d 0.0.0.0/8 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 10.0.0.0/8 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 127.0.0.0/8 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 169.254.0.0/16 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 172.16.0.0/12 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 192.168.0.0/16 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 224.0.0.0/4 -j RETURN
# 忽略192.168.1.128到192.168.1.255之间的IP
/sbin/iptables -t nat -A SSNAT -s 192.168.1.128/25 -j RETURN
# 将剩下IP段(国外)的流量全部转发到gost的透明代理网口1080中
/sbin/iptables -t nat -A SSNAT -p tcp -j REDIRECT --to-port 1080
# 最后将所有进入R2S的数据包转入`SSNAT`规则集合中
/sbin/iptables -t nat -A PREROUTING -p tcp -j SSNAT
# 将出站数据包的源地址进行NAT避免被防火墙拦截
/sbin/iptables -t nat -I POSTROUTING -j MASQUERADE
对于需要使用透明代理的设备,则可以通过 DHCP 服务来指定分配到 192.168.1.2 至 192.168.1.127 之间的IP,这些IP将被透明代理处理
编辑:/etc/dhcp/dhcpd.conf
...
# 默认的租约时间12小时
default-lease-time 43200;
# 允许的最大租约时间7天
max-lease-time 604800;
...
# 局域网设备将自动分配 192.168.1.128 到 192.168.1.254 的IP段
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.128 192.168.1.254;
option routers 192.168.1.1;
option domain-name-servers 192.168.1.1;
# 固定某个设备的IP为192.168.1.50
host My-Windows-PC {
hardware ethernet 00:a0:ae:aa:a0:ac;
fixed-address 192.168.1.50;
}
}
停止 dhcp 服务并清空分配信息然后重新启动
systemctl stop isc-dhcp-server
rm /var/lib/dhcp/dhcpd.leases
systemctl start isc-dhcp-server
使用被固定IP的设备进行网络测试,确认分流效果,再使用无分流设备,确认只有直连的效果
如果发现网络有异常或者没有走透明代理,可以使用 watch 结合 iptables 来监控数据包走向来判断问题:
watch -n 1 iptables -L -n -v -t nat
nftables 是一个用于 Linux 操作系统的网络包过滤和分类框架,旨在替代 iptables 及其相关的工具(如 ip6tables、arptables 和 ebtables)
由 Netfilter 项目开发,并在 Linux 内核 3.13 版本中引入,相较于 iptables 而言,对高并发、高流量的场景性能提升很大
在设备性能不佳的情况下,采用 nftables 来取代 iptables 提升性能可一定程度上缓解性能问题
于是,你可以改写上面 iptables 的脚本如下:
#!/bin/bash
# 清除旧的 /usr/sbin/nftables 规则(如果有)
/usr/sbin/nft flush ruleset
# 创建一个新的 `nat` 表
/usr/sbin/nft add table ip nat
# 创建 NAT 链
/usr/sbin/nft add chain ip nat SSNAT { type nat hook prerouting priority 0\; }
/usr/sbin/nft add chain ip nat POSTROUTING { type nat hook postrouting priority 100\; policy accept\; }
# 创建一个名为 `china` 的集合,添加 'flags interval' 以支持前缀
/usr/sbin/nft add set ip nat china { type ipv4_addr\; flags interval\; }
# 从 curl 获取 IP 地址并直接添加到集合中
{
echo "add element ip nat china {"
curl -s https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt | while read -r ip; do
echo "$ip,"
done
echo "}"
} | /usr/sbin/nft -f -
# 符合国内IP列表的则直接转发出去
/usr/sbin/nft add rule ip nat SSNAT ip daddr @china return
# 局域网以及一些常见网段也选择直接转发
/usr/sbin/nft add rule ip nat SSNAT ip daddr 0.0.0.0/8 return
/usr/sbin/nft add rule ip nat SSNAT ip daddr 10.0.0.0/8 return
/usr/sbin/nft add rule ip nat SSNAT ip daddr 127.0.0.0/8 return
/usr/sbin/nft add rule ip nat SSNAT ip daddr 169.254.0.0/16 return
/usr/sbin/nft add rule ip nat SSNAT ip daddr 172.16.0.0/12 return
/usr/sbin/nft add rule ip nat SSNAT ip daddr 192.168.0.0/16 return
/usr/sbin/nft add rule ip nat SSNAT ip daddr 224.0.0.0/4 return
# 来源IP为192.168.11.100到192.168.11.254的IP也RETURN
/usr/sbin/nft add rule ip nat SSNAT ip saddr 192.168.11.128/25 return
# 不代理的特定IP
/usr/sbin/nft add rule ip nat SSNAT ip daddr 103.99.178.98 return
# 将剩下IP段(国外)的流量全部转发到gost的透明代理网口1080中
/usr/sbin/nft add rule ip nat SSNAT tcp dport "{ 1-65535 }" redirect to :1080
# 将出站数据包的源地址进行NAT避免被防火墙拦截
/usr/sbin/nft add rule ip nat POSTROUTING masquerade
将以上脚本取代 iptables.sh 文件,并设置开机执行
...
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
@reboot /bin/bash /root/nftables.sh
重启后检查规则是否正确:
nft list ruleset
CoreDNS 是 Kubernetes 中默认的 DNS 解决方案,也是一个灵活且可扩展的 DNS 服务器,与 Overture 相比:
CoreDNS 适合更复杂的 DNS 配置需求,同时对性能的需求也更高,一般的 Arm 架构设备会较为吃力
所以,不建议内存小于4G的设备使用
仓库地址:
在仓库的 Releases 中可下载最新版本的二进制程序,假设目录为 /root/coredns
,编写一个简单的配置文件
编辑: /root/coredns/Corefile
.:53 {
loadbalance
reload 30s
log . "{remote} {name} {type} {proto} {duration}"
forward . 114.114.114.114
}
运行程序
./coredns -conf Corefile
尝试解析国内地址
$ dig 163.com @127.0.0.1
; <<>> DiG 9.18.28-0ubuntu0.22.04.1-Ubuntu <<>> 163.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 725
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 7, ADDITIONAL: 9
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;163.com. IN A
;; ANSWER SECTION:
163.com. 502 IN A 59.111.160.244
;; AUTHORITY SECTION:
163.com. 502 IN NS ns2.166.com.
163.com. 502 IN NS ns1.nease.net.
163.com. 502 IN NS ns6.nease.net.
163.com. 502 IN NS ns8.166.com.
163.com. 502 IN NS ns4.nease.net.
163.com. 502 IN NS ns5.nease.net.
163.com. 502 IN NS ns3.nease.net.
;; ADDITIONAL SECTION:
ns8.166.com. 502 IN A 18.182.82.158
ns2.166.com. 502 IN A 103.71.201.3
ns3.nease.net. 502 IN A 103.72.12.150
ns4.nease.net. 502 IN A 103.72.12.151
ns5.nease.net. 502 IN A 103.71.201.3
ns6.nease.net. 502 IN A 54.228.156.72
ns1.nease.net. 502 IN A 42.186.35.222
ns8.166.com. 502 IN A 44.228.163.69
;; Query time: 40 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Wed Jul 24 16:11:06 CST 2024
;; MSG SIZE rcvd: 319
Coredns 也可以实现国外域名走代理解析,国内域名走运营商解析,步骤如下:
编辑: /root/coredns/generate-zones.sh
#!/bin/bash
# 检查参数
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <forward_address>"
exit 1
fi
FORWARD_ADDRESS=$1
URL="https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf"
OUTPUT_FILE="/root/coredns/chinazones"
# 创建输出文件(如果文件存在则清空内容)
> "$OUTPUT_FILE"
# 使用 curl 获取文件内容并处理
curl -s "$URL" | while read -r line; do
# 从每一行中提取域名部分
if [[ $line =~ ^server=/(.*)/.*$ ]]; then
DOMAIN="${BASH_REMATCH[1]}"
echo "forward $DOMAIN $FORWARD_ADDRESS" >> "$OUTPUT_FILE"
fi
done
echo "zones file has been generated."
Coredns 生成 Zones 参考官方文档
执行脚本:
# 参数是代理解析国外域名的端口
$ bash /root/coredns/generate-zones.sh 127.0.0.1:5301
127.0.0.1:5301
是待会在Coredns配置文件中设置的国内域名解析服务器,检查并确保 /root/coredns/chinazons
的文件内容如下:
forward zvereff.com 127.0.0.1:5301
forward zynamics.com 127.0.0.1:5301
forward zyns.com 127.0.0.1:5301
forward zyxel.com 127.0.0.1:5301
forward zzcartoon.com 127.0.0.1:5301
...
接下来只需引入 zones 到 Coredns 即可
编辑: /root/coredns/Corefile
.:53 {
# 拒绝IPV6解析请求
rewrite stop type AAAA A
template ANY AAAA {
# 设置响应码为 NOERROR
rcode NOERROR
# 设置权威信息,包含 SOA 记录
authority "{{ .Zone }} 3600 {{ .Class }} SOA ns1.home.net. dnsadmin.home.net (2022122100 14400 3600 604800 30)"
}
# 启用负载均衡
loadbalance
# 每 30 秒重新加载配置
reload 30s
# 导入所有大陆域名的处理规则
import /root/coredns/chinazones
# 将剩下的所有DNS查询转发到本地的 5302 端口
forward . 127.0.0.1:5302
}
# 大陆域名解析
.:5301 {
# 将查询转发到大陆的 DNS 服务器,建议使用运营商的 DNS 解析器,享受 CDN 加速
forward . 114.114.114.114 223.5.5.5 {
# 使用顺序策略进行转发
policy sequential
# 优先使用 UDP 协议
prefer_udp
# 设置查询过期时间为 7200 秒
expire 7200s
}
log . "{remote} -> {114.114.114.114/223.5.5.5} {name} {type} {proto} {duration}"
# 启用缓存
cache
}
# 国外域名解析
.:5302 {
forward . 127.0.0.1:1080 {
# 优先使用 UDP 协议
prefer_udp
# 设置查询过期时间为 7200 秒
expire 21600s
}
log . "{remote} -> {127.0.0.1:1080} {name} {type} {proto} {duration}"
# 启用缓存
cache
}
分别访问 bilibili.com 和 doc.docker.com ,观察 coredns 日志,可以看到分流处理
[INFO] 192.168.4.20 -> {114.114.114.114/223.5.5.5} www.bilibili.com. HTTPS udp 0.001724367s
[INFO] 192.168.4.20 -> {114.114.114.114/223.5.5.5} www.bilibili.com. A udp 0.014779333s
[INFO] 192.168.4.20 -> {114.114.114.114/223.5.5.5} a.w.bilicdn1.com. HTTPS udp 0.015117338s
...
[INFO] 192.168.4.20 -> {127.0.0.1:1080} docs.docker.com. HTTPS udp 0.00227847s
[INFO] 192.168.4.20 -> {127.0.0.1:1080} docs.docker.com. HTTPS udp 2.00356337s
[INFO] 192.168.4.20 -> {127.0.0.1:1080} docs.docker.com. HTTPS udp 4.00517469s
[INFO] 192.168.4.20 -> {127.0.0.1:1080} . NS udp 0.000151141s
[INFO] 192.168.4.20 -> {127.0.0.1:1080} . NS udp 0.000135951s
无论是 Overture 还是 Coredns 都不太合适我,我的需求比较少:
基于以上需求,我使用了 Golang 编写了一个简易的 DNS 服务器:
只需下载 Releases 中的二进制文件,直接执行即可,如:
./easydns -d 114.114.114.114:53 -o 8.8.8.8:53 -f domestic-domain.txt -p 53 -l 4096
仓库中也包含了 domestic-domain.txt
文件的生成,功能简单代码量也很少,欢迎审阅
以上内容较为复杂,还需耐心检查每一步的日志输出