![Debian LAN 数据包转发唤醒?](https://linux22.com/image/15525/Debian%20LAN%20%E6%95%B0%E6%8D%AE%E5%8C%85%E8%BD%AC%E5%8F%91%E5%94%A4%E9%86%92%EF%BC%9F.png)
我有一个 untangle box(下面是 debian 10),我正在尝试将 WOL 数据包从一个子网中的主机转发到另一个子网中的主机。
我最初的解决方案是使用 Knockd,在一个子网上的一个接口上监听 syn 数据包,然后在另一个子网上执行 etherwake 命令来唤醒主机。我将使用 netcat 从第一个子网中的 Linux 服务器发送 syn 数据包,将数据包发送到网关 IP(解开盒)。
问题是,发往防火墙本身的流量最初是在未寻址的 vlan 接口上处理的。这有点奇怪,syn 数据包只能在未寻址的接口上看到,然后所有其他数据包都可以在实际寻址的 vlan 接口上看到。我已经用 tcpdump 确认了这一点。它打破了我使用 Knockd 的计划,因为 Knockd 拒绝侦听没有 IP 地址的接口。
我可以看到 syn 数据包进入带有 tcpdump 的未寻址接口,并且 knockd 在幕后使用 tcpdump。那么有没有办法强制 Knockd 监听未寻址的接口呢?
如果 Knockd 完全不可能,那么您将如何在 Debian 10 上实现 WOL 数据包转发器?
答案1
唤醒主机的问题是,要向其发送数据包,网络堆栈必须知道 NIC 的 MAC 地址。通常它是动态处理的ARP。如果 MAC 条目已从路由器的 ARP 表中逐出,则当主机处于睡眠状态时,它无法回答 ARP 查询,因此路由器无法获取到达睡眠主机所需的 MAC 地址以向其发送 WOL Magic Packet ™ 即使该数据包包含该 MAC 地址的 16 倍在其有效负载中。
这里有两种方法来克服这个问题,仅依靠网络堆栈(以及像iptables或者TC)。
永久ARP
由于路由器具有控制权,因此可以在路由器上为休眠主机设置永久 ARP 条目。这样就永远不会出现之前的问题了。路由器现在可以轻松发送或转发 WOL Magic Packet™,而无需在任何地方使用任何广播。通过 NAT 进行“端口转发”,远程主机就可以使用wakeonlan
命令(而不是命令etherwake
,因为它可以改变UDP端口)。
因此,休眠主机需要一个静态地址(或具有永久 DHCP 租约的地址)。假设路由器上的 WAN 地址是 192.0.2.2旺0,路由器LAN侧接口为192.168.1.1/24局域网0以及 MAC 地址为 12:34:56:78:9a:bc 的接口上的睡眠主机 192.168.1.101/24。
在路由器上:
ip neighbour replace 192.168.1.101 lladdr 12:34:56:78:9a:bc dev lan0 nud permanent
由于尚不清楚 NIC 接收到的数据包是否会被消耗或仍然正确地可供唤醒的主机使用,因此传统上选择端口 9,因为这是丢弃服务如果它正在“运行”并且两者都是相同的。如果需要,请选择 9 之外的其他端口。睡眠主机上的此端口最好不使用并受防火墙保护(丢弃数据包),或者实际运行丢弃服务。由于一个端口映射到一个目标,因此如果有多个 WOL 主机,则每个主机都应具有不同的端口。
通过选择所有不属于 OP 描述的接口,可以解决第一个数据包到达 OP 描述中其他地方的问题。局域网0界面。
所以仍然在路由器上,使用iptables,执行 DNAT 并允许重定向数据包:
iptables -t nat -I PREROUTING ! -i lan0 -p udp --dport 9 -j DNAT --to-destination 192.168.1.101
iptables -I FORWARD -m conntrack --ctstate DNAT -d 192.168.1.101 -j ACCEPT
Internet 上的远程主机现在可以执行此操作来唤醒休眠的主机:
wakeonlan -i 192.0.2.2 -p 9 12:34:56:78:9a:bc
系统集成取决于网络配置所使用的方法。例如,如果配置为interfaces
和如果向上向下,这两个命令可以作为节中的命令iptables
添加(并在命令中删除)和as命令。pre-up
iface lan0 ...
down
ip neighbour
up
定向子网广播(从内核 4.19 开始)
工具始终可以选择使用广播数据包,这些数据包最终作为广播以太网帧到达所有主机,包括目标主机。
路由时可以这样做,但涉及更多风险(包括参与反射攻击)。使用前请考虑安全性。
必须全局启用定向子网广播和在接收 WAN 接口(不是目标 LAN 接口)上。如果可能有多个 WAN 接口(OP 描述数据包首先到达一个接口,然后到达另一个接口),请在所有涉及的接口上启用它。
sysctl -w net.ipv4.conf.all.bc_forwarding=1
sysctl -w net.ipv4.conf.wan0.bc_forwarding=1
添加 NAT 和 FORWARD 规则:
iptables -t nat -I PREROUTING ! -i lan0 -p udp --dport 9 -j DNAT --to-destination 192.168.1.255
iptables -I FORWARD -m conntrack --ctstate DNAT -d 192.168.1.255 -j ACCEPT
作为限制风险的选项,最终将 IPv4 以太网帧 (ethertype 0x800) 转换为用于 WOL 的事实上的 ethertype 0x842,使用TC,因此结果将被网络堆栈忽略(但不会被 WOL NIC 忽略)。可以使用 iptables 设置的标记,或者这里只考虑 IP 目标和 UDP 目标端口 9。如果 Untangle 使用前一种方法,则前一种方法会与标记发生冲突,如果 Untangle 使用,任何一种方法都会发生冲突TC用于服务质量。
tc qdisc add dev lan0 root handle 1: prio # simple classful qdisc used only to enable filters
tc filter add dev lan0 parent 1: protocol ip basic match '
cmp (u32 at 16 layer network eq 0xc0a801ff) and
cmp (u8 at 9 layer network eq 17) and
cmp (u16 at 2 layer transport eq 9)
' action skbmod set etype 0x842
多于,
- u32在16层网络eq 0xc0a801ff表示IP地址目的地192.168.1.255,
- u8在9层网络eq 17表示UDP,
- u16 在 2 层传输 eq 9 表示目标端口 9。
- 结果是将以太类型更改为 0x842
同样,互联网上的远程主机现在可以这样做来唤醒休眠的主机:
wakeonlan -i 192.0.2.2 -p 9 12:34:56:78:9a:bc
但它每次都会针对整个 LAN,因此当有多个睡眠 WOL 主机时,保持相同的端口并仅更改 MAC 地址就足够了。
其他可考虑的方法:
fwknopd
安装在服务器上并且fwknop
安装在客户端实现加密单身的数据包授权机制来触发命令。它可用于触发在路由器上运行wakeonlan
/ 。etherwake