使用Nftables来劫持流量

在网关劫持特定的DNS流量

在树莓派或者路由网关上,我们可以通过以下的nft配置来劫持特定设备的UDP流量

map user_dnat_udp_port {
    type ipv4_addr . inet_service : ipv4_addr . inet_service
    elements = { 10.0.0.0 . 53 : 8.8.8.8 . 53 }
}

chain nat_prerouting {
    type nat hook prerouting priority 100; policy accept;
    dnat ip addr . port to ip saddr . udp dport map @user_dnat_udp_port
}

chain postrouting {
	type nat hook postrouting priority 100; policy accept;
	masquerade random,persistent
}
  • user_dnat_udp_port 是一个数据集合,用户的劫持策略可以动态加减
  • concatenations 配合dnat to, 可以简化规则,将逻辑与数据分离

控制出口的路由

通过策略路由 (ip rule),我们可以很轻松完成路由控制,例如

ip rule add to 8.8.8.8/32 lookup 10001

但是,如果每一个IP都写一条规则的话,策略路由会无限增加。除了from/to,策略路由还可以支持 fwmark/uidrange/sport/dport

方法1-指定用户 uid

ip rule add uidrange 1001-1001 lookup 10001

也就是uid范围内的用户,对外访问都优先匹配 10001 路由表

方法2-指定数据包标签 fwmark

默认的数据包的 fwmark 为 0x0,通过nftables meta mark set, 可以为数据包增加标签

set user_ip_addr {
    type ipv4_addr
    elements = { 10.0.0.0/8 }
}

chain OUTPUT {
		type nat hook output priority -100; policy accept;
		ip daddr @user_ip_addr meta mark 0x00000011
	}