All posts by Phil

Compiling and using mk_livestatus on Nagios4 on Debian 10/Buster


# apt install rrdtool-dev librrd-dev librrd8 libboost-dev libboost-system-dev

Get latest source from, at time of writing, and unpack

# wget
# tar -zxvf mk-livestatus-1.5.0p23.tar.gz
# cd mk-livestatus-1.5.0p23

Configure for nagios4, compile and install

# ./configure --with-nagios4 --prefix=/usr/local/nagios && make install

Enable the broker module in Nagios4 – add this to, eg, your nagios.cfg – first make sure that this is set to send all events to the broker:


Then configure the broker_module – here, telling it to create the socket for livestatus at /var/lib/nagios4/rw/livestatus

broker_module=/usr/local/lib/mk-livestatus/livestatus.o /var/lib/nagios4/rw/livestatus

Now you can restart Nagios4 and test that the livestatus socket is working

# systemctl restart nagios4

# echo "GET status" | /usr/local/bin/unixcat /var/lib/nagios4/rw/livestatus

And you should get something like this:


Installing (and Booting) Linux on/FROM Intel vROC NVMe

Just remember to disable Secure Boot (at least, Supermicro’s guide to vROC says that vROC is not compatible with Secure Boot), and ensure that you boot your O/S installer in (U)EFI mode, and make sure you boot in (U)EFI mode afterwards.

Otherwise, expect problems like the CentOS 7 installer complaining that something went wrong as the installer GUI starts (this seems to mostly stem from not seeing the vROC RAID device, but still seeing the member NVMe devices but being confused by the mdraid-esque nature of vROC RAID sets.)

Once you boot the CentOS installer in EFI mode, you’ll be able to see and install to your “BIOS RAID” device. The same will apply to standalone NVMe drives – which on most boards will only work if everything is done in EFI mode.

Nextcloud “Could not load at least one of your enabled two-factor auth methods” after upgrade

Seems that upgrades in Nextcloud have a propensity to break 2FA provider apps as this is apparently something that bit people going to NC15 but in our case got us after we upgraded to NC16

Far as I can tell, what happens is that you have upgraded to the latest NextCloud before a compatible version of your 2FA providers “apps” is available (why you would release without 2FA is beyond me), and so the provider apps get disabled.

When you try to log in, all you’ll see is this:

To fix this, run the following in the nextcloud web root – these sudo commands have to be run as the same UID as the owner of the config file, so if in your environment you aren’t running nextcloud under www-data then you’ll have to adjust the sudo commands as necessary to specify the correct user.

NB: that I’m running these sudo commands as root, so I don’t need any sudo pre-configuration as such to allow me to run these as www-data.

First, identify what 2FA provides your affected user has configured – so, for a user called “adminusername”:

# sudo -u www-data php occ twofactorauth:state adminusername
Two-factor authentication is enabled for user adminusername

Enabled providers:
- totp
- u2f
Disabled providers:
- backup_codes

So, what we see here is this user had both TOTP and U2F (but, tsk, no backup codes – in our experience, twofactor_backup_codes was still working, so a user with backup codes would be able to still log in – you’d still have to understand what to do to fix your install though!)

Check to see if your modules are missing:

# sudo -u www-data php occ app:list | grep twofactor
  - twofactor_backupcodes: 1.5.0

Uh-oh, no twofactor_totp OR twofactor_u2f.

Make sure your nextcloud apps are up to date:

# sudo -u www-data php occ app:update --all

Then re-enable your twofactor provider apps, so for “totp” and “u2f”, you want:

# sudo -u www-data php occ app:enable twofactor_totp
twofactor_totp enabled

# sudo -u www-data php occ app:enable twofactor_u2f
twofactor_u2f enabled

Now you should be able to log back in as normal with your 2FA.

Configuring TACACS+ authentication and accounting on IOS 15

Just the bare minimum:

! you probably have this already, if you don't; you should read up on it first
aaa new-model

! use local users, and then all tacacs+ servers, to authenticate logins 
aaa authentication login default local group tacacs+ 

! give enable to tacacs+ users 
aaa authentication enable default group tacacs+ 

! send accounting records for when logins ('exec mode') begin and end 
aaa accounting exec default start-stop group tacacs+
! send accounting records for config commands 
aaa accounting commands 15 default stop-only group tacacs+ 

! send accounting records for outgoing connections made to other systems 
aaa accounting connection default start-stop group tacacs+ 

! send system event account records (reloads etc) 
aaa accounting system default start-stop group tacacs+ 

! OPTIONAL: On a router with multiple interfaces that could be chosen to
! reach the TACACS server it is best to specify one; we use Loopback addresses
! for iBGP peering, so it makes sense to use them here too
ip tacacs source-interface Loopback0 

! define at least one tacacs server with some friendly $SERVERNAME 
tacacs server $SERVERNAME
   ! Set the TACACS+ server's ipv4 $ADDRESS (or ipv6, adjust accordingly)
   address ipv4 $ADDRESS
   ! Set the encryption $KEY to match the key configured on the TACACS+ server for this device
   key $KEY

Now: BEFORE you log off, try to log in again and make sure you can still log in with your original local credentials.

If you can no longer login after making the above changes, you’ll need to fix that first before you disconnect to prevent you locking yourself out.

vSphere Client 5.1 plugins & search: Could not create SSL\TLS secure channel

If you can’t download vSphere Client 5.1 Plugins (eg vShield), and can’t use the search in the client because of:

An unknown connection error occured. (The request failed due to an SSL Error. (The request was aborted. Could not create SSL\TLS secure channel.)

And is of no help (you already allow all SSL.Versions), and your SSL certs don’t appear to be broken or expired, then you’ve probably been bitten by some recent changes in a windows update that’s evidently changed some defaults around the minimum DH key size.

Create the following key; everything will start working immediately (you’ll need to re-enable any disabled vSphere Client plugins) as you will start permitting 512bit DH keys.


You should consider upgrading to newer versions of vSphere, but then if we all sat around doing things as complicated as that, we’d not have time for any actual work, would we.

Replace wildcard SSL certificate on all subomains on cPanel server

You’ve got a wildcard certificate you’ve been using on your cPanel server, and you’ve created loads of subdomain SSL accounts, only now your wildcard cert is expiring and there is no trivial way in WHM to replace a wildcard cert and have it replace the cert in use on all the subdomains that use the same original certificate.

Fear not: I have a script for that. I have tried to make the comments useful, so pass no further comment here. This script basically does a two-pair search and replace – so searching and replacing the crt filename, and the key filename.

Hopefully this is useful for someone.

# - v0.1 - Phillip Baker, Netcalibre Ltd -
# YOUR BACKUP AND CALL /scripts/rebuildinstalledssldb AND YOU SHOULD BE OK
# This script should be run sudo/su as root.
# Quickly replace one SSL cert and key file for another already existing on cPanel server
# then rebuild apache config and the ssl.db before restarting apache.
# Useful when replacing a wildcard cert on lots of subdomain accounts
# Install the new cert on the server using WHM in the usual way on one of the accounts
# (perhaps you install it on the root - - account)
# Determine the old cert string you are targeting by looking in a subdomain using
# the old certificate still:
# cat /var/cpanel/userdata/<username>/subdomain.example.com_SSL | grep crt
# Will spit out a crt filename that looks a bit like:
# _wildcard_example.com_aad23_12314_124112312_adsfasdfasdfasdfasdf.crt
# Determine the new cert string in the same way from the domain you installed the new cert on
# cat /var/cpanel/userdata/<username>/example.com_SSL | grep crt
# Do the same for the old / new key (if the key is unchanged, just specify the same string 
# twice)
# Then: ./ <oldcrt> <newcrt> <oldkey> <newkey>

if [ $# -ne 4 ]; then
    echo "./ <oldcrt> <newcrt> <oldkey> <newkey>"
    exit 1



# change to the appropriate directory
cd /var/cpanel/userdata/

# For each _SSL file
for i in `find . -iname *_SSL`
 if grep -q $OLDCRT $i
  echo $i
  # copy to an intermediate file, precrt has the original file before the crt is replaced
  cp $i $i.precrt
  # modify the metadata file to replace the crt filename
  sed "s/$OLDCRT/$NEWCRT/g" $i.precrt > $i
  # copy to another intermediate file, prekey has the file after the crt was replaced 
  # but before the key was replaced
  cp $i $i.prekey
  # modify the metadata file to replace the key filename
  sed "s/$OLDKEY/$NEWKEY/g" $i.prekey > $i

if [[ "$CRTFOUND" -eq 1 ]]
 # rebuild apache config

 # restart apache
 service httpd restart

 # rebuild ssl.db so that the WHM "Manage SSL hosts" section looks accurate

 # Once you're sure it worked
 echo "Pausing so you can check apache is still working and SSL Manager looks sane"
 echo "Press enter if everything is ok, or press ctrl-c to keep *.precrt/*.prekey files"
 echo "for manual inspection to try and figure out what went wrong."

 # clean up
 for i in `find . -iname *.precrt`
  rm $i
 for i in `find . -iname *.prekey`
  rm $i
 echo "Old cert string not found - no changes made!"

“ isn’t renewing my certs!”

There’s been a change at some point to the JSON format that Let’s Encrypt returns challenges in.

If you have an “old” installation of that pre-dates v0.2.0, is probably doing this:

$ ./ -c
# INFO: Using main config file /home/letsencrypt/
 + Checking domain name(s) of existing cert... unchanged.
 + Checking expire date of existing cert...
 + Valid till Jun 22 16:24:00 2016 GMT (Less than 30 days). Renewing!
 + Signing domains...
 + Generating signing request...
 + Requesting challenge for

and then it silently exits.

Update it from git, move your config file to the new location:

git pull
mv config
./ -c

Using DNS challenge with Let’s Encrypt (and migrating from the official client)

Edited 09/03/2020: Tweaked to reflect the change in the project status and repo change
Edited 23/06/2018: Long overdue update to reflect the fact that the project has changed name from to dehydrated

Edited 30/03/2016: Tweaked to reflect where can be found in’s repo these days
Edited 02/06/2016: Tweaked again to reflect the change from “” to “config”, and an addition about securing private_key.pem

Let’s be honest – Let’s Encrypt is a great project with lofty ideals, but their official client is just awful bloatware.

I ended up duct-taping functionality I needed by wrapping their client in a shell script that could look at a list of domains and take the appropriate renew actions as required.

With the advent of support for DNS challenges in the Let’s Encrypt infrastructure but apparently no plans to add it to the standard client.. I found myself looking for alternatives.

Enter dehydrated – essentially a 28KB bash wrapper for standard OpenSSL binaries (compare to the 14MB of crap that the official client entails) that doesn’t insist on putting things into /etc/ by default, and includes the functionality to manage a list of hostnames from a text file.

This lightweight client has added support for the DNS-01 challenge mechanism, and calls a hook script during the challenge/completion stage to achieve the actual DNS record changes (and certificate installation) necessary. You can obviously write this hook script in whatever language you see fit. There are plenty of sample hookscripts here.

A chunk of this guide will include the effort required to migrate from an existing Let’s Encrypt install, but you can just skip those bits if you are setting up a “green field” dehydrated deployment.

Getting dehydrated

First, get dehydrated downloaded, copy the sample config file, and start a blank domains.txt file (this file tracks the domains you have/want certs for – more on this later):

git clone dehydrated
cd dehydrated
cp docs/examples/config config
touch domains.txt

Edit config with your preferred editor; if, like me, you want to use the dns-01 challenge mechanism, make sure you set:




(or wherever your hook script/binary will be)

You’ll probably also want to set CONTACT_EMAIL to something sensible if you’re setting up a new install and want to be able to recover your Let’s Encrypt ‘account’ if something goes wrong somehow (presumably, if you lose your private key). If you’re importing an existing Let’s Encrypt install and key, the contact email, if you set one, was determined when you created your first certificate with that installation.

Everything else can be left commented out unless you know that you need something specific for your environment.

Migrating from the Let’s Encrypt Python client

Moving from the official client to dehydrated is pretty straightforward with a few migration scripts (source). I offer a copy of the scripts here for expediency and as a backup record in case something happens to the originals, but if the versions here don’t work for you, check the source link to see if there’s an updated version available.

Import existing keys/certs/etc

First, let’s import your existing private keys, Let’s Encrypt issued certs, etc – create a script called in your dehydrated directory with the following contents:

#!/usr/bin/env bash

set -e
set -u
set -o pipefail

umask 077 # paranoid umask, we're creating private keys

SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

eval "$("${SCRIPTDIR}/dehydrated" --env)"

if [[ ! -e "${LETSENCRYPT}" ]]; then
  echo "No existing letsencrypt files found."
  exit 1

if [[ -e "${BASEDIR}/domains.txt" ]]; then
elif [[ -e "${SCRIPTDIR}/domains.txt" ]]; then
  echo "You have to create a domains.txt file listing the domains you want certificates for. Have a look at domains.txt.example."
  echo "For the purpose of this import script the file can be empty, but it has to exist."
  exit 1

for certdir in "${LETSENCRYPT}/live/"*; do
  domain="$(basename "${certdir}")"
  echo "Processing ${domain}"

  # Check if we already have a certificate for the same (main) domain
  if [ -e "${BASEDIR}/certs/${domain}" ]; then
    echo " + Skipping: Found existing certificate directory, don't want to delete anything."

  # Check if private-key, certificate and fullchain exist
  if [[ ! -e "${certdir}/privkey.pem" ]]; then
    echo " + Skipping: Private key is missing."
  if [[ ! -e "${certdir}/cert.pem" ]]; then
    echo " + Skipping: Certificate is missing."
  if [[ ! -e "${certdir}/fullchain.pem" ]]; then
    echo " + Skipping: Chain is missing."

  # Check if certificate still valid
  if ! openssl x509 -checkend 0 -noout -in "${certdir}/cert.pem" >/dev/null 2>&1; then
    echo " + Skipping: Certificate is expired."

  # Import certificate
  timestamp="$(date +%s)"

  echo " + Adding list of domains to ${DOMAINS_TXT}"
  SAN="$(openssl x509 -in "${certdir}/cert.pem" -noout -text | grep -A1 "Subject Alternative Name" | grep "DNS")"
  SAN="${SAN//, / }"
  for altname in ${SAN}; do
    if [[ ! "${altname}" = "${domain}" ]]; then
      altnames="${altnames} ${altname}"
  echo "${altnames}" >> "${DOMAINS_TXT}"

  mkdir -p "${BASEDIR}/certs/${domain}"

  echo " + Importing private key"
  cat "${certdir}/privkey.pem" > "${BASEDIR}/certs/${domain}/privkey-${timestamp}.pem"
  ln -s "privkey-${timestamp}.pem" "${BASEDIR}/certs/${domain}/privkey.pem"

  echo " + Importing certificate"
  cat "${certdir}/cert.pem" > "${BASEDIR}/certs/${domain}/cert-${timestamp}.pem"
  ln -s "cert-${timestamp}.pem" "${BASEDIR}/certs/${domain}/cert.pem"

  echo " + Importing chain"
  cat "${certdir}/fullchain.pem" > "${BASEDIR}/certs/${domain}/fullchain-${timestamp}.pem"
  ln -s "fullchain-${timestamp}.pem" "${BASEDIR}/certs/${domain}/fullchain.pem"

and run it to import all your keys/certs/domains into your dehydrated environment.


Certs, Keys and the like will end up in individual dehydrated/certs/<domain> directories so make sure you update any paths to the certs in your Apache/nginx/Exim/whatever configuration to reflect this.

Importing your Let’s Encrypt account private key

Then to import your private key – create a script called next to your private_key.json file in your existing Let’s Encrypt installation – by default, you’ll find this in a unique-to-you subdirectory under /etc/letsencrypt/accounts/ (eg: /etc/letsencrypt/accounts/

NB: You’ll need the perl JSON library for this script to work. ( Debian users can just apt-get install libjson-perl )

#!/usr/bin/env perl

use strict;

use Crypt::OpenSSL::RSA;
use Crypt::OpenSSL::Bignum;
use JSON;
use File::Slurp;
use MIME::Base64;

my $json_file = "private_key.json";
my $json_content = read_file($json_file);
$json_content =~ tr/-/+/;
$json_content =~ tr/_/\//;

my $json = decode_json($json_content);

my $n = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{n}));
my $e = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{e}));
my $d = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{d}));
my $p = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{p}));
my $q = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{q}));

my $rsa = Crypt::OpenSSL::RSA->new_key_from_parameters($n, $e, $d, $p, $q);


and execute it:


This will spit out your private key in the standard PEM format. Cut and paste the output into a new file – private_key.pem – in your dehydrated directory.

Setting up your DNS challenge hook script

With the DNS-01 challenge mechanism, you need some way of creating/deleting DNS records on the fly. If you use a DNS service that provides an API or uses a database back-end, this should be nice and easy for you to implement. If you don’t, well, you’re going to need to figure out that stuff on your own.

If you use one of the DNS services covered by the sample scripts I linked to earlier, you can just download, tweak, and away you go.

If you’re writing your own hook script, your script needs to take arguments on the command line:

$1 = operation
$2 = hostname
$3 = challenge token (not used in DNS-01)
$4 = challenge response

$1 has three possible values indicating the required action from your script:

  • deploy_challenge – create the DNS record
  • clean_challenge – delete the DNS record (cleaning up after the challenge attempt)
  • deploy_cert – deploy the new certificate (you may or may not need to do anything here depending on your environment; such as reload daemons to load the new cert)

The DNS record you need to create/delete is then, effectively:

_acme-challenge.$2. IN TXT “$4”

How best you do this is left as an exercise to you, the reader. If you want to “try out” the DNS challenge mechanism, you can create a manual hook script that simply outputs the record to create/delete and waits for you to press enter to continue – that way you can run dehydrated, the hook script will spit out the DNS record, you can create it, reload your nameserver if necessary, and then press enter in the hookscript when you’re ready to continue:


echo "Method: $1"
echo "_acme-challenge.$2.  IN  TXT \"$4\""

read -s -r -e < /dev/tty

Using dehydrated

NB: If you haven’t imported an existing account key (and perhaps even if you have?) you might need to run the following to accept LEs terms and conditions (read them first!)

./dehydrated --register --accept-terms

Run dehydrated -c once to see what happens (it should check your existing certs and renew any less than 30 days old)

./dehydrated -c

Run a cron, say, once a month, that executes dehydrated -c to refresh any certs that have less than 30 days left on them.

Getting a cert for a new domain

Add your domain to the end of domains.txt followed by any SANs you want, such as the below:

Remember that combining hostnames into one cert means using the same private key and cert (duh) for all of those hostnames – consider if this is an acceptable risk to you!

Then run

dehydrated -c

to create the request, do the challenge/response – done!


I’ve just realised that on my test systems when migrating, private_key.pem was created world readable. Given this key is used to identify you to Let’s Encrypt, you should definitely consider changing the permissions to only be readable by the user you run dehydrated as:

chmod go-r private_key.pem

Internal IPMI error / Stopping kipmi0

As previously documented on this site, I use Nagios extensively. I’ve used the check_ipmi_sensor plugin for a while now, but have had problems on a Centos 6.6 Supermicro box that I had installed it on.

I’d regularly get hit with failures caused by the IPMI failing to return full payloads, and the freeipmi tools frequently dumping out halfway through execution stating that there was an “Internal IPMI Error” – here’s an example running check_ipmi_sensor from the command line:

# ./check_ipmi_sensor -H localhost -fc 5 -v
ID   | Name            | Type              | State    | Reading    | Units | Event
4    | CPU1 Temp       | Temperature       | Nominal  | 38.00      | C     | 'OK'
71   | CPU2 Temp       | Temperature       | Nominal  | 40.00      | C     | 'OK'
138  | PCH Temp        | Temperature       | Nominal  | 31.00      | C     | 'OK'
205  | System Temp     | Temperature       | Nominal  | 26.00      | C     | 'OK'
272  | Peripheral Temp | Temperature       | Nominal  | 41.00      | C     | 'OK'
339  | Vcpu1VRM Temp   | Temperature       | Nominal  | 33.00      | C     | 'OK'
406  | Vcpu2VRM Temp   | Temperature       | Nominal  | 39.00      | C     | 'OK'
473  | VmemABVRM Temp  | Temperature       | Nominal  | 29.00      | C     | 'OK'
540  | VmemCDVRM Temp  | Temperature       | Nominal  | 26.00      | C     | 'OK'
607  | VmemEFVRM Temp  | Temperature       | Nominal  | 38.00      | C     | 'OK'
674  | VmemGHVRM Temp  | Temperature       | Nominal  | 32.00      | C     | 'OK'
741  | P1-DIMMA1 Temp  | Temperature       | Nominal  | 27.00      | C     | 'OK'
808  | P1-DIMMB1 Temp  | Temperature       | Nominal  | 27.00      | C     | 'OK'
875  | P1-DIMMC1 Temp  | Temperature       | Nominal  | 27.00      | C     | 'OK'
942  | P1-DIMMD1 Temp  | Temperature       | Nominal  | 26.00      | C     | 'OK'
1009 | P2-DIMME1 Temp  | Temperature       | Nominal  | 28.00      | C     | 'OK'
1076 | P2-DIMMF1 Temp  | Temperature       | Nominal  | 29.00      | C     | 'OK'
1143 | P2-DIMMG1 Temp  | Temperature       | Nominal  | 28.00      | C     | 'OK'
1210 | P2-DIMMH1 Temp  | Temperature       | Nominal  | 29.00      | C     | 'OK'
1411 | FAN3            | Fan               | Nominal  | 6500.00    | RPM   | 'OK'
1478 | FAN4            | Fan               | Nominal  | 6400.00    | RPM   | 'OK'
ipmi_sensor_read: internal IPMI error

-> Execution of /usr/sbin/ipmi-sensors failed with return code 1.
-> /usr/sbin/ipmi-sensors was executed with the following parameters:
   sudo /usr/sbin/ipmi-sensors --quiet-cache --sdr-cache-recreate --interpret-oem-data --output-sensor-state --ignore-not-available-sensors

This obviously isn’t especially ideal – and I was seeing this every 10-30 minutes when Nagios was running its regular checks. First glances, it looked like it could be caused by defective hardware, but fortunately, that wasn’t the case – just my checks colliding with kipmid.

Centos 6 has built ipmi_si into the kernel by default – and kipmid starts on boot and starts polling any detected IPMI devices (you’ll probably see [kipmi0] running). Given I’m configuring Nagios for monitoring, I’ve no interest in the kernel helper polling my IPMI and tying it up, and if you’re reading this and you have a kernel ipmid thread, chances are, neither do you. Alternatively, it’s possible you’re reading this because your kipmi0 process is claiming to use 100% of a CPU core, perhaps because you did a bmc cold reboot or similar – in which case, this is probably useful for you too, even if you want to keep kipmid running.

You can stop kipmid in its tracks by hot-removing the IPMI device from it’s list of detected devices; first, get the parameters for the detected device like this:

# cat /proc/ipmi/0/params

Then, take the output from the above, prefix it with “remove,” and use /sys/module/ipmi_si/parameters/hotmod to remove the device:

# echo "remove,kcs,i/o,0xca2,rsp=1,rsi=1,rsh=0,irq=0,ipmb=0" > /sys/module/ipmi_si/parameters/hotmod

The kipmid thread will be cleaned up immediately without requiring a reboot. freeipmi’s various utilities do not use ipmi_si/kipmid and will continue to work just fine.

If all you wanted to do was restart kipmid for some reason, you could then re-add the device by instead prefixing with “add,”:

# echo "add,kcs,i/o,0xca2,rsp=1,rsi=1,rsh=0,irq=0,ipmb=0" > /sys/module/ipmi_si/parameters/hotmod

Whereupon kipmi0 will resume.

If stopping kipmid fixes your issue (it provided immediate relief in my case), make sure it stays gone by adding the following to your kernel options in /boot/grub/menu.lst (or, wherever your bootloader configuration is, if you’re not using the default grub environment)


Weirdly, kipmid doesn’t seem to cause problems with Ubuntu 14.04 (on a Dell R200) or Debian 8 (on a different Supermicro board), so perhaps this is a centos specific issue.

Tips for Configuring Nagios3 Efficiently – part 1

Back when I started using Nagios (I think ~1.2 or earlier) I don’t remember many options for being all that efficient in terms of “lines of config written” – certainly, any options for being efficient that there may have been ended up being overlooked in the rush to get it up and running, and I’ve been largely been using the same configuration files (and style) ever since – though I did start using host and service templates as soon as I became aware of them some time back in the 2.x branch days.

In the spirit of self-improvement, I’ve been revisiting the Nagios configuration syntax as part of rolling out a fresh monitoring host based on Nagios3, and have significantly reduced the number of lines of config my Nagios installation depends on as a result.

Continue reading Tips for Configuring Nagios3 Efficiently – part 1