
Доброго времени суток! Всё началось с того, что работая удалённо в терминале понадобилось перезагрузить сервер. Толи день не задался, толи мысли были о чём-то другом и вместо команды:
1 |
sudo shutdown -r now |
отправил его отдыхать после нелёгкого рабочего дня, командой:
1 |
sudo shutdown now |
И всё произошло машинально и так быстро, что даже сам не успел понять. Понимание стало приходить минут через 15-20, после безудержных попыток подключится удалённо к терминалу. И думаю даже не стоит говорить о том как далеко находился сервер, и добраться до него было практически невозможно. После долгих телефонных разговоров и объяснений куда кому пойти, и что где нажать, сервер всё же вернулся в рабочий ритм. После чего и появилась идея о включении сервера удалённо.
И так имеем:
- Сервер с Ethernet интерфейсом с поддержкой Wake-on-LAN (далее WOL)
- Операционная система: Ubuntu Server 12.04.2 LTS
- Маршрутизатор Cisco 85/86/87/88/89x
- Мобильный телефон Nokia N9
A. Включаем/проверяем в BIOS сервера поддержку WOL
B. Включаем/проверяем поддержку WOL в Ubuntu Server
Для этого устанавливаем пакет ethtool:
1 |
sudo apt-get install ethtool |
После чего проверяем поддерку WOL:
1 |
sudo ethtool <интерфейс> | grep Wake |
Вывод команды должен быть следующим:
1 2 |
Supports Wake-on: g Wake-on: g |
Это говорит о том, что сетевая карта поддерживает WOL и он включен. Если же:
1 |
Supports Wake-on: |
Буква отличная от g, то сетевая карта не поддерживает WOL. И если он выключен:
1 |
Wake-on:d |
То включим его следующей командой:
1 |
sudo ethtool -s <интерфейс> wol g |
На многих системах эту команду приходится выполнять после перезагрузки, поэтому сделаем чтобы она выполнялась каждый раз при загрузке системы автоматически. Для этого создадим файл wakeonlan.conf следующими командами:
1 2 3 4 5 6 7 8 9 |
sudo bash -c "cat > /etc/init/wakeonlan.conf" <<`EOF` start on started network script for interface in $(cut -d: -f1 /proc/net/dev | tail -n +3); do logger -t `wakeonlan init script` enabling wake on lan for $interface ethtool -s $interface wol g done end script |
Сделаем файл исполняемым:
1 |
sudo chmod +x /etc/init/wakeonlan.conf |
И запустим службу:
1 |
sudo service wakeonlan start |
C. На маршрутизаторе Cisco настроим пересылку WOL пакета. Для этого добавим следующие команды:
1 2 3 4 5 |
interface X ip directed-broadcast ! ! ip nat inside source static udp a.b.c.255 7 interface Y 7 |
Где:
- interface X — локальный интерфейс (ip nat inside)
- interface Y — внешний интерфейс (ip nat outside)
D. На телефон Nokia N9 добавим perl скрипт создающий WOL пакет следующего содержания:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#!/usr/bin/perl -w # wol.pl, written 20031220 by Walter Roberson robe...@ibd.nrc-cnrc.gc.ca # this program constructs a WOL (Wake on Lan) packet suitable for # sending locally or over a net. The MAC of the system to be woken # is required. # # The IP address the user supplies should NOT be # the IP address of the system to be woken: instead it should be the # subnet directed broadcast IP (e.g., 192.168.1.255) of any subnet # known to be present on the segment of the target system. This # would usually be the directed broadcast IP of the target system itself, # but need not be in cases of multiple subnets that aren`t carefully # VLAN`d away from each other. # # To repeat: do NOT use the IP address of the target system. Not unless # you are on the same subnet and you are using a static ARP entry. # The target system is asleep, so it isn`t going to answer an ARP # from a router trying to find that particular address. Use a # broadcast address, or some other packet forwarding trick. use strict; require 5.002; use Socket; use Sys::Hostname; my ( $hisiaddr, $hispaddr, $hisMACtext, $hisaddr, $hisport, $proto, @MACbytes, $hisMACbin, $magicbody ); die "Syntax: $0 MAC ipaddr [port]" if @ARGV < 2; $hisMACtext = shift @ARGV; $hisaddr = shift @ARGV; $hisport = shift @ARGV || 22357; # default `WU`, no significance $magicbody = "xff" x 6; @MACbytes = split /[:-]/, $hisMACtext; die "MAC wrong size" unless @MACbytes == 6; $hisMACbin = pack "H*H*H*H*H*H*", @MACbytes; $magicbody .= $hisMACbin x 16; $proto = getprotobyname(`udp`); socket(SOCKET, PF_INET, SOCK_DGRAM, $proto) || die "socket: $!"; $| = 1; print "WOL packet being sent to udp port $hisport of ip $hisaddr "; $hisiaddr = inet_aton($hisaddr) || die "unknown host $hisaddr"; $hispaddr = sockaddr_in($hisport, $hisiaddr); defined(send(SOCKET, $magicbody, 0, $hispaddr)) || die "send $hisaddr: $!"; |
Сделаем скрипт исполняемым в терминале телефона:
1 |
chmod +x wol.pl |
Запускается скрипт в терминале со следующими параметрами:
1 |
./wol.pl <внешний IP адрес или доменное имя> <номер udp порта (в нашем случае 7)> |
Самое удивительное, с момента той нелепой ошибки, так и не приходилось использовать это, разве что только в период тесто-наладки.