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 确认成功唤醒.