hide:
分流需要实现的功能如下:
对应的流程图如下:
%%{init: {'theme':'forest'}}%%
flowchart
style client color:white,fill:#dd5555,stroke:#ee00,stroke-width:2px
style ipset color:white,fill:green,stroke:#ee00,stroke-width:2px
style ipset1 color:white,fill:green,stroke:#ee00,stroke-width:2px
style speed-check color:white,fill:green,stroke:#ee00,stroke-width:2px
client(((客户端)))-----> |1\. 请求|smartdns
smartdns---->|2\. 获取到IP|client
client--->|3\. 使用IP请求数据|router
subgraph smartdns [SmartDNS  ]
server(DNS服务)-->|a. 处理规则namserver|rule(域名规则)
rule-->|b. 外部域名|public-group(外部服务器组)
rule-->|b. 内部域名|private-group(内部服务器组)
public-group-->|d. IP加入IPSet|ipset1(IPSet,NFTSet)
private-group-->|d. 测速获取最快IP|speed-check(测速)
end
router-->ipset(IPSet,NFTSet)
subgraph router [路由网关]
NAT-->|a. 收取数据包|ipset-->|b. 数据转发|tproxy(TPROXY转发服务)
end
tproxy----->|VPN|ProxyServer
tproxy----->|SOCKS5|ProxyServer
tproxy----->|HTTP PROXY|ProxyServer
public-group--->|c. 查询外部域名|public-servers(外部DNS服务器)
private-group--->|c. 查询内部域名|private-servers(内部DNS服务器)
在上述流程图中,SmartDNS分流数据,需要做如下设置
基本配置
启用SmartDNS服务,并设置相关的功能。
# 启用服务器
bind [::]:53
# 启用测速
speed-check-mode ping,tcp:80,tcp:443
# 启用双栈优选
dualstack-ip-selection yes
# 启用缓存和持久化
cache-size 32768
cache-persist yes
prefetch-domain yes
serve-expired yes
添加DNS服务器
添加上游服务器,并通过-group参数指定内外服务器组。
# 外部服务器组
server 1.2.3.4 -group public
# 内部服务器组
server 1.2.3.4 -group private
注意:
-exclude-default-group参数,避免内部域名通过外部服务器查询。proxy-server选项,配置通过socks5,http代理查询,这样结果会更好。配置域名规则
配置白名单域名,对名单中的域名走public服务器组,并关闭测速,关闭IPV6,加入IPSET。
# 添加域名列表,格式为一行一个域名
domain-set -name public-domain-list -file /path/to/public/domain/list
# 设置对应域名列表的规则。
domain-rules /domain-set:public-domain-list/ -ipset public -nftset #4:ip#table#set -c none -address #6 -nameserver public
注意:
域名列表可以配置crontab周期自动更新,其格式为一行一个域名。
a.com
b.com
...
域名规则中:
public为例子,可按需修改为对应的ipset名称。#4:ip#table#set为例子,需要修改为对应的ipset名称。为配合smartdns完成外部请求的转发,好需要配置相关的ipset,和规则。具体配置步骤如下:
创建IPSet
执行shell命令,创建IPSET。
# 创建ipset集合
ipset create public hash:net
SmartDNS中配置规则
ipset /example.com/public
设置透明转发规则:
Linux透明转发分为TPROXY和REDIRECT两种模式,这两种模式使用上有如下区别,可按需求选择配置。
模式:TPROXY,REDIRECT
TPROXY:支持UDP,TCP的转发,配置稍复杂。
REDIRECT:仅支持TCP,配置简单。
方式一:仅TCP转发(容易)
设置规则
# 设置转发规则,将匹配的请求转发到本机的1081端口
iptables -t nat -I PREROUTING -p tcp -m set --match-set public dst -j REDIRECT --to-ports 1081
启用转发程序
本机1081端口开启REDIRECT模式的转发程序。
删除规则:
iptables -t nat -D PREROUTING -p tcp -m set --match-set public dst -j REDIRECT --to-ports 1081
方式二:TCP/UDP TPROXY转发
执行shell命令,设置iptable规则,将匹配的域名TCP/UDP请求进行TPROXY方式透明转发,规则参考如下:
设置规则
# 设置路由规则
ip rule add fwmark 1104 lookup 1104
ip route add local 0.0.0.0/0 dev lo table 1104
# 设置转发规则,UDP,TCP方式的TPROXY转发,将数据转发到本机的1081端口
iptables -t mangle -N SMARTDNS
iptables -t mangle -A SMARTDNS -p tcp -m set --match-set public dst -j TPROXY --on-ip 127.0.0.1 --on-port 1081 --tproxy-mark 1104
iptables -t mangle -A SMARTDNS -p udp -m set --match-set public dst -j TPROXY --on-ip 127.0.0.1 --on-port 1081 --tproxy-mark 1104
iptables -t mangle -A SMARTDNS -j ACCEPT
iptables -t mangle -A PREROUTING -j SMARTDNS
启用转发程序
本机1081端口开启TPROXY模式的转发程序。
删除规则:
ip rule del fwmark 1104
iptables -t mangle -D PREROUTING -j SMARTDNS
iptables -t mangle -F SMARTDNS
iptables -t mangle -X SMARTDNS
方式一:仅TCP转发 (容易)
创建nftable的nftset集合,集合名称为#4:ip#nat#public_set
nft add set ip nat public_set { type ipv4_addr\; flags interval\; auto-merge\; }
设置REDIRECT转发规则
nft add rule ip nat PREROUTING meta l4proto tcp ip daddr @public_set redirect to :1081
smartdns中配置nftable规则
nftset /example.com/#4:ip#nat#public_set
启用转发程序
本机1081端口开启REDIRECT模式的转发程序。
注意可以单独创建一张转发表,方便管理,如下,创建smartdns表,nftset名称为#4:ip#smartdns#public
# 创建smartdns表
nft add table ip smartdns
# 创建NFTSET集合
nft add set ip smartdns public { type ipv4_addr\; flags interval\; auto-merge\; }
# 设置转发规则
nft add chain ip smartdns prerouting { type nat hook prerouting priority dstnat + 1\; }
nft add rule ip smartdns prerouting meta l4proto tcp ip daddr @public redirect to :1081
# 删除表格
nft delete table ip smartdns
方式二:TPROXY模式转发TCP和UDP
配置规则
# 设置路由规则
ip rule add fwmark 1104 lookup 1104
ip route add local 0.0.0.0/0 dev lo table 1104
# 创建smartdns表
nft add table ip smartdns
# 创建NFTSET集合
nft add set ip smartdns public { type ipv4_addr\; flags interval\; auto-merge\; }
# 设置转发规则
nft add chain ip smartdns prerouting { type filter hook prerouting priority 0\; }
nft add rule ip smartdns prerouting meta l4proto tcp ip daddr @public tproxy to :1081 mark set 1104
nft add rule ip smartdns prerouting meta l4proto udp ip daddr @public tproxy to :1081 mark set 1104
# 查询规则
nft list table ip smartdns
# 删除已有规则
nft delete table ip smartdns
smartdns配置nftset
nftset /example.com/#4:ip#smartdns#public
启用转发程序
本机1081端口开启TPROXY模式的转发程序。
如果使用OpenWrt的luci界面,可以直接在界面配置相关的域名分流规则。