Synopsis

guardcat [config-directives]

Description

guardcat is a watchdog program intended to monitor sensor readings provided by the "hwmon" interface of the Linux kernel. It can also read values from external programs. It can raise alerts if the readings go outside of limits you define. Alerts can be indicated using syslog(3), mail(1), and/or wall(1). It can log sensor readings to a data log file periodically. It can control fan speed in response to temperature inputs. All these features are optional and configurable.

Using guardcat to control your fans may damage your hardware. There is NO WARRANTY or assumption of liability. Use it strictly AT YOUR OWN RISK. See the section on WARNINGS below for more. There may also be security implications; see the SECURITY section.

Invocation

guardcat is a Perl script intended to be run as a daemon. It does not automatically fork; you will need to background it yourself, or use a daemon control facility such as inittab(5) or systemd(8). A suitable systemd service unit is provided with the guardcat package. It can also be run in the foreground, which is useful mainly for debugging.

Command-line arguments to guardcat are configuration directives, as described in guardcat.conf(5). If no such areguments are given, the default configuration file is read, instead. If neither are present, guardcat aborts.

Configuration

guardcat requires a user-specified configuration to run. Configuration directives can be supplied on the command-line, or using a configuration file (/etc/guardcat.conf by default), or both. Using a file is the recommended method.

The configuration must define the inputs you want to monitor. It can optionally define alarms, outputs, logging, and other parameters, as well. Thee guardcat.conf(5) for the available configuration directives and their usage.

To alter the configurarion of a running guardcat instance, you must restart the guardcat program.

Theory of Operation

Polling Loop

Guardcat runs a polling loop that consists of:

  1. Read inputs (sensors)

  2. Transform input values

    1. Scaling (mult option)

    2. Shifting (offset option)

    3. Celsius to Fahrenheit conversion (temp and america options)

    4. Rounding

    5. Normalization

    6. Aggregation

  3. Write outputs (fan speeds), if configured

  4. Check alarm limits and raise alerts

  5. Write sensor values to data log, if appropriate (per logint)

  6. Sleep for the poll interval (pollint)

  7. Repeat

Fan Control

When configured for fan control, guardcat sets the output in direct proportion to the controlling sensor input. For example, if you have defined a sensor with a range from 20 to 40, and the sensor is read at 30, then guardcat will set any corresponding output to 50%. If the output range was configured as from 30 to 255, 50% would result in 113 being written.

By adjusting the input (temperature) range, one can fine-tune how aggressive the fan response is to that input. Lowering the hi value will result in the fan speed increasing sooner. Raising the hi value will cause the fan speed to increase more slowly.

For aggregate channels, the normalized values of the inputs are the ones considered when used to control an output. So, for a max aggregate, given two inputs, one reading 39 with range 20 to 40 (95%), and the other reading 45 with range 20 to 80 (42%), any output would be set to 95% (despite 45 being larger than 39).

In the future, more sophisticated control algorithms and mechanisms may be offered. (Patches welcome!)

Invalid Readings

If any sensor value cannot be read, or cannot be interpreted as a number, that input channel will be considered invalid for that poll cycle. This could happen if a path is specified incorrectly, a device is removed while running, permission is denied, an external program fails, or any number of other problems.

guardcat will continue to try and read the channel with each poll cycle, as problems may be temporary and be resolved during the program run.

If data logging is configured for an invalid channel, it will be logged as -1 (negative one). This has the advantage of being obviously bad, while still being plottable or otherwise processed by external utilities.

If an output depends on an invalid channel, the output will be set to its maximum value (i.e., fan at highest speed).

If an invalid channel is being used as part of an aggregate input, it will be ignored for purposes of computing the absolute reading (i.e., the value displayed or logged), but the maximal normalized reading (100%) from the invalid channel will be propagated to any outputs. Thus, the data log for an aggregate will reflect available data, ignoring bad channels, while fans will still be forced to maximum.

Signals

Like most daemon-type programs, guardcat will trap termination signals (SIGTERM, SIGINT, etc.), perform a graceful shutdown, and then exit. In particular, it will process exit config directives, which (if one is using guardcat for fan control) should reset fans to maximum. It will also try to do the same on abort signals (SIGSEGV, etc.).

Aside from the above, guardcat recognizes the following operational signals:

SIGHUP

Upon receipt of SIGHUP, guardcat will close any data log file, and then re-open it with the same name. The header will be written again. Logging will then resume as before. If no data log is configured, the signal does nothing.

This is intended for log rotation scenarios. The active log can be safely moved to a new name/directory, and then SIGHUP sent to create a new log file at the original name and location.

SIGUSR1

Upon receipt of SIGUSR1, guardcat will immediately perform a full poll cycle (including any slow inputs), and log the resulting values to any data log. When debugging is enabled, guardcat will also dump its internal state.

Intended for use when someone is following the data log (perhaps with tail(1) and the -f switch), and wants to see current values immediately.

SIGUSR2

Toggles debugging on and off. Debugging dumps gobs of information to stderr and/or syslog LOG_DEBUG, and is generally only useful if you are familiar with the program internals. See also the "debug" directive in guardcat.conf(5).

Warnings

Using guardcat to control your fans may damage your hardware. There is NO WARRANTY or assumption of liability. Use it strictly AT YOUR OWN RISK.

If you are using guardcat for fan control, the proper cooling of your hardware will depend on how you configure guardcat. Improper cooling can result in high component temperatures, stressing the components, and possibly causing premature failure (immediately, or over time).

If guardcat crashes, and appropriate exit directives were not configured, or guardcat fails to process them, the system may be left without fan control. If system load or heat then increases, it may result in overheating.

If an input file (sensor) blocks while guardcat is trying to read it, guardcat will hang, waiting for the data. This isn’t supposed to happen, but a kernel bug or malfunctioning sensor chip may cause unexpected problems. In such a hung state, guardcat will not adjust any fans, nor raise any alerts. This could be worse than a crash, since a crash might at least process exit directives. The same scenario applies to an external program (prog inputs) which does not produce output in a timely matter.

See also the warnings in the SECURITY section.

Security

In order to adjust fan speeds, guardcat will need to be run as root.

If guardcat is running as root, it of course has the highest privilege. Any privileged process warrants a higher level of security concern.

Exposures

By design, the guardcat config file can be used to tell guardcat to write an arbitrary value to an arbitrary file, or run an arbitrary program with arbitrary arguments. If running privileged, it is a very short step from this, to taking total control of the system, or simply rendering it unusable. (For example, overwriting the /etc/passwd or /vmlinuz files, or something less obvious.)

Specifics: The "logfile", "init", "exit", and "outputs" directives all specify files to write to. The "init" and "exit" directives additionally specify an arbitrary value to be written. The "prog" input type runs an external program.

Config File Permissions

The config file should thus be protected from modification by anyone other than fully trusted users. Appropriate ownership and permissions are most likely root/root with mode 600. Typical commands to do so would be:

chown root:root /etc/guardcat.conf
chmod u=rw,og=  /etc/guardcat.conf

External Programs

If you do run an external program from guardcat, it will run with the same privileges as guardcat, i.e., root in this scenario. Make sure the external program is fully suited to this privilege level as well.

Output Files

If an attacker can write to the directory containing any output file (log file, control nodes, etc.), they can redirect the output with a symlink, again potentially leading to system corruption, or worse.

Restricted Operation

If you are only using guardcat for monitoring, alerting, and/or logging, it should be able to run with limited privileges, as normally any user can read hwmon values. The usual method would be to create a dedicated user for guardcat, and configure the systemd unit (or rc script, or whatever) to run guardcat as that user. If logging data, the log file should be set with permissions that allow that user to write to the file.

See Also

guardcat.conf(5), sensors(1), pwmconfig(1)

Dedication

guardcat is dedicated to the author’s dear departed cat Franklin, who was the original Guard Cat.

License

This manual page and accompnaing software is licensed under the terms of the Unlicense. For the full terms, see the accompaning UNLICENSE file, or the http://unlicense.org/ website. To summarize, you can do anything you want with it, and there is NO WARRANTY, nor any assumptuion of liability. Any and all use is strictly AT YOUR OWN RISK.