Ubuntu2004使用dnsmasq+Clash+Iptables+Ipset


工作思路

dnsmasq

为局域网中客户端提供DHCP服务和DNS解析缓存,在客户机数量多(成百上千)的时候缓存的意义重大。将DNS转发给Clash,由Clash来防止防止DNS被污染。

Clash

支持各种代理协议,支持各种分流规则,拥有防止DNS污染的解决途径。
DNS污染对Clash的影响
浅谈在代理环境中的 DNS 解析行为

Iptables

透明代理必备,将特定TCP请求和DNS请求按需转发给Clash和dnsmasq。

Ipset

Iptables的功能插件可以按国家设置Iptables策略,我们在这里配合Iptables用来实现:国内IP地址直接NAT不进入代理,去访问国外IP地址的时候再送给Clash。

数据流程图

具体配置

以下都以Ubuntu2004为例。另外,不论在什么时候,你需要把自己的双网卡先配置好IP地址,保证自己的服务器可以上网。再进行接下来的步骤。

前置任务

编辑配置文件优化内核参数(IPV6关闭功能无效,后续补充)

vi /etc/sysctl.conf

在末尾追加

在这里关于ip_forward是否打开网上说的貌似都不大对。我要说一说。如果只是Clash代理不用开启IP包转发功能,但是我为了能降低Clash的压力,让国内的IP地址不要进入Clash进行处理,直接NAT去访问。那么此处就必须开启IP包转发。

代理这个功能本身根本用不到ip包转发

#开启流量转发
net.ipv4.ip_forward=1

#增大打开文件数限制。请注意,该参数非常关键,否则将收到打开文件数量过多的提示错误,代理服务器将无法工作。
fs.file-max = 999999

#增大所有类型数据包的缓冲区大小(通用设置,其中default值会被下方具体类型包的设置覆盖)
#最大缓冲区大小为64M,初始大小64K。下同
#此大小适用于一般的使用场景。如果场景偏向于传输大数据包,则可以按倍数扩大该值,去匹配单个包大小
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.core.rmem_default = 6291456
net.core.wmem_default = 6291456
net.core.netdev_max_backlog = 65535
net.core.somaxconn = 262114

#增大TCP数据包的缓冲区大小,并优化连接保持
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.tcp_mem = 8192 131072 67108864
net.ipv4.tcp_rmem = 10240 87380 12582912
net.ipv4.tcp_wmem = 10240 87380 12582912
net.ipv4.tcp_mtu_probing = 1
net.ipv4.tcp_notsent_lowat = 16384
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_orphans= 262114
net.ipv4.tcp_fastopen = 3

net.ipv4.ip_local_port_range = 1024 65000

#增大UDP数据包的缓冲区大小
net.ipv4.udp_mem = 8192 131072 67108864
net.ipv4.udp_rmem_min = 4096
net.ipv4.udp_wmem_min = 4096

# 关闭IPv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

重新加载内核配置参数

sysctl -p

dnsmasq

dnsmasq负责为客户端分配IP地址的DHCP和域名解析DNS。

停用系统自带dns服务
# 编辑配置文件
vi /etc/systemd/resolved.conf
# 取消注释,修改yes为no
DNSStubListener=no

# 停用服务
systemctl stop systemd-resolved
systemctl disable systemd-resolved

# 系统将无法解析IP地址,这时候需要编辑配置文件
vi /etc/resolv.conf
# 将其中nameserver修改为如下:
nameserver 114.114.114.114
# 保存退出即可
安装dnsmasq
apt install dnsmasq
修改配置文件
vi /etc/dnsmasq.conf
# 编辑配置文件在末尾添加。按需修改你自己的配置我的Lan地址为172.16.16.254。
# dnsmasq的上游服务器为本机853端口,这个是clash将要使用的dns域名解析服务端口。
bogus-priv
no-resolv
listen-address=127.0.0.1,172.16.16.254
#interface=ens38,lo
server=127.0.0.1#853
domain=lan,172.16.16.0/24
dhcp-range=172.16.16.11,172.16.16.240,12h
dhcp-leasefile=/var/lib/misc/dnsmasq.leases
cache-size=2048
# 保存配置文件并开启服务
systemctl enable dnsmasq
systemctl start dnsmasq

安装Clash

Clash提供了两个版本,这里我使用了闭源的,因为功能更多一些。到https://github.com/Dreamacro/clash/releases/tag/premium下载最新版即可这里不再讲述解压缩啥的。

执行一次生成配置文件
./clash

一般会自行下载国家IP地址文件Country.mmdb和生成配置文件config.yaml

ls ~/.config/clash
cache.db      config.yaml   Country.mmdb
移动文件位置
mkdir -p /usr/local/clash/conf
cp clash /usr/local/clash
cp ~/.config/clash/* /usr/local/clash/conf/
下载Clash管理面板yacd

https://github.com/haishanh/yacd/releases下载yacd.tar.xz并且解压缩复制到/usr/local/clash中。服务运行后可以通过http://172.16.16.254:9090/ui来访问yacd管理面板。

ls /usr/local/clash/
clash  conf  yacd
配置文件
vi /usr/local/clash/conf/config.yaml
# 删掉所有内容,根据自己的需求修改
port: 7890
socks-port: 7891
redir-port: 7892
allow-lan: true
mode: Rule
log-level: info
external-controller: '172.16.16.254:9090'
secret: '7758521'
external-ui: '/usr/local/clash/yacd'
dns:
  enable: true
  ipv6: false
  listen: 127.0.0.1:853
  enhanced-mode: redir-host
  nameserver:
    - 'tls://dns.rubyfish.cn:853'
    - '223.5.5.5'
  fallback:
    - 'tls://1.1.1.1:853'
    - 'tls://dns.google'
proxies:
  - 你的代理服务器配置,按需修改。
proxy-groups:
  - 你的代理组配置
  - ??国外流量
  - ??直接连接
rules:
  - 规则例如下面
  - DOMAIN-KEYWORD,google,??国外流量
  - DOMAIN-KEYWORD,ethermine,??国外流量
  - DOMAIN-KEYWORD,whatismyipaddress,??国外流量
  - MATCH,??直接连接
创建守护进程配置文件
vi /etc/systemd/system/clash.service
[Unit]
Description=Clash daemon, A rule-based proxy in Go.
After=network.target

[Service]
Type=simple
Restart=always
ExecStart=/usr/local/clash/clash -d /usr/local/clash/conf

[Install]
WantedBy=multi-user.target

设置开机自动运行

systemctl daemon-reload
systemctl enable clash
systemctl start clash
journalctl -xe

配置Iptables

安装需要的组件
apt install ipset iptables netfilter-persistent ipset-persistent iptables-persistent conntrack
停用自带防火墙ufw
systemctl disable ufw
systemctl stop ufw
创建ipset规则
ipset -N cnip hash:net
wget -O ~/cn.txt http://www.ipdeny.com/ipblocks/data/countries/cn.zone
for ip in $(cat /root/cn.txt ); do ipset -A cnip $ip; done
# 查看导入的ipset规则
ipset list | more
# 测试IP是否命中
ipset test cnip 114.114.114.114
创建iptables规则
# 删除所有已有规则
iptables -F -t nat
iptables -X -t nat
iptables -Z -t nat

iptables -t nat -N CLASH
#排除环形地址与保留地址,匹配之后直接RETURN返还给PREROUTING链
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
#重定向tcp流量到本机7892端口
iptables -t nat -A CLASH -s 172.16.16.0/24 -p tcp -j REDIRECT --to-port 7892

#在nat表中新建一个clash_dns规则链
iptables -t nat -N CLASH_DNS
#dnat劫持所有dns请求
iptables -t nat -A CLASH_DNS -p udp --dport 53 -j DNAT --to-destination 172.16.16.254:53
iptables -t nat -A CLASH_DNS -p tcp --dport 53 -j DNAT --to-destination 172.16.16.254:53

# 配置DNS请求劫持
iptables -t nat -A PREROUTING -p udp --dport 53 -j CLASH_DNS
iptables -t nat -A PREROUTING -p tcp --dport 53 -j CLASH_DNS
# 配置TCP协议请求非国内IP地址范围劫持进入Clash
iptables -t nat -A PREROUTING -p tcp -m set ! --match-set cnip dst -g CLASH
# 国内IP地址范围TCP和其他53端口之外的UDP进入系统NAT
iptables -t nat -A POSTROUTING -j MASQUERADE
保存配置
# 保存两个
netfilter-persistent save
# 分别保存
dpkg-reconfigure ipset-persistent
dpkg-reconfigure iptables-persistent

主机加固

主要是使用Iptables对外网WAN接口进行包过滤,丢弃所有。访问WAN接口的请求。

# filter表中创建一个专门处理wan接口流量的链
iptables -t nat -N enp1s0
# 允许pingwan接口其他数据统统丢弃
-A enp1s0 -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A enp1s0 -j DROP

# 已经建立的连接防止断开,Lan接口和lo接口允许访问
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i enp2s0 -j ACCEPT
-A INPUT -i lo -j ACCEPT
# 配置截获所有到Wan接口的流量
-A INPUT -i enp1s0 -j enp1s0

补充知识

iptables相关
# 查看规则和计数
iptables -t filter -L -n -v
# 清空计数器
iptables -t filter -Z
# 带编号显示规则
iptables -t nat -nvL --line-number
# 添加到第3号,原来的3号变4号
iptables -t filter -I INPUT 3 -s 192.168.1.3 -j DROP
# 按编号删除规则
iptables -t filter -D INPUT 2
# 查看会话表
conntrack -L