2011-10-20 15:12:05

Включаем компьютер по сети

Linux Windows

Технология Wake-on-LAN известна давно, но применяется не часто. В моем случае встала задача включать домашний компьютер из офиса. Казалось бы все просто, но требовалось не только включить, но и понять включился-ли он в автоматическом режиме. В общем ситуация отображена на схеме:

С удаленного компьютера у меня есть доступ по SSH к моему домашнему серверу, который постоянно включен. С этого сервера будет отправляться команда на включение соседнего компьютера. Все выглядит вполне просто, пока речь не заходит о проверке, включился компьютер или нет силами того, кто его пытался включить. Но обо всем по порядку.


Wake-on-LAN

Википедия говорит нам, что сетевой адаптер управляемого компьютера находится в режиме пониженного энергопотребления, просматривая все пакеты, приходящие на его MAC-адрес, и ничего не отвечая на них. Если одним из пакетов окажется magic packet, сетевой адаптер выдаст сигнал на включение питания компьютера. Magic packet — это специальная последовательность байтов, которую для нормального прохождения по локальным сетям можно вставить в пакеты UDP или IPX. Обычно для WOL пакеты протоколов верхнего уровня рассылают широковещательно, так как в случае динамического присвоения адресов неизвестно, какой, скажем, IP-адрес соответствует какому MAC-адресу. Однако, для корректного прохождения через маршрутизатор, запрещающий широковещательные пакеты, можно послать пакет по какому-то определённому адресу. В начале пакета идет так называемая «цепочка синхронизации»: 6 байт, равных 0xFF. Затем — MAC-адрес сетевой платы, повторённый 16 раз.

На управляемом компьютере должна быть аппаратная поддержка (ну это есть у всех современных плат и сетевых карт), идеальным случаем является компьютер со встроенной сетевухой. Возможность включения по сети нужно разрешить в БИОСе в разделе Power Management. Пункт обычно называется Wake-On-Lan from Soft-off или Resume by MAC, нужно поставить Enabled.

 

Также (особенно если сетвуха не встроенная) можно поковыряться в дополнительных параметрах сетевухи через ОС. В Windows заходим в диспетчер устройств, там находим нужный сетевой адаптер, заходим в свойства и на вкладке дополнительно разрешаем Wake-On-Lan.

В случае UNIX-подобной ОС ethtool и гугль в помощь ;)

Управляющий (пробуждающий ;) скрипт 

Поскольку команда на включение будет даваться с сервера под управлением Linux (Ubuntu), то рассказ дальше пойдет про Linux. В случае Windows существует масса инструментов для включения соседних компов, как у них обстоят дела с проверкой включенности - не знаю. Также обращаю внимание, что оба компьютера находятся в одном сегменте сети.

Для начала понадобится инструмент для включения по сети - он так и называется wakeonlan.

apt-get install wakeonlan

Теперь если в консоли сказать

wakeonlan МАК:НУЖНОГО:КОМПА

он отправит magic packet и компьютер включится. Если МАК не известен, то поможет команда arp.

Теоретически, после отправки magic packet, целевой компьютер включается, загружается и все проходит успешно. На практике все выглядит немного иначе: если был длительный перебой в питании у включаемого компьютера, то он может и не среагировать на команду wake-on-lan, или он может быть просто отключен от сети, или может включиться, но не загрузиться и еще масса чего другого. Именно по этому и нужно иметь понимание о происходящем после отправки команды на включение.

Идея метода определения включился-ли компьютер заключается в следующем: мы отправляем magic packet и потом пингуем целевой комп. Если получаем ответ на пинг - считаем, что все прошло успешно. Если в течении 90 секунд (примерно столько уходило на загрузку в моем случае) ответ не получен - то решаем, что включить не удалось.

Для реализации метода мной был написан скрипт, который знает МАК включаемого компа, отправляет ему magic packet, далее в течении 90 секунд пытается найти IP а ARP таблице и пинговать его. Получилось вот так

#!/bin/bash

MAC="МАК:НУЖНОГО:КОМПА"
SEC=90

/usr/bin/wakeonlan $MAC

IP=''
n=0
while [ $n -lt $SEC ]
do
if [ $IP ]
then
ping -c 1 -q -W 1 $IP | grep '0 received'
if [ $? -gt 0 ]
then
echo "Wake OK (completed in $n seconds)"
exit 0
fi
else
sleep 1
echo "Looking for IP in ARP table ($n)"
IP=`arp | grep $MAC | awk '{ print $1 }'`
fi
n=`expr $n + 1`
done
echo "Wake failed (no response within $SEC seconds)"
exit 1

Этот скрипт выводи на экран вполне читаемые данные о своих действиях и результатах. Для меня это стало удобным инструментом.