Posts
多peer组网-远程唤醒Ubuntu主机
简要
上篇已经使用wireguard组网好了,现在在老家的情况下远程唤醒家里的Ubuntu Linux主机.
使用
确定网卡是否支持
首先ifconfig确定网卡的名称。
然后:
sudo ethtool enp7s0 | grep Wake-on #我的网卡设备名是enp7s0
确定输出模式:
* g模式(GENERIC):只需要NIC芯片和驱动支持唤醒扩展就可以工作,兼容性最好。这是wol标准实现。
* p模式(PHY):需要NIC PHY层支持未对齐帧检测唤醒,支持程度较低。
* u模式(UNICAST):需要NIC芯片支持L2/L3过滤和单播唤醒功能,支持程度一般。
* m模式(MULTICAST):同时支持g和p模式,兼容性次于g模式。
* b模式(BROADCAST):同时支持所有模式,兼容性汇总下来可能性最低。
我们使用g模式
设置g模式
sudo ethtool -s enp7s0 wol g来通过命令设置.
有一个问题是:当前设置后,下次开机后会丢失这个设置。可以每次开机自动永久设置为g.
永久设置g模式
方法有3种:
* udevadm
* systemd service 
* netplan
只说netplan吧,其它2种我在ubuntu下没尝试成功.
netplan
link这个link解释了network-manager
会使用netplan配置脚本进行配置渲染。 
我使用如下:  
# Let NetworkManager manage all devices on this system
network:
  version: 2
  renderer: NetworkManager
  ethernets:
    enp6s0:
      dhcp4: no
      addresses: [192.168.50.27/24]
      gateway4: 192.168.50.1
      wakeonlan: true
      nameservers:
          addresses: [192.168.50.1,8.8.8.8]
wakeonlan: true 只用添加这条配置即可ubuntu每次开机会自动打开唤醒功能。
测试
我使用python脚本在另外一台电脑来测试开机:
需要 修改python中的mac address.  
list1 = ["xx:xx:xx:xx:xx:xx"]  ##give your MAC addresses here in this format
import socket
import struct
def wake_on_lan(macaddress):
    if len(macaddress) == 12:
        pass
    elif len(macaddress) == 12 + 5:
        sep = macaddress[2]
        macaddress = macaddress.replace(sep, '')
    else:
        raise ValueError('Incorrect MAC address format')
    data = ''.join(['FFFFFFFFFFFF', macaddress * 16])
    send_data = b''
    for i in range(0, len(data), 2):
        send_data = b''.join([send_data,
                             struct.pack('B', int(data[i: i + 2], 16))])
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    sock.sendto(send_data, ('<broadcast>', 7))
if __name__ == '__main__':
    for i in range(0, len(list1)):
        wake_on_lan(list1[i])
print("System is Powered ON")
开机后ping 确认成功唤醒.