Updates from March, 2011 Toggle Comment Threads | Keyboard Shortcuts

  • Jeff Forman 1:18 pm on March 6, 2011 Permalink
    Tags: apc, , , snmp, ups   

    Remind Me: Adding SNMP mibs for querying 

    I was having issues trying to get Nagios to more easily query my APC UPS with the APC-provided MIB. It took me a while to figure out the right bits both on the file system and in my query to have the MIB ‘processed.’ I still don’t know how to add that MIB to the “automatically process me too if snmpwalk is run” piece of the puzzle.

    But for what I have running a home, some notes for myself and others who ripped out enough hair already.

    jforman@monitor:/usr/share/snmp/mibs$ ls
    powernet401.mib
    
    jforman@monitor:~$ cat /etc/snmp/snmp.conf
    mibs +PowerNet-MIB
    
    jforman@monitor:/usr/share/snmp/mibs$ snmpwalk -v1 -c snmpcommunity ups1 apc
    PowerNet-MIB::upsBasicIdentModel.0 = STRING: "SMART-UPS 700"
    PowerNet-MIB::upsBasicIdentName.0 = STRING: "ups1"
    PowerNet-MIB::upsAdvIdentFirmwareRevision.0 = STRING: "50.14.D"
    .....
    

    Relevant Nagios configs:

    define service {
           use                              generic-service
           check_command                    snmp_apcups_batterystatus!snmpcommunity
           service_description              UPS Battery Status
           host_name                        ups1
    }
    
    define command {
           # OID corresponds to: PowerNet-MIB::upsBasicBatteryStatus.0
           command_name      snmp_apcups_batterystatus
           command_line      /usr/lib/nagios/plugins/check_snmp -H '$HOSTADDRESS$' -C '$ARG1$' -o upsBasicBatteryStatus.0 -s "batteryNormal(2)"
    }
    

    Help and inspiration courtesy of http://www.cuddletech.com/articles/snmp/node13.html

     
  • Jeff Forman 10:35 pm on November 16, 2010 Permalink  

    Howto: Git, hooks, Nagios, oh my. 

    At work we have a monitoring configuration workflow where our Nagios config files are parsed and generated before they are allowed to be ‘svn commit’ed. I know this verification has saved me many times when trying to add new hosts or services, since everything might not be ready for prime time. I wanted to see if I could recreate this scenario at home using Git hooks, if only for my own interest and curiosity.

    My proposed workflow: Start with a local clone of the Nagios configs. Add a host,  service, or contact to a local nagios Config file. Git commit locally. Git push to the remote repo on the monitoring box. The Nagios config parser would run remotely verifying the syntactic-correctness of the proposed-check in. If these checks fail, reject the push. If parsing succeeds, accept the push, and restart Nagios (hence reloading the new configs). I wanted to alleviate the need for an admin to log into the monitoring machine at all. This would eliminate the need to add sudo permissions to a group of users to allow them to restart the Nagios service.

    Without further delay, on to the code. The first piece, was the pre-receive hook with Git. I used this hook specifically because it has the power to accept or reject a push.

    Behold, $git_repo/.hooks/pre-receive:

    #!/bin/bash
    while read OLD_SHA1 NEW_SHA1 REFNAME; do
     export GIT_WORK_TREE=/tmp/nagiosworkdir
     /usr/bin/git checkout -f $NEW_SHA1
     sed -i "s|cfg_dir=CHANGEWITHGIT|cfg_dir=${GIT_WORK_TREE}\/config|g" $GIT_WORK_TREE/nagios.cfg
     sudo -u root /bin/chgrp -R nagios $GIT_WORK_TREE
     sudo -u root /usr/sbin/nagios3 -v $GIT_WORK_TREE/nagios.cfg > $GIT_WORK_TREE/check.out
     NAGIOS_CHECK_STATUS=$?
     echo "Nagios Config Check Exit Status:" $NAGIOS_CHECK_STATUS
     if [ "$NAGIOS_CHECK_STATUS" -ne 0 ]
       then
       echo "Your configs did not parse correctly, there was an error. Output follows."
       cat $GIT_WORK_TREE/check.out
       exit 1
     else
       echo "Your configs look good and parsed correctly."
       exit 0
     fi
    done
    

    The operations here flow from checking out the pending push to a ‘temporary directory’ (explained below), and then making a slight modification to the nagios.cfg to handle our temp configs being somewhere other than the Nagios install directory. This is needed since we want to parse our configs, and not the ones currently in-use on the machine. After this is done, we parse the output of that check, and based upon that output, either accept or reject the push. In the case of a rejection, the output of the verification is printed for the user to see. This output is pretty clear when explaining where the error is.

    And now the post-receive:

    #!/bin/bash
    cd /etc/nagios3/testing
    /usr/bin/env -i /usr/bin/git pull
    echo "Restarting Nagios now"
    sudo -u root /usr/sbin/service nagios3 restart
    

    The post-receive happens after the entire process is done [1]. We change into the directory of the Git clone of your monitoring config repository. which itself is inside /etc/nagios3, and execute a ‘git pull.’ The need to wrap it around ‘env’ is because of an issue I also learned in this process. [2] The GIT_DIR directory is set to the directory of your repository. In this case, we must change to another directory on this machine, which is outside of our initial Git repo. Therefore we must ‘unset’ this variable, which is what the ‘env’ execution does.

    This is pretty straightforward for the most part. The part of the process new to me was the GIT_WORK_TREE. I received a a pretty simple explanation from the author of Gitolite. He explained that the work tree directory is a directory where the potential new commit can be checked out before it is actually allowed to be pushed into the remote repository. Essentially, the opposite of a bare repository. The reason I do this is because I want to do the parsing check before I actually allow the push. I can’t ‘git pull’ the new repository directly into the Nagios configuration directory before it is actually committed. GIT_WORK_TREE allows this intermediary functionality.

    The reasoning for the ‘sed’ modification in that file is that since I will be checking-out the intermediary files into a new directory, I need a Nagios config file that references this intermediary directory. How did I get around this? I copied the nagios.cfg file I would run my install with into the repo, and changed the cfg_dir directory to something I can easily modify during the check in (cfg_dir=CHANGEWITHGIT). This file is not expected to be used on the actual server, so do not copy this one over your actual Nagios.cfg file.

    The chgrp magic is because the user who runs the Nagios application must have read access to the configuration files.

    Relevant sudoers lines needed:

    git ALL=(ALL) NOPASSWD: /bin/chgrp -R nagios /tmp/nagiosworkdir
    git ALL=(ALL) NOPASSWD: /usr/sbin/nagios3 -v /tmp/nagiosworkdir/nagios.cfg
    git ALL=(ALL) NOPASSWD: /usr/sbin/service nagios3 restart
    

    The three lines above are as such. (1) Allow the git user to, without a password, change the group of the temporary Nagios work dir. (2) Allow the git user to, without password, run the verification of the to-be-committed files. (3) Actually restart the Nagios service.

    A successful commit, including a restart of Nagios looks like the following:

    jforman@merlot:~/devel/testing/config$ git commit . && git push
    [master 2f796e3] testing for the blog post
     1 files changed, 1 insertions(+), 1 deletions(-)
    Counting objects: 7, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (4/4), done.
    Writing objects: 100% (4/4), 394 bytes, done.
    Total 4 (delta 2), reused 0 (delta 0)
    remote: Previous HEAD position was ca6dd74... fix now
    remote: HEAD is now at 2f796e3... testing for the blog post
    remote: Nagios Config Check Exit Status: 0
    remote: Your configs look good and parsed correctly.
    remote: From /home/git/repositories/testing
    remote:    ca6dd74..2f796e3  master     -> origin/master
    remote: Updating ca6dd74..2f796e3
    remote: Fast-forward
    remote:  config/contacts_nagios2.cfg |    2 +-
    remote:  1 files changed, 1 insertions(+), 1 deletions(-)
    remote: Restarting Nagios now
    remote:  * Restarting nagios3 monitoring daemon nagios3
    remote: 
    remote:    ...done.
    To git@monitor:testing.git
       ca6dd74..2f796e3  master -> master
    

    This was definitely an eye-opening learning process for me into all the moving parts of Git. I hope this Howto helps those out there looking for a solution like this. Enjoy!

    Addendum:

    For those wondering about the various permissions of the git_work_tree directory and also the repo checkout inside /etc/Nagios3:

    monitor:/tmp/nagiosworkdir

    drwxrwxr-x  3 git  nagios  4096 2010-11-16 16:13 nagiosworkdir
    

    monitor:/etc/nagios3/testing

    drwxr-xr-x  4 git  nagios  4096 2010-11-15 08:36 testing
    

    [1] http://progit.org/book/ch7-3.html

    [2] http://debuggable.com/posts/git-tip-auto-update-working-tree-via-post-receive-hook:49551efe-6414-4e86-aec6-544f4834cda3

     
  • Jeff Forman 7:52 pm on September 26, 2010 Permalink  

    Network printing at home, over-engineered. 

    Compared to most other home networks, mine is a bit more complicated. I admit networking has always been an interest of mine, so I run my own OpenBSD firewall/router/vpn-endpoint, which itself runs the ISC Dhcpd v3 and BIND. With these together, I am able to run dynamic DNS. But some background first.

    Insert my 11-year old HP2100m printer that I have outfitted with an HP Jetdirect 610N 10/100 internal print server. This allows me to stick this printer on my network and print away, no intermediary required. What does this save? The printer is not tied to one computer’s parallel/USB port. I can shut off my main desktop, and still print over the network.

    The next problem: Who wants to print to 10.10.0.205? Hard coding an IP address into the printer config is just asking for bad news, especially with DHCP involved. Better yet, if I shut off the printer for a week, its DHCP lease could expire, and upon restarting the printer, it could grab 10.10.0.215. Now I have to go around and fix my printer config, my wife’s, and all the other devices.

    Enter dynamic DNS:

    Snippet from /etc/dhcpd.conf:

    # Dynamic Updates
    ddns-updates on;
    ddns-update-style interim;
    
    host hp2100m {
        hardware ethernet 00:01:e6:23:df:4f;
        ddns-hostname "hp2100m";
    }
    

    Here we see I have specified the MAC address of the print server and the dynamic dns host name. According to the page which I stole most of the information from, you can specify a ddns-domain-name as well. When trying to do that, I recieved the following error:

    /etc/dhcpd.conf line 60: semicolon expected.
    ddns-domain-name "home.jeffreyforman.net"
    

    Even with the semicolons present, I still need to tinker around with that line and figure out why I can’t set the domain name explicitly. I can only assume the domain name is deduced according to the layer 3 subnet which the printer is on.

    Now you need the BIND configuration from named.conf

    zone "home.jeffreyforman.net" IN {
     type master;
     file "master/db.home.jeffreyforman.net";
     allow-update { key "ddns-key"; };
    };
     
    zone "0.10.10.in-addr.arpa" IN {
     type master;
     file "master/db.10.10.0";
     allow-update { key "ddns-key"; };
    };
    

    These are the forward and reverse DNS respectively. Using a shared key, this enables only the allowed DHCPd to enable DNS records on this particular BIND server.

    Snippet from daemon log:

    Sep 24 08:29:12 formangate dhcpd: DHCPDISCOVER from 00:01:e6:23:df:4f via vr1
    Sep 24 08:29:13 formangate dhcpd: DHCPOFFER on 10.10.0.205 to 00:01:e6:23:df:4f (hp2100m) via vr1
    Sep 24 08:29:18 formangate dhcpd: Added new forward map from hp2100m.home.jeffreyforman.net to 10.10.0.205
    Sep 24 08:29:18 formangate dhcpd: added reverse map from 205.0.10.10.in-addr.arpa to hp2100m.home.jeffreyforman.net
    Sep 24 08:29:18 formangate dhcpd: DHCPREQUEST for 10.10.0.205 (10.10.0.1) from 00:01:e6:23:df:4f (hp2100m) via vr1
    Sep 24 08:29:18 formangate dhcpd: DHCPACK on 10.10.0.205 to 00:01:e6:23:df:4f (hp2100m) via vr1
    

    This shows the DHCP server interacting with the printer, and then sending the new forward and reverse DNS mappings to the DNS server.

    I can now ping hp2100m from machines at home, and configure all printing to use that hostname, no matter what IP address it points to.

    jforman@server1f:~$ ping hp2100m
    PING hp2100m.home.jeffreyforman.net (10.10.0.205) 56(84) bytes of data.
    64 bytes from hp2100m.home.jeffreyforman.net (10.10.0.205): icmp_seq=1 ttl=64 time=5.69 ms
    

    *Note: The configuration snippets above are not complete, and will require other information to complete this roll out and enable Dynamic DNS.

     
  • Jeff Forman 7:46 am on September 24, 2010 Permalink  

    Testing wp->twitter oath 

    Is this new oAuth thing the apocalypse we all predicted?

     
  • Jeff Forman 9:13 pm on July 25, 2010 Permalink  

    New and Shiny – Comcast IPv6 

    A few months ago Comcast began publicizing their IPv6 trials for their customers. For those who don’t have a lot of spare time, IPv6 is the next addressing system for the Internet. Currently IPv4 is the predominant addressing system, akin to a phone number. With the growing number of people using the global Internet, these numbers are bound to run out. Various predictions have put this exhaustion anywhere from tomorrow to a hundred years from now for that Internet-apocalypse to arrive. IPv6 among other things, offers a near limit-less number of addresses (2^128 for the curious).

    Comcast, loved or hated, started IPv6 trials on their own network, turning up customers on their (trial?) IPv6 network. Since IPv6 is not in widespread use today, and not all destinations on the Internet can handle v6 requests, there are several stop-gap solutions. One of them is IPv6 6RD, where RD stands for “Rapid deployment.” From my little understanding, this allows Comcast customers to encapsulate v6 traffic inside v4 packets through Comcast’s network to the IPv6-enabled destinations.

    Without further wait, this is how I did it (save the several weeks of headbanging frustration that ensued):

    Comcast provides their customers with some network addressing information:

    IPv6 prefix = 2001:55c::/32
    6rd BR FQDN = 6rd.comcast.net
    IPv4 prefix length = 0</pre>
    

    Having only a very cursory knowledge of IPv6 addressing, I stumbled my way through the configuration. The IPv6 prefix is used to determine the breadth of Comcast’s v6 network, which octets are network bits, and what bits are host bits. The BR FQDN (border router, fully qualified domain name) is the IPv4 hostname for the gateway in which my firewall will connect to reach the “v6 Internet.” IPv6 packets are encapsulated inside v4 packets, and passed through this border router for further transit.

    On to the configuration. First off, I use OpenBSD 4.7 on my firewall/router. It runs on a little embedded box, using pf as the firewall packet filter.

    First we must set some system variables via sysctl (via command line and commit to /etc/sysctl.conf):

    net.inet6.ip6.accept_rtadv=0
    net.inet6.ip6.forwarding=0
    

    These two variables tell your machine not to accept router advertisements (don’t act like a DHCP client accepting network configuration), and the second one tells your machine not to forward IPv6 packets. v6 unlike v4, for the most part, obviates the need for NAT. Therefore if this value were ’1′, you would be forwarding v6 traffic from the external Internet to all v6-enabled devices on your home network. Unless you really intend to open up your home network to the entire Internet, keep this value as 0 for now.

    I created a little shell script that creates the tunnel interface (gif0), and then configures the interface and default routes.

    #!/bin/sh -x
    WANIP=`ifconfig vr0 | grep -v inet6 | grep inet | awk '{print $2}'`
    HOSTRD=`host 6rd.comcast.net | awk '{print $4}'`
    V6PREFIX=`printf '%02x%02x:%02x%02x' $(echo $WANIP | tr . ' ')`
    ifconfig gif0 destroy
    ifconfig gif0 create
    ifconfig gif0 tunnel ${WANIP} ${HOSTRD}
    ifconfig gif0 inet6 2001:55c:${V6PREFIX}::1 prefixlen 32
    ifconfig gif0 up
    route -n add -inet6 default ::1 -ifp gif0
    

    The nasty bits are mostly in the first three variables.
    WANIP is the external IPv4 IP of my firewall
    HOSTRD is the IPv4 IP of Comcast’s IPv6 border router
    V6PREFIX: This takes WANIP and converts the IP into its hexadecimal equivalent. This is the format used in IPv6 addresses, and will make up the rest of my personal IPv6 prefix.

    Most of the script is self explanatory, and large chunks are stolen from others on the Comcast IPv6 message boards. I have set my external IPv6 tunnel interface to $prefix::1, and set the route for all IPv6 traffic to go out over the gif0 tunnel interface.

    At this point, if pf is disabled (therefore allowing all packets through to your machine), you should be able to ping6/traceroute6 to various IPv6-enabled Internet sites. These include ipv6.google.com, http://www.kame.net and ipv6.comcast.net.

    # traceroute6 ipv6.google.com
    traceroute6: Warning: ipv6.l.google.com has multiple addresses; using 2001:4860:800f::63
    traceroute6 to ipv6.l.google.com (2001:4860:800f::63) from 2001:55c:MY:PREFIX::1, 64 hops max, 12 byte packets
    1  2001:55c:MY:PREFIX::1  21.491 ms  19.103 ms  22.759 ms
    2  2001:558:e0:52::1  20.734 ms  19.227 ms  16.623 ms
    3  2001:558:e0:24::1  17.903 ms  18.821 ms  19.193 ms
    4  te-0-3-0-4-cr01.newyork.ny.ibone.comcast.net  21.704 ms  23.512 ms  24.715 ms
    5  pos-1-12-0-0-cr01.mclean.va.ibone.comcast.net  27.821 ms  41.616 ms  31.4 ms
    6  pos-0-3-0-0-pe01.ashburn.va.ibone.comcast.net  25.451 ms  34.823 ms  25.43 ms
    7  2001:558:0:f749::2  29.801 ms  39.119 ms  33.211 ms
    8  Vlan22.icore1.AEQ-Ashburn.ipv6.as6453.net  34.592 ms  36.29 ms  33.039 ms
    9  pr61.iad07.net.google.com  34.766 ms  34.493 ms  39.389 ms
    10  2001:4860::1:0:9ff  34.941 ms  35.911 ms  32.12 ms
    11  2001:4860:0:1::149  37.298 ms 2001:4860:0:1::14b  48.993 ms 2001:4860:0:1::149  37.446 ms
    12  iad04s01-in-x63.1e100.net  36.593 ms  31.367 ms  33.089 ms</pre>
    

    This post only involves getting your gateway machine speaking IPv6. I have been able to wire up the rest of my internal LAN using rtadvd, and allow them IPv6 access. There are a lot more pieces here, including rtadvd and packet filtering that I don’t quite fully understand yet how they all interact, and will require another post.

    Added update
    To use tcpdump to watch IPv6 traffic: tcpdump -i $interface ip6

     
c
compose new post
j
next post/next comment
k
previous post/previous comment
r
reply
e
edit
o
show/hide comments
t
go to top
l
go to login
h
show/hide help
shift + esc
cancel