Доброго времени суток читатели! Всё началось с того, что работая удалённо в терминале понадобилось перезагрузить сервер. Толи день не задался, толи мысли были о чём-то другом и вместо команды:
sudo shutdown -r now
отправил его отдыхать после нелёгкого рабочего дня, командой:
sudo shutdown now
Enter
И всё произошло машинально и так быстро, что даже сам не успел понять. Понимание стало приходить минут через 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
sudo apt-get install ethtool
после чего проверяем поддерку WOL
sudo ethtool <интерфейс> | grep Wake
выввод команды должен быть следующим
Supports Wake-on: g
Wake-on: g
это говорит о том, что сетевая карта поддерживает WOL и он включен. Если же
Supports Wake-on:
буква отличная от g, то сетевая карта не поддерживает WOL. И если он выключен
Wake-on:d
то включим его следующей командой:
sudo ethtool -s <интерфейс> wol g
На многих системах эту команду приходится выполнять после перезагрузки, поэтому сделаем чтобы она выполнялась каждый раз при загрузке системы автоматически. Для этого создадим файл wakeonlan.conf следующими командами:
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
Сделаем файл исполняемым
sudo chmod +x /etc/init/wakeonlan.conf
и запустим службу
sudo service wakeonlan start
c. на маршрутизаторе Cisco настроим пересылку WOL пакета. Для этого добавим следующие команды:
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 пакет следующего содержания:
#!/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 $hisaddrn";
$hisiaddr = inet_aton($hisaddr) || die "unknown host $hisaddr";
$hispaddr = sockaddr_in($hisport, $hisiaddr);
defined(send(SOCKET, $magicbody, 0, $hispaddr)) ||
die "send $hisaddr: $!";
сделаем скрипт исполняемым в терминале телефона
chmod +x wol.pl
запускается скрипт в терминале со следующими параметрами
./wol.pl <MAC адрес интерфейса сервера воткнутого в машрутизатор в формате XX-XX-XX-XX-XX-XX> <внешний IP адрес или доменное имя> <номер udp порта (в нашем случае 7)>
Самое удивительное, с момента той нелепой ошибки, так и не приходилось использовать это, разве что только в период тесто-наладки.
Использованная литература:
- https://help.ubuntu.com/community/WakeOnLan
- https://gist.github.com/jevinskie/721245
- https://supportforums.cisco.com/docs/DOC-14333
- https://groups.google.com/forum/?hl=en#!msg/alt.internet.wireless/h1bH7K6x1MI/-6PTCfFe-qwJ
Автор: avsavchenko