ZEDAT ZEDAT UPS Daemon (ZUPS)
Home » Documentation

Documentation

Manual Pages

Mini-HOWTO

The following Mini-HOWTO should give you an idea on how to install and configure ZUPS. ZUPS uses external commands for shutting down hosts and can be configured to call arbitrary commands in order to check something else than the status of UPS devices. Therefore, it could be used in various ways. However, this HOWTO describes how to use ZUPS for shutting down remote hosts via SSH in case of power outage. Obviously, this assumes you have an SSH daemon running on each of the remote systems (on Microsoft® Windows™ systems, you could use copSSH, for example). Also note that, using the following setup, ZUPS will be run by root and remote shutdown commands would be executed by logging in as root on the remote system(s). If you want to run ZUPS without superuser privileges, see the notes below and adjust the HOWTO instructions accordingly.

  1. Give ZUPS access to the remote systems. On the machine which will be running ZUPS, run the following command as root to generate an SSH key and confirm the questions by pressing <Enter> in order to accept the defaults and to set an empty passphrase:
    # ssh-keygen
    Make sure PermitRootLogin is set to yes within the /etc/ssh/sshd_config file on each remote system which should be shut down by ZUPS in case of power outage. Then, copy the SSH pubkey over to the remote systems and add it to the list of authorized keys:
    # ssh-copy-id remote.example.com
    Now, logging in via SSH should work without being prompted for a password:
    # ssh remote.example.com
  2. Check the requirements. The Net-SNMP library (version 5.0.5 or newer) is required on the system running ZUPS. During the installation of ZUPS, the Net-SNMP header files are also needed. They are often found in some separate Net-SNMP-development package. For example, on Debian it's called libsnmp5-dev, so in this case, the following command should install the necessary files:
    # apt-get install libsnmp5-dev
  3. Install ZUPS. Usually, the following commands should do:
    $ wget http://www.zups.sw.fu-berlin.de/download/zups-1.1.tar.gz
    $ tar xzvf zups-1.1.tar.gz
    $ cd zups-1.1
    $ ./configure
    $ make
    $ su root -c "make install"
  4. Configure ZUPS. Open the file /usr/local/etc/zupsd.conf with your favourite editor and adjust the (commented out) example settings. A minimal configuration with a single UPS device could look like this (see the zupsd.conf(5) manual page for details):
    [general]
    shutdown_cmd = "/usr/local/libexec/shutdown-%t.sh %h"
    suicide_cmd = "/sbin/shutdown -h now power outage" # shutdown local machine
    pidfile = "/var/run/zupsd.pid" # change path if not running as root
    
    [ups]
    hostname = "ups.example.com"
    community = "public"
    alert_threshold = "10" # ALERT, if less than 10 minutes battery left
    email_cmd = "/usr/bin/printf '%b' '%m' | /usr/bin/mail -s 'ZUPS alert' %r"
    email_contact = "admin@example.com foo@example.com"
    Then, the remote systems which should be shut down by ZUPS in case of power outage must be added to the file /usr/local/etc/zupsd-hosts. For each host, some "type" and "delay" must be specified. The "type" field is used in order to allow for system-specific shutdown commands: Within the shutdown_cmd specified above, "%t" will be replaced by the "type" string prior to executing the command; and "%h" will be replaced by the hostname. That is, if you specify a "type" of linux for the host foo.example.com, the shutdown command /usr/local/libexec/shutdown-linux.sh foo.example.com would be executed. The "delay" field specifies the number of minutes ZUPS should wait before executing this command after a power outage was encountered. Therefore, the zupsd-hosts file could look like this:
    # host                                  type            delay
    # -----------------------------------------------------------
      test.example.com                      linux           1
      mail.example.com                      linux           20
    #
    # ns.example.com should be shut down only if ZUPS encountered an
    # "ALERT" condition, that is, if the UPS device is running out of
    # battery power.  We simply set the delay to a number of minutes
    # which is a lot higher than the number of minutes the UPS devices
    # will be able to run on battery.
    #
      ns.example.com                        linux           9999

    As we've specified linux as the "type" for all hosts, the only shutdown script needed with this configuration would be /usr/local/libexec/shutdown-linux.sh. A sample shutdown script is provided with ZUPS, copy it into place in order to use it:

    # mkdir -p /usr/local/libexec
    # cp /usr/local/share/zups/examples/shutdown-linux.sh /usr/local/libexec/
    # chmod 755 /usr/local/libexec/shutdown-linux.sh
  5. Starting and stopping ZUPS. In order to start and stop the ZUPS daemon manually, just copy the init script provided with ZUPS to some appropriate place and call it with the start or stop parameters:
    # cp /usr/local/share/zups/examples/zupsd-init /etc/init.d
    # chmod 755 /etc/init.d/zupsd-init
    # /etc/init.d/zupsd-init start
    # /etc/init.d/zupsd-init stop
    How to start ZUPS automatically during system boot depends on your operating system. On most Linux® and System V systems, you'd create appropriately named symlinks to zupsd-init in the desired runlevel directories, such as (depending on your system) /etc/rc2.d, /etc/rc3.d, and so on. On Debian, update-rc.d(8) can be used to create those symlinks. On BSD systems, assuming you've copied zupsd-init to the directory /usr/local/etc/rc.d, the following line can be added to /etc/rc.local in order to start ZUPS at boot time:
    test -x /usr/local/etc/rc.d/zupsd-init && /usr/local/etc/rc.d/zupsd-init start
  6. Test your setup. Use the following command in order to check the local ZUPS configuration:
    # zupsd -t
    If everything looks fine, make a copy of your zupsd-hosts file and temporarily remove all production hosts from that file, so that you can test shutting down some noncritical system(s). Assuming you've copied the zupsd-init script to /etc/init.d, such a test shutdown can be triggered using the following commands:
    # /etc/init.d/zupsd-init reload
    # /etc/init.d/zupsd-init toggle
    If that works as expected, copy your original zupsd-hosts file back into place. If you encounter any problems, the system logfiles should give some useful hints in most cases (simply grep(1) for zupsd and shutdown-linux in /var/log/*).

Running ZUPS without Superuser Privileges

In order to let an unprivileged user run ZUPS, just make sure to specify a pidfile pathname which can be created (and if needed a suicide_cmd which can be run) by this user without permission problems. If ZUPS is started using the supplied zupsd-init script, set the RUNAS variable at the top of that script to the user in question.

Apart from that, if the shutdown command should be run by some unprivileged user on the remote system (using a setuid shutdown(8) command, Sudo, or some other mechanism), ZUPS must have SSH access to this account and the REMOTE_USER variable within the shutdown-linux.sh script must be adjusted accordingly.

No matter whether or not the shutdown commands are run by root, you can easily restrict SSH access so that nothing but the shutdown command may be executed when logging in via the SSH pubkey ZUPS is using. See the description of the authorized_keys file format in the sshd(8) manual.

© ZEDAT, Freie Universität Berlin