MRTG with URONode

Introduction

This page explains how to set up and graph/monitor your traffic on your URONode interfaces using MRTG/RRDTool/SNMP on your web server. I run a 3-tier type setup with a generic multi-graph, a generic listing of individual interfaces, and then finally one with more specific data on a specific interface. Setup is fairly simple but the SNMP side of things may seem confusing. I hope to shed some light on this for you.

What you'll need

Since you'll be viewing these locally on a web server you'll want to install one. I prefer Apache2 but you can use something so basic as your JNOS2 web server to view your web pages! Just insure you use JNOS2's naming schema for your .html files. You'll also need MRTG, RRDTool, SNMP, SNMPD... and of course your favorite text editor as you'll need to edit some files. I use a debian-based distro and these are all within the repositories. You can install them as root be executing:
apt-get install mrtg rrdtool snmp snmpd libsnmp-base (apache2)
You'll be doing your own custom configs so we'll tackle the configs further down. Once you have the packages installed, you'll be off to the races in your configurations.

SNMP/SNMPD

First, if you run a firewall you'll want to insure you at least have local access to your own local UDP port 161 which is the SNMP port. If you don't then you'll be denied your statistics readings and graphing will reflect nothing since it won't have any data to graph. There will be two files to configure here:
/etc/snmp/snmp.conf
/etc/snmp/snmpd.conf
You'll want to choose a community name (typically your server's name – HP/Pi/callsign/etc) and a username you'll want to use to query your data. I use “uronode” since that's what the purpose of the graphing will be – polling uronode interface traffic.

SNMP Client config

Configuring your client by default install on debian based systems will contain one line however this line will prevent you from polling the data you want. Just comment it out:


n1uro@n1uro:~$ sudo cat /etc/snmp/snmp.conf
#
# As the snmp packages come without MIB files due to license reasons, loading
# of MIBs is disabled by default. If you added the MIBs you can reenable
# loaging them by commenting out the following line.
# mibs :

By specifying a list of MIBs you'll be telling the client to ignore others so unless you know which you need just allow it to query them all if needed.

SNMPD Server config

Configuring the server is a bit trickier as you have 2 places you need to edit:
/etc/default/snmpd and
/etc/snmp/snmpd.conf
Let's start with the file in the /etc/default directory. Configure it so that it reads as such:


n1uro@n1uro:~$ cat /etc/default/snmpd
# This file controls the activity of snmpd and snmptrapd

# Don't load any MIBs by default.
# You might comment this lines once you have the MIBs downloaded.
export MIBS=/usr/share/snmp/mibs

# snmpd control (yes means start daemon).
SNMPDRUN=yes

# snmpd options (use syslog, close stdin/out/err).
SNMPDOPTS='-Lsd -Lf /dev/null -u snmp -g snmp -I -smux -p /var/run/snmpd.pid'

# snmptrapd control (yes means start daemon).  As of net-snmp version
# 5.0, master agentx support must be enabled in snmpd before snmptrapd
# can be run.  See snmpd.conf(5) for how to do this.
TRAPDRUN=no

# snmptrapd options (use syslog).
TRAPDOPTS='-Lsd -p /var/run/snmptrapd.pid'

# create symlink on Debian legacy location to official RFC path
SNMPDCOMPAT=yes

Save this file. Now let's take a look at my /etc/snmp/snmpd.conf file:


###############################################################################
#
# EXAMPLE.conf:
#   An example configuration file for configuring the Net-SNMP agent ('snmpd')
#   See the 'snmpd.conf(5)' man page for details
#
#  Some entries are deliberately commented out, and will need to be explicitly a
ctivated
#
###############################################################################
#
#  Some entries are deliberately commented out, and will need to be explicitly activated
#
###############################################################################
#
#  AGENT BEHAVIOUR
#
#  Listen for connections from the local system only BUT you must use your 44-net IP:
agentAddress  udp:44.x.x.x:161
#  Listen for connections on all interfaces (both IPv4 *and* IPv6)
#agentAddress udp:161,udp6:[::1]:161



###############################################################################
#
#  SNMPv3 AUTHENTICATION
#
#  Note that these particular settings don't actually belong here.
#  They should be copied to the file /var/lib/snmp/snmpd.conf
#     and the passwords changed, before being uncommented in that file *only*.
#  Then restart the agent

#  createUser authOnlyUser  MD5 "remember to change this password"
#  createUser authPrivUser  SHA "remember to change this one too"  DES
#  createUser internalUser  MD5 "this is only ever used internally, but still change the password"

#  If you also change the usernames (which might be sensible),
#  then remember to update the other occurances in this example config file to match.



###############################################################################
#
#  ACCESS CONTROL
#

                                                 #  system + hrSystem groups only
view   systemview  included   .1.3.6.1.2.1.1
view   systemview  included   .1.3.6.1.2.1.25.1
view   systemview  included   .1
                                                 #  Full access from the local host
#rocommunity public  localhost
                                                 #  Default access to basic system info
# rocommunity uronode  default    -V systemview

                                                 #  Full access from an example network
                                                 #     Adjust this network address to match your 44-net
                                                 #     settings, change the community string,
                                                 #     and check the 'agentAddress' setting above
rocommunity uronode 44.x.x.x
#rocommunity secret  10.0.0.0/16

                                                 #  Full read-only access for SNMPv3
 rouser   authOnlyUser
                                                 #  Full write access for encrypted requests
                                                 #     Remember to activate the 'createUser' lines above
#rwuser   authPrivUser   priv
#  It's no longer typically necessary to use the full 'com2sec/group/access' configuration
#  r[ou]user and r[ow]community, together with suitable views, should cover most requirements



###############################################################################
#
#  SYSTEM INFORMATION
#
#  Note that setting these values here, results in the corresponding MIB objects being 'read-only'
#  See snmpd.conf(5) for more details
sysLocation    UNIVLE
sysContact     Brian <brian@nc-ct.net>
                                                 # Application + End-to-End layers
sysServices    72
#
#  Process Monitoring
#
                               # At least one  'mountd' process
proc  mountd
                               # No more than 4 'ntalkd' processes - 0 is OK
proc  ntalkd    4
                               # At least one 'sendmail' process, but no more than 10
proc  sendmail 10 1

#  Walk the UCD-SNMP-MIB::prTable to see the resulting output
#  Note that this table will be empty if there are no "proc" entries in the snmpd.conf file
#
#  Disk Monitoring
#
                               # 10MBs required on root disk, 5% free on /var, 10% free on all other disks
disk       /     10000
disk       /var  5%
includeAllDisks  10%

#  Walk the UCD-SNMP-MIB::dskTable to see the resulting output
#  Note that this table will be empty if there are no "disk" entries in the snmpd.conf file
#
#  System Load
#
                               # Unacceptable 1-, 5-, and 15-minute load averages
load   12 10 5
#  Walk the UCD-SNMP-MIB::laTable to see the resulting output
#  Note that this table *will* be populated, even without a "load" entry in the snmpd.conf file
###############################################################################
#
#  ACTIVE MONITORING
#
                                    #   send SNMPv1  traps
 trapsink     localhost uronode
                                    #   send SNMPv2c traps
#trap2sink    localhost public
                                    #   send SNMPv2c INFORMs
#informsink   localhost public
#  Note that you typically only want *one* of these three lines
#  Uncommenting two (or all three) will result in multiple copies of each notification.
#
#  Event MIB - automatically generate alerts
#
                                   # Remember to activate the 'createUser' lines above
iquerySecName   internalUser
rouser          internalUser
                                   # generate traps on UCD error conditions
defaultMonitors          yes
                                   # generate traps on linkUp/Down
linkUpDownNotifications  yes
###############################################################################
#
#  EXTENDING THE AGENT
#
#  Arbitrary extension commands
#
 extend    test1   /bin/echo  Hello, world!
 extend-sh test2   echo Hello, world! ; echo Hi there ; exit 35
#extend-sh test3   /bin/sh /tmp/shtest
#  Note that this last entry requires the script '/tmp/shtest' to be created first,
#    containing the same three shell commands, before the line is uncommented
#  Walk the NET-SNMP-EXTEND-MIB tables (nsExtendConfigTable, nsExtendOutput1Table
#     and nsExtendOutput2Table) to see the resulting output
#  Note that the "extend" directive supercedes the previous "exec" and "sh" directives
#  However, walking the UCD-SNMP-MIB::extTable should still returns the same output,
#     as well as the fuller results in the above tables.
#
#  "Pass-through" MIB extension command
#
#pass .1.3.6.1.4.1.8072.2.255  /bin/sh       PREFIX/local/passtest
#pass .1.3.6.1.4.1.8072.2.255  /usr/bin/perl PREFIX/local/passtest.pl
# Note that this requires one of the two 'passtest' scripts to be installed first,
#    before the appropriate line is uncommented.
# These scripts can be found in the 'local' directory of the source distribution,
#     and are not installed automatically.
#  Walk the NET-SNMP-PASS-MIB::netSnmpPassExamples subtree to see the resulting output
#
#  AgentX Sub-agents
#
                                           #  Run as an AgentX master agent
 master          agentx
                                           #  Listen for network connections (from localhost)
                                           #    rather than the default named socket /var/agentx/master
#agentXSocket    tcp:localhost:705

Save and restart snmpd, chances are you may run “service snmpd restart” to restart it. Test your configuration by running the following command: snmpwalk -v 1 -c <user> <server> ifName and if it's successful you'll see a listing of your network interfaces and their number:


root@n1uro:/home/n1uro# snmpwalk -v 1 -c uronode 44.88.0.9  ifName
IF-MIB::ifName.1 = STRING: lo
IF-MIB::ifName.2 = STRING: ra0
IF-MIB::ifName.3 = STRING: tunl0
IF-MIB::ifName.4 = STRING: nr0
IF-MIB::ifName.5 = STRING: nr1
IF-MIB::ifName.6 = STRING: nr2
IF-MIB::ifName.7 = STRING: nr3
IF-MIB::ifName.8 = STRING: ax0
IF-MIB::ifName.9 = STRING: ax1
IF-MIB::ifName.10 = STRING: sl0
IF-MIB::ifName.11 = STRING: ax2
IF-MIB::ifName.12 = STRING: ax3
IF-MIB::ifName.13 = STRING: ax4
IF-MIB::ifName.14 = STRING: rose0
IF-MIB::ifName.15 = STRING: rose1
IF-MIB::ifName.16 = STRING: rose2
IF-MIB::ifName.17 = STRING: rose3
IF-MIB::ifName.18 = STRING: rose4
IF-MIB::ifName.19 = STRING: rose5
IF-MIB::ifName.20 = STRING: rose6
IF-MIB::ifName.21 = STRING: rose7
IF-MIB::ifName.22 = STRING: rose8
IF-MIB::ifName.23 = STRING: rose9
IF-MIB::ifName.25 = STRING: tap0
IF-MIB::ifName.44 = STRING: tun0

If you see something similar then you've configured your snmp/snmpd correctly. If not, then go back and double check the configuration of your files, restart snmpd and retest. This should complete this section.

MRTG Configuration

This is very straight forward as MRTG comes with it's own configuration utility. By default, mrtg will place it's configuration file in /etc/mrtg.cfg but I prefer to make mine in the directory that the graphs and databases will live, typically this will be a path within your web server directory. Test what the file will create by typing:

cfgmaker <username>@<44.x.x.x>.

If you try to use your localhost/127.0.0.1 you'll get errors so insure you use the amprnet IP assigned to your tunl0 interface. You'll see a bunch of stuff on the screen most of it with comments in the lines. For some reason cfgmaker is not familiar with ham-based network interfaces but it does see them so it just comments them out. Rerun “cfgmaker <username>@<44.x.x.x> > /path/to/web/dir/mrtg.cfg and then open mrtg.cfg. UNCOMMENT everything that's been commented out.

Test your mrtg system by running: env LANG=C /usr/bin/mrtg /path/to/mrtg.cfg, wait at least 60 seconds and run it again. Then open your web browser and try to open one of the .png files or .html files. Hopefully you'll see data starting to build. If not then you have an error and you'll need to debug.

RRDTool Configuration

What I do first is cp mrtg.cfg mrtgrrd.cfg so you have a separate mrtg config file for your rrdtool database files. Edit mrtgrrd.cfg and under the global options add the line:
LogFormat: rrdtool
and save the file. The rrdtool graphs will be made by a simple shell script you can cron later after doing successful testing. I do mine in 3 sections:
ax.25 interfaces
internal network interfaces
external facing network interfaces
One thing you'll notice with Rose and NetRom interfaces is that no data is collected by the kernel. This is because they're encapsulated under the ax.25 interfaces so since those interfaces will collect the data, there's no sense or reason to duplicate the byte count for graphing it'll simply be collected under your native ax.25 interfaces. My file looks as such:


--- start gengraph.sh ---
cd /path/to/working/directory

# run MRTG for both regular and rrdtool databases, prohibit screen
# output for cron purposes:
env LANG=C /usr/bin/mrtg /path/to/working/directory/mrtg.cfg > /dev/null 2>&1
env LANG=C /usr/bin/mrtg /path/to/working/directory/mrtgrrd.cfg > /dev/null 2>&1

now=`date | awk '{print $1 " " $2 " " $3 " " $6 " "'}`
end=$(date +%r)
now_formatted=`echo -n $now; echo -n " "; echo $end`
# Make rrdtool graphs for ax25 interfaces:
rrdtool graph ax25day.png -a PNG \
\
 -A --width 850 --height 200 \
 --title "AXIP/AXUDP interfaces traffic inbound (+) and outbound (-) on ALIAS:CALLSIGN-SSID at $now_formatted" \
 --vertical-label "(K)Bytes per second in/out (+/-)" \
 --watermark "(©) $(date +%Y) Brian N1URO and Maiko VE4KLM" --font WATERMARK:9 \
\
 DEF:server_ax0_in=server_ax0.rrd:ds0:AVERAGE \
 DEF:server_ax0_out=server_ax0.rrd:ds1:AVERAGE \
 DEF:server_ax1_in=server_ax1.rrd:ds0:AVERAGE \
 DEF:server_ax1_out=server_ax1.rrd:ds1:AVERAGE \
 DEF:server_ax2_in=server_ax2.rrd:ds0:AVERAGE \
 DEF:server_ax2_out=server_ax2.rrd:ds1:AVERAGE \
 DEF:server_ax3_in=server_ax3.rrd:ds0:AVERAGE \
 DEF:server_ax3_out=server_ax3.rrd:ds1:AVERAGE \
 DEF:server_ax4_in=server_ax4.rrd:ds0:AVERAGE \
 DEF:server_ax4_out=server_ax4.rrd:ds1:AVERAGE \
\
 CDEF:server_ax0O=server_ax0_out,-1,* \
 CDEF:server_ax1O=server_ax1_out,-1,* \
 CDEF:server_ax2O=server_ax2_out,-1,* \
 CDEF:server_ax3O=server_ax3_out,-1,* \
 CDEF:server_ax4O=server_ax4_out,-1,* \
\
 AREA:server_ax0_in#00FF00:"ax0 in" \
 AREA:server_ax0O#00FF00:"ax0 out":STACK \
 AREA:server_ax1_in#FF0000:"ax1 in":STACK \
 AREA:server_ax1O#FF0000:"ax1 out":STACK \
 AREA:server_ax2_in#000066:"ax2 in":STACK \
 AREA:server_ax2O#000066:"ax2 out":STACK \
 AREA:server_ax3_in#779922:"ax3 in":STACK \
 AREA:server_ax3O#779922:"ax3 out":STACK \
 AREA:server_ax4_in#FFFF00:"ax4 in":STACK \
 AREA:server_ax4O#FFFF00:"ax4 out":STACK

now=`date | awk '{print $1 " " $2 " " $3 " " $6 " "'}`
end=$(date +%r)
now_formatted=`echo -n $now; echo -n " "; echo $end`
rrdtool graph stackday.png -a PNG \
\
 -A --width 850 --height 200 \
 --title "Internal network interfaces traffic inbound (+) and outbound (-) on UNIVLE:N1URO-5 at $now_formatted" \
 --vertical-label "(K)Bytes per second in/out (+/-)" \
 --watermark "(©) $(date +%Y) Brian N1URO and Maiko VE4KLM" --font WATERMARK:9 \
\
 DEF:server_lo_in=server_lo.rrd:ds0:AVERAGE \
 DEF:server_lo_out=server_lo.rrd:ds1:AVERAGE \
 CDEF:server_loO=server_lo_out,-1,* \
 DEF:server_tun0_in=server_tun0.rrd:ds0:AVERAGE \
 DEF:server_tun0_out=server_tun0.rrd:ds1:AVERAGE \
 CDEF:server_tun0O=server_tun0_out,-1,* \
 DEF:server_tap0_in=server_tap0.rrd:ds0:AVERAGE \
 DEF:server_tap0_out=server_tap0.rrd:ds1:AVERAGE \
 CDEF:server_tap0O=server_tap0_out,-1,* \
 DEF:server_sl0_in=server_sl0.rrd:ds0:AVERAGE \
 DEF:server_sl0_out=server_sl0.rrd:ds1:AVERAGE \
 CDEF:server_sl0O=server_sl0_out,-1,* \
 AREA:server_lo_in#FF0000:"Loopback in":STACK \
 AREA:server_loO#FF0000:"Loopback out":STACK \
 AREA:server_tap0_in#FFFF00:"tap0 in":STACK \
 AREA:server_tap0O#FFFF00:"tap0 out":STACK \
 AREA:server_sl0_in#00FF00:"sl0 in":STACK \
 AREA:server_sl0O#00FF00:"sl0 out":STACK \
 AREA:server_tun0_in#000066:"tun0 in":STACK \
 AREA:server_tun0O#000066:"tun0 out":STACK


now=`date | awk '{print $1 " " $2 " " $3 " " $6 " "'}`
end=$(date +%r)
now_formatted=`echo -n $now; echo -n " "; echo $end`
rrdtool graph inetday.png -a PNG \
\
 -A --width 850 --height 200 \
 --title "Network interfaces traffic inbound (+) and outbound (-) on UNIVLE:N1URO-5 at $now_formatted" \
 --vertical-label "(K)Bytes per second in/out (+/-)" \
 --watermark "(©) $(date +%Y) Brian N1URO and Maiko VE4KLM" --font WATERMARK:9 \
\
 DEF:server_ra0_in=server_ra0.rrd:ds0:AVERAGE \
 DEF:server_ra0_out=server_ra0.rrd:ds1:AVERAGE \
 DEF:server_tunl0_in=server_tunl0.rrd:ds0:AVERAGE \
 DEF:server_tunl0_out=server_tunl0.rrd:ds1:AVERAGE \
\
 CDEF:server_ra0O=server_ra0_out,-1,* \
 CDEF:server_tunl0O=server_tunl0_out,-1,* \
\
 AREA:server_ra0_in#00FF00:"Internet in" \
 AREA:server_ra0O#00FF00:"Internet out":STACK \
 AREA:server_tunl0_in#000066:"Amprnet in":STACK \
 AREA:server_tunl0O#000066:"Amprnet out":STACK
--------- EOF --------

What displays for the actual graph colors is defined in the AREA: section using HEX HTML color codes. You may search for these online if you need to see a pallet or you may visit my link at n1uro.com to see the various codes. Run the script after making it chmod +x so it'll run. You should see *.rrd files, and the various .png files to match what you told the script to make. Verify them with your web browser for integrigy. If successful you can move onto making your main web pages.

Make your HTML files

I make 2 .html files in the directory. One calls the RRDTool graphs as a summary page with links to the individual interfaces day MRTG graphs which then will show links to a more detailed page of all the MRTG graphs for the interface you wish to review. For my RRDTool / main index.html page I do this the following. Note: I call my directory “univle”:

<!DOCTYPE HTML>
<html lang="en">
<META NAME="AUTHOR" CONTENT="N1URO">
<style>
body {
        background-color: lightblue;
}
div {
        text-align: center;
}
img {
        border: 0;
}
</style>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta http-equiv="refresh" content="60">
<TITLE>RRDTOOL/MRTG of URONode Interfaces</TITLE>
</head>
<BODY>
<DIV><H2>Click on a graph to see specifics of the interfaces on UNIVLE:N1URO-5:</H2></DIV>
<div><a href="https://n1uro.ampr.org/univle/univle.html"><img src="https://www.n1uro.com/univle/pastday.png" alt="UNIVLE AXIP/AXUDP links"></a></div>
<div><a href="https://n1uro.ampr.org/univle/univle.html"><img src="https://www.n1uro.com/univle/stackday.png" alt="UNIVLE internal interfaces"></a></div>
<div><a href="https://n1uro.ampr.org/univle/univle.html"><img src="https://www.n1uro.com/univle/inetday.png" alt="UNIVLE network interfaces"></a></div>
<br><div><a href="https://n1uro.ampr.org/">Go </a>to my webserver.</div>
</BODY>
</HTML>

Next I make the secondary tier page I call univle.html:
<!DOCTYPE HTML>
<html lang="en">
<META NAME="AUTHOR" CONTENT="N1URO">
<style>
body {
        background-color: lightblue;
}
div {
        text-align: center;
}
img {
        border: 0;
}
</style>
<TITLE>MRTG of UNIVLE Interfaces</TITLE>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta http-equiv="refresh" content="60">
</HEAD>
<BODY>
<DIV><H2>Click on a graph to see details of that interface from UNIVLE:N1URO-5:</H2><BR></DIV>
<div><a href="https://www.n1uro.com/univle/n1uro_ax0.html"><img src="https://www.n1uro.com/univle/n1uro_ax0-day.png" alt="AXIP"></a></div>
<br><div><a href="https://www.n1uro.com/univle/n1uro_ax1.html"><img src="https://www.n1uro.com/univle/n1uro_ax1-day.png" alt="ROSE interface"></a></div>
<br><div><a href="https://www.n1uro.com/univle/n1uro_ax2.html"><img src="https://www.n1uro.com/univle/n1uro_ax2-day.png" alt="AXUDP"></a></div>
<br><div><a href="https://www.n1uro.com/univle/n1uro_ax3.html"><img src="https://www.n1uro.com/univle/n1uro_ax3-day.png" alt="shim to CTJNOS:N1URO-7"></a></div>
<br><div><a href="https://www.n1uro.com/univle/n1uro_ax4.html"><img src="https://www.n1uro.com/univle/n1uro_ax4-day.png" alt="KISS to X-URO"></a></div>
<br><div><a href="https://www.n1uro.com/univle/n1uro_lo.html"><img src="https://www.n1uro.com/univle/n1uro_lo-day.png" alt="Loopback"></a></div>
<br><div><a href="https://www.n1uro.com/univle/n1uro_ra0.html"><img src="https://www.n1uro.com/univle/n1uro_ra0-day.png" alt="802.11 Wifi"></a></div>
<br><div><a href="https://www.n1uro.com/univle/n1uro_sl0.html"><img src="https://www.n1uro.com/univle/n1uro_sl0-day.png" alt="Slip to MFNOS:N1URO-14"></a></div>
<br><div><a href="https://www.n1uro.com/univle/n1uro_tap0.html"><img src="https://www.n1uro.com/univle/n1uro_tap0-day.png" alt="kernel shim to N1URO-1 pc/FlexNet"></a></div>
<br><div><a href="https://www.n1uro.com/univle/n1uro_tun0.html"><img src="https://www.n1uro.com/univle/n1uro_tun0-day.png" alt="shim to CTJNOS:N1URO-7"></a></div>
<br><div><a href="https://www.n1uro.com/univle/n1uro_tunl0.html"><img src="https://www.n1uro.com/univle/n1uro_tunl0-day.png" alt="IP Encapsulation to AmprNet"></a></div>
<div>Back <a href="/univle">home</a></div>
</BODY>
</HTML>

You'll notice I put in links to each individual interface as I call references to the 24-hour MRTG graph. This allows you to see a listing of each current graph and if you wish you can go in another tier to see more specifics of the history of each interface. Once you create your .html files you can test them with your web browser. Hopefully you'll have success and the pages will auto-refresh for you to keep what you see fairly up-to-date with data. You may need to view the source of the page to see my html code. 73 de N1URO

Back one page.