$USER@bit-of-a-byte ~ $ cat $(find /var/log -name '*.log' -print | awk 'NR>15&&NR<=20')

Just as an example..

of what I mean when I say I spend my time meddling in software or hardware that I really don’t have any business meddling in, I’ve got this website split into two branches now: Master, and Development. I do all my work in development, then push to remote. Travis-CI then pulls the changes and builds them, then runs HTML-Proofer over the output, and then sends me an e-mail if something is broken. If nothing is broken, then I rebase my Development branch on master, and then merge it into master to make sure my changes are preserved.

I guess it should read “I meddle in software that I don’t need in the slightest.”

Icinga2 Tutorial: Part 3 - Agent-Based Checks

EDIT (2018/12/09): These guides haven’t been updated since 2015. It is possible that there are dead links, or that the configuration syntax has changed dramatically. These posts are also some of the most popular on my blog. I plan to do a new guide eventually, but for right now please take the following entries with a grain of salt.

For this part of the tutorial, we are actually going to be rewriting the host file for localhost. Unfortunately, I thought the EdgeRouter would be capable of running an Icinga2 client, but it isn’t available through the apt repositories, and after the ntopng incident of July and August, I am not stressing that processor any more than it needs to be to run my network. (It is stressed enough as it is, but that is a post for another day.)

Since I have done most of the explaining in the files, these tutorials will start including the configuration files, and any external resources I have used.

Configuration File

/*
 * File:        /etc/icinga2/conf.d/captor.conf
 * Title:       Captor Host Configuration File
 * Description: Host and services definition for Icinga2 for
 *              the Captor Localhost.
 * Host:        captor.zyradyl.org
 * System:      Linux Mint Debian Edition 2
 * License:     Creative Commons Zero - Public Domain
 * Version:     1.0
 * Date:        August 16, 2015
 */

//
// Host Declaration Block
//
object Host "captor.zyradyl.org" {
    // Define the host IPv4 Address
    address         = "127.0.0.1"
    // Define the host IPv6 Address
    address6        = "::1"
    // Define the operating system
    vars.os         = "Linux"
    // Define a basic functionality test
    // Hostalive does a basic ICMP ECHO to the target
    // specified in the address directive.
    check_command   = "hostalive"
}

//
// There are two ways that we can configure Icinga2.
// The first method is to write specific files for
// every host, which is a good idea if you only have
// a few hosts, and every host has something
// different going on. The other method wold be to
// use apply service logic, which is better for
// larger deployments. I have provided links to
// both a best practices guide as well as to a guide
// on apply logic. I will be using files on a per
// host basis for my deployment.
//

// For demonstration purposes I am setting up an
// IPv6 Ping check.

//
// Service Declaration Block
// Service:     Ping6
// Description: Check if Host is responding to IPv6
// Note:        The address6 specified in the above directive  
//              is carried into the service declaration
//              blocks via specifying the host_name variable
//
object Service "ping6" {
    host_name     = "captor.zyradyl.org"
    check_command = "ping6"
}

//
// Service Declaration Block
// Service:     HTTP.server
// Description: Checks if Apache in general is up.
// Note:        The address specified in the above directive  
//              is carried into the service declaration
//              blocks via specifying the host_name variable
//
// We are specifying an additional part on the service
// because we are also going to check to make sure that
// IcingaWeb2 is running.
//
object Service "http.server" {
    host_name               = "captor.zyradyl.org"
    // This tells Icinga to check only this specific
    // page.
    vars.http_uri           = "/"
    check_command           = "http"
}

//
// Service Declaration Block
// Service:     HTTP.icingaweb2
// Description: Check if the IcingaWeb service is up.
// Note:        The address specified in the above directive  
//              is carried into the service declaration
//              blocks via specifying the host_name variable
//
object Service "http.icingaweb" {
    host_name               = "captor.zyradyl.org"
    // This tells Icinga to check only this specific
    // page.
    vars.http_uri           = "/icingaweb2"
    check_command           = "http"
}

//
// Service Declaration Block
// Service:     SSL Cert Check
// Description: Check expiration date of SSL certificates.
// Note:        The address specified in the above directive  
//              is carried into the service declaration
//              blocks via specifying the host_name variable
//
// The following is commented out because captor doesnt offer
// HTTPS.
//
//object Service "ssl" {
//    host_name                         = "wepwawet.zyradyl.org"
//    vars.ssl_port                     = "443"
//    vars.ssl_cert_valid_days_warn     = "30"
//    vars.ssl_cert_valid_days_critical = "15"
//    check_command                     = "ssl"
//}

//
// Service Declaration Block
// Service:     Disks
// Description: Checks status of all installed disks.
// Note:        The address specified in the above directive  
//              is carried into the service declaration
//              blocks via specifying the host_name variable
//
object Service "disks" {
    host_name                     = "captor.zyradyl.org"
    // We need to exclude a particular partition due to
    // access denials.
    vars.disk_partitions_excluded = "/run/user/1000/gvfs"
    check_command                 = "disk"
}

//
// Service Declaration Block
// Service:     Icinga
// Description: Checks status of Icinga Instance.
// Note:        The address specified in the above directive  
//              is carried into the service declaration
//              blocks via specifying the host_name variable
//
object Service "icinga" {
    host_name     = "captor.zyradyl.org"
    check_command = "icinga"
}

// Service Declaration Block
// Service:     Load
// Description: Checks how much load the host is under.
// Note:        The address specified in the above directive  
//              is carried into the service declaration
//              blocks via specifying the host_name variable
//
object Service "load" {
    host_name     = "captor.zyradyl.org"
    check_command = "load"
}

// Service Declaration Block
// Service:     Procs
// Description: Checks number of processes on host.
// Note:        The address specified in the above directive  
//              is carried into the service declaration
//              blocks via specifying the host_name variable
//
object Service "procs" {
    host_name     = "captor.zyradyl.org"
    check_command = "procs"
}

//
// Service Declaration Block
// Service:     SSH
// Description: Checks if SSH is available.
// Note:        The address specified in the above directive  
//              is carried into the service declaration
//              blocks via specifying the host_name variable
//
// Note:        Captor does not provide ssh services.
//              Commenting out this service.
//
//object Service "ssh" {
//    host_name     = "captor.zyradyl.org"
//    check_command = "ssh"
//}

// Service Declaration Block
// Service:     Swap
// Description: Checks status of swap space on host.
// Note:        The address specified in the above directive  
//              is carried into the service declaration
//              blocks via specifying the host_name variable
//
object Service "swap" {
    host_name     = "captor.zyradyl.org"
    check_command = "swap"
}

// Service Declaration Block
// Service:     Users
// Description: Checks number of users on the system
// Note:        The address specified in the above directive  
//              is carried into the service declaration
//              blocks via specifying the host_name variable
//
object Service "users" {
    host_name     = "captor.zyradyl.org"
    check_command = "users"
}

// Service Declaration Block
// Service:     Apt
// Description: Checks status of the apt package manager.
// Note:        The address specified in the above directive  
//              is carried into the service declaration
//              blocks via specifying the host_name variable
//
object Service "apt" {
    host_name     = "captor.zyradyl.org"
    check_command = "apt"
}

// EOF

Import Notes

It is worth noting that this article was intended to be a quick write up to get something online. In time, I may come back to rewrite things, but at the very least I hope the comments in the file are helpful.

Ubiquiti EdgeRouter Lite SquashFS Block Read Error: Part 1

Problem Description

Upon booting the EdgeRouter Lite, the system will not boot. Connecting to console reveals the following log:

SQUASHFS error: zlib_inflate error, data probably corrupt
SQUASHFS error: squashfs_read_data failed to read block 0x1b4574
SQUASHFS error: Unable to read fragment cache entry [1b4574]
SQUASHFS error: Unable to read page, block 1b4574, size 8519
SQUASHFS error: Unable to read fragment cache entry [1b4574]
SQUASHFS error: Unable to read page, block 1b4574, size 8519

This can be caused by an unclean shutdown, which could potentially occur with a power failure. Due to the failure, parts of the internal ext3 filesystem become corrupted, which causes the inability to load the SquashFS partition which contains EdgeOS. The end result, of course, is a non-functional unit.

Problem Severity

There are four potential levels to determining the severity of this issue:

  • Can the filesystem be salvaged by fscking the ext3 partition until it is salvageable? (Severity: Annoying.)
  • If the answer to the above is no, can the flash drive be saved by zeroing out the device and writing a new filesystem to it? (Severity: Hardware issue - End user repair possible..)
  • If the answer to the above is no, is the device capable of booting? If yes, it is possible you may be suffering from the EdgeRouter Lite RAM issue. (Severity: Hardware issue - RMA the device.)
  • If the answer to the above is no, is the device under warranty? If yes, (Severity: Hardware issue - RMA the device.) If no, (Severity: Device Replacement.)

Problem Resolution

Resolutions will be broken down into two posts, one for each problem the user could resolve without warranty work.

Resolution Credits

A special thanks to Ubiquiti for providing a community support option via their official website. Additionally, special thanks to all those users that utilize said forum, your information was invaluable in helping me to fix my EdgeRouter, and write this article.

Resolution One: Repair the File System

This is by far the easiest resolution. Open the EdgeRouter Lite (Caution: Your warranty is now void. Depending on how soon you need the device back in operation, it may be acceptable for you to void the warranty on a $100USD device if you can get it back in service by the end of the day. If you think your device may need to be RMA’d, do not open the device and proceed to UBNT’s Support Site.) by removing two screws on the bottom of the device, located right under where the interface connections are. Your device will slide apart, revealing the internal board. On the board you will see a soldered on female USB port with a small silver USB flash drive, roughly 3cm long. This is your 2GB of internal memory, but the device itself is 2.6GB.

Remove the USB drive and plug it into a USB port on your Mac OSX or Linux powered device. Open a terminal, and run dmesg. You are looking for the devfs name of your device.

[  262.645401] scsi 2:0:0:0: Direct-Access                               5.00 PQ: 0 ANSI: 2
[  262.647109] sd 2:0:0:0: Attached scsi generic sg1 type 0
[  262.648527] sd 2:0:0:0: [sdb] 4057088 512-byte logical blocks: (2.07 GB/1.93 GiB)
[  262.648795] sd 2:0:0:0: [sdb] Write Protect is off
[  262.648817] sd 2:0:0:0: [sdb] Mode Sense: 0b 00 00 08
[  262.649095] sd 2:0:0:0: [sdb] No Caching mode page found
[  262.649114] sd 2:0:0:0: [sdb] Assuming drive cache: write through
[  262.652309]  sdb: sdb1
[  262.655018] sd 2:0:0:0: [sdb] Attached SCSI removable disk

In this case, my device name is sdb. Please note that for this guide I am not using an actual EdgeRouter flash drive. This is a stand-in device. The next thing to do is make sure none of the partitions on the device have been automatically mounted. Where I used sdb in the following example, use whatever dmesg identified as your USB device.

zyradyl@captor ~ $ mount | grep sdb
/dev/sdb1 on /media/zyradyl/b7bcf200-26a1-41ed-9122-625558dbc907 type ext4 (rw,nosuid,nodev,relatime,data=ordered,uhelper=udisks2)

This would indicate that at least one of the partitions on the disk has been mounted. To correct this we need to use the umount command. Note that in some operating systems an eject button exists in the taskbar. In my experience, not only do these buttons unmount the mounted partitions, it also removed the device entry from the kernel. So I prefer to use manual umount commands. In the following example, do one line per mounted partition, substituting the device names of your partitions where I specified /dev/sdb1.

zyradyl@captor ~ $ sudo umount /dev/sdb1

Once you have unmounted the devices, you can use fdisk to get a good view of the partition layout on your USB device. I like to do this even if I know what I should expect, just as a form of a sanity test to make sure I have the right device. Note that, as previously stated, this device is a stand in. I have tried to recreate the partition table to the best of my memory.

zyradyl@captor ~ $ sudo fdisk -l /dev/sdb

Disk /dev/sdb: 2 GiB, 2077229056 bytes, 4057088 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xd9dd6356

Device     Boot  Start     End Sectors  Size Id Type
/dev/sdb1         2048  264191  262144  128M  b W95 FAT32
/dev/sdb2       264192 4057087 3792896  1.8G 83 Linux

So we can see from the above that we have two partitions on the USB device. In your case, when using an actual EdgeRouter flash drive, one of the partitions will be a vfat partition type, and the second one will be a linux partition type. Now that we know where our partitions are, and that they are safely unmounted, we can use fsck. Remember to replace my instance of sdb2 with the correct partition for your device. Note that depending on the damage to the filesystem, this has the potential to be a destructive operation.

zyradyl@captor ~ $ fsck.ext3 -fvy /dev/sdb2

Allow the program to run till completion. If you notice the command has become looped, you will need to clear the journal out on your device. Note that this is a potentially destructive operation to data that had not been written from the journal to the disk. The first thing that we need to do is clear out the recovery indicator using debugfs Remember to replace sdb2 with the proper device name of your ext3 partition.

zyradyl@captor ~ $ debugfs -w -R “feature ^needs_recovery” /dev/sdb2

After clearing out this flag, it is now possible to use tune2fs to force removal of the journal.

zyradyl@captor ~ $ tune2fs -f -O ^has_journal /dev/sdb2

Now you can go back up and run the fsck command. Once that is done, you will need to re-enable the journal on your filesystem.

zyradyl@captor ~ $ tune2fs -f -O has_journal -j size=128M /dev/sdb2

Once you have a clean fsck output, and you have your journal enabled again, plug the USB device back into the EdgeRouter and boot. If you are lucky, everything will come back as it should. As there may be data loss, make sure to restore from a recent configuration backup (you do have configuration backups, right?) and reboot, before logging into the device through ssh to make sure everything is where it should be.

If you are still having problems, stick around for part two of this guide, where I will be walking you through using a separate host computer to recreate the filesystem.

EDIT (2018/12/09): Part 2 was never written, but this is actually a fairly common issue with EdgeRouter Lites. A simple Google search should turn up the EdgeRouter Emergency Recovery Kit GitHub, and that plus some posts on the UBNT forums should help you solve the problem. Sorry about my inability to deliver on what I mention in my posts.

[How to Recover an EXT3 Volume with an Unreadable Journal][2]

Icinga2 Tutorial: Part 2 - Agent-Less Checks

EDIT (2018/12/09): These guides haven’t been updated since 2015. It is possible that there are dead links, or that the configuration syntax has changed dramatically. These posts are also some of the most popular on my blog. I plan to do a new guide eventually, but for right now please take the following entries with a grain of salt.

Master Host Configuration

So in our last part we focused on getting your machine set up as the Icinga2 master controller. Now we can focus on getting interoperability setup. As always, this tutorial assumes you are sudo’d as root. You can do this by running “sudo -s”. Then we need to set ourselves up as the master node on our network.

captor zyradyl # icinga2 node wizard
Welcome to the Icinga 2 Setup Wizard!

We'll guide you through all required configuration details.

Please specify if this is a satellite setup ('n' installs a master setup) [Y/n]: n
Starting the Master setup routine…
Please specifiy the common name (CN) [captor.zyradyl.org]:
information/cli: Generating new CSR in '/etc/icinga2/pki/captor.zyradyl.org.csr'.
information/cli: Created backup file '/etc/icinga2/pki/captor.zyradyl.org.key.orig'.
information/cli: Created backup file '/etc/icinga2/pki/captor.zyradyl.org.csr.orig'.
information/base: Writing private key to '/etc/icinga2/pki/captor.zyradyl.org.key'.
information/base: Writing certificate signing request to '/etc/icinga2/pki/captor.zyradyl.org.csr'.
information/cli: Signing CSR with CA and writing certificate to '/etc/icinga2/pki/captor.zyradyl.org.crt'.
information/cli: Created backup file '/etc/icinga2/pki/captor.zyradyl.org.crt.orig'.
information/cli: Copying CA certificate to '/etc/icinga2/pki/ca.crt'.
information/cli: Created backup file '/etc/icinga2/pki/ca.crt.orig'.
information/cli: Dumping config items to file '/etc/icinga2/zones.conf'.
Please specify the API bind host/port (optional):
Bind Host []:
Bind Port []:
information/cli: Enabling the APIlistener feature.
information/cli: Updating constants.conf.
information/cli: Updating constants file '/etc/icinga2/constants.conf'.
information/cli: Updating constants file '/etc/icinga2/constants.conf'.
Done.
Now restart your Icinga 2 daemon to finish the installation!

captor zyradyl # service icinga2 restart
checking Icinga2 configuration.
[...]
captor zyradyl #

Note that in your case, you may see one or two warning messages, but if it pertains to files already existing, don’t worry about it, I also clipped all the output that Icinga2 spits out when it restarts in order to save space. These posts are long enough as it is. After restarting, if you check the website for your master node, you will see a whole bunch of new information. This has also established the certificates the icinga2 protocol uses for security.

Host Monitoring

Now, while it is nice to have access to the Icinga protocol, in our case we will be working with devices that do not make the option of installing Icinga possible. Instead, we will be monitoring through four different protocols: SSH, SNMP(v1), HTTP/S, and ICMP.

We are going to go simple in this route through the use of agent-less checks. Agent-less checks do not rely on having a remote program installed, and this is useful for embedded devices that may not have enough memory to host another program. This is also helpful if your client only offers one or two services and it isn’t worth taking the time to install and configure a node setup. For example, you can check if SSH is available on a remote host, or check if the HTTP server is alive, or even simply see if the host is alive. We will start there.

Before we get into editing the actual files, Syntax highlighting can make life a whole lot easier. Note, you should repeat this process with a non-privileged user as that will give you a way to take a look at icinga2 configuration files without having to be the root user.

captor conf.d # mkdir -p ~/.vim/{syntax,ftdetect}
captor conf.d # cd /usr/share/icinga2-common/syntax/
captor syntax # cp vim/syntax/icinga2.vim ~/.vim/syntax/
captor syntax # cp vim/ftdetect/icinga2.vim ~/.vim/ftdetect/

Now test it by opening any file under the /etc/icinga2/conf.d/ directory. You can find instructions to do this for nano here. Now, there are a lot of ways to configure Icinga2. You can choose to use the pre-existing hosts.conf and services.conf, or, since the conf.d directory is read on startup, you can use one file per host. I will be doing the latter, as I think it keeps it a lot neater. The Access point is named Wepwawet, so let’s get started. (Note that you clearly do not need to use my header method. You can also indent with tabs, I mean.. if you like that kind of uncertainty in how the file will be displayed.)

captor conf.d # vim /etc/icinga2/conf.d/wepwawet.conf

You can find the document, with syntax highlighting, here.

So with this basic configuration, we get three checks:

  • An ICMP Echo (hostalive)
  • A HTTPS Up Check (http)
  • A SSH Up check (ssh)

For my HTTP check, the website uses HTTPS, and no HTTP site is available. So by setting the SSL variable, we can ensure that just HTTPS is being checked. This ensures we are getting an accurate reading. Now we need to ensure that our declaration works.

captor conf.d # /etc/init.d/icinga2 checkconfig
checking Icinga2 configuration.
captor conf.d # /etc/init.d/icinga2 reload
checking Icinga2 configuration.
Reloading icinga2 monitoring daemon: icinga2.
captor conf.d #

Then log in to your web page, and you should see your new host and service definition. If this works, then move on to the next section. If not, you should consult the error messages printed out as well as the Icinga2 log that can be found in /var/log. A useful method to check if the error is in your configuration is to run the checks manually. Attempt to ping the host, or ssh to the host, or access a web page. If you are unable to do these things manually, the problem may very well be with your host.

The one final thing I would like to do is to demonstrate that you can actually do a fairly nice amount of checks without needing to have a remote agent. For this next example, we are going to setup a check that will verify if our SSL certificate is still valid, or how long we have till it runs out. Previously, this was done through an external custom command but Icinga2 now has a TCP check plugin that can do this natively.

Open your configuration file and make the edits. You can follow this file with syntax colouring as an example.

Once done, reload your configuration as demonstrated above. It is worth stating that the reload parameter also calls checkconfig, however I prefer to run them as two separate commands. It is also worth stating that you could combine the SSL certificate check with the HTTPS check. I separate them because for me a certificate expiring isn’t too big of a deal – it will only throw an error – but the HTTPS server going down is a much bigger deal.

You can see the configuration of the monitoring setup for my core router here.

External Resources:

Icinga2 Tutorial: Part 1 - Installation and Configuration

EDIT (2018/12/09): These guides haven’t been updated since 2015. It is possible that there are dead links, or that the configuration syntax has changed dramatically. These posts are also some of the most popular on my blog. I plan to do a new guide eventually, but for right now please take the following entries with a grain of salt.

Introduction ## {: #icinga2-part-1-introduction }

I wanted to get this out fairly quickly, because I just actually did this, and while the default Icinga2 tutorial is pretty good, it is lacking in some areas, and since everything is fresh in my mind I wanted to go ahead and draft this up.

It is worth noting that in this post I will assume you are root. You can get to root as a sustained environment by using sudo -s.

I do not condone this for day to day usage, it is bloody dangerous.

So, let’s get started. Sudo to root.

zyradyl@captor ~ $ sudo -s
[sudo] password for zyradyl:
captor zyradyl #

Installing Icinga2

This assumes you are root, and on a Debian based system. For other systems, you can find additional documentation here. Note that I follow that documentation very closely except for a few small notes, so it should be easy to adjust this tutorial for your needs.

Adding Repositories

captor zyradyl # wget -O - http://debmon.org/debmon/repo.key 2>/dev/null | apt-key add -
captor zyradyl # echo deb http://debmon.org/debmon debmon-jessie main >/etc/apt/sources.list.d/debmon.list
captor zyradyl # apt-get update

The first command downloads the cryptographic key for the debmon repository and hands it over to apt. Apt then installs that key, which allows you to verify that you are using packages signed off by and validated by that repository. The second command is then echoing the debmon main repository into your apt-sources, so that the software available there is added to your system’s list, which allows you to install with just a command. The third command tells your system to update its internal package list to incorporate the changes. After that we can go ahead and install.

Installation

captor zyradyl # apt-get install icinga2 monitoring-plugins

This will install both icinga2 and the nagios monitoring plugins that are compatible. This gives you a very good base. Start the program through the service command, and then set it to start on boot with update-rc.d.

captor zyradyl # service icinga2 start
captor zyradyl # update-rc.d icinga2 enable

Tada! You now have a data aggregator/network monitor setup! However, we want a nice way to get information from our monitoring host, so now we need to install the web front end.

Installing IcingaWeb2

Let’s start with all the essentials.

Package Installation

captor zyradyl # apt-get install postgresql icinga2-ido-pgsql apache2 php5-ldap php5-imagick php5-pgsql php5-intl icingaweb2 icingaweb2-module-doc icingaweb2-module-monitoring icingaweb2-module-setup

This is a big one, so if you are living on about a meg down, prepare to settle in for a bit. In order, this will install the PostgreSQL database, the Icinga2 database connector, the apache2 web server, the ldap php5 module, the imagemagick module for php5, the postgresql php5 module, the intl php5 module, the IcingaWeb2 core, the IcingaWeb2 documentation module, the IcingaWeb2 monitoring module, and the IcingaWeb2 setup module. Note that on debian systems, it will prompt you to allow it to setup the database. I strongly recommend you say NO to that, and do it manually.

Once this completes, get everything running and added to the default runlevel.

captor zyradyl # service postgresql start
captor zyradyl # update-rc.d postgresql enable
captor zyradyl # service apache2 start
captor zyradyl # update-rc.d apache2 enable

Database Configuration

Now we need to make that database. The first command defines a new user named “icinga” with a password of the same name. The second command then creates a database named icinga, and grants ownership to the user icinga.

captor zyradyl # cd /tmp
captor tmp # sudo -u postgres psql -c "CREATE ROLE icinga WITH LOGIN PASSWORD 'icinga';"
captor tmp # sudo -u postgres createdb -O icinga -E UTF8 icinga

Once this is done, edit the file pg_hba.conf. This file controls the way that hosts can authenticate with your database. We want to make sure that icinga can utilize standard password login, or md5.

captor tmp # vim /etc/postgresql/9.4/main/pg_hba.conf

    # icinga
    local    icinga    icinga                    md5
    host     icinga    icinga    127.0.0.1/32    md5
    host     icinga    icinga    ::1/128         md5

Save, and then restart the database to activate the changes. Once restarted, we can import the IDO SQL schema into Postgres. The export line pushes the password into the environment, thus allowing us to avoid having to type it in.

captor tmp # service postgresql restart
captor tmp # export PGPASSWORD=icinga
captor tmp # psql -U icinga -d icinga < /usr/share/icinga2-ido-pgsql/schema/pgsql.sql

Now we need to go ahead and enable the features that icinga2 will use.

captor tmp # icinga2 feature enable command
captor tmp # icinga2 feature enable ido-pgsql
captor tmp # icinga2 feature enable livestatus
captor tmp # icinga2 feature enable statusdata
captor tmp # service icinga2 restart

The final line restarts icinga2, which is the final step to enable these modules. Now, we need to update the configuration file for ido-pgsql to connect it to our database that we manually set up above.

captor tmp # vim /etc/icinga2/features-enabled/ido-pgsql.conf

Fill in the needed information as appropriate. Now you need to update the date.timezone variable in the php configuration, which can be found below.

captor tmp # vim /etc/php5/apache2/php.ini

As an example, mine is set to “America/Detroit”. Now, to allow the web server to pass commands to icinga2, we need to modify the www-data user into the proper group. On Debian, this is the nagios group.

captor tmp # usermod -a -G nagios www-data

Finally, we need to use icingacli to generate our authentication token to run initial setup.

captor tmp # icingacli setup token create
captor tmp # icingacli setup token show

The second command will show you the token should you forget it. Now open a browser and navigate to the localhost web page. and follow along.

Something to note is that you should never select skip verification until you have checked all your log files in /var/log, and you are certain everything is correct, and the programming is just being buggy. Also keep in mind that postgres uses port 5432, not the default port of 3306. Finally, you should set a password for the postgres’ database superuser, because you are going to need to use the superuser’s account credentials in the setup program to create the database.

captor tmp # sudo -u postgres psql postgres

# \password postgres
Enter Password:

This will change the password, and with that, we can end this part. Next up will be configuring hosts both capable of using the icinga2 protocol, and configuring icinga to speak to simple hosts.