Wake-on-LAN: как включить компьютер по сети и написать WOL-инструмент на Go

Включить выключенный компьютер по сети — одной командой, без физического доступа. Разбираем протокол WOL и пишем инструмент на Go: от структуры Magic Packet до UDP-отправки.

Обложка: Wake-on-LAN: как включить компьютер по сети и написать WOL-инструмент на Go

Wake-on-LAN (WOL) — сетевой протокол, который позволяет включить любой компьютер в локальной сети одной командой, без физического доступа к кнопке питания. Удобно, когда нужно срочно добраться до файла на выключенной рабочей машине или запустить ночные обновления на сотне серверов, не обходя каждый.

Ключевые выводы
Wake-on-LAN за 30 секунд
  • Wake-on-LAN — сетевой протокол для удалённого включения компьютера через Magic Packet.
  • Magic Packet: 6 байт 0xFF + MAC-адрес, повторённый 16 раз.
  • Пакет отправляется по UDP на широковещательный адрес 255.255.255.255, де-факто стандарт — порт 9.
  • Ограничения: только в пределах одной сети или VLAN, только по Ethernet, нет подтверждения доставки.
  • Реализуем собственный WOL-инструмент на Go с нуля.

Что такое Wake-on-LAN

Wake-on-LAN (WOL) — протокол канального уровня, который будит компьютер или сервер, когда сетевой интерфейс получает специальный Magic Packet. Сетевая карта с активированной функцией WOL постоянно прослушивает широковещательный трафик даже когда компьютер выключен, но подключён к сети. При обнаружении Magic Packet она посылает сигнал на BIOS, и система загружается.

Для работы WOL необходимо, во-первых, включить поддержку в BIOS или UEFI (обычно называется Wake-on-LAN или Power On by PCI-E); во-вторых, активировать её в операционной системе для нужного сетевого адаптера. На Linux это делается одной командой:

			sudo ethtool -s eth0 wol g
		

Здесь g — режим MagicPacket. Проверить текущее состояние — ethtool eth0 | grep Wake. На Windows нужную опцию ищите в «Свойства сетевого адаптера → Управление электропитанием → Разрешить этому устройству выводить компьютер из ждущего режима».

Как устроен Magic Packet

Magic Packet — бинарный фрейм с жёстко заданной структурой. Сначала идёт синхропоследовательность: 6 байт 0xFF. Эти байты сигнализируют сетевой карте о начале нового фрейма.

			FF FF FF FF FF FF
		

Сразу после синхропоследовательности — MAC-адрес целевой машины, повторённый 16 раз без пробелов и разделителей. Именно по нему сетевая карта понимает, что пакет адресован ей. В итоге Magic Packet занимает 102 байта: 6 байт синхропоследовательности плюс 6 байт MAC × 16 повторений.

Пример реального Magic Packet с MAC-адресом 12:34:56:78:9a:bc, захваченного в Wireshark:

			ff ff ff ff ff ff 12 34 56 78 9a bc 12 34 56 78
9a bc 12 34 56 78 9a bc 12 34 56 78 9a bc 12 34
56 78 9a bc 12 34 56 78 9a bc 12 34 56 78 9a bc
12 34 56 78 9a bc 12 34 56 78 9a bc 12 34 56 78
9a bc 12 34 56 78 9a bc 12 34 56 78 9a bc 12 34
56 78 9a bc 12 34 56 78 9a bc 12 34 56 78 9a bc
12 34 56 78 9a bc
		

Некоторые реализации WOL поддерживают опциональный пароль в конце пакета — для защиты от несанкционированного включения. Механизм SecureOn использует 6 байт, AMD-спецификация допускает 4 байта. Однако не каждый BIOS поддерживает эту функцию.

Как отправить Magic Packet

Magic Packet может быть передан поверх любого сетевого протокола — сетевой карте достаточно найти нужную последовательность байт в полученном фрейме. На практике пакет отправляют как UDP-датаграмму на широковещательный адрес.

Для IPv4 используется широковещательный адрес 255.255.255.255 — он охватывает всю локальную сеть или сегмент. IPv6 вместо broadcast использует multicast. Де-факто стандарт для порта назначения — 9 (Discard Protocol), реже используют 7 или 0.

Ограничения Wake-on-LAN

Прежде чем настраивать WOL в продакшне, важно понять его ограничения:

  • Только одна сеть или VLAN. Magic Packet не маршрутизируется — получить его может лишь устройство в той же локальной сети или VLAN, что и отправитель. Для удалённого включения через интернет нужен промежуточный узел в этой сети: VPN, Raspberry Pi или роутер с поддержкой WOL.
  • Нужен MAC-адрес. WOL работает на канальном уровне, поэтому нельзя разбудить компьютер, зная только его IP-адрес.
  • Только проводной Ethernet. Большинство Wi-Fi-адаптеров не поддерживают WOL. Исключение — устройства с поддержкой стандарта WoWLAN (Wake on Wireless LAN), но на практике их мало, и настройка требует совместимого драйвера.
  • Нет подтверждения доставки. UDP — протокол без установления соединения, поэтому после отправки Magic Packet невозможно узнать, получил ли его компьютер и включился ли он.
  • Зависимость от BIOS. Некоторые материнские платы пробуждаются только из состояний S3 или S4, но не из полного выключения S5. Проверяйте документацию к платформе.

Реализация на Go

Напишем собственный WOL-инструмент на Go — одна из немногих задач, где стандартной библиотеки хватает полностью. Если хочется погрузиться в Go глубже, у нас есть обзор Golang-фреймворков 2026 года. Нам понадобятся две функции: CreateMagicPacket для формирования пакета и SendMagicPacket для его отправки.

CreateMagicPacket: формируем пакет

Функция принимает MAC-адрес строкой и возвращает готовый байтовый срез или ошибку. Первым делом проверяем валидность MAC-адреса с помощью регулярного выражения:

			// Разрешённые разделители в MAC-адресе
delimiter := []string{":", "-"}

// reMAC проверяет корректность MAC-адреса
reMAC := regexp.MustCompile(`^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$`)
MAC := reMAC.Find([]byte(MACAddress))

// Если MAC-адрес невалидный — возвращаем ошибку
if MAC == nil {
    return nil, fmt.Errorf("%q is not a valid MAC address", MACAddress)
}
		

После валидации убираем разделители из MAC-адреса, затем повторяем его 16 раз:

			// Удаляем разделители (: или -)
MACAddress = string(MAC)
for _, v := range delimiter {
    MACAddress = strings.ReplaceAll(MACAddress, v, "")
}

// Повторяем MAC-адрес 16 раз
tMAC := strings.Repeat(MACAddress, 16)
		

Объединяем синхропоследовательность с повторённым MAC-адресом и декодируем hex-строку в байтовый срез:

			// syncStream = "ffffffffffff"
magicPacket, err := hex.DecodeString(syncStream + tMAC)
if err != nil {
    return nil, err
}
return magicPacket, nil
		

SendMagicPacket: отправляем пакет

Функция принимает Magic Packet ([]byte), IP-адрес назначения и порт. Сначала проверяем валидность IP через стандартную функцию net.ParseIP — в отличие от regex, она корректно обрабатывает и IPv4, и IPv6:

			// Проверяем корректность IP-адреса
ip := net.ParseIP(addr)
if ip == nil {
    return fmt.Errorf("%q is not a valid IP address", addr)
}

// Формируем строку подключения "IP:порт"
address := fmt.Sprintf("%s:%d", ip, port)
		

Открываем UDP-соединение через net.Dial. WOL не требует установления соединения — UDP идеально подходит: быстро, без handshake. Ключевое слово defer гарантирует закрытие соединения по завершении функции:

			// Создаём UDP-соединение
conn, err := net.Dial("udp", address)
if err != nil {
    return err
}
defer conn.Close()
		

Отправляем Magic Packet в сеть через conn.Write. Если функция возвращает nil — пакет ушёл в сеть. Получил ли его компьютер и включился ли — WOL не сообщает, это ограничение протокола:

			// Отправляем Magic Packet
_, err = conn.Write(mp)
if err != nil {
    return err
}
return nil
		

Полный рабочий код обеих функций и готовую утилиту командной строки можно найти на GitHub: xaner4/Gowakeup. Типичный вызов после сборки — ./gowakeup -mac AA:BB:CC:DD:EE:FF.

Часто задаваемые вопросы
1
Можно ли включить компьютер через WOL из интернета?

Напрямую — нет, WOL работает только в пределах одной локальной сети или VLAN. Для удалённого включения через интернет нужен промежуточный узел в этой сети: например, Raspberry Pi, роутер с поддержкой WOL или VPN до локальной сети.

2
Нужно ли, чтобы компьютер был полностью выключен?

Не обязательно. WOL способен работать при нескольких состояниях питания: сон (S3), гибернация (S4) и полное выключение (S5). Поддержка S5 зависит от BIOS — некоторые платформы будят систему только из сна или гибернации. Главное — компьютер должен быть подключён к питанию, а сетевой адаптер — активен в режиме ожидания.

3
Почему Magic Packet не доходит до компьютера?

Частые причины: WOL не включён в BIOS или UEFI; функция не активирована в настройках ОС для сетевого адаптера; компьютер подключён по Wi-Fi без поддержки WoWLAN; broadcast блокирует сетевое оборудование или NAT на роутере. Проверьте настройки BIOS, драйвер сетевой карты и правила файрвола.

4
Какой порт использовать для Magic Packet?

Де-факто стандарт — порт 9 (Discard Protocol). Реже встречаются 7 и 0. Сетевая карта проверяет содержимое фрейма, а не порт, поэтому на практике работает любой из трёх — выбор порта не влияет на результат.

5
Зачем MAC-адрес повторяется именно 16 раз?

Это требование стандарта WOL для надёжного обнаружения пакета сетевой картой. Многократное повторение гарантирует, что даже при небольших помехах в кадре сетевой интерфейс распознает Magic Packet и корректно идентифицирует целевой MAC-адрес.

Выводы

Wake-on-LAN — простой и элегантный протокол канального уровня. Всего 102 байта — и компьютер включается по сети без дополнительной инфраструктуры. Ограничения (только Ethernet, только локальная сеть, нет подтверждения) — следствие намеренной простоты протокола: он работает даже тогда, когда ОС не загружена. В отличие от устаревших сетевых стеков, которые ядро Linux постепенно отбрасывает, WOL остаётся в строю уже третье десятилетие.

Реализация на Go показывает, как стандартная библиотека net и базовые операции со строками позволяют собрать рабочий сетевой инструмент в нескольких десятках строк. Готовый проект: github.com/xaner4/Gowakeup. Исходная статья: blog.xaner.dev.