<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Networking on mapletree.moe</title><link>https://mapletree.moe/tags/networking/</link><description>Recent content in Networking on mapletree.moe</description><generator>Hugo -- 0.160.1</generator><language>en-us</language><copyright>This work is licensed under the MIT0 License.</copyright><lastBuildDate>Mon, 07 Sep 2015 16:18:00 -0500</lastBuildDate><atom:link href="https://mapletree.moe/tags/networking/index.xml" rel="self" type="application/rss+xml"/><item><title>Icinga2 Tutorial Part 4 - Expanding Checks to SNMP</title><link>https://mapletree.moe/posts/icinga2-tutorial-part-4/</link><pubDate>Mon, 07 Sep 2015 16:18:00 -0500</pubDate><author>bakayuki</author><guid>https://mapletree.moe/posts/icinga2-tutorial-part-4/</guid><description>&amp;lt;no value&amp;gt;</description><content type="text/html" mode="escaped"><![CDATA[<h1 id="icinga2-tutorial-series">Icinga2 Tutorial Series<a href="#icinga2-tutorial-series" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<ul>
<li><a href="/posts/icinga2-tutorial-part-0">Icinga2 Tutorial: Part 0 - Network Monitoring for the Masses</a></li>
<li><a href="/posts/icinga2-tutorial-part-1">Icinga2 Tutorial: Part 1 - Installation and Configuration</a></li>
<li><a href="/posts/icinga2-tutorial-part-2">Icinga2 Tutorial: Part 2 - Agent-Less Checks</a></li>
<li><a href="/posts/icinga2-tutorial-part-3">Icinga2 Tutorial: Part 3 - Agent-Based Checks</a></li>
<li>Icinga2 Tutorial: Part 4 - Expanding Checks to SNMP <strong>(You are here.)</strong></li>
</ul>
<p><strong>EDIT (2018/12/09):</strong> <em>These guides haven&rsquo;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.</em></p>
<h1 id="introduction">Introduction<a href="#introduction" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<p>Well I have finally persuaded myself to continue writing these posts by
completely deleting all the configuration I had already set up. It is worth
noting that I have switched over to Debian Jessie, for no other reason than
to cause myself more <a href="https://jimlynch.com/linux-articles/the-psychology-of-a-distrohopper/">frustration and suffering</a>. Anyways, let’s get started.</p>
<p>SNMP is considered an <a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/toc#!/icinga2/latest/doc/module/icinga2/chapter/agent-based-checks-addon">Agent-Based Check</a>, and is actually quite
flexible. You can even go as far as to code in custom return options, to check
things you normally wouldn’t be able to check over snmp, for example,
<a href="https://wiki.icinga.org/display/howtos/check_apt+via+SNMP">apt status</a>, and other such things.</p>
<p>It is worth noting that due to using a very small LAN, I will not be
fiddling around with SNMPv3, I will be going with straight SNMPv1,
just with a modified community string. We will get started with my core
router, Djehuti. It is outside the scope of this tutorial to discuss
how to enable SNMP on your device, but if you use a Ubiquiti device,
hey that might come soon.</p>
<p>Starting from this post forward, I will be embedding code here instead of
referring to an external link, as embedding will encourage me to be a bit more
complete in my explanations. So, with all of that said, let’s get started.</p>
<h1 id="initial-setup">Initial Setup<a href="#initial-setup" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<p>To monitor SNMP we will be using the <a href="https://nagios.manubulon.com/">Manubulon SNMP Plugins</a>. So we first
need to install them.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">sudo apt-get install nagios-snmp-plugins
</span></span></code></pre></div><p>Now we need to open up the main Icinga2 Configuration file and add in the
proper include to allow us to use these plugins. You may notice while poking
around this file that there are many things you either don’t need or would like
to change. I do plan to come back to this file at a later time, but feel free to
edit this file before that happens. Once you have made the proper changes,
restart Icinga2 so the new settings take effect.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">sudo vim /etc/icinga2/icinga2.conf
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">    include &lt;manubulon&gt;
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">sudo service icinga2 restart
</span></span></code></pre></div><p>With that, we can move on to creating configuration files!</p>
<h1 id="router">Router<a href="#router" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<p>We will be starting with my core router, which is running SNMPv1. The first
thing we will want to do is to add some essential variables to our host
directive so that we don’t have to redefine them with every service.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// Host Declaration Block
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Host &#34;router.example.org&#34; {
</span></span><span class="line"><span class="cl">    // Define the host IPv4 Address
</span></span><span class="line"><span class="cl">    address             = &#34;10.0.0.1&#34;
</span></span><span class="line"><span class="cl">    // Define a basic functionality test
</span></span><span class="line"><span class="cl">    // Hostalive does a basic ICMP ECHO to the target
</span></span><span class="line"><span class="cl">    // specified in the address directive.
</span></span><span class="line"><span class="cl">    check_command       = &#34;hostalive&#34;
</span></span><span class="line"><span class="cl">    // Define SNMP Variables
</span></span><span class="line"><span class="cl">    vars.snmp_address   = &#34;10.0.0.1&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_community = &#34;example&#34;
</span></span><span class="line"><span class="cl">    // These are not strictly needed. I add them
</span></span><span class="line"><span class="cl">    // so I know at a glance what version of snmp
</span></span><span class="line"><span class="cl">    // I am using.
</span></span><span class="line"><span class="cl">    vars.snmp_v2        = &#34;false&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_v3        = &#34;false&#34;
</span></span><span class="line"><span class="cl">}
</span></span></code></pre></div><p>The new additions are any of the <code>var.snmp*</code> commands located under the
<code>check_command</code> line. With our host variables set up, we can now move on to
defining a service. The first service defined in the
<a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/toc#!/icinga2/latest/doc/module/icinga2/chapter/plugin-check-commands#snmp-manubulon-plugin-check-commands">Icinga2 Manubulon Documentation</a> is the <code>snmp-load</code> check. Seems like a
good starting place to me!</p>
<h2 id="snmp-load">SNMP-Load<a href="#snmp-load" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">//    
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     snmp_load
</span></span><span class="line"><span class="cl">// Description: Uses SNMP commands to check the load averages
</span></span><span class="line"><span class="cl">//              on the device.
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Service &#34;snmp-load&#34; {
</span></span><span class="line"><span class="cl">    host_name           = &#34;router.example.org&#34;
</span></span><span class="line"><span class="cl">    // Set the type of load check to use.
</span></span><span class="line"><span class="cl">    vars.snmp_load_type = &#34;netsl&#34;
</span></span><span class="line"><span class="cl">    // Set the Load Average warning threshold.
</span></span><span class="line"><span class="cl">    vars.snmp_warn      = &#34;5,3,2&#34;
</span></span><span class="line"><span class="cl">    // Set the Load Average critical threshold.
</span></span><span class="line"><span class="cl">    vars.snmp_crit      = &#34;6,5,3&#34;
</span></span><span class="line"><span class="cl">    check_command       = &#34;snmp-load&#34;
</span></span><span class="line"><span class="cl">}
</span></span></code></pre></div><p>I feel I should take a minute to explain the warning and critical variables,
because the icinga2 documentation doesn’t do a very good job. When checking
load averages on *nix systems, there are three parameters:</p>
<ul>
<li>Average Load over one minute</li>
<li>Average Load over five Minutes</li>
<li>Average Load over fifteen minutes</li>
</ul>
<p>Since my router is a dual core device, I have set it up so that if the system
is at full load for 15 minutes, I get a warning. If it has one process over
full load for five minutes, I get a warning. If it is three processes over full
load in one minute, I want a warning. Same thing applies to critical. If you
are trying to figure out what to set your levels at, I tend to use the following
formulas:</p>
<ul>
<li><strong>Warning:</strong>
<ul>
<li>1min: 2*\(Number of Cores\)+1</li>
<li>5min: \(Number of Cores\)+1</li>
<li>15min: \(Number of Cores\)</li>
</ul>
</li>
<li><strong>Critical:</strong>
<ul>
<li>1min: 3*\(Number of Cores\)</li>
<li>5min: 2*\(Number of Cores\)+1</li>
<li>15min: \(Number of Cores\)+1</li>
</ul>
</li>
</ul>
<p>Once you have your file saved, restart Icinga2, and check the web interface.
Your new check will likely have an <em>Unknown</em> Status in purple, just click on
the check, and manually run it by clicking “Check Now” in the right most panel.</p>
<p>With that, we can move on to the next check!</p>
<h2 id="snmp-memory">SNMP-Memory<a href="#snmp-memory" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     SNMP-Memory
</span></span><span class="line"><span class="cl">// Description: Uses SNMP commands to check status of RAM
</span></span><span class="line"><span class="cl">//              and swap on the device.
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Service &#34;snmp-memory&#34; {
</span></span><span class="line"><span class="cl">    host_name      = &#34;router.example.org&#34;
</span></span><span class="line"><span class="cl">    // Set the Memory warning for Ram and swap Respectively.
</span></span><span class="line"><span class="cl">    // Uses percents.
</span></span><span class="line"><span class="cl">    vars.snmp_warn = &#34;50,0&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_crit = &#34;80,0&#34;
</span></span><span class="line"><span class="cl">    check_command  = &#34;snmp-memory&#34;
</span></span><span class="line"><span class="cl">}
</span></span></code></pre></div><p>The warning and critical values are expressed as percentages of the total
amount of their applicable setting. The first one applies to RAM and the second
value corresponds to swap. Restart Icinga2 and log on to the web interface to
check that the new service works.</p>
<h2 id="snmp-storage">SNMP-Storage<a href="#snmp-storage" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     SNMP-Storage
</span></span><span class="line"><span class="cl">// Description: Uses SNMP commands to check the status of disk
</span></span><span class="line"><span class="cl">//              storage space.
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Service &#34;snmp-storage&#34; {
</span></span><span class="line"><span class="cl">    host_name              = &#34;router.example.org&#34;
</span></span><span class="line"><span class="cl">    // Uses percents.
</span></span><span class="line"><span class="cl">    vars.snmp_warn         = &#34;50&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_crit         = &#34;80&#34;
</span></span><span class="line"><span class="cl">    // Specify which partition to monitor
</span></span><span class="line"><span class="cl">    vars.snmp_storage_name = &#34;/root.dev&#34;
</span></span><span class="line"><span class="cl">    check_command          = &#34;snmp-storage&#34;
</span></span><span class="line"><span class="cl">}
</span></span></code></pre></div><p>The <code>snmp_storage_name</code> variable is used to specify which device you want to
check the status of. If you aren’t sure which device you need to check, set
it to blank, then let it run. It will return a list of partitions that you can
check. Simply enter the name into that variable and you are good to go.</p>
<p>Just as memory, <code>snmp-storage</code> uses percent values in the warning and critical
threshold variables.</p>
<h2 id="snmp-interfaces">SNMP-Interfaces<a href="#snmp-interfaces" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h2>
<p>I personally like to specify a different service block for each interface
that I am monitoring, so I am not sure if it is possible to mix interfaces
together, but I don’t see any reason it wouldn’t be possible. I’m going to
list the interface configurations below, and if any variables need to be
explained I will do that below the code.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     SNMP-Interface
</span></span><span class="line"><span class="cl">// Description: Uses SNMP commands to check the status of
</span></span><span class="line"><span class="cl">//              various network interfaces on device.
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Service &#34;snmp-int-lan&#34; {
</span></span><span class="line"><span class="cl">    host_name                      = &#34;router.example.org&#34;
</span></span><span class="line"><span class="cl">    // Define interface variables.
</span></span><span class="line"><span class="cl">    vars.snmp_interface            = &#34;eth0&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_interface_label      = &#34;LAN&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_interface_perf       = &#34;true&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_interface_bits_bytes = &#34;true&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_interface_megabytes  = &#34;true&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_interface_noregexp   = &#34;true&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_warncrit_percent     = &#34;true&#34;
</span></span><span class="line"><span class="cl">    // Set warning and crits to 100 to disable.
</span></span><span class="line"><span class="cl">    vars.snmp_warn                 = &#34;100,100&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_crit                 = &#34;100,100&#34;
</span></span><span class="line"><span class="cl">    check_command                  = &#34;snmp-interface&#34;
</span></span><span class="line"><span class="cl">}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     SNMP-Interface
</span></span><span class="line"><span class="cl">// Description: Uses SNMP commands to check the status of
</span></span><span class="line"><span class="cl">//              various network interfaces on device.
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Service &#34;snmp-int-wan&#34; {
</span></span><span class="line"><span class="cl">    host_name                      = &#34;router.example.org&#34;
</span></span><span class="line"><span class="cl">    // Define interface variables.
</span></span><span class="line"><span class="cl">    vars.snmp_interface            = &#34;eth1&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_interface_label      = &#34;WAN&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_interface_perf       = &#34;true&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_interface_bits_bytes = &#34;true&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_interface_megabytes  = &#34;true&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_interface_noregexp   = &#34;true&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_warncrit_percent     = &#34;true&#34;
</span></span><span class="line"><span class="cl">    // Set warning and crits to 100 to disable.
</span></span><span class="line"><span class="cl">    vars.snmp_warn                 = &#34;100,100&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_crit                 = &#34;100,100&#34;
</span></span><span class="line"><span class="cl">    check_command                  = &#34;snmp-interface&#34;
</span></span><span class="line"><span class="cl">}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     SNMP-Interface
</span></span><span class="line"><span class="cl">// Description: Uses SNMP commands to check the status of
</span></span><span class="line"><span class="cl">//              various network interfaces on device.
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Service &#34;snmp-int-dmz&#34; {
</span></span><span class="line"><span class="cl">    host_name                      = &#34;router.example.org&#34;
</span></span><span class="line"><span class="cl">    // Define interface variables.
</span></span><span class="line"><span class="cl">    vars.snmp_interface            = &#34;eth2&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_interface_label      = &#34;DMZ&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_interface_perf       = &#34;true&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_interface_bits_bytes = &#34;true&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_interface_megabytes  = &#34;true&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_interface_noregexp   = &#34;true&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_warncrit_percent     = &#34;true&#34;
</span></span><span class="line"><span class="cl">    // Set warning and crits to 100 to disable.
</span></span><span class="line"><span class="cl">    vars.snmp_warn                 = &#34;100,100&#34;
</span></span><span class="line"><span class="cl">    vars.snmp_crit                 = &#34;100,100&#34;
</span></span><span class="line"><span class="cl">    check_command                  = &#34;snmp-interface&#34;
</span></span><span class="line"><span class="cl">}
</span></span></code></pre></div><p>So a few things in here need some explanation. The variable
<code>vars.snmp_interface</code> specifies which interface we will be checking.
<code>vars.snmp_interface_noregexp</code> is related to this in that it tells icinga2
to not use regex matching. <code>vars.snmp_interface_label</code> configures a label
that will be shown in the console. <code>vars.snmp_interface_megabytes</code>, and
<code>vars.snmp_interface_bits_bytes</code> tells Icinga2 that we want to see bandwidth
measured in megabits. These variables can be adjusted accordingly. Finally,
<code>vars.snmp_interface_perf</code> tells Icinga2 that we want to monitor bandwidth
usage.</p>
<p>As for warning and critical values, while I like to monitor my bandwidth, I
don’t actually care how high it goes, at least not at the moment. More relevant
than that is the fact that my bandwidth is much less than a gigabit, but let’s
move on from that. <code>vars.snmp_warncrit_percent</code> says that we are going to
specify our warning and critical thresholds as a percent of total available
bandwidth on that port. I then set <code>vars.snmp_warn</code>, and <code>vars.snmp_crit</code> to
100 so that it is effectively disabled.</p>
<p>Once activating these services, you should reset Icinga2. It is worth noting
that you will first get a pending, and then an unknown status for about five
minutes, depending on your check time. Icinga compares the newest reading to
a previous reading that is sufficently old enough, which is usually about five
minutes, to calculate what has changed. Until you have a row in the database
that is the proper age, you will get a big <em>Unknown</em> status. Nothing to worry
about, check back in a half hour.</p>
<h1 id="conclusion">Conclusion<a href="#conclusion" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<p>There is one more snmp check that is available, and that is the process check.
While I previously used this setup on my core router, it ended up causing some
rather wonky effects, so I have elected to not use it. This check would be
useful to monitor the status of a mission critical process, such as a webserver
or even a database server. It works by searching the process list for the number
of times a string appears, and then going from there. I may cover this in the
future, but I won’t be at the moment.</p>
<p>Thank you for reading, and I hope to have part five up with less of a lag time.
I am also planning to do Icinga2 integration with slack soon, so stay tuned
for that!</p>
]]></content></item><item><title>Icinga2 Tutorial: Part 3 - Agent-Based Checks</title><link>https://mapletree.moe/posts/icinga2-tutorial-part-3/</link><pubDate>Mon, 17 Aug 2015 00:00:00 -0500</pubDate><author>bakayuki</author><guid>https://mapletree.moe/posts/icinga2-tutorial-part-3/</guid><description>&amp;lt;no value&amp;gt;</description><content type="text/html" mode="escaped"><![CDATA[<h1 id="icinga2-tutorial-series">Icinga2 Tutorial Series<a href="#icinga2-tutorial-series" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<ul>
<li><a href="/posts/icinga2-tutorial-part-0">Icinga2 Tutorial: Part 0 - Network Monitoring for the Masses</a></li>
<li><a href="/posts/icinga2-tutorial-part-1">Icinga2 Tutorial: Part 1 - Installation and Configuration</a></li>
<li>Icinga2 Tutorial: Part 3 - Agent-Based Checks <strong>(You are here.)</strong></li>
<li><a href="/posts/icinga2-tutorial-part-2">Icinga2 Tutorial: Part 2 - Agent-Less Checks</a></li>
<li><a href="/posts/icinga2-tutorial-part-4">Icinga2 Tutorial: Part 4 - Extending Checks to SNMP</a></li>
</ul>
<p><strong>EDIT (2018/12/09):</strong> <em>These guides haven&rsquo;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.</em></p>
<p>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 <a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/toc" title="Icinga2 Official Documentation">Icinga2</a> client, but it isn’t available through the
apt repositories, and after the <code>ntopng</code> 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.)</p>
<p>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.</p>
<h1 id="configuration-file">Configuration File<a href="#configuration-file" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">/*
</span></span><span class="line"><span class="cl"> * File:        /etc/icinga2/conf.d/captor.conf
</span></span><span class="line"><span class="cl"> * Title:       Captor Host Configuration File
</span></span><span class="line"><span class="cl"> * Description: Host and services definition for Icinga2 for
</span></span><span class="line"><span class="cl"> *              the Captor Localhost.
</span></span><span class="line"><span class="cl"> * Host:        captor.zyradyl.org
</span></span><span class="line"><span class="cl"> * System:      Linux Mint Debian Edition 2
</span></span><span class="line"><span class="cl"> * License:     Creative Commons Zero - Public Domain
</span></span><span class="line"><span class="cl"> * Version:     1.0
</span></span><span class="line"><span class="cl"> * Date:        August 16, 2015
</span></span><span class="line"><span class="cl"> */
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// Host Declaration Block
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Host &#34;boxen.example.org&#34; {
</span></span><span class="line"><span class="cl">    // Define the host IPv4 Address
</span></span><span class="line"><span class="cl">    address         = &#34;127.0.0.1&#34;
</span></span><span class="line"><span class="cl">    // Define the host IPv6 Address
</span></span><span class="line"><span class="cl">    address6        = &#34;::1&#34;
</span></span><span class="line"><span class="cl">    // Define the operating system
</span></span><span class="line"><span class="cl">    vars.os         = &#34;Linux&#34;
</span></span><span class="line"><span class="cl">    // Define a basic functionality test
</span></span><span class="line"><span class="cl">    // Hostalive does a basic ICMP ECHO to the target
</span></span><span class="line"><span class="cl">    // specified in the address directive.
</span></span><span class="line"><span class="cl">    check_command   = &#34;hostalive&#34;
</span></span><span class="line"><span class="cl">}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// There are two ways that we can configure Icinga2.
</span></span><span class="line"><span class="cl">// The first method is to write specific files for
</span></span><span class="line"><span class="cl">// every host, which is a good idea if you only have
</span></span><span class="line"><span class="cl">// a few hosts, and every host has something
</span></span><span class="line"><span class="cl">// different going on. The other method wold be to
</span></span><span class="line"><span class="cl">// use apply service logic, which is better for
</span></span><span class="line"><span class="cl">// larger deployments. I have provided links to
</span></span><span class="line"><span class="cl">// both a best practices guide as well as to a guide
</span></span><span class="line"><span class="cl">// on apply logic. I will be using files on a per
</span></span><span class="line"><span class="cl">// host basis for my deployment.
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">// For demonstration purposes I am setting up an
</span></span><span class="line"><span class="cl">// IPv6 Ping check.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     Ping6
</span></span><span class="line"><span class="cl">// Description: Check if Host is responding to IPv6
</span></span><span class="line"><span class="cl">// Note:        The address6 specified in the above directive  
</span></span><span class="line"><span class="cl">//              is carried into the service declaration
</span></span><span class="line"><span class="cl">//              blocks via specifying the host_name variable
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Service &#34;ping6&#34; {
</span></span><span class="line"><span class="cl">    host_name     = &#34;boxen.example.org&#34;
</span></span><span class="line"><span class="cl">    check_command = &#34;ping6&#34;
</span></span><span class="line"><span class="cl">}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     HTTP.server
</span></span><span class="line"><span class="cl">// Description: Checks if Apache in general is up.
</span></span><span class="line"><span class="cl">// Note:        The address specified in the above directive  
</span></span><span class="line"><span class="cl">//              is carried into the service declaration
</span></span><span class="line"><span class="cl">//              blocks via specifying the host_name variable
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// We are specifying an additional part on the service
</span></span><span class="line"><span class="cl">// because we are also going to check to make sure that
</span></span><span class="line"><span class="cl">// IcingaWeb2 is running.
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Service &#34;http.server&#34; {
</span></span><span class="line"><span class="cl">    host_name               = &#34;boxen.example.org&#34;
</span></span><span class="line"><span class="cl">    // This tells Icinga to check only this specific
</span></span><span class="line"><span class="cl">    // page.
</span></span><span class="line"><span class="cl">    vars.http_uri           = &#34;/&#34;
</span></span><span class="line"><span class="cl">    check_command           = &#34;http&#34;
</span></span><span class="line"><span class="cl">}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     HTTP.icingaweb2
</span></span><span class="line"><span class="cl">// Description: Check if the IcingaWeb service is up.
</span></span><span class="line"><span class="cl">// Note:        The address specified in the above directive  
</span></span><span class="line"><span class="cl">//              is carried into the service declaration
</span></span><span class="line"><span class="cl">//              blocks via specifying the host_name variable
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Service &#34;http.icingaweb&#34; {
</span></span><span class="line"><span class="cl">    host_name               = &#34;boxen.example.org&#34;
</span></span><span class="line"><span class="cl">    // This tells Icinga to check only this specific
</span></span><span class="line"><span class="cl">    // page.
</span></span><span class="line"><span class="cl">    vars.http_uri           = &#34;/icingaweb2&#34;
</span></span><span class="line"><span class="cl">    check_command           = &#34;http&#34;
</span></span><span class="line"><span class="cl">}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     SSL Cert Check
</span></span><span class="line"><span class="cl">// Description: Check expiration date of SSL certificates.
</span></span><span class="line"><span class="cl">// Note:        The address specified in the above directive  
</span></span><span class="line"><span class="cl">//              is carried into the service declaration
</span></span><span class="line"><span class="cl">//              blocks via specifying the host_name variable
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// The following is commented out because boxen doesnt offer
</span></span><span class="line"><span class="cl">// HTTPS.
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">//object Service &#34;ssl&#34; {
</span></span><span class="line"><span class="cl">//    host_name                         = &#34;boxen.example.org&#34;
</span></span><span class="line"><span class="cl">//    vars.ssl_port                     = &#34;443&#34;
</span></span><span class="line"><span class="cl">//    vars.ssl_cert_valid_days_warn     = &#34;30&#34;
</span></span><span class="line"><span class="cl">//    vars.ssl_cert_valid_days_critical = &#34;15&#34;
</span></span><span class="line"><span class="cl">//    check_command                     = &#34;ssl&#34;
</span></span><span class="line"><span class="cl">//}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     Disks
</span></span><span class="line"><span class="cl">// Description: Checks status of all installed disks.
</span></span><span class="line"><span class="cl">// Note:        The address specified in the above directive  
</span></span><span class="line"><span class="cl">//              is carried into the service declaration
</span></span><span class="line"><span class="cl">//              blocks via specifying the host_name variable
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Service &#34;disks&#34; {
</span></span><span class="line"><span class="cl">    host_name                     = &#34;boxen.example.org&#34;
</span></span><span class="line"><span class="cl">    // We need to exclude a particular partition due to
</span></span><span class="line"><span class="cl">    // access denials.
</span></span><span class="line"><span class="cl">    vars.disk_partitions_excluded = &#34;/run/user/1000/gvfs&#34;
</span></span><span class="line"><span class="cl">    check_command                 = &#34;disk&#34;
</span></span><span class="line"><span class="cl">}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     Icinga
</span></span><span class="line"><span class="cl">// Description: Checks status of Icinga Instance.
</span></span><span class="line"><span class="cl">// Note:        The address specified in the above directive  
</span></span><span class="line"><span class="cl">//              is carried into the service declaration
</span></span><span class="line"><span class="cl">//              blocks via specifying the host_name variable
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Service &#34;icinga&#34; {
</span></span><span class="line"><span class="cl">    host_name     = &#34;boxen.example.org&#34;
</span></span><span class="line"><span class="cl">    check_command = &#34;icinga&#34;
</span></span><span class="line"><span class="cl">}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     Load
</span></span><span class="line"><span class="cl">// Description: Checks how much load the host is under.
</span></span><span class="line"><span class="cl">// Note:        The address specified in the above directive  
</span></span><span class="line"><span class="cl">//              is carried into the service declaration
</span></span><span class="line"><span class="cl">//              blocks via specifying the host_name variable
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Service &#34;load&#34; {
</span></span><span class="line"><span class="cl">    host_name     = &#34;boxen.example.org&#34;
</span></span><span class="line"><span class="cl">    check_command = &#34;load&#34;
</span></span><span class="line"><span class="cl">}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     Procs
</span></span><span class="line"><span class="cl">// Description: Checks number of processes on host.
</span></span><span class="line"><span class="cl">// Note:        The address specified in the above directive  
</span></span><span class="line"><span class="cl">//              is carried into the service declaration
</span></span><span class="line"><span class="cl">//              blocks via specifying the host_name variable
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Service &#34;procs&#34; {
</span></span><span class="line"><span class="cl">    host_name     = &#34;boxen.example.org&#34;
</span></span><span class="line"><span class="cl">    check_command = &#34;procs&#34;
</span></span><span class="line"><span class="cl">}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     SSH
</span></span><span class="line"><span class="cl">// Description: Checks if SSH is available.
</span></span><span class="line"><span class="cl">// Note:        The address specified in the above directive  
</span></span><span class="line"><span class="cl">//              is carried into the service declaration
</span></span><span class="line"><span class="cl">//              blocks via specifying the host_name variable
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">// Note:        Captor does not provide ssh services.
</span></span><span class="line"><span class="cl">//              Commenting out this service.
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">//object Service &#34;ssh&#34; {
</span></span><span class="line"><span class="cl">//    host_name     = &#34;boxen.example.org&#34;
</span></span><span class="line"><span class="cl">//    check_command = &#34;ssh&#34;
</span></span><span class="line"><span class="cl">//}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     Swap
</span></span><span class="line"><span class="cl">// Description: Checks status of swap space on host.
</span></span><span class="line"><span class="cl">// Note:        The address specified in the above directive  
</span></span><span class="line"><span class="cl">//              is carried into the service declaration
</span></span><span class="line"><span class="cl">//              blocks via specifying the host_name variable
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Service &#34;swap&#34; {
</span></span><span class="line"><span class="cl">    host_name     = &#34;boxen.example.org&#34;
</span></span><span class="line"><span class="cl">    check_command = &#34;swap&#34;
</span></span><span class="line"><span class="cl">}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     Users
</span></span><span class="line"><span class="cl">// Description: Checks number of users on the system
</span></span><span class="line"><span class="cl">// Note:        The address specified in the above directive  
</span></span><span class="line"><span class="cl">//              is carried into the service declaration
</span></span><span class="line"><span class="cl">//              blocks via specifying the host_name variable
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Service &#34;users&#34; {
</span></span><span class="line"><span class="cl">    host_name     = &#34;boxen.example.org&#34;
</span></span><span class="line"><span class="cl">    check_command = &#34;users&#34;
</span></span><span class="line"><span class="cl">}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">// Service Declaration Block
</span></span><span class="line"><span class="cl">// Service:     Apt
</span></span><span class="line"><span class="cl">// Description: Checks status of the apt package manager.
</span></span><span class="line"><span class="cl">// Note:        The address specified in the above directive  
</span></span><span class="line"><span class="cl">//              is carried into the service declaration
</span></span><span class="line"><span class="cl">//              blocks via specifying the host_name variable
</span></span><span class="line"><span class="cl">//
</span></span><span class="line"><span class="cl">object Service &#34;apt&#34; {
</span></span><span class="line"><span class="cl">    host_name     = &#34;boxen.example.org&#34;
</span></span><span class="line"><span class="cl">    check_command = &#34;apt&#34;
</span></span><span class="line"><span class="cl">}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">// EOF
</span></span></code></pre></div><h1 id="import-notes">Import Notes<a href="#import-notes" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<p>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.</p>
]]></content></item><item><title>Ubiquiti EdgeRouter Lite SquashFS Block Read Error: Part 1</title><link>https://mapletree.moe/posts/ubnt-erl-squashfs-read-error/</link><pubDate>Sun, 16 Aug 2015 00:00:00 -0500</pubDate><author>bakayuki</author><guid>https://mapletree.moe/posts/ubnt-erl-squashfs-read-error/</guid><description>&amp;lt;no value&amp;gt;</description><content type="text/html" mode="escaped"><![CDATA[<p><strong>EDIT (2018/12/09):</strong> <em>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.</em></p>
<h1 id="problem-description">Problem Description<a href="#problem-description" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<p>Upon booting the EdgeRouter Lite, the system will not boot. Connecting to
console reveals the following log:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">SQUASHFS error: zlib_inflate error, data probably corrupt
</span></span><span class="line"><span class="cl">SQUASHFS error: squashfs_read_data failed to read block 0x1b4574
</span></span><span class="line"><span class="cl">SQUASHFS error: Unable to read fragment cache entry [1b4574]
</span></span><span class="line"><span class="cl">SQUASHFS error: Unable to read page, block 1b4574, size 8519
</span></span><span class="line"><span class="cl">SQUASHFS error: Unable to read fragment cache entry [1b4574]
</span></span><span class="line"><span class="cl">SQUASHFS error: Unable to read page, block 1b4574, size 8519
</span></span></code></pre></div><p>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.</p>
<h1 id="problem-severity">Problem Severity<a href="#problem-severity" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<p>There are four potential levels to determining the severity of this issue:</p>
<ul>
<li>Can the filesystem be salvaged by fscking the ext3 partition until it is
salvageable? (<strong>Severity:</strong> Annoying.)</li>
<li>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? (<strong>Severity:</strong> Hardware
issue - End user repair possible..)</li>
<li>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 <a href="https://community.ubnt.com/t5/EdgeMAX/EdgeRouter-LITE-OS-and-hardware-problems/td-p/667557">EdgeRouter Lite RAM issue</a>. (
<strong>Severity:</strong> Hardware issue - RMA the device.)</li>
<li>If the answer to the above is no, is the device under warranty? If yes,
(<strong>Severity:</strong> Hardware issue - RMA the device.) If no, (<strong>Severity:</strong> Device
Replacement.)</li>
</ul>
<h1 id="problem-resolution">Problem Resolution<a href="#problem-resolution" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<p>Resolutions will be broken down into two posts, one for each problem the user
could resolve without warranty work.</p>
<h2 id="resolution-credits">Resolution Credits<a href="#resolution-credits" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h2>
<p>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.</p>
<h2 id="resolution-one-repair-the-file-system">Resolution One: Repair the File System<a href="#resolution-one-repair-the-file-system" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h2>
<p>This is by far the easiest resolution. Open the EdgeRouter Lite (<strong>Caution:</strong>
<em>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.</em>) 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.</p>
<p>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.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">[  262.645401] scsi 2:0:0:0: Direct-Access                               5.00 PQ: 0 ANSI: 2
</span></span><span class="line"><span class="cl">[  262.647109] sd 2:0:0:0: Attached scsi generic sg1 type 0
</span></span><span class="line"><span class="cl">[  262.648527] sd 2:0:0:0: [sdb] 4057088 512-byte logical blocks: (2.07 GB/1.93 GiB)
</span></span><span class="line"><span class="cl">[  262.648795] sd 2:0:0:0: [sdb] Write Protect is off
</span></span><span class="line"><span class="cl">[  262.648817] sd 2:0:0:0: [sdb] Mode Sense: 0b 00 00 08
</span></span><span class="line"><span class="cl">[  262.649095] sd 2:0:0:0: [sdb] No Caching mode page found
</span></span><span class="line"><span class="cl">[  262.649114] sd 2:0:0:0: [sdb] Assuming drive cache: write through
</span></span><span class="line"><span class="cl">[  262.652309]  sdb: sdb1
</span></span><span class="line"><span class="cl">[  262.655018] sd 2:0:0:0: [sdb] Attached SCSI removable disk
</span></span></code></pre></div><p>In this case, my device name is <code>sdb</code>. 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 <code>sdb</code> in the following example, use whatever
dmesg identified as your USB device.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">mount <span class="p">|</span> grep sdb
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">/dev/sdb1 on /media/bakayuki/b7bcf200-26a1-41ed-9122-625558dbc907 type ext4 (rw,nosuid,nodev,relatime,data=ordered,uhelper=udisks2)
</span></span></code></pre></div><p>This would indicate that at least one of the partitions on the disk has been
mounted. To correct this we need to use the <code>umount</code> 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 <code>umount</code> commands. In
the following example, do one line per mounted partition, substituting the
device names of your partitions where I specified <code>/dev/sdb1</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">sudo umount /dev/sdb1
</span></span></code></pre></div><p>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.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">sudo fdisk -l /dev/sdb
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">Disk /dev/sdb: 2 GiB, 2077229056 bytes, 4057088 sectors
</span></span><span class="line"><span class="cl">Units: sectors of 1 * 512 = 512 bytes
</span></span><span class="line"><span class="cl">Sector size (logical/physical): 512 bytes / 512 bytes
</span></span><span class="line"><span class="cl">I/O size (minimum/optimal): 512 bytes / 512 bytes
</span></span><span class="line"><span class="cl">Disklabel type: dos
</span></span><span class="line"><span class="cl">Disk identifier: 0xd9dd6356
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Device     Boot  Start     End Sectors  Size Id Type
</span></span><span class="line"><span class="cl">/dev/sdb1         2048  264191  262144  128M  b W95 FAT32
</span></span><span class="line"><span class="cl">/dev/sdb2       264192 4057087 3792896  1.8G 83 Linux
</span></span></code></pre></div><p>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 <code>sdb2</code>
with the correct partition for your device. Note that depending on the damage to
the filesystem, this has the potential to be a <strong>destructive operation</strong>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">fsck.ext3 -fvy /dev/sdb2
</span></span></code></pre></div><p>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 <strong>potentially destructive operation</strong> 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 <code>debugfs</code> Remember to replace <code>sdb2</code>
with the proper device name of your ext3 partition.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">debugfs -w -R “feature ^needs_recovery” /dev/sdb2
</span></span></code></pre></div><p>After clearing out this flag, it is now possible to use <code>tune2fs</code> to force
removal of the journal.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">tune2fs -f -O ^has_journal /dev/sdb2
</span></span></code></pre></div><p>Now you can go back up and run the <code>fsck</code> command. Once that is done, you will
need to re-enable the journal on your filesystem.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">tune2fs -f -O has_journal -j <span class="nv">size</span><span class="o">=</span>128M /dev/sdb2
</span></span></code></pre></div><p>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 <strong>do</strong> have configuration backups,
right?) and reboot, before logging into the device through ssh to make sure
everything is where it should be.</p>
<p>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.</p>
<h1 id="external-links--resources">External Links &amp; Resources<a href="#external-links--resources" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<p><a href="https://trick.vanstaveren.us/wp/2009/06/19/how-to-recover-an-ext3-volume-with-an-unreadable-journal/">How to Recover an EXT3 Volume with an Unreadable Journal</a></p>
]]></content></item><item><title>Icinga2 Tutorial: Part 2 - Agent-Less Checks</title><link>https://mapletree.moe/posts/icinga2-tutorial-part-2/</link><pubDate>Wed, 12 Aug 2015 03:00:00 -0500</pubDate><author>bakayuki</author><guid>https://mapletree.moe/posts/icinga2-tutorial-part-2/</guid><description>&amp;lt;no value&amp;gt;</description><content type="text/html" mode="escaped"><![CDATA[<h1 id="icinga2-tutorial-series">Icinga2 Tutorial Series<a href="#icinga2-tutorial-series" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<ul>
<li><a href="/posts/icinga2-tutorial-part-0">Icinga2 Tutorial: Part 0 - Network Monitoring for the Masses</a></li>
<li><a href="/posts/icinga2-tutorial-part-1">Icinga2 Tutorial: Part 1 - Installation and Configuration</a></li>
<li>Icinga2 Tutorial: Part 2 - Agent-Less Checks <strong>(You are here.)</strong></li>
<li><a href="/posts/icinga2-tutorial-part-3">Icinga2 Tutorial: Part 3 - Agent-Based Checks</a></li>
<li><a href="/posts/icinga2-tutorial-part-4">Icinga2 Tutorial: Part 4 - Extending Checks to SNMP</a></li>
</ul>
<p><strong>EDIT (2018/12/09):</strong> <em>These guides haven&rsquo;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.</em></p>
<h1 id="master-host-configuration">Master Host Configuration<a href="#master-host-configuration" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<p>So in our last part we focused on getting your machine set up as the
<a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/toc#!/icinga2/latest/doc/module/icinga2/chapter/distributed-monitoring#distributed-monitoring-setup-master">Icinga2 master controller</a>. 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 <code>sudo -s</code>. Then we need to set ourselves up as the master node on our
network.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">icinga2 node wizard
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">Welcome to the Icinga 2 Setup Wizard!
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">We&#39;ll guide you through all required configuration details.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Please specify if this is a satellite setup (&#39;n&#39; installs a master setup) [Y/n]: n
</span></span><span class="line"><span class="cl">Starting the Master setup routine…
</span></span><span class="line"><span class="cl">Please specifiy the common name (CN) [boxen.example.org]:
</span></span><span class="line"><span class="cl">information/cli: Generating new CSR in &#39;/etc/icinga2/pki/boxen.example.org.csr&#39;.
</span></span><span class="line"><span class="cl">information/cli: Created backup file &#39;/etc/icinga2/pki/boxen.example.org.key.orig&#39;.
</span></span><span class="line"><span class="cl">information/cli: Created backup file &#39;/etc/icinga2/pki/boxen.example.org.csr.orig&#39;.
</span></span><span class="line"><span class="cl">information/base: Writing private key to &#39;/etc/icinga2/pki/boxen.example.org.key&#39;.
</span></span><span class="line"><span class="cl">information/base: Writing certificate signing request to &#39;/etc/icinga2/pki/boxen.example.org.csr&#39;.
</span></span><span class="line"><span class="cl">information/cli: Signing CSR with CA and writing certificate to &#39;/etc/icinga2/pki/boxen.example.org.crt&#39;.
</span></span><span class="line"><span class="cl">information/cli: Created backup file &#39;/etc/icinga2/pki/boxen.example.org.crt.orig&#39;.
</span></span><span class="line"><span class="cl">information/cli: Copying CA certificate to &#39;/etc/icinga2/pki/ca.crt&#39;.
</span></span><span class="line"><span class="cl">information/cli: Created backup file &#39;/etc/icinga2/pki/ca.crt.orig&#39;.
</span></span><span class="line"><span class="cl">information/cli: Dumping config items to file &#39;/etc/icinga2/zones.conf&#39;.
</span></span><span class="line"><span class="cl">Please specify the API bind host/port (optional):
</span></span><span class="line"><span class="cl">Bind Host []:
</span></span><span class="line"><span class="cl">Bind Port []:
</span></span><span class="line"><span class="cl">information/cli: Enabling the APIlistener feature.
</span></span><span class="line"><span class="cl">information/cli: Updating constants.conf.
</span></span><span class="line"><span class="cl">information/cli: Updating constants file &#39;/etc/icinga2/constants.conf&#39;.
</span></span><span class="line"><span class="cl">information/cli: Updating constants file &#39;/etc/icinga2/constants.conf&#39;.
</span></span><span class="line"><span class="cl">Done.
</span></span><span class="line"><span class="cl">Now restart your Icinga 2 daemon to finish the installation!
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">service icinga2 restart
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">checking Icinga2 configuration.
</span></span><span class="line"><span class="cl">[...]
</span></span></code></pre></div><p>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 <a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/toc">Icinga2</a> 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 <a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/toc#!/icinga2/latest/doc/module/icinga2/chapter/distributed-monitoring#distributed-monitoring-setup-satellite-client">icinga2 protocol</a> uses for
security.</p>
<h1 id="host-monitoring">Host Monitoring<a href="#host-monitoring" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<p>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.</p>
<p>We are going to go simple in this route through the use of
<a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/toc#!/icinga2/latest/doc/module/icinga2/chapter/monitoring-basics#check-commands">agent-less checks.</a> 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.</p>
<p>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.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">mkdir -p ~/.vim/<span class="o">{</span>syntax,ftdetect<span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> /usr/share/icinga2-common/syntax/
</span></span><span class="line"><span class="cl">cp vim/syntax/icinga2.vim ~/.vim/syntax/
</span></span><span class="line"><span class="cl">cp vim/ftdetect/icinga2.vim ~/.vim/ftdetect/
</span></span></code></pre></div><p>Now test it by opening any file under the <code>/etc/icinga2/conf.d/</code> directory. You
can find <a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/chapter/getting-started#configuration-syntax-highlighting-nano">instructions to do this for nano here</a>. Now, there are a lot of
ways to configure Icinga2. You can choose to use the pre-existing
<a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/chapter/configuring-icinga2-first-steps#hosts-conf">hosts.conf</a> and <a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/chapter/configuring-icinga2-first-steps#services-conf">services.conf</a>, or, since the <a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/chapter/configuring-icinga2-first-steps#conf-d">conf.d</a> 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.)</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">vim /etc/icinga2/conf.d/wepwawet.conf
</span></span></code></pre></div><p><a href="https://pastebin.com/twTv3bem">You can find the document, with syntax highlighting, here</a>.</p>
<p>So with this basic configuration, we get three checks:</p>
<ul>
<li>An ICMP Echo (hostalive)</li>
<li>A HTTPS Up Check (http)</li>
<li>A SSH Up check (ssh)</li>
</ul>
<p>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.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">/etc/init.d/icinga2 checkconfig
</span></span><span class="line"><span class="cl">/etc/init.d/icinga2 reload
</span></span></code></pre></div><p>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 <code>/var/log</code>. 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.</p>
<p>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 <a href="https://namsep.blogspot.com/2014/07/icinga-2-https-and-ssl-key-expiry-check.html">external custom command</a> but Icinga2
now has a <a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/chapter/plugin-check-commands#plugin-check-command-tcp">TCP check plugin</a> that can do this natively.</p>
<p>Open your configuration file and make the edits. You can follow this file with
syntax colouring <a href="https://pastebin.com/H7TMnCpQ">as an example</a>.</p>
<p>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.</p>
<p>You can see the
<a href="https://pastebin.com/NnJCYuLM">configuration of the monitoring setup for my core router here</a>.</p>
<h1 id="external-resources">External Resources<a href="#external-resources" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<ul>
<li><a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/toc#!/icinga2/latest/doc/module/icinga2/chapter/monitoring-remote-systems#agent-less-checks">Icinga2 Monitoring Remote Systems: Agentless Checks</a></li>
<li><a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/toc#!/icinga2/latest/doc/module/icinga2/chapter/monitoring-basics#hosts-services">Icinga2 Monitoring Basics: Hosts and Services</a></li>
<li><a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/toc#!/icinga2/latest/doc/module/icinga2/chapter/plugin-check-commands#plugin-check-command-ssh">Icinga2 Plugin Check Commands: SSH</a></li>
<li><a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/toc#!/icinga2/latest/doc/module/icinga2/chapter/plugin-check-commands#plugin-check-command-ssl">Icinga2 Plugin Check Commands: SSL</a></li>
<li><a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/toc#!/icinga2/latest/doc/module/icinga2/chapter/monitoring-basics#command-passing-parameters">Icinga2 Monitoring Basics: Command Passing Variables</a></li>
<li><a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/toc#!/icinga2/latest/doc/module/icinga2/chapter/cli-commands#config-validation">Icinga2 Configuration Validation</a></li>
</ul>
]]></content></item><item><title>Icinga2 Tutorial: Part 1 - Installation and Configuration</title><link>https://mapletree.moe/posts/icinga2-tutorial-part-1/</link><pubDate>Tue, 11 Aug 2015 02:00:00 -0500</pubDate><author>bakayuki</author><guid>https://mapletree.moe/posts/icinga2-tutorial-part-1/</guid><description>&amp;lt;no value&amp;gt;</description><content type="text/html" mode="escaped"><![CDATA[<h1 id="icinga2-tutorial-series">Icinga2 Tutorial Series<a href="#icinga2-tutorial-series" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<ul>
<li><a href="/posts/icinga2-tutorial-part-0">Icinga2 Tutorial: Part 0 - Network Monitoring for the Masses</a></li>
<li>Icinga2 Tutorial: Part 1 - Installation and Configuration <strong>(You are here.)</strong></li>
<li><a href="/posts/icinga2-tutorial-part-2">Icinga2 Tutorial: Part 2 - Agent-less Checks</a></li>
<li><a href="/posts/icinga2-tutorial-part-3">Icinga2 Tutorial: Part 3 - Agent-Based Checks</a></li>
<li><a href="/posts/icinga2-tutorial-part-4">Icinga2 Tutorial: Part 4 - Extending Checks to SNMP</a></li>
</ul>
<p><strong>EDIT (2018/12/09):</strong> <em>These guides haven&rsquo;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.</em></p>
<h1 id="introduction">Introduction<a href="#introduction" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<p>I wanted to get this out fairly quickly, because I just actually did this, and
while the default <a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/chapter/getting-started#setting-up-icinga2">Icinga2 tutorial</a> 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.</p>
<p>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 <code>sudo -s</code>.</p>
<p>I do not condone this for day to day usage, it is <strong>bloody dangerous</strong>.</p>
<p>So, let’s get started. Sudo to root.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">sudo -s
</span></span></code></pre></div><h2 id="installing-icinga2">Installing Icinga2<a href="#installing-icinga2" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h2>
<p>This assumes you are root, and on a Debian based system. For other
systems, you can find <a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/chapter/getting-started#setting-up-icinga2">additional documentation here</a>. 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.</p>
<h3 id="adding-repositories">Adding Repositories<a href="#adding-repositories" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">wget -O - http://debmon.org/debmon/repo.key 2&gt;/dev/null <span class="p">|</span> apt-key add -
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> deb http://debmon.org/debmon debmon-jessie main &gt;/etc/apt/sources.list.d/debmon.list
</span></span><span class="line"><span class="cl">apt-get update
</span></span></code></pre></div><p>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.</p>
<h3 id="installation">Installation<a href="#installation" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">apt-get install icinga2 monitoring-plugins
</span></span></code></pre></div><p>This will install both <a href="https://www.icinga.org/icinga/icinga-2/">icinga2</a> 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 <code>update-rc.d</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">service icinga2 start
</span></span><span class="line"><span class="cl">update-rc.d icinga2 <span class="nb">enable</span>
</span></span></code></pre></div><p>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.</p>
<h1 id="installing-icingaweb2">Installing IcingaWeb2<a href="#installing-icingaweb2" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<p>Let’s start with all the essentials.</p>
<h2 id="package-installation">Package Installation<a href="#package-installation" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">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
</span></span></code></pre></div><p>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
<a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/chapter/advanced-topics#db-ido">Icinga2 database connector</a>, 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 <strong>strongly</strong> recommend
you say NO to that, and do it manually.</p>
<p>Once this completes, get everything running and added to the default runlevel.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">service postgresql start
</span></span><span class="line"><span class="cl">update-rc.d postgresql <span class="nb">enable</span>
</span></span><span class="line"><span class="cl">service apache2 start
</span></span><span class="line"><span class="cl">update-rc.d apache2 <span class="nb">enable</span>
</span></span></code></pre></div><h2 id="database-configuration">Database Configuration<a href="#database-configuration" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h2>
<p>Now we need to make that database. The first command defines a new user named
“<em>icinga</em>” with a password of the same name. The second command then creates a
database named <strong>icinga</strong>, and grants ownership to the user <strong>icinga</strong>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl"><span class="nb">cd</span> /tmp
</span></span><span class="line"><span class="cl">sudo -u postgres psql -c <span class="s2">&#34;CREATE ROLE icinga WITH LOGIN PASSWORD &#39;icinga&#39;;&#34;</span>
</span></span><span class="line"><span class="cl">sudo -u postgres createdb -O icinga -E UTF8 icinga
</span></span></code></pre></div><p>Once this is done, edit the file <code>pg_hba.conf</code>. 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.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">vim /etc/postgresql/9.4/main/pg_hba.conf
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">    # icinga
</span></span><span class="line"><span class="cl">    local    icinga    icinga                    md5
</span></span><span class="line"><span class="cl">    host     icinga    icinga    127.0.0.1/32    md5
</span></span><span class="line"><span class="cl">    host     icinga    icinga    ::1/128         md5
</span></span></code></pre></div><p>Save, and then restart the database to activate the changes. Once restarted,
we can import the <a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/chapter/getting-started#configuring-db-ido-postgresql">IDO SQL</a> schema into Postgres. The export line pushes
the password into the environment, thus allowing us to avoid having to type it
in.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">service postgresql restart
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">PGPASSWORD</span><span class="o">=</span>icinga
</span></span><span class="line"><span class="cl">psql -U icinga -d icinga &lt; /usr/share/icinga2-ido-pgsql/schema/pgsql.sql
</span></span></code></pre></div><p>Now we need to go ahead and enable the features that icinga2 will use.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">icinga2 feature <span class="nb">enable</span> <span class="nb">command</span>
</span></span><span class="line"><span class="cl">icinga2 feature <span class="nb">enable</span> ido-pgsql
</span></span><span class="line"><span class="cl">icinga2 feature <span class="nb">enable</span> livestatus
</span></span><span class="line"><span class="cl">icinga2 feature <span class="nb">enable</span> statusdata
</span></span><span class="line"><span class="cl">service icinga2 restart
</span></span></code></pre></div><p>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.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">vim /etc/icinga2/features-enabled/ido-pgsql.conf
</span></span></code></pre></div><p>Fill in the needed information as appropriate. Now you need to update the
<a href="https://php.net/manual/en/timezones.php">date.timezone</a> variable in the php configuration, which can be found
below.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">vim /etc/php5/apache2/php.ini
</span></span></code></pre></div><p>As an example, mine is set to “<em>America/Detroit</em>”. Now, to allow the web server
to pass commands to icinga2, we need to modify the <strong>www-data</strong> user into the
proper group. On Debian, this is the nagios group.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">usermod -a -G nagios www-data
</span></span></code></pre></div><p>Finally, we need to use icingacli to generate our authentication token to run
initial setup.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">icingacli setup token create
</span></span><span class="line"><span class="cl">icingacli setup token show
</span></span></code></pre></div><p>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.</p>
<p>Something to note is that you should never select skip verification until you
have checked all your log files in <code>/var/log</code>, and you are certain everything
is correct, and the programming is just being buggy. Also keep in mind that
postgres uses <strong>port 5432</strong>, 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.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">sudo -u postgres psql postgres
</span></span><span class="line"><span class="cl"><span class="se">\p</span>assword postgres
</span></span></code></pre></div><p>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.</p>
]]></content></item><item><title>Icinga2 Tutorial: Part 0 - Introduction</title><link>https://mapletree.moe/posts/icinga2-tutorial-part-0/</link><pubDate>Mon, 10 Aug 2015 01:00:00 -0500</pubDate><author>bakayuki</author><guid>https://mapletree.moe/posts/icinga2-tutorial-part-0/</guid><description>&amp;lt;no value&amp;gt;</description><content type="text/html" mode="escaped"><![CDATA[<h1 id="icinga2-tutorial-series">Icinga2 Tutorial Series<a href="#icinga2-tutorial-series" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<ul>
<li>Icinga2 Tutorial: Part 0 - Introduction <strong>(You are here.)</strong></li>
<li><a href="/posts/icinga2-tutorial-part-1">Icinga2 Tutorial: Part 1 - Installation and Configuration</a></li>
<li><a href="/posts/icinga2-tutorial-part-2">Icinga2 Tutorial: Part 2 - Agent-Less Checks</a></li>
<li><a href="/posts/icinga2-tutorial-part-3">Icinga2 Tutorial: Part 3 - Agent-Based Checks</a></li>
<li><a href="/posts/icinga2-tutorial-part-4">Icinga2 Tutorial: Part 4 - Expanding Checks to SNMP</a></li>
</ul>
<p><strong>EDIT (2018/12/09):</strong> <em>These guides haven&rsquo;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.</em></p>
<h1 id="introduction">Introduction<a href="#introduction" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h1>
<p>This will be a bit more informal than most of my posts as this is more of a
hobby project than anything with really standardized applications. I’ve been
exploring the network protocols available to me on my EdgeRouter now for the
past year, and last night I sat down and taught myself SNMP. After three
hours and poking around the MIBs, I realized that I absolutely hate SNMP.
That being said, I very much like the idea of it. I have to use a CLI and
a GUI on the same device most of the time to watch all the stats I like to
watch, and I immensely dislike putting that kind of rendering work on my
EdgeRouter, because I can assure you, the poor thing is taxed enough.</p>
<p>So I started exploring multi-protocol management systems today. Clearly,
Spiceworks is one of the best programs you can get. However, it is Windows
only. Here on Linux, I really only have NAGIOS, or so I thought.</p>
<h2 id="enter-icinga2">Enter Icinga2<a href="#enter-icinga2" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h2>
<p>Icinga2 is a very interesting program to me in the same way that Maxthon
was a very interesting browser. Both Maxthon 2 and Icinga 1 were built on top
of existing applications (Internet Explorer and NAGIOS, respectively) with the
intent of expanding their functionality. I know a good many people who would
insist that NAGIOS has all the functionality you could ever need, and I would
agree, except for one thing. If I want ease of configuration, I have to pay
<a href="https://assets.nagios.com/handouts/nagiosxi/Nagios-XI-2014-Pricing-Documentation.pdf">$2000USD</a> for my small home network. I don’t have that kind of money, and
if I did, you can bet your ass it would go to getting me embedded development
boards or external controllers for debugging and programming. Anyways, then
Maxthon 3 came out, and it stepped away from the Trident engine, and went with
Google’s WebKit. Just like Maxthon, Icinga2 has stepped away from NAGIOS and has
become its own solution, but still remains compatibility with NAGIOS monitoring
plugins.</p>
<h2 id="purpose-of-these-posts">Purpose of These Posts<a href="#purpose-of-these-posts" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h2>
<p>At first this was just going to be something fun for me to do. However, I have
noticed a somewhat disturbing lack of end to end documentation for Icinga.
Yes, all the information is there in the <a href="https://docs.icinga.org/icinga2/latest/doc/module/icinga2/toc">manuals</a>, but it is still nice to
see how someone sets it up from end to end. This series of posts is going to
show how to do just that, starting with how to install Icinga, which will go up
in the next post.</p>
<h2 id="some-things-to-consider">Some Things to Consider<a href="#some-things-to-consider" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round" class="feather">
      <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path>
      <line x1="8" y1="12" x2="16" y2="12"></line>
   </svg></a></h2>
<p>This is my first time using Icinga2. You will be learning right along with me.
Which means some posts may spend a lot of time going back and working on things
that should have already been done. Besides that, I am not using an Icinga
dedicated machine, which means I am running a desktop release, Linux Mint
Debian Edition 2 to be exact. I like 2. It is a good number. Also the
distribution is really nice, and DOESN’T have systemd, but
that’s a post for another day.</p>
<p>Additionally, my deployment is rather small. All told I will be monitoring
about 10 devices at most across four or five protocols, a fairly standard home
network. I will keep adding updates the more I learn about it, or if I add more
services. However, you may need to do some extra research to tweak things for
your deployment.</p>
<p>I do plan to branch off into Netflow at some point. So you can expect
that in the future.</p>
]]></content></item></channel></rss>