1<table width="100%"> 2<tbody> 3<tr> 4<td width="33%"><a href="../rshdown/" title="rshdown">← Previous</a></td> 5<td><a href="../Home/#programs" title="Programs table of contents">↑ Programs TOC</a></td> 6<td width="33%"><a href="../dkwt%20dkwtadm/" title="dkwt dkwtadm">→ Next</a></td> 7</tr> 8</tbody> 9</table> 10 11# rshdown — Remote shutdown 12 13[TOC] 14 15<a name="synopsis" id="synopsis"></a> 16## Synopsis 17 18For the host _receiving_ the shutdown packet: 19~~~ 20rshdown [-c _configfile_] 21~~~ 22 23For the host _sending_ the shutdown packet: 24~~~ 25rshdown -s [-n _number_] [-l _port_] [-b] _host_ _port_ _file_ 26~~~ 27 28--- 29 30<a name="description" id="description"></a> 31## Description 32 33If a server is shut down by the uninterruptable power supply (UPS) it might be a good idea to shut down all the clients requiring server resources before shutting down the server itself as the clients may hang if the server is not available. 34Especially NFS clients should be shut down before shutting down the NFS server. 35 36Rshdown is: 37 38* A SysV style daemon waiting for a shutdown data packet and 39* a client to send a shutdown data packet to one or multiple rshdown daemons. 40 41The shutdown sender (the client) and the shutdown recipients (daemons) have a pre-shared secret (a file containing up to 1460 bytes of random data distributed between the involved computers on a secure channel). 42 43To initiate a remote shutdown the sender reads the data from it's copy of the file and sends an UDP packet containing the data to the recipients. 44 45The recipients wait for incoming UDP data packets on a specified port. Incoming packets on this port are checked for sender address, sender port and packet contents. On successful check the recipient shuts down. 46 47--- 48 49<a name="options" id="options"></a> 50## Options 51 52Option / Argument|Purpose 53-----------------|------- 54-c _file_|Configuration file name for the daemon. 55-s|Send data. This option runs the sender functionality. If -s is omitted, the program will run as recipient (daemon) and wait for incoming data packets. 56-l _number_|Local port number for the sender to use. 57-b|Initialize the socket to send broadcast packets. Specify a broadcast address for the recipient host. 58_host_|Recipients address as host name, IPv4 or IPv6 address. When specifying broadcast addresses like 255.255.255.255 or 192.0.2.255 you have to use the -b option to enable broadcast sending. 59_port_|Port number the recipient ist listening on. 60_file_|Path name of file containing the pre-shared secret. 61--help|Show short help text. 62--version|Show version information. 63--license|Show license information. 64 65--- 66 67<a name="exitstatus" id="exitstatus"></a> 68## Exit status 69 700 on success, all other status codes indicate an error. 71 72--- 73 74<a name="environment" id="environment"></a> 75## Environment 76 77Rshdown uses the _system()_ function to run the command specified in the configuration file. This function passes the given command to the /bin/sh shell. So all environment variables relevant for /bin/sh are relevant for rshdown running as daemon too. 78 79--- 80 81<a name="files" id="files"></a> 82## Files 83 84### Server configuration file 85 86The default configuration file name ${sysconfdir}/rshdown/rshdown.conf 87can be overwritten by the -c option. 88 89Lines beginning with the raute character "#" are comments lines. 90 91Each line contains one _key_=_value_ pair. 92 93The following lines can be used: 94 95Line|Purpose 96----|------- 97sender=_address_<br>sender=_address_/_mask_|IP address(es) we accept packets from. Optional, no default. 98sender port = _port_|Port number on sender. Optional, default 0 accepts any sender port. 99receiver port = _port_|Local port number to read UDP packets. Required, no default. 100file = _path_|Full path name of file containing the pre-shared secret. 101signal = _number_|Signal number (preferred) or name. The signal specified here is sent to process 1 (init) to initiate a shutdown if an acceptable shutdown packet was received unless a command to execute is specified (see below). Optional, default: SIGPWR. 102command = _command_|Command to execute if an acceptable shutdown packet was received, overwrites any specified signal number. Optional, no default. The keys "signal" and "command" are mutually exclusive. 103syslog facility = _name_|Name of syslog facility. Optional, default "auth". 104debug = _boolean_|Write additional debug messages to syslog for discarded packets. 105 106--- 107 108<a name="restrictions" id="restrictions"></a> 109## Restrictions 110 111**The contents of the secret file is sent unencrypted.** 112 113**After an emergency shutdown you should replace it by a new file on all involved machines to avoid denial of service attacks using the sniffed file!** 114 115An emergency shutdown due to power failure and UPS battery running low should be as fast as possible for both the server and the clients. So I decided to do notification using UDP packets including sending the notification packet to a broadcast address for several reasons: 116 117* Using TCP connections would require timeout mechanisms for connect and send operations resulting in a longer time needed on the server connected to the UPS. 118* Opening multiple TCP connections at same time would result in multiple processes on the server and a higher resource usage. This is not a good idea because the server might need these resources to cleanly shut down all server processes as fast as possible. 119* A challenge/response mechanism would reduce the risk of replay attacks leading to denial of service but require a TCP connection to each recipient and the cryptographic operations would result in additional CPU load and computing time. 120 121 122--- 123 124<a name="notes" id="notes"></a> 125## Notes 126 127This program uses DK libraries version 4. 128 129It is not available on the Windows platform. 130 131This is a simple program: All texts are shown in English, the program is not relocatable. 132 133--- 134 135<a name="examples" id="examples"></a> 136## Examples 137 138<ul> 139<li><b>Generate pre-shared secret file:</b> 140<pre> 141touch /etc/rshdown/secret 142chmod 600 /etc/rshdown/secret 143dk-pwgen -b -l 1450-1460 > /etc/rshdown/secret 144chmod 600 /etc/rshdown/secret 145</pre> 146On Windows systems the -b option for dk-pwgen is not available, replace 147the dk-pwgen line by 148<pre> 149dk-rand -b 1460 > /etc/rshdown/secret 150</pre> 151<br> 152</li> 153<li><b>Use scp to copy secret file (on destination machine):</b> 154<pre> 155mkdir -p /etc/rshdown 156chmod 755 /etc/rshdown 157touch /etc/rshdown/secret 158chmod 600 /etc/rshdown/secret 159scp <i>user</i>@<i>host</i>:/etc/rshdown/secret /etc/rshdown/secret 160chmod 600 /etc/rshdown/secret 161</pre> 162<br> 163</li> 164<li><b>Generate /etc/rshdown/rshdown.conf file on recipient hosts:</b> 165<pre> 166# Allowed sender address 167sender = 192.0.2.100 168 169# Allowed sender port (any if not specified here) 170sender port = 1234 171 172# Local UDP port we are using 173receiver port = 1234 174 175# File containing data to compare against packet contents 176file = /etc/rshdown/secret 177 178# Signal number to send to init process 179# Only used if no command specified below 180signal = sigpwr 181 182# Command to execute on arrival of shutdown packet 183# The command should return immediately (so you can run a task in background) 184# NOTE: The shutdown command differs between operating systems. 185# I.e. on Solaris you would use "shutdown -i0 -g0 -y" instead. 186command = /sbin/shutdown -h now > /dev/null 2>&1 & 187 188# Syslog facility used by daemon 189syslog facility = auth 190 191# Flag: Enable/disable debug messages in syslog for discarded packets 192debug = off 193</pre> 194<br> 195</li> 196<li><b>On the recipients: Create the /etc/init.d/rshdn file.</b><br> 197The contents of the file is system-dependant, the examle file was derived 198from typical start scripts on Scientific Linux systems and 199<i>not tested</i>.<br> 200You should make it looking like other init scripts on your system.<br> 201<b>This template file may need modifications before you use it!</b><br> 202<pre> 203#!/bin/sh 204# 205# "$Id: rshdn.sh,v 1.10 2016/03/01 13:49:00 dirk Exp $" 206# 207# Startup/shutdown script for the remote shutdown daemon 208# 209# Linux chkconfig stuff: 210# 211# chkconfig: 2345 17 83 212# description: Startup/shutdown script for the remote shutdown daemon 213# 214# Copyright 2016 by Dirk Krause, all rights reserved. 215# 216# Redistribution and use in source and binary forms, with or without 217# modification, are permitted provided that the following conditions are met: 218# 219# * Redistributions of source code must retain the above copyright notice, 220# this list of conditions and the following disclaimer. 221# * Redistributions in binary form must reproduce the above copyright 222# notice, this list of conditions and the following disclaimer in the 223# documentation and/or other materials provided with the distribution. 224# * Neither the name of the Dirk Krause nor the names of contributors may be 225# used to endorse or promote products derived from this software without 226# specific prior written permission. 227# 228# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 229# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 230# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231# ARE DISCLAIMED. 232# 233# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY 234# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 235# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 236# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 237# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 238# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 239# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 240# 241### BEGIN INIT INFO 242# Provides: rshdn 243# Required-Start: $syslog $local_fs 244# Required-Stop: $syslog $local_fs 245# Default-Start: 2 3 4 5 246# Default-Stop: 0 1 6 247# Short-Description: The remote shutdown daemon 248# Description: The remote shutdown daemon 249### END INIT INFO 250 251# Source function library. 252# ------------------------ 253 254# Found on Scientific Linux 255[ ! -x /etc/rc.d/init.d/functions ] || . /etc/rc.d/init.d/functions 256 257# Found on Debian 258[ ! -x /lib/lsb/init-functions ] || . /lib/lsb/init-functions 259 260DAEMON=rshdown 261exec=/usr/bin/rshdown 262prog=rshdown 263config=/etc/rshdown/rshdown.conf 264lockfile=/var/lock/subsys/rshdown 265 266check() { 267 # Check that we're a privileged user 268 [ `id -u` = 0 ] || exit 4 269 270 # Check if executable is available 271 [ -x $exec ] || exit 5 272} 273 274start () { 275 check 276 [ -f $config ] || exit 6 277 278 echo -n $"Starting $prog: " 279 280 # start daemon 281 ${exec} 282 RETVAL=$? 283 echo 284 [ $RETVAL = 0 ] && touch $lockfile 285 286 return 0 287} 288 289stop () { 290 check 291 292 # stop daemon 293 echo -n $"Stopping $prog: " 294 killproc $DAEMON 295 RETVAL=$? 296 echo 297 [ $RETVAL = 0 ] && rm -f $lockfile 298 return 0 299} 300 301restart() { 302 stop 303 start 304} 305 306case $1 in 307 start) 308 start 309 ;; 310 stop) 311 stop 312 ;; 313 restart) 314 restart 315 ;; 316 condrestart|try-restart) 317 [ -f $lockfile ] && restart || : 318 ;; 319 reload) 320 echo -n $"Reloading $prog: " 321 restart 322 RETVAL=$? 323 echo 324 ;; 325 force-reload) 326 echo -n $"Reloading $prog: " 327 restart 328 echo 329 ;; 330 status) 331 status -l $(basename $lockfile) $DAEMON 332 RETVAL=$? 333 ;; 334 restartlog) 335 stop 336 start 337 ;; 338 *) 339 340 echo $"Usage: $prog {start|stop|restart|restartlog|condrestart|try-restart|reload|force-reload|status}" 341 exit 2 342esac 343 344exit $RETVAL 345</pre> 346<br> 347</li> 348<li><b>On the recipients: Create symbolic links for different runlevels</b><br> 349The details here are system-specific.<br> 350When changing from runlevel <i>old</i> 351to <i>new</i> some *x systems like Solaris execute the 352/etc/rc<i>old</i>.d/K<i>XYname</i> and /etc/rc<i>new</i>.d/S<i>XYname</i> 353scripts, the K… scripts are used from the directory for the run-level 354we are leaving.<br> 355Other systems - i.e. Linux - execute 356/etc/rc<i>new</i>.d/K<i>XYname</i> and /etc/rc<i>new</i>.d/S<i>XYname</i>, 357the K… scripts are used from the directory for the run-level 358we are entering.<br> 359On Linux 360<pre> 361chkconfig rshdn on 362</pre> 363should create the correct symlinks. 364<br> 365</li> 366<li><b>On the sender: Create start script and symbolic links</b><br> 367These files are system-specific again.<br> 368<b>This template file needs modifications before you use it, at least 369in the CONFIGURATION section!</b><br> 370<pre> 371#!/bin/sh 372# 373# "$Id: rshdn.sh,v 1.10 2016/03/01 13:49:00 dirk Exp $" 374# 375# Startup/shutdown script for the remote shutdown daemon sender 376# 377# Linux chkconfig stuff: 378# 379# chkconfig: 2345 18 82 380# description: Startup/shutdown script for the remote shutdown daemon sender 381# 382# Copyright 2016 by Dirk Krause, all rights reserved. 383# 384# Redistribution and use in source and binary forms, with or without 385# modification, are permitted provided that the following conditions are met: 386# 387# * Redistributions of source code must retain the above copyright notice, 388# this list of conditions and the following disclaimer. 389# * Redistributions in binary form must reproduce the above copyright 390# notice, this list of conditions and the following disclaimer in the 391# documentation and/or other materials provided with the distribution. 392# * Neither the name of the Dirk Krause nor the names of contributors may be 393# used to endorse or promote products derived from this software without 394# specific prior written permission. 395# 396# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 397# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 398# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 399# ARE DISCLAIMED. 400# 401# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY 402# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 403# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 404# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 405# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 406# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 407# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 408# 409### BEGIN INIT INFO 410# Provides: rshdn 411# Required-Start: $syslog $local_fs 412# Required-Stop: $syslog $local_fs 413# Default-Start: 2 3 4 5 414# Default-Stop: 0 1 6 415# Short-Description: The remote shutdown daemon sender 416# Description: The remote shutdown daemon sender 417### END INIT INFO 418 419# Source function library. 420# ------------------------ 421 422# Found on Scientific Linux 423[ ! -x /etc/rc.d/init.d/functions ] || . /etc/rc.d/init.d/functions 424 425# Found on Debian 426[ ! -x /lib/lsb/init-functions ] || . /lib/lsb/init-functions 427 428DAEMON=rshdown 429exec=/usr/bin/rshdown 430prog=rshdown 431config=/etc/rshdown/rshdown.conf 432 433 434 435# ##### CONFIGURATION SECTION START 436 437# Indicator for planned shutdown (not due to power failure). 438# If this file is present, not shutdown message is sent. 439INDICATOR=/etc/rshdown/planned-shutdown 440 441# Destination address, hostname, IPv4 or IPv6 address or IPv4 broadcast address 442DESTHOST=192.0.2.255 443 444# Destination port number. 445DESTPORT=1234 446 447# Local port number used when sending. 448LOCALPORT=1234 449 450# Data file containing the pre-shared secret. 451DATAFILE=/etc/rshdown/secret 452 453# ##### CONFIGURATION SECTION END 454 455 456 457check() { 458 # Check that we're a privileged user 459 [ `id -u` = 0 ] || exit 4 460 461 # Check if executable is available 462 [ -x $exec ] || exit 5 463} 464 465start () { 466 check 467 [ -f $config ] || exit 6 468 469 echo -n $"Starting $prog: " 470 471 [ ! -f ${INDICATOR} ] || rm -f ${INDICATOR} 472 RETVAL=0 473 echo 474 475 return 0 476} 477 478stop () { 479 check 480 481 # stop daemon 482 echo -n $"Stopping $prog: " 483 [ -f ${INDICATOR} ] || ${exec} -s -l ${LOCALPORT} -b ${DESTHOST} ${DESTPORT} ${DATAFILE} 484 RETVAL=$? 485 echo 486 return 0 487} 488 489 490case $1 in 491 start) 492 start 493 ;; 494 stop) 495 stop 496 ;; 497 restart) 498 ;; 499 condrestart|try-restart) 500 ;; 501 reload) 502 echo -n $"Reloading $prog: " 503 RETVAL=0 504 echo 505 ;; 506 force-reload) 507 echo -n $"Reloading $prog: " 508 RETVAL=0 509 echo 510 ;; 511 status) 512 RETVAL=0 513 ;; 514 restartlog) 515 RETVAL=0 516 ;; 517 *) 518 519 echo $"Usage: $prog {start|stop|restart|restartlog|condrestart|try-restart|reload|force-reload|status}" 520 exit 2 521esac 522 523exit $RETVAL 524</pre> 525<br> 526</li> 527</ul> 528 529--- 530 531<a name="author" id="author"></a> 532## Author 533 534Dirk Krause 535 536<table width="100%"> 537<tbody> 538<tr> 539<td width="33%"><a href="../rshdown/" title="rshdown">← Previous</a></td> 540<td><a href="../Home/#programs" title="Programs table of contents">↑ Programs TOC</a></td> 541<td width="33%"><a href="../dkwt%20dkwtadm/" title="dkwt dkwtadm">→ Next</a></td> 542</tr> 543</tbody> 544</table> 545 546