Доброго времени суток! Всё началось с того, что работая удалённо в терминале понадобилось перезагрузить сервер. Толи день не задался, толи мысли были о чём-то другом и вместо команды:
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
&
lt
;интерфейс&
gt
;
|
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
&
lt
;интерфейс&
gt
;
wol
g
|
На многих системах эту команду приходится выполнять после перезагрузки, поэтому сделаем чтобы она выполнялась каждый раз при загрузке системы автоматически. Для этого создадим файл wakeonlan.conf следующими командами:
1
2
3
4
5
6
7
8
9
|
sudo
bash
-
c
"cat > /etc/init/wakeonlan.conf"
&
lt
;
&
lt
;
`
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 [email protected]
# 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
&
lt
;внешний
IP
адрес или доменное имя&
gt
;
&
lt
;номер
udp
порта
(в нашем случае
7
)
&
gt
;
|
Самое удивительное, с момента той нелепой ошибки, так и не приходилось использовать это, разве что только в период тесто-наладки.