启用双向NAT的多网卡环境下,如何配置DHCP中继实现NAT网络的PXE网络启动?
你的这个场景确实有点绕——双向NAT(NETMAP+地址映射)加上跨NAT的DHCP/PXE中继,不过好在OpenWRT默认带的dnsmasq刚好能搞定这个需求,我结合你现有的iptables规则,一步步给你捋清楚配置:
首先得明确咱们要解决的核心矛盾:DHCP中继不仅要把客户端的请求转发给主服务器,还要偷偷修改DHCP响应里的地址,让NAT网络里的客户端以为是直接和10.10.0.100(主服务器的暴露地址)通信,同时还要让主服务器看到的是NAT转换后的10.90.0.0/16网段地址。
一、先给OpenWRT的dnsmasq做基础配置调整
首先,我们要让dnsmasq只当DHCP中继,别抢着当权威DHCP服务器。编辑OpenWRT的DHCP配置文件/etc/config/dhcp,找到config dnsmasq段,修改这几个关键参数:
config dnsmasq option domainneeded '1' option boguspriv '1' option localise_queries '1' option rebind_protection '1' option rebind_localhost '1' option local '/lan/' option domain 'lan' option expandhosts '1' option nonegcache '0' option authoritative '0' # 重要:别让dnsmasq自己当DHCP服务器 option readethers '1' option leasefile '/tmp/dhcp.leases' option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto' option nonwildcard '1' option localservice '1' option dhcp_relay_override '1' # 允许dnsmasq修改中继的DHCP响应内容 option dhcp_option 'option:tftp-server-name,"10.10.0.100"' # 强制TFTP服务器地址为客户端看到的10.10.0.100
二、配置针对NAT网络的DHCP中继规则
在同一个/etc/config/dhcp文件里,新增一个DHCP中继的专用配置段。这里要注意替换成你实际的接口名:假设OpenWRT上连接NAT网络(真实10.10.0.0/16)的接口是eth1,连接主服务器的接口是eth0:
config dhcp 'relay_nat_network' option interface 'eth1' # 接NAT客户端的接口 option relay '192.168.200.1' # 主服务器的真实地址(DHCP/PXE服务器所在地址) option dhcp_option 'option:server-identifier,10.10.0.100' # 把DHCP响应里的服务器ID改成10.10.0.100 option pxe_service '0,"PXE Boot Server",10.10.0.100' # 给PXE客户端指定启动服务器地址 option dhcp_range '10.10.0.0,proxy' # 声明这是代理模式,不分配IP,只中继
这个配置的核心是:把主服务器返回的DHCP响应里的服务器地址,强制替换成10.10.0.100,这样客户端就会用这个地址和DHCP/PXE服务器通信,而不是主服务器的真实192.168.200.1。
三、补充iptables规则适配DHCP流量
你现有的iptables规则已经覆盖了普通数据流量,但DHCP用的是UDP 67/68端口,得单独处理这些包的NAT转换,确保它们能在接口间正确转发:
- 先允许DHCP包的转发:
iptables -A FORWARD -i eth1 -o eth0 -p udp --dport 67 -j ACCEPT iptables -A FORWARD -i eth0 -o eth1 -p udp --dport 68 -j ACCEPT
- 给DHCP请求做地址映射,让主服务器看到的是NAT后的10.90.0.0/16网段:
# 客户端发的DHCP请求,源地址从10.10.0.0/16转成10.90.0.0/16再发给主服务器 iptables -A PREROUTING -i eth1 -p udp --dport 67 -s 10.10.0.0/16 -j NETMAP --to 10.90.0.0/16 # 主服务器返回的DHCP响应,目的地址从10.90.0.0/16转成10.10.0.0/16再发给客户端 iptables -A POSTROUTING -o eth1 -p udp --dport 68 -d 10.90.0.0/16 -j NETMAP --to 10.10.0.0/16
要把这些规则加到你现有的iptables配置里,或者在OpenWRT的/etc/firewall.user里添加,这样重启防火墙后不会丢失。
四、主服务器上的DHCP/PXE配置调整
主服务器上的DHCP服务器(不管是isc-dhcp还是dnsmasq),需要针对10.90.0.0/16网段配置DHCP范围,因为主服务器看到的NAT网络是这个网段:
比如用isc-dhcp-server的话,配置片段可以写成这样:
subnet 10.90.0.0 netmask 255.255.0.0 { range 10.90.0.10 10.90.0.200; # 分配的IP范围(主服务器视角的NAT网段) option routers 10.90.0.1; # 若要客户端看到的路由器是10.10.0.1,可在OpenWRT的中继配置里加`option dhcp_option 'option:router,10.10.0.1'`覆盖 option bootfile-name "pxelinux.0"; # PXE启动文件名 }
这里不用在主服务器里写10.10.0.100,因为OpenWRT的dnsmasq会自动把DHCP响应里的服务器地址、TFTP地址替换成10.10.0.100。
五、测试验证
- 重启OpenWRT的dnsmasq服务:
/etc/init.d/dnsmasq restart - 重启防火墙让新的iptables规则生效:
/etc/init.d/firewall restart - 在NAT网络里找一台支持PXE的机器开机,抓包排查:
- 客户端发的DHCP Discover会被中继到主服务器的192.168.200.1,源地址是10.90.0.x
- 主服务器返回的DHCP Offer里,Server ID是10.10.0.100,TFTP地址也是10.10.0.100
- 客户端能正常获取IP,并且能从10.10.0.100下载PXE启动文件,完成网络启动
如果遇到问题,可以看OpenWRT的系统日志logread | grep dnsmasq和主服务器的DHCP日志,排查地址转换或中继的问题。
备注:内容来源于stack exchange,提问作者raj

