Wake-on-LAN Qua Internet: Cấu Hình Router và Linux Server để Khởi Động Máy Từ Xa

Networking tutorial - IT technology blog
Networking tutorial - IT technology blog

Vấn Đề Lúc 2 Giờ Sáng: Server Tắt Nguồn Và Bạn Không Có Mặt Ở Đó

Chuyện xảy ra vào một ngày thứ Ba. Nguồn điện chập chờn ở văn phòng khiến UPS ngắt, và khi điện trở lại, một trong những máy chủ bare-metal không chịu khởi động theo. Máy đã được cài tự động tắt nhưng không có tự động bật lại. Lúc đó là 2:47 sáng, tôi đang ở cách đó 40 kilomet, và có người cần khôi phục database trước 6 giờ sáng.

Đêm đó tôi phải lái xe vào. Sáng hôm sau, tôi thiết lập Wake-on-LAN cho tất cả các máy vật lý mình quản lý. Từ đó đến nay tôi đã dùng nó trên nhiều môi trường production — bật máy qua NAT từ điện thoại ở phía bên kia thành phố, chưa một lần thất bại kể từ khi cài đặt đã ổn định.

Nếu bạn đang chạy Linux server hay home lab, WoL từ xa là kiểu cài đặt 20 phút mà sẽ chứng minh giá trị ngay lần đầu tiên điện cúp lúc 3 giờ sáng.

Wake-on-LAN Thực Sự Hoạt Động Như Thế Nào

Wake-on-LAN gửi một gói UDP được thiết kế đặc biệt — gọi là Magic Packet — đến card mạng của máy. NIC vẫn duy trì nguồn ở trạng thái tiêu thụ thấp ngay cả khi máy đã tắt (miễn là còn cắm điện), chờ gói tin đó. Khi nhận được, NIC sẽ báo hiệu cho bo mạch chủ bật nguồn.

Cấu trúc Magic Packet rất đơn giản: 6 byte 0xFF, tiếp theo là địa chỉ MAC đích lặp lại 16 lần — tổng cộng 102 byte. Không có IP header. Không có TCP handshake. Chỉ là UDP thuần trên cổng 9 hoặc 7.

Điểm mấu chốt: gói broadcast mặc định không vượt qua được router. Để WoL packet đi từ internet vào máy sau NAT, bạn cần một relay hoặc directed broadcast — đó là lúc cấu hình router phát huy tác dụng.

Yêu Cầu Trước Khi Bắt Đầu

  • Máy Linux có NIC hỗ trợ WoL (hầu hết đều có, nhưng BIOS phải được bật)
  • Máy kết nối qua Ethernet — WoL không hoạt động qua Wi-Fi trong hầu hết trường hợp
  • Quyền truy cập router để cấu hình port forwarding và tùy chọn subnet-directed broadcast
  • Thiết bị gửi Magic Packet từ xa: server khác, VPS, hoặc ứng dụng di động

Bước 1: Bật WoL Trong BIOS/UEFI

Trước khi động vào hệ điều hành, khởi động vào BIOS và tìm các tùy chọn có tên:

  • Wake on LAN
  • Power On By PCI-E / PCI
  • Resume By LAN

Bật lên. Lưu và thoát. Bỏ qua bước này và bạn sẽ ngồi nhìn đầu ra ethtool cả tiếng đồng hồ mà không hiểu tại sao không có gì hoạt động.

Bước 2: Cấu Hình WoL Trên Linux

Kiểm tra xem NIC của bạn có hỗ trợ Wake-on-LAN không:

sudo ethtool eth0 | grep -i wake

Bạn cần thấy đầu ra như thế này:

Supports Wake-on: pumbg
Wake-on: d

Chữ g trong Supports Wake-on xác nhận hỗ trợ Magic Packet. Chữ d trong Wake-on nghĩa là hiện đang tắt. Bật lên:

sudo ethtool -s eth0 wol g

Kiểm tra lại:

sudo ethtool eth0 | grep 'Wake-on'

Đầu ra mong đợi:

Wake-on: g

Một vấn đề: cài đặt này sẽ bị reset mỗi lần khởi động lại. Cần cấu hình để giữ nguyên.

Giữ WoL Qua Các Lần Khởi Động Với systemd (Hệ Thống Hiện Đại)

Tạo một oneshot service chạy ethtool khi khởi động:

sudo nano /etc/systemd/system/wol.service
[Unit]
Description=Bật Wake-on-LAN trên eth0
After=network.target

[Service]
Type=oneshot
ExecStart=/sbin/ethtool -s eth0 wol g
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable wol.service
sudo systemctl start wol.service

Thay eth0 bằng tên interface thực tế của bạn. Chạy ip link nếu không chắc tên là gì.

Cách Thay Thế: NetworkManager (Ubuntu/Fedora Desktop)

Nếu máy chạy NetworkManager, hãy cài WoL theo từng kết nối:

nmcli connection modify "Wired connection 1" 802-3-ethernet.wake-on-lan magic

Bước 3: Ghi Lại Địa Chỉ MAC

Lấy địa chỉ MAC ngay bây giờ — bạn sẽ cần nó để tạo Magic Packet sau:

ip link show eth0 | grep ether

Ví dụ đầu ra:

    link/ether b8:27:eb:a1:2c:44 brd ff:ff:ff:ff:ff:ff

Ghi lại ở chỗ nào đó bạn có thể tìm được lúc 2 giờ sáng.

Bước 4: Cấu Hình Router Để Bật Máy Từ Xa

Đây là phần mà hầu hết các hướng dẫn bỏ qua. Để bật máy qua internet, bạn có hai lựa chọn:

Phương Án A: Chuyển Tiếp UDP Đến Địa Chỉ Broadcast

Trên hầu hết router dân dụng (OpenWrt, pfSense, ASUS, TP-Link):

  1. Mở phần cài đặt Port Forwarding hoặc Virtual Server
  2. Tạo rule: UDP cổng ngoài 9 → IP nội bộ 192.168.1.255 (broadcast subnet), cổng 9
  3. Nếu router chặn forward đến địa chỉ broadcast, hãy forward trực tiếp đến IP tĩnh của máy thay vào đó

Cấp IP tĩnh hoặc DHCP reservation theo địa chỉ MAC cho máy đích. Máy đổi IP mỗi lần khởi động sẽ không thể truy cập đúng lúc bạn cần nhất. Nếu bạn chưa có DHCP server riêng, hãy xem hướng dẫn cài đặt DHCP Server trên Linux để kiểm soát cấp phát IP tốt hơn.

Phương Án B: Dùng VPS Hoặc Relay Server

Router không cho phép forward đến địa chỉ broadcast? Dùng relay. VPS giá rẻ 5$/tháng là đủ, hoặc một Raspberry Pi ngồi trong mạng LAN cũng được. SSH vào relay, rồi gửi packet từ bên trong mạng nội bộ.

Cài wakeonlan trên relay:

# Debian/Ubuntu
sudo apt install wakeonlan

# RHEL/Fedora
sudo dnf install wol

Gửi packet từ relay:

wakeonlan b8:27:eb:a1:2c:44

Hoặc chỉ định broadcast và cổng cụ thể:

wakeonlan -i 192.168.1.255 -p 9 b8:27:eb:a1:2c:44

Bước 5: Kiểm Tra Quá Trình Wake

Tắt máy đích. Từ một máy khác trong cùng mạng LAN, gửi packet:

wakeonlan b8:27:eb:a1:2c:44

Chờ 15–30 giây, rồi ping hoặc SSH vào. Nếu máy bật được, WoL phía LAN đã hoạt động.

Bây giờ thử từ bên ngoài. Dùng VPS hoặc chuyển điện thoại sang LTE — bất cứ thứ gì chắc chắn không nằm trong mạng nội bộ. Gửi packet đến IP công khai của router:

wakeonlan -i YOUR.PUBLIC.IP -p 9 b8:27:eb:a1:2c:44

Muốn viết script? Đây là phiên bản Python tự tạo packet trực tiếp:

import socket

def send_magic_packet(mac: str, broadcast_ip: str = '255.255.255.255', port: int = 9):
    mac_clean = mac.replace(':', '').replace('-', '')
    if len(mac_clean) != 12:
        raise ValueError(f"Địa chỉ MAC không hợp lệ: {mac}")
    payload = bytes.fromhex('FF' * 6 + mac_clean * 16)
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        sock.sendto(payload, (broadcast_ip, port))
    print(f"Đã gửi magic packet đến {mac} qua {broadcast_ip}:{port}")

send_magic_packet('b8:27:eb:a1:2c:44', broadcast_ip='YOUR.PUBLIC.IP')

Xử Lý Các Sự Cố Thường Gặp

  • Packet đến nhưng máy không bật: Kiểm tra BIOS trước. Sau đó chạy ethtool eth0 | grep 'Wake-on' — cài đặt có thể đã reset về d sau khi khởi động lại.
  • Hoạt động trong LAN nhưng thất bại từ internet: Router có thể đang chặn gói UDP. Thử cổng 7 thay thế. Một số ISP cũng chặn UDP trên các cổng không chuẩn.
  • Vấn đề ARP cache: Sau khi máy tắt đủ lâu, router xóa ARP entry và không forward packet đến IP đó nữa. Nhắm đến địa chỉ broadcast (192.168.1.255) sẽ bỏ qua hoàn toàn vấn đề này — không cần ARP lookup.
  • Máy bật lên rồi tắt ngay: Đây là vấn đề về trạng thái nguồn trong BIOS. Tìm cài đặt liên quan đến S4/S5 power states trong phần quản lý nguồn và điều chỉnh cho phù hợp.

Lưu Ý Bảo Mật

Mở UDP cho WoL tự thân rủi ro không cao — kịch bản tệ nhất là kẻ tấn công bật máy của bạn lên. Nhưng máy đang bật là một bề mặt tấn công, vì vậy một vài biện pháp phòng ngừa cơ bản là đáng làm:

  • Dùng cổng ngoài không chuẩn (ví dụ: forward 19872/UDP bên ngoài → 9/UDP bên trong)
  • Giới hạn rule forwarding chỉ từ một IP nguồn cụ thể nếu địa chỉ WAN của bạn là tĩnh
  • Đảm bảo SSH trên máy đích dùng xác thực bằng key — không cho phép đăng nhập bằng mật khẩu. Nếu cần truy cập an toàn qua các mạng khác nhau, SSH Tunneling là lớp bảo vệ bổ sung đáng cân nhắc.

Thêm Một Mẹo: Script Tự Động Wake + Chờ + SSH

Khi WoL đã ổn định, hãy gộp toàn bộ quy trình vào một script:

#!/bin/bash
MAC="b8:27:eb:a1:2c:44"
HOST="192.168.1.50"
USER="admin"

echo "Đang gửi magic packet..."
wakeonlan $MAC

echo "Đang chờ máy khởi động..."
for i in $(seq 1 12); do
  sleep 5
  if ping -c1 -W1 $HOST &>/dev/null; then
    echo "Máy đã bật. Đang kết nối..."
    ssh ${USER}@${HOST}
    exit 0
  fi
  echo "Vẫn đang chờ... (${i}/12)"
done

echo "Máy không phản hồi sau 60 giây."
exit 1

Vậy Là Xong

WoL là công cụ chạy ngầm — vô hình cho đến khi một chiếc máy tắt nguồn đúng lúc tệ nhất có thể. Cài đặt chỉ mất khoảng 20 phút: cấu hình ethtool, một systemd service, và một rule port forwarding. Sau đó, bạn có thể truy cập bất kỳ máy vật lý nào mình quản lý từ bất cứ đâu, bất kỳ giờ nào. Để kiểm soát tường lửa chặt chẽ hơn trước khi mở port UDP ra ngoài, hãy tham khảo hướng dẫn cấu hình tường lửa Linux với iptables và nftables.

Chuyến lái xe 40 kilomet lúc 3 giờ sáng đó là lần cuối cùng tôi phải đi vì sự cố nguồn điện. Đó là một kết quả tốt.

Share: