Как удалённо выключить компьютер под управлением ОС Linux?
Друзья, подскажите, пожалуйста, как поизящнее удалённо выключить компьютер под управлением ОС Linux с компьютера под управлением Windows? На случай аварийной ситуации на объекте :-(. Виндоусовские компьютеры выключает задача в планировщике задач, когда детектирует запись определённого события в протокол приложений ОС. Есть ли что-нибудь подобное в Linux? Или предложите, пожалуйста, какое-нибудь решение. Как пример - резидентое приложение, которое периодически проверяет наличие определённого файла и при его появлении останавливает систему (могу такое сделать).
Ответы (5 шт):
Можно воспользоваться утилитой Plink (PuTTY Link), она поддерживает опции командной строки для ввода пользователя и пароля ssh-сессии
plink -ssh -t -l <user> -pw <password> -batch <user>@<server_address> shutdown -h now
у винды начиная с win10 есть встроенный SSH (OpenSSH) так что проще всего будет воспользоваться им, также для надёжности настраиваем доступ по ключу а не по паролю.
для выключения скармливаем команду:
ssh <poweroff_user>@<hostname> 'sudo systemctl poweroff'
ну а на целевом линуксе в файле /etc/sudoers прописываем для sudo возможность выключать без запроса на ввод пароля :
<poweroff_user> ALL =NOPASSWD: /usr/bin/systemctl poweroff
где <poweroff_user> и < hostname> заменяем на свои
Fail2ban
Слова "протокол приложений ОС" - очень напоминают syslog. Если есть такое событие в журналах ОС, то есть специальная программа fail2ban которая читает журнал и выполняет действия.
Агент
Можно запустить маленького агента:
#!/bin/bash
nc -u -l -k 0.0.0.0 4546 | \
while read line; do
if [ "x$line" = "xachtung" ]
then
echo systemctl poweroff -i
fi
done
и если послать с другого компа бродкаст командой
echo achtung | nc -u -b -w1 192.168.0.255 4546
то выполнится команда echo systemctl poweroff -i
nc в виндовс нет, но можно скачать с оф.сайта. а также можно использовать System.Net.Sockets в powershell.
предложите, пожалуйста, какое-нибудь решение
Т.к. не озвучено ни дистр. Linux, ни службы которые слушают, ни условия события предлагаю вариант выполнения команды poweroff, при событии неправильной аутентификации службы sshd, можно использовать любое другое событие, другой службы, важно чтобы это событие фиксировалось в журнал systemd. Запускаете скрипт как вам нравится, в фоне, при запуске, как службу в общем ваше решение, но только от суперпользователя
#!/bin/bash
# Читаем поток journalctl -f построчно
journalctl -f | while read -r line; do
# Здесь можно анализировать строку $line, например, искать ошибки
if echo "$line" | grep -q "87d788566ebdf4ef9469df4861d2988f"; then
poweroff
# Можно добавить другие действия, например, отправку уведомления
fi
done
В windows 10 и выше, есть встроенный ssh клиент, достаточно выполнить команду ssh 87d788566ebdf4ef9469df4861d2988f@address_ssh
условие сработает, естественно что в системе не должно быть пользователя 87d788566ebdf4ef9469df4861d2988f -это срока от фонаря длина имени пользователя до 256 символов.
Проверил работает Debian GNU/Linux 12 (bookworm)
ну раз пошла такая пьянка вот еще один вариант
Принцип довольно простой, нужно "постучаться пингом" в нужную нам "дверь" определённым образом, а на это за дверью должен сработать механизм и выполнить нужное нам действие.
Назовём его - "Cтук Леона" так как его принцип я взял из фильма "Леон", это тогда когда в квартиру ломился спецназ но вот верного кода(стука в дверь) они не знали за что в итого и поплатились. Если кто забыл то там было - два стука, один стук, два стука.
В общем, для наглядности пусть 192.168.1.13 это то куда мы стучимся, а 192.168.1.2 это тот кто стучит.
Команда стука 212:
ping -c2 192.168.1.13 && sleep 2 && ping -c1 192.168.1.13 && sleep 2 && ping -c2 192.168.1.13
минимальная пауза между стуками 1 секунда, долгая 2 секунды
На усыпляемом объекте, нам необходимо слушать кто там стучится снаружи, а для этого нам нужно слушающая программа, здесь мы будем использовать tcpdump хотя по идее для этих целей можно использовать тот же iptables
sudo tcpdump -ntt ip proto \\icmp -l | awk -v ip1="192.168.1.2" -v ip2="$(hostname -i)" -F. '$0 ~ "IP "ip1" > "ip2": ICMP echo request" {x=$1-p;if(x<3) {sum=sum""x;if(sum==1221){S=" --> BINGO";system("date")} else S="";print x " --> " sum""S} else {print 0;sum=""}}{p=$1}'
это черновой вариант с выводом примерно следующего
0
1 --> 1
2 --> 12
2 --> 122
Чт 24 апр 2025 05:18:58 EEST
1 --> 1221 --> BINGO
0
1 --> 1
2 --> 12
0
1 --> 1
1 --> 11
0
1 --> 1
2 --> 12
2 --> 122
Чт 24 апр 2025 05:35:26 EEST
1 --> 1221 --> BINGO
здесь мы ловим и замеряем интервал между пингами от определённого хоста, если интервал больше 2-х секунд то пишем ноль, если 1 и 2 секунды то оставляем эту же разницу, параллельно мы конкатенируем эти значения пытаясь словить нужную нам последовательность 1221, ноль обрывает последовательность.
1221 это интервалы между стуками 212 --> |_|__|__|_|
по итогу вместо date вставляем выключалку и подчищаем принты, получим:
sudo tcpdump -ntt ip proto \\icmp -l | awk -v ip1="192.168.1.2" -v ip2="$(hostname -i)" -F. '$0 ~ "IP "ip1" > "ip2": ICMP echo request" {x=$1-p;if(x<3) {sum=sum""x;if(sum==1221)system("systemctl poweroff");else S=""} else sum=""}{p=$1}'