Logitech QuickCam Communicate STX

Earlier, I wrote about setting up a Mac Mini user running OSX Tiger 10.4.x with a Logitech QuickCam Pro 5000, and how there was trouble using the camera's microphone. Fixing it involved mucking around with Mac OSX kernel extensions, and later automatic updates seem to have messed that up.

Rather than keep fighting with OSX, I swapped out that webcam for a Logitech QuickCam Communicate STX. Specifically, the model with part # 961464-0403.

It's not supported by default with OSX 10.4.x, but it is supported by macam, which is ridiculously easy to install. After doing so it worked fine with Skype, and the auto-exposure feature even worked, where it adjusted itself automatically for the lighting in the room.

SSH in a FreeBSD jail

I've been running lots of FreeBSD jails on various servers I maintain, and one thing I've noticed is that using ssh or scp from inside a jail often results in the error: Host key verification failed. A little Google searching turns up this explanation, that the problem is caused when you jexec into the jail instead of logging in normally through SSH.

I often run the jails in a pretty minimal way and don't really want to run sshd in them, and fortunately the problem can be worked around somewhat. Apparently the Host key verification failed. error is caused when SSH is unable to show you this type of prompt:

The authenticity of host 'foobar.edu' can't be established.
DSA key fingerprint is 7c:ac:b0:da:be:3c:c2:00:00:00:00:ce:db:fb:49:77.
Are you sure you want to continue connecting (yes/no)?

when connecting to a host you haven't connected to before. All you have to do to get around this is manually add a line to the jail's ~/.ssh/known_hosts for the server you're trying to connect to, probably by copying one from a known_hosts on another box or outside the jail.

Once past that, you may find that SSH is still unhappy in the jail if you don't have publickey authentication setup with the server you're trying to connect to, with an error like:

Permission denied, please try again.
Permission denied, please try again.
Permission denied (publickey,password).

Fixing that is just a matter of generating or copying a private/public key pair into the jail's ~/.ssh directory, and putting the public key on the server you're connecting to.

Mac OSX USB-Serial Adapter

At work I occasionally need to work with devices that have serial interfaces, like Cisco Access points, and wanted to do so with my MacBook. One particular USB-to-Serial adapter that I found works OK is a Sabrent SBT-USC1K, which uses the same MacOSX Prolific driver I had installed a while back for use with a GPS. I've used this on both MacOSX Tiger (10.4) and Leopard (10.5).

There are probably lots of USB-Serial adapters that work with a Mac, and even use that same driver. I just thought I'd jot down one in particular, so someone doesn't have to make a wild guess and order something hoping it happens to work with OSX.

"man" annoyance

I work on several different Unix-type machines, some FreeBSD, some Linux, and there are always small differences between them that can be very annoying.

One that's driven me crazy many times is how on some machines, when using man to read a manpage, after getting to the part I'm interested in, and hitting 'q' to quit - the contents of the manpage completely disappear and the screen is restored to what was shown before I ran man. Other machines I work on don't do that - the contents of the manpage remain on the screen so you can see them as you type the next command.

After finally getting fed up, I looked into this and it turns out the machines that were acting the way I like have the PAGER environment variable set to more, so man uses that instead of less which has the screen-restore-on-quit behavior. Adding:

PAGER=more; export PAGER

to .bashrc seems to have done the trick on my Ubuntu box. Seems the FreeBSDs already had this by default.

It's not a big deal, but I'm just jotting this down in case anyone else has the same annoyance. Good luck finding this in Google though, if you're just using words like 'more', 'less', and 'man' ;)

Daemontools mishap

While working on my DiskCompare.com website I had a weird problem with daemontools. The Django process I had running under daemontools became unresponsive, it wouldn't shutdown normally with svc -d, and after kill -9 and restarting, it still wouldn't respond - it just seemed hung up or frozen. No messages in /var/log/messages, but running the service manually outside of daemontools worked fine. What the heck?

I had the service also setup to run multilog, and it turns out that I had mistakenly changed the ownership of the log directory it was supposed to be writing to. My guess is that it was the multilog process that was really hung up, since it couldn't write to the files it wanted to, and that my Django processes were then blocked because the pipe between them and multilog was full.

Simply correcting the permissions of the log directory cleared the jam and things took off again. So if you're seeing strange behavior with daemontools, that's one area to check out.

DiskCompare.com

What's a good deal in hard disks? I don't mean which reseller sells a particular model for less than other resellers - but how does one model compare to another in terms of what you get for the money. If you're looking to buy a 400gb disk, does it make sense to spend a little more for a 500gb disk? or are you paying an excessive premium for that extra 100gb?

A good way to compare disks is to look at their value in terms of Gigabytes-per-dollar. Resellers usually don't display that information or make it easy to compare one disk against another, so I whipped together a website named DiskCompare.com that does that, based on prices from Newegg.

So for example, if you're interested in a Seagate 7200.10 500gb disk, you'd see a page like the one below. It compares the Seagate to other 500gb drives, and possibly to larger drives that are not too far off in price - and shows that some Western Digital models give you more for the money (at least at the moment I took this screenshot), although one is at the expense of a smaller cache.

screengrab of dicksompare.com

Other things it shows are relevant reviews, recent Newegg price changes, and price histories for each drive (some of those price changes are a bit shocking, today one SAS drive went up $390)

The site is still a work-in-progress, powered by Django, Python, PostgreSQL, and jQuery. It's been an interesting winter-time project, something to do when it's too dang cold to be outside. If you happen to follow the links on the site to Newegg and make a purchase, I'll get a small commission to help defray my bandwith costs, although I hope the site isn't too obnoxious about it.

Django comments

I've tried adding a comments feature to this site, using the stock django.contrib.comments application, mostly following the instructions from the Django Wiki, and also using James Bennet's comment-utils described here.

The Wiki is pretty thorough, but one thing I think it missed was that in the template for displaying comments, you should have a

<a name="c{{ comment.id }}" />

Near the beginning of where your comment starts being output, so the standard get_absolute_url() method for the FreeComment model has a place to point to.

A couple things that were not really talked about in the comment-utils docs were where to get the Python Akismet library, and the need for a comment_utils/comment_notification_email.txt template if you want e-mail notifications. I ended up with something simple like:

Comment: http://127.0.0.1{{ comment.get_absolute_url }}
From: {{ comment.person_name }}

-----
{{ comment.comment }}
-----

Admin: http://127.0.0.1/admin/comments/freecomment/{{comment.id}}/

I'm a bit skeptical about how well the Akismet spam-filtering service will work, but we'll see how it goes.

Apache in FreeBSD Jail Error

In one of my FreeBSD 6.2 jails running Apache, even though the server seemed to respond ok, I saw lots of these errors in the logfile:

[warn] (61)Connection refused: connect to listener on 0.0.0.0:443

Google searching found lots of other people asking about this, but I didn't really see any good answers. Others complained about the same thing on port 80

[warn] (61)Connection refused: connect to listener on 0.0.0.0:80

I think the problem is just that Apache in a jail can't listen to :443 or 0.0.0.0:443 (or :80 or 0.0.0.0:80). If your jail has the IP 1.2.3.4 for example, then in httpd.conf, changing

Listen 80

to

Listen 1.2.3.4:80

and/or in extra/httpd-ssl.conf

Listen 443

to

Listen 1.2.3.4:443

Seems to fix the problem

Split tunnel between FreeBSD boxes using OpenVPN

At work there are machines I'd like to access from home using Windows networking (Samba servers mostly), but the catch is that the work firewall is blocking NetBIOS traffic (an awfully good idea). My home network uses a FreeBSD box for NAT (Network Address Translation). Here's a diagram of what we're talking about.

Diagram of NetBIOS being blocked

In the picture above, my home NAT box has the public IP 1.2.3.4, the internal home network is 10.0.0.0/24, and I'm trying to reach a work server 5.6.7.100 on the 5.6.7.0/24 network.

Fortunately, I have a FreeBSD box at work, with an address 5.6.7.8, and it's fairly easy to setup a simple OpenVPN tunnel between 1.2.3.4 and 5.6.7.8, and route NetBIOS traffic over that.

OpenVPN will make it appear as if the two machines have a point-to-point network connection, when in reality the traffic is passing encrypted over the public internet. We need to pull a couple IP numbers out of our hat to use for the VPN endpoints - I'll use 192.168.88.1 for the home machine and 192.168.88.2 for the work machine.

Diagram of using OpenVPN

Settting up OpenVPN

On each box install the security/openvpn port. After that's done, on one machine, go to /usr/local/etc/openvpn and run:

openvpn --genkey --secret mykey

Copy the mykey file you just generated over to the other box's /usr/local/etc/openvpn directory. The two OpenVPN endpoints will used that shared key to authenticate each other.

On the 1.2.3.4 machine, create a /usr/local/etc/openvpn/openvpn.conf file containing:

remote 5.6.7.8
dev tun0
ifconfig 192.168.88.1 192.168.88.2
secret mykey

On the 5.6.7.8 machine, create a /usr/local/etc/openvpn/openvpn.conf file containing:

remote 1.2.3.4
dev tun0
ifconfig 192.168.88.2 192.168.88.1
secret mykey

(note that the ifconfig line swapped the IPs compared to the other machine's config)

Throw an openvpn_enable="YES" in each machine's /etc/rc.conf, and start the daemons: /usr/local/etc/rc.d/openvpn start

If necessary, allow OpenVPN traffic through your firewall, for the 1.2.3.4 box it might look something like:

pass in on $ext_if inet proto udp from 5.6.7.8 to $ext_if port 1194
pass on tun0

If this works, you should be able to sit at the 1.2.3.4 box and ping 192.168.88.2 and get a response. On the 5.6.7.8 box, running tcpdump -n -i tun0 should show the ICMP packets reaching the machine.

Routing specific traffic

I don't want to route all my traffic going to the 5.6.7.0/24 network through the VPN, I just want the NetBIOS stuff so I'll setup a split tunnel. PF makes it pretty easy to redirect network traffic through the VPN, in fact, I ended up doing a double-NAT, one on each end of the tunnel.

Diagram of double-natting

So when the home workstation contacts the Samba server, the Samba server sees the traffic as coming from the 5.6.7.8 box, and the 5.6.7.8 box saw the traffic as coming from the home FreeBSD NAT machine. So interestingly, neither of the work machines needs to have any clue about the home network. The PF state tables take care of reversing everything when the Samba server responds.

On the home 1.2.3.4 machine, these lines are added in the appropriate places to /etc/pf.conf:

int_if="eth1"
internal_net="10.0.0.0/24"
work_net="5.6.7.0/24"
.
.
nat on tun0    from $internal_net to any -> (tun0)
.
.
pass in on $int_if route-to tun0 proto tcp from any to $work_net port {139, 445} flags S/SA modulate state

That last line is the key to the whole thing, it's responsible for diverting the traffic we want to go through the VPN instead of over the public internet. If you want to secure additional protocols, just add similar lines.

The PF config on the work 5.6.7.8 machine is simpler, just

nat on $ext_if from 192.168.88.1 to any -> 5.6.7.8

To perform that 2nd NATting, making VPN traffic seem like it came from the work box.

Lastly, both machine need gateway_enable="YES" in /etc/rc.conf. A home NAT box probably already has that though.

There's a lot more that OpenVPN can do, we barely scratched the surface with the simple setup described above, check the docs for more info.

More DHCP Failover

Earlier I wrote about DHCP failover, but there's another thing I thought I might mention that could be useful to others....

I had a problem in that one of my servers' CMOS clocks tends to be a bit off, maybe 90 seconds. When dhcpd starts up, it is unable to enter a normal failover state because of the time difference between it and the other dhcpd server.

I have

ntpdate_enable="YES"
ntpdate_flags="-b x.x.x.x"

in my /etc/rc.conf, along with running openntpd, but for some reason ntpdate wasn't setting the clock at boot time, and by the time openntpd got the clock tuned up, dhcpd had given up on trying to re-establish failover. Restarting dhcpd by hand later on always worked OK.

I think what was happening was that the network jack this server was plugged into wasn't coming alive quick enough to be up and running when ntpdate tried to do its thing. Something to do with the Cisco switch not having portfast enabled.

I don't have access to do anything about the switches, so I came up with the workaround of adding a simple script /usr/local/etc/rc.d/000.afterboot.sh to schedule a job to run a few minutes after the machine boots - to adjust the clock and restart dhcpd. It looks something like:

#!/bin/sh
at now + 5 minutes <<EOF
/etc/rc.d/ntpdate restart
/usr/local/etc/rc.d/isc-dhcpd restart
EOF

It's a bit of a kludge, but seems to do the trick.