У меня есть группа серверов Linux в моей подсети, которую я хочу иметь возможность удаленного выключения с главного компьютера. Я не хочу, чтобы машины, не являющиеся ведущими, должны были заранее координировать свои действия с мастером, то есть знать его IP-адрес и т.д. Поэтому что-то, основанное на широковещательных или многоадресных сообщениях, может показаться очевидным подходом.
Я уже реализовал решение с помощью socat
но мне было интересно, есть ли лучшее, менее специализированное решение, например, с использованием одной из установленных служб, поддерживающих многоадресную передачу, таких как SNMP или Bonjour?
Мое решение заключается в следующем. На всех неосновных машинах я бегу:
$ socat UDP4-RECVFROM:6666,broadcast,fork SYSTEM:'hostname; shutdown now'
Это говорит socat
прослушивать широковещательные сообщения через порт 6666, и когда он получает сообщение, он возвращает имя хоста и выключает компьютер.
Теперь любая машина в той же подсети может завершить работу всех машин, на которых это выполняется, с помощью следующей команды (она ожидает ввода, поэтому введите что-нибудь, например, bye
):
$ socat STDOUT UDP4-DATAGRAM:255.255.255.255:6666,broadcast
bye
Это будет транслировать сообщение (в данном случае bye
), socat
затем выведет имена хостов, которые были возвращены всем машинам, которые прослушивали широковещательные сообщения через порт 6666.
Очевидно, что в этом подходе нет защиты - если какая-либо машина в той же подсети передает что-либо на порт 6666, то системы выключатся. Можно добавить простой дополнительный слой - вместо простого запуска hostname; shutdown now
можно запустить скрипт, который на самом деле проверяет, что было передано и отключается, только если видно длинное случайное число, которое должно быть известно только заинтересованным сторонам.