惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy International News Feed
Simon Willison's Weblog
Simon Willison's Weblog
I
Intezer
Spread Privacy
Spread Privacy
The Hacker News
The Hacker News
P
Palo Alto Networks Blog
TaoSecurity Blog
TaoSecurity Blog
S
Secure Thoughts
Google Online Security Blog
Google Online Security Blog
H
Heimdal Security Blog
N
News | PayPal Newsroom
Attack and Defense Labs
Attack and Defense Labs
Recent Commits to openclaw:main
Recent Commits to openclaw:main
博客园 - 【当耐特】
Webroot Blog
Webroot Blog
小众软件
小众软件
Help Net Security
Help Net Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
N
News and Events Feed by Topic
Hacker News - Newest:
Hacker News - Newest: "LLM"
PCI Perspectives
PCI Perspectives
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The Cloudflare Blog
Cloudbric
Cloudbric
AI
AI
WordPress大学
WordPress大学
博客园 - 聂微东
Jina AI
Jina AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 三生石上(FineUI控件)
Hacker News: Ask HN
Hacker News: Ask HN
H
Hacker News: Front Page
博客园 - Franky
V
V2EX
Schneier on Security
Schneier on Security
G
GRAHAM CLULEY
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队
H
Help Net Security
量子位
S
Security @ Cisco Blogs
大猫的无限游戏
大猫的无限游戏
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Recorded Future
Recorded Future
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
J
Java Code Geeks
C
Cisco Blogs
S
Security Affairs

K.I.S.S

身在 Kimi 的 800 天 写在 Kimi K2 发布之后:再也不仅仅是 ChatBot macOS 按域名切换 DNS 解析 | K.I.S.S 为什么说 GPT 是无损压缩 | K.I.S.S 握着你的手训一个类GPT语言模型 (二) | K.I.S.S 握着你的手训一个类GPT语言模型 (一) | K.I.S.S Rosetta in Linux Virtual Machine on Apple Silicon Fit an Overfit with MegEngine 把 CUPS 扔进 docker 里 ASUS Chromebook Flip | K.I.S.S GPG 与 SSH Agent 转发 YubiKey 4 简介与配置 | K.I.S.S 定制GH60机械键盘 | K.I.S.S Debian 网络安装内核参数 | K.I.S.S 我的 Vim 配置 | K.I.S.S Libinput 与 Udev | K.I.S.S 给妹子看的 Arch Linux 桌面日常安装 | K.I.S.S 修复GTK3 CSD外观 | K.I.S.S 握着你的手教你画哀女王 | K.I.S.S R.I.P Google Reader | K.I.S.S Richard Stallman仍然是对的 | K.I.S.S Scala 自定义控制结构 | K.I.S.S 入手Wacom Bamboo CTL470 | K.I.S.S 转个型? | K.I.S.S Wish List | K.I.S.S pulseaudio音量问题 | K.I.S.S 入手yubikey,一点小心得 | K.I.S.S 迁移到Octopress | K.I.S.S 自动更新DNSPod记录 | K.I.S.S Linux 用作 IPv6 网关 | K.I.S.S Conky从豆瓣获取MPD专辑封面 | K.I.S.S 我和Linus大学时那些事儿 | K.I.S.S Micro$oft依然是那副老德行 | K.I.S.S 用PulseAudio TCP Forwarding实现网络传声 | K.I.S.S 利用tmpfs加速gnome-shell overview模式Applications索引 | K.I.S.S 新的短网址 | K.I.S.S 紧张的一个月 | K.I.S.S 5月11日活动有感 | K.I.S.S 西电开源社区2011年Tee 最终版 | K.I.S.S 多头多尾的Linux | K.I.S.S Linux的中文名称怎么翻译呢? | K.I.S.S iPhone使用OpenVPN | K.I.S.S 我的人人网敏感词 | K.I.S.S 纪念钱立生老师 | K.I.S.S twitter键盘控:Twittperator | K.I.S.S 天生的暴力倾向? | K.I.S.S The Open Source Spirit | K.I.S.S Libreoffice | K.I.S.S Hello world! | K.I.S.S Python 调用gnuplot的例子 | K.I.S.S The Beginning | K.I.S.S About Me | K.I.S.S
使用 dnsmasq 和 ipset 的策略路由
2016-02-20 · via K.I.S.S

今天试了一把 dnsmasq 的 ipset 功能,配合 iptables 和 iproute2 即可实现基于域名的策略路由。 网上已有一些文章介绍了这种方法,但多是面向 OpenWrt 在路由器上做, 我直接拿来则发现在本地跑其实有坑。

基本需求和思路

我平时一直开着 VPN,配合 chnroute 实现策略路由。但是在学校里访问各类学术数据库需要用学校 IP,过去的做法是把几个常用数据库的 IP 加进路由表里,然而最近一些数据库开始使用 CDN 了,IP 三天两头的变化…… 所以基于域名实现策略路由势在必行。

Ipset 是一个可以和 iptables 配合使用的工具,可以把一系列 ip 放进一个集合中,iptables 则根据集合名进行规则匹配。Dnsmasq 从 2.66 版本之后就支持将一些域名的查询结果放进 ipset 中,这样就可以对这些域名对应的 IP 使用 iptables 处理。集合中的数据包在 iptables mangle 表打上 mark,再使用 iproute2 的规则(rule),对该 mark 的数据包查询一个单独的路由表,从而实现策略路由。

配置流程

VPN?

这个不用说了。

IPSET

首先创建 ipset

ipset create bypass_vpn hash:ip

这个每次重启就会丢失,可以 ipset save 导出配置文件,Arch Linux 的 ipset 包还带了 systemd service,所以

sudo ipset save | sudo tee /etc/ipset.conf
sudo systemctl enable ipset.service

即可。

DNSMASQ

配置 dnsmasq,这里推荐一下 @felixonmars 的 dnsmasq-china-list,把国内 常见网站都涵盖了,自己再把常见学术数据库的域名加进去。但是这份配置中不包含 ipset 的配置,这个简单,简单的全文替换就好。

格式如下:

server=/cn/114.114.114.114  # 这里指定域名的上级 DNS 
ipset=/cn/bypass_vpn        # 这里指定查询结果要放入的 ipset
server=/sciencedirect.com/166.111.8.28
ipset=/sciencedirect.com/bypass_vpn

我自己是将server=ipset=开头的配置分别放在了 china.confchina-ipset.conf 两个文件中,/etc/dnsmasq.conf 中再使用 conf-dir=/etc/dnsmasq.d 配置。

路由表,IPTABLES, IP RULE

首先创建路由表(重启仍有效)

echo "200 bypass_vpn" | sudo tee -a /etc/iproute2/rt_tables   # 这里数字在 1 到 252 之间,不要重复

再加 iptables 规则

sudo iptables -t mangle -N fwmark
sudo iptables -t mangle -A PREROUTING -j fwmark  # 对转发数据包有效
sudo iptables -t mangle -A OUTPUT -j fwmark      # 对从本地发出的数据包有效
sudo iptables -t mangle -A fwmark -m set --match-set bypass_vpn dst -j MARK --set-mark 1  # 给目标地址在 bypass_vpn 中的数据包打上mark 1

在 VPN 启动后,执行一些操作:

  • 把默认物理路由设为 bypass_vpn 表的默认路由
  • 让 mark=1 的数据包查询 bypass_vpn 表

我是在 VPN 的 post-up 脚本中加了这么几句:

OLDGW=$(ip route show 1/0 | head -n1 | sed -e 's/^default//')

gwdev=$(echo $OLDGW|awk '{print $4}')   # 物理设备
ip route show dev $gwdev | while read gwroute; do
	ip route add $gwroute dev $gwdev table bypass_vpn
done

ip rule add fwmark 1 table bypass_vpn

填坑

按理说到这里就该好了,但是实际是跑不起来的,抓包发现,虽然 iptables 的 mark 打上了,路由查询也是对的,但是发出去的包源IP竟然是我的 VPN 网卡地址。

然后 @shankerwangmiao 和 @hexchain 帮我找到了下面这张图还有这份文档。 大致意思就是,Linux 给数据包设置的源 IP 是通过查路由表决定的,而 Routing Decision 的过程发生在进入 iptables 之前,所以这时候根据规则,查询的是默认路由表,策略 路由没有起作用。在经过 mangle OUTPUT chain 之后,有一次 reroute check 过程,如果被打上了 mark,则再决定是不是要根据别的路由表发包,但是这时源地址中央已经 决定了。

解决的办法也比较简单,通过 NAT 把源地址改了就好

sudo iptables -t nat -A POSTROUTING -m mark --mark 0x1 -j MASQUERADE
# 或者使用
sudo iptables -t nat -A POSTROUTING -m mark --mark 0x1 -j SNAT --to-source <your ip>

这时 tcpdump 发现 ICMP reply 已经收到了,但是 ping 仍然没反应。这是因为 Arch Linux 默认的 rp_filter 策略是严格路由匹配,即我收到 ICMP 包的网卡(物理网卡)并不是 最佳路径(默认路由表中VPN才是最佳路径)所以就丢掉了。所以把 rp_filter 改成宽松模式(路由可达即认为数据包合法)

sudo sysctl net.ipv4.conf.{all,enp2s0}.rp_filter=2  # 你的网卡不一定叫 enp2s0

其实默认改成宽松也行,编辑 /etc/sysctl.d/60-rp_filter.conf

net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.all.rp_filter = 2

以上。