New toy, Nikon style.

It had only been ‘recently’ that I had purchased myself a micro four-thirds digital camera for my honeymoon. It took pretty good pictures, and I loved its compactness when roaming around Portugal for 10 days. But I had always wanted a bit more control over the photos I took; whether it was exposure modification, lense type, or overall flexiblity for shooting in different situations (low light at night).

‘Lo and behold, Nikon announced the D7000. It had all the features of my Father’s D90, but with better HD video capture, an upgraded AF sensor and a whole host of other functionality too long to list. Patiently I waited for my bonus to be direct deposited, reading up on the manual (a hefty 350 pages), investigating some photography walks and classes in the area. Now in my hot little hands:

The weather finally reached an acceptable temperature where it was just above the level of being uncomfortable for an afternoon stroll. I wandered my way through Somerville and Cambridge on my way through Harvard Square. I captured the below uniquely-painted house. I was mainly playing around with Aperture-priority today, but look forward to digging into more of the image control options to bring out different detail.

Overall the camera is great, not too heavy for a couple hours slung over my shoulder, even with the included Nikon strap and an 18-105mm lens connected. The Op/Tech neoprene strap I have on order should make things a heck of a lot more comfortable when that arrives. I am really looking forward to the weather warming up when I can explore more of Boston with the camera and take it up into the mountains for some day-hikes.

Posted in Outdoors | Tagged , | Comments Off

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

Posted in General | Tagged , , , , | Comments Off

You go here, you go there. Bending DHCP to your will.

TL;DR: How to hand out DNS servers in different orders to different clients based upon MAC address.

Background: I was connected into my office’s VPN a few months ago and was noticed some very slow DNS resolution of host names back at the office. I would attempt to ssh into another host, and the connection would sit there for more than a few seconds before finally proceeding. This didn’t happen for just ssh, but also for making http requests. I dug into my resolv.conf locally and tried sending a few DNS queries via dig to the two DNS servers I was provided. The first one failed, the second one returned immediately with the correct response. I swapped the two entries and DNS resolution locally was back to where I would expect it, very fast. I alerted our IT group and the issue was fixed (the first DNS server had become hung, and needed a process restart).

Curiosity: This got me thinking, was everyone suffering my issue? Did the two DNS servers handed out always come in that same order? If so, DNS would have been slow for everyone. We’d all be timing out trying to query the first server, waiting for our local resolvers to query the second operational server. Could I get a DHCP server to randomize the list of DNS servers to its querying clients?

Assumptions: I am ignoring the fact that our VPN concentrator might not be running the ISC DHCPD, which my examples are based upon. I will split up each DHCP subnet into two groups, in a binary fashion.

How I did it: After doing some Google searches, I came across a post on the mailing list for ISC DHCPD users. It explained that you could do some logic on the incoming MAC address, and based upon that, hand out unique information, among it, DNS, routers, domain names, etc.I was curious to see if I could actually get this working.

I figure the easiest way to do this is paste some config data and go from there.

dhcpd.conf:
class "binary-group-0" {
    match if suffix(binary-to-ascii(2, 8, "", substring(hardware, 6, 1)), 1) = "0";
}

class "binary-group-1" {
    match if suffix(binary-to-ascii(2, 8, "", substring(hardware, 6, 1)), 1) = "1";
}

subnet 10.30.0.0 netmask 255.255.255.0 {
    option routers 10.30.0.1;
    option domain-name "vmtest.jeffreyforman.net";

    pool {
        allow members of "binary-group-0";
        range 10.30.0.20 10.30.0.30;
        option domain-name-servers 1.1.1.1, 2.2.2.2;
        on commit {
            execute("/bin/echo", "GROUP ZERO");
        }
    }
    pool {
        allow members of "binary-group-1";
        range 10.30.0.200 10.30.0.210;
        option domain-name-servers 4.4.4.4, 5.5.5.5;
        on commit {
            execute("/bin/echo", "GROUP ONE");
        }
    }
}

Configuration explination:
On lines 2-8, each named class is populated by clients whose MAC address corresponds to the appropriate ‘match’ line. These match do the following: Starting from the 6th byte of the client’s MAC address, grab one byte of data. Once we have that data, convert the binary data to ascii characters, without a separator using base two, each bit of data being eight bits long. With that data, take a string onecharacter from the end. We have created two classes here, one where the last character is 0 (zero), and the other is 1 (one).

On lines 10-30,we have a standard subnet declaration, with two pools. Each pool (lines 14-20, 21-29) uses the ‘allow members of’ to control which class of users from above the pool applies to. In this instance, we hand out two different ranges and sets of domain name servers depending on what class a user belongs. For my own debugging, I stick an ‘on commit’ execution in each pool. This outputs in the log when a lease is acquired for a particular client, and gave me some explanation about where I was in the config. These ‘on commit’ lines are purely for debugging, and can be removed for production. Clients whose MAC address ends in a binary ’0′, are placed in the 10.30.0.20-30 range with DNS servers 1.1.1.1 and 2.2.2.2. Those whose MAC address ends in a binary ’1′ are given an address in the 10.30.0.200-210 pool, with DNS servers 4.4.4.4, 5.5.5.5. You could easily put your own DNS servers in this section, modifying the order in any way you please.

Log Output:
Using a couple of VM’s on an isolated network at home (and playing with the MAC address of the client), I was able to test my above configuration. Notice on each they are given IP’s from each appropriate range, with the correct ‘echo’ statement being executed.

DHCPDISCOVER from 52:54:00:4c:f3:d4 (testvm1) via re1
DHCPOFFER on 10.30.0.21 to 52:54:00:4c:f3:d4 (testvm1) via re1
execute_statement argv[0] = /bin/echo
execute_statement argv[1] = GROUP ZERO
GROUP ZERO
DHCPREQUEST for 10.30.0.21 (10.30.0.1) from 52:54:00:4c:f3:d4 (testvm1) via re1
DHCPACK on 10.30.0.21 to 52:54:00:4c:f3:d4 (testvm1) via re1

DHCPDISCOVER from 52:54:00:4c:f3:d3 via re1
DHCPOFFER on 10.30.0.201 to 52:54:00:4c:f3:d3 (testvm1) via re1
execute_statement argv[0] = /bin/echo
execute_statement argv[1] = GROUP ONE
GROUP ONE
DHCPREQUEST for 10.30.0.201 (10.30.0.1) from 52:54:00:4c:f3:d3 (testvm1) via re1
DHCPACK on 10.30.0.201 to 52:54:00:4c:f3:d3 (testvm1) via re1

Appendix:
For those curious about how I came to breaking up the MAC address of the client, I became painfully familiar with the dhcp-eval man page. I honestly would not wish that man page on anyone, it is woefully confusing for someone who does not dabble in DHCPD configuration on a daily basis.

MAC Address: 52:54:00:4c:f3:d3

binary-to-ascii(2, 8, ":", hardware);
1:1010010:1010100:0:1001100:11110011:11010011

binary-to-ascii(2,8,".", substring(hardware,6,1));
11010011

suffix(binary-to-ascii(2, 8, ":", hardware), 1);
1

There you have it. Now you can break up your clients into binary groups, handing them different network information depending on where they fall. Obviously if you want to split them up into more than two groups, the match statements become a bit more verbose for each condition. Ultimately this would not have solved my problem of being given a ‘bad’ DNS server first in line for my request (since my MAC address would always be the same), but it does spread the load among DNS servers over local clients. I am now curious, when I get the free time, to play around with creating an on-commit-like command that based upon its execution (generate a random number for example), changes the order of DNS servers handed out to clients.

References:

  • http://easycalculation.com/hex-converter.php
  • http://www.linuxmanpages.com/man5/dhcpd.conf.5.php
  • https://lists.isc.org/pipermail/dhcp-users/2011-February/012784.html
Posted in Open Source/Internet | Tagged , , | Comments Off

Remind me: Configuring BIND9 plugin for Munin on FreeBSD (and Linux)

I was attempting to get Munin working on a new FreeBSD machine, monitoring the rate of queries to a Bind9 DNS server. Every time I attempted ‘munin-run bind9′ I was presented with the same error:

2011/01/29-18:09:55 [3581] Error output from bind9:
2011/01/29-18:09:55 [3581]     Died at /usr/local/etc/munin/plugins/bind9 line 41.
2011/01/29-18:09:55 [3581] Service 'bind9' exited with status 2/0.

Digging around in the Bind9 Munin plugin, line 41 complains about a state file that Munin uses. The plugin immediately tries to open the state file, without checking if the file is actually present. (TODO: Check to see what ramifications there are to just creating the file if it is not present.)

Line 41:

    open(Q,"< $STATEFILE") or die;

After digging around to figure out the plugin state directory (/var/munin/plugin-state, for those following along at home), I was back in business.

[root@dns1 ~]# cd /var/munin/plugin-state
[root@dns1 /var/munin/plugin-state]# touch bind9.state
[root@dns1 /var/munin/plugin-state]# chgrp munin bind9.state
[root@dns1 /var/munin/plugin-state]# chmod g+rw bind9.state
[root@dns1 /var/munin/plugin-state]# ls -al
total 4
drwxrwxr-x  2 nobody  munin  512 Jan 29 18:13 .
drwxr-xr-x  3 munin   munin  512 Jan 29 14:47 ..
-rw-rw-r--  1 root    munin    0 Jan 29 18:13 bind9.state

Relevant bind named.conf stanza for query logging:

logging {
  channel default_queries {
    file "/var/log/queries.log" versions 3 size 500k;
    severity info;
    print-severity yes;
    print-category yes;
    print-time yes;
  };
  category queries { default_queries; };
};

With that, ‘munin-run bind9′ worked. I restarted the munin-node process and queries are now being graphed as expected.

[Update 2012-02-20: Getting this working on Ubuntu Server]

After banging my head against the wall trying to get this plugin working on Linux, dying on the same line (about the inability to find the state file), this is how I got it working.

Create the following file with the appropriate permissions.

root@grenache:/var/lib/munin/plugin-state# ls -al bind9.state
-rw-rw-r-- 1 nobody munin 22 2012-02-20 15:39 bind9.state

And now, voila:

 root@grenache:/var/lib/munin/plugin-state# munin-run bind9
 query_PTR.value 25
 query_A.value 109
 query_AAAA.value 199
 query_other.value 0
Posted in Open Source/Internet | Tagged , | Comments Off

Munin monitoring your SB6120 Comcast Cable Modem

For those who have spent time debugging their Comcast Internet connection, we all know the frustration of trying to explain to Comcast that something on their end is the problem. In this case, more data is better: latency history, ping times, traceroutes, etc. You can run Smokeping to monitor latency between your home connection and a remote Internet IP address for example. You can also print out traceroute examples and email them if you have an astute support contact. But if you want to monitor the data your cable modem is seeing, you need to look at the signal to noise ratio of your connection. This ratio refers to how much of your signal has been disturbed by noise on the physical line (Thanks Wikipedia). Newer cable modems will use multiple channels along the same line to increase your download and upload speed, and each channel can be disturbed independently.

Enter Munin, an RRD-graph based tool that creates easy to understand (for the most part) graphs of data over time. Munin plugins can be written to scrape any data you are able to programatically retrieve and whip it into a pretty graph. The plugin I wrote for Munin scrapes the data from a Motorola Surfboard SB6120 modem’s status page, and presents it in an easy-to-digest format for Munin. Previous Munin plugins handled the old SB4120 and SB5120 modems. These are old DOCSIS 2.0 products, and therefore the status page has evolved, and displays the connection data in a way where the old plugin does not work on the SB6120 modem.

Without further adieu, the graph produced by my plugin is:
The graph shows the various downstream and upstream channels, graphing the signal-to-noise ratio dB (decibel) of each respective channel.  Suggested values for Comcast in particular can be found in a FAQ entry from Broadband Reports. These are just suggestions, and different values will have different effects on your Internet connection. A severe dip in the graph could correspond to your modem being unable to stay sycned with Comcast’s infrastructure, which translates to an unstable Internet connection.

Installation instructions follow common Munin plugin practices, by creating the plugin (or a symlink to the plugin) in the /etc/munin/plugins/ directory to the plugin code. Mine is written in Python, so a basic Python install is required on your machine. Source can be found can be found in my munin-surfboard6120 repo on Github.

Enjoy! (Comments/criticisms are welcomed to improve the usefulness of this plugin)

Posted in Open Source/Internet | Comments Off