我正在使用 dnsmasq 来创建某种强制门户。
想法是:
dnsmasq
默认将所有 DNS 请求重写为本地 ip(address=/#/123.123.123.123
),并且nginx
已在这里设置为显示“访问受限页面”。
但我想添加某种排除列表:
ipset create captive-allowed hash:ip
ipset add captive-allowed 222.222.222.222
这将包含客户端的 IP 地址,该地址不应被重写,/#/
并将使用 dnsmasq 作为代理来1.1.1.1/1.0.0.1
传递真实 IP。
据我了解,dnsmasq
ipset 设置仅适用于每个域。所以我必须这样做:
ipset=/google.com/captive-allowed/go.ogle.real.ip
ipset=/amazon.com/captive-allowed/ama.zon.real.ip
... billion records more ...
我的假设正确吗?或者我可能忽略了什么?
答案1
千万不要通过 dnsmasq 来做这件事——让 DNS 参与进来只会增加不必要的复杂性(缓存、DNSSEC 失败、即使意外也容易绕过等)。相反,只使用 iptables/nft 在 IP 级别重定向所有 HTTP 数据包(通过-j DNAT
或使用 DNAT -j REDIRECT
)。例如:
-A FORWARD_CAPTIVE -m set --match-set AllowedClientsMAC src -j ACCEPT
-A FORWARD_CAPTIVE -j REJECT
<...>
-A PREROUTING_CAPTIVE -m set --match-set AllowedClientsMAC src -j ACCEPT
-A PREROUTING_CAPTIVE -p tcp -m tcp --dport 53 -j DNAT --to-destination 192.168.1.53
-A PREROUTING_CAPTIVE -p tcp -m udp --dport 53 -j DNAT --to-destination 192.168.1.53
-A PREROUTING_CAPTIVE -p tcp -m tcp --dport 80 -j REDIRECT
-A PREROUTING_CAPTIVE -p tcp -m tcp --dport 443 -j REDIRECT