sho*_*key 3 openwrt wake-on-lan router python3
我的家庭网络图很简单,如下所示:
internet --> Optical modem --> router --> pc1 ,pc2
111.111.111.111--> 192.168.1.1 -->192.168.31.1 --> 192.168.31.144,192.168.31.173
Run Code Online (Sandbox Code Playgroud)
ISP提供一个静态ip,假设它是111.111.111.111
,光调制解调器的ip地址是192.168.1.1
,路由器的ip地址是192.168.31.1
,pc1的ip地址是,pc2的192.168.31.144
ip地址是192.168.31.173
,pc1的mac地址xx.xx.xx.xx
。
该openwrt
是我的路由器上运行,将在路由器和防火墙开放某个端口转发规则:
forwarding rule
name protocl outer port inner IP address inner port
wakeonwan UDP 9 192.168.31.144 9
ssh TCP and UDP 10000 192.168.31.1 22
Run Code Online (Sandbox Code Playgroud)
并在openwrt中绑定ip地址和mac:
ip address mac interface
192.168.31.144 xx.xx.xx.xx ??
Run Code Online (Sandbox Code Playgroud)
从以下选项中选择哪个界面?
远程登录我的路由器:
ssh root@111.111.111.111 -p 10000
Run Code Online (Sandbox Code Playgroud)
从路由器发出 wol 命令:
/usr/bin/wol -i 192.168.31.255 xx.xx.xx.xx
Run Code Online (Sandbox Code Playgroud)
pc1 可以从路由器唤醒!
关闭 pc1,使用以下 python 代码从 pc2 唤醒它wakeonlan.py
:
from wakeonlan import send_magic_packet
send_magic_packet('xx.xx.xx.xx')
Run Code Online (Sandbox Code Playgroud)
python3 wakeonlan.py
在pc2中执行命令可以成功唤醒我的pc1。
python3 wakeonwan.py
远程执行命令(例如——在我公司的电脑中)无法唤醒我的 pc1。
cat wakeonwan.py
mac = "xx.xx.xx.xx"
target_ip = "111.111.111.111"
from wakeonlan import send_magic_packet
send_magic_packet(mac, ip_address=target_ip,port=9)
Run Code Online (Sandbox Code Playgroud)
它没有遇到错误,为什么pc1无法唤醒wakeonwan.py
?
让我们用 lib-- 来做paramiko
。
pip install paramiko
Run Code Online (Sandbox Code Playgroud)
艾特wakeonwan-paramiko.py
:
import paramiko
from contextlib import contextmanager
host = '111.111.111.111'
username = 'root'
password = 'password'
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=username, password=password,port=10000)
stdin, stdout, stderr = ssh.exec_command("/usr/bin/wol -i 192.168.31.255 xx:xx:xx:xx")
ssh.close()
Run Code Online (Sandbox Code Playgroud)
python3 wakeonwan-paramiko.py
可以从外网唤醒我的家用电脑,我觉得编辑wakeonwan.py
远程唤醒电脑更简单吗?
如何解决?
从本地网络之外发送 Wake-on-LAN 数据包的棘手部分是让路由器将数据包发送到本地网络,以便完全被动的 PC1 可以接收它。
魔术数据包寻址到路由器的外部 IP 地址,这使其成为单播数据包。路由器中的转发规则将目标PC自己的IP地址指定为内部IP地址。因此,按照转发单播流量的标准程序,路由器将首先发出 ARP 请求以找出目标 PC 的 MAC 地址……但没有得到答复,因为目标 PC 已关闭。等待 LAN 唤醒数据包的网络接口处于低功耗仅接收模式:它通常无法响应 ARP 请求。
当 ARP 请求失败时,路由器可能会发回一个 ICMP 错误数据包,指示“主机无法访问”……但 Python 唤醒兰模块似乎没有处理此类错误响应的设施,即使假设 ICMP 消息没有得到在返回的路上被偏执防火墙过滤掉。
将 MAC 地址嵌入到魔术数据包负载中这一事实无济于事,因为路由器既不知道也不关心这一点。对于路由器来说,魔术包只是另一个 TCP 或 UDP 数据包,将像往常一样进行处理。
您必须配置转发规则,将魔术数据包发送到内部网络的广播地址,以使其成为广播。这样,路由器在将数据包传递到内部网络之前不需要进行 ARP 查询。因此,如果您的内部网络的掩码是 255.255.255.0,那么您应该使用 192.168.31.255 作为转发规则中的内部 IP 地址。
但是......正如@AB 在评论中提到的,基于 Linux 的路由器通常不喜欢将单播转换为广播,所以这种方法可能行不通。
另一种解决方案是将目标 PC 的静态 ARP 表条目添加到路由器的 ARP 表中,这样它就不需要进行 ARP 查询,而可以继续将数据包转发到内部网络。
通过快速源代码检查,wakeonlan python 模块似乎使用 SOCK_DGRAM,这意味着它使用 UDP。因此,您应该能够将转发规则从“TCP 和 UDP”更改为“仅 UDP”。
归档时间: |
|
查看次数: |
166 次 |
最近记录: |