Thursday, May 14, 2009

The Jaunty Jitters - Will it work?

My firewall / desktop machine at home has been running Ubuntu Intrepid happily for some time now. The recent release of Jaunty piqued my interest, so I went ahead and upgraded. For system changes like this I usually prefer a command line solution, so I used do-release-upgrade, which needs a package installed.
sudo apt-get install update-manager-core

Then:
sudo do-release-upgrade

It will download what's needed and ask you before it starts downloading packages.

I run shorewall, and to connect to my home network I use an atheros wireless card. This card doesn't like the ath5k module that is the default atheros handler in Ubuntu. This machine acts as the AP, so I also run hostapd. Because of these custom tweaks, I copied some configs to be sure I wouldn't lose anything, including /etc/shorewall, /usr/share/shorewall, /etc/hostapd, and the whole of /etc/modprobe.d.

This would prove to be a good thing.

After the upgrade and reboot, the ethernet to the world worked fine, but wireless not so much. Looking at the output of
sudo lsmod|grep ath

and
sudo iwconfig

showed that the ath0 interface was not alive, thus the madwifi driver ath_pci had never been loaded. As I said earlier, Ubuntu likes to use the ath5k driver by default.

The ath_pci madwifi driver is normally 'enabled' using the restrited drivers manager, or what is now just the Hardware Drivers manager (Administration/Hardware Drivers). The easy way out may have been to make sure the driver was enabled there first, but my fix was to edit the offending blacklist entry that had been added to /etc/modprobe.d in the form of the file /etc/modprobe.d/blacklist-ath_pci.conf
I edited this file and commented out the line
#blacklist ath_pci

I already have a filed called madwifi.conf in /etc/modprobe.d that blacklists the ath5k module

This took care of wireless, and a reboot brought things back to normal.

Another issue I ran into was that I was getting numerous pop up dialogs from the tracker applet complaining that my index was corrupted. Asking it to reindex just caused another failure. Obviously things are more corrupted than it can handle.

This issue was fixed by installing
sudo apt-get install tracker-utils

and as the user
tracker-processes -r
tracker-applet &
/usr/lib/tracker/trackerd &

The last two commands could be skipped if you just reboot the machine.

Now I just need to decide if I want to go through the fun of disabling the pulseaudio mess, or give it another day in court.

Monday, May 11, 2009

Pluto, why won't you eroute and just popen already?

I was recently working on an OpenS/WAN to OpenS/WAN IPSEC configuration, when I was perturbed at the fact that the tunnel just wasn't working.

Like many others, I pounded my head over the configurations - just looking for the slightest problem. I naturally confirmed that both left and right were identical on both nodes, secrets were correct, iptables rules weren't botched in any manner, rp_filter - everything, it was all correct just like the other several hundred nodes I've configured.

When initiating the tunnel from the other side, I saw an interesting error:

117 "tun2128" #149016: STATE_QUICK_I1: initiate
003 "
tun2128" #149016: unable to popen up-client command
032 "
tun2128" #149016: STATE_QUICK_I1: internal error


Unfortunately, the only reference to this error message was with regard to memory issues. Since this server was fine on memory (and all other active tunnels were "fine"), I directed my attention to the hordes of messages scrolling across my screen when executing ipsec whack --name tun128 --debug-all. Eventually, I found a few more errors that meant absolutely nothing to me:
STF_INTERNAL_ERROR, STF_SUSPEND, and then finally this:

May 4 10:08:56 localhost pluto[25544]: | ******parse ISAKMP Oakley attribute:
May 4 10:08:56 localhost pluto[25544]: | af+type: OAKLEY_GROUP_DESCRIPTION
May 4 10:08:56 localhost pluto[25544]: | length/value: 5
May 4 10:08:56 localhost pluto[25544]: | [5 is OAKLEY_GROUP_MODP1536]
May 4 10:08:56 localhost pluto[25544]: | Oakley Transform 0 accepted
May 4 10:08:56 localhost pluto[25544]: | sender checking NAT-t: 0 and 0
May 4 10:08:56 localhost pluto[25544]: | 0: w->pcw_dead: 0 w->pcw_work: 0 cnt: 1
May 4 10:08:56 localhost pluto[25544]: | asking helper 0 to do build_kenonce op on seq: 135267
May 4 10:08:56 localhost pluto[25544]: | inserting event EVENT_CRYPTO_FAILED, timeout in 300 seconds for #148978
May 4 10:08:56 localhost pluto[25544]: | complete state transition with STF_SUSPEND


A lot of crazy messages sure, but the most important string of all - "asking helper ...". It reminds me of a series of posts that I came across while debugging a ridiculous ISAKMP issue with a Cisco Router. The posts (which I can no longer remember the case for which they originated) all indicated setting nhelpers=0 in /etc/ipsec.conf (under 'config setup' of course)....

After making the change, calling ipsec setup --restart - all was dandy in magical OpenS/WAN world.

But what does it actually mean? From the PlutoHelper file from OpenS/WAN 2.6.19:

Pluto helpers are started by pluto to do cryptographic operations.

Pluto will start n-1 of them, where n is the number of CPUs that you have
(including hypher threaded CPUs). If you have fewer than 2 CPUs, you will
always get at least one helper.

You can tell pluto never to start any helpers with the command line option
--nhelpers. A value of 0 forces pluto to do all operations in the main
process. A value of -1 tells pluto to perform the above calculation. Any
other value forces the number to that amount.


In one translation or another, it means that pluto will handle its own encryption, and if for some reason your ipsec tunnels that use pre-shared keys start magically complaining about some obscure error that doesn't give you an answer you like, try setting nhelpers=0 and see what happens...

Monday, May 4, 2009

Flushing the DNS Resolver Cache

Sometimes, a DNS change you made needs to be understood by the remote end very quickly - maybe because your testing your web server and you just changed remote IP addresses. When you configure your DNS server with long TTL values, waiting a day for the everything to time out just takes too long. Here are a few commands on various platforms that will help clear the local resolver cache:

Microsoft Windows
C:\> ipconfig /flushdns

Linux
# rndc refresh || ndc refresh

Mac OS X
# lookupd -flushcache || dscacheutil -flushcache


Now, if only there were a command that would remind the user that they added the entry in /etc/hosts or %windir%\system32\drivers\etc\hosts, so that instead of looking at this article, they remember that the host was configured there...

Don't forget the forgotten perl pragmas...

In the past 10 years, I've seen countless people banging their heads over why their perl code is not functioning correctly. When I ask about using the strict and warnings pragma, either they stare at me with a blank expression - or their incorrect usage of the modules loses the purpose...

Why 'warnings'?

Add this to the top of your perl package or script:

use warnings;

This will import the warnings module into your namespace and, if you have some mistakes, it will tell you about them.... What mistakes you might ask? For starters, it will tell you about a few typo conditions - where you use a variable but don't do anything with it. Example:
    #!/usr/bin/perl
use warnings;
$filename = "/tmp/foo";
print "hello world\n";
This will throw a warning like this: 'Name "main::filename used only once: possible typo at ...' nice eh? There's more! The warnings pragma will also tell you if you do something silly like this:
    #!/usr/bin/perl
use warnings;
$filename = "/tmp/foo";
open(FILE,"w");
close(FILE);
print FILE, "Hello world\n";
Oops! That print statement is not in the right spot - perl will remind you gently by warning you that you're trying to write to a closed file handle.. Sure it will continue, but now you know why there is no data in your file!

Now comes my favorite - the "uninitialized value" warning - This code doesn't work:
    #!/usr/bin/perl
use warnings;
print "I need " . $something . "\n";
$something = "help";
Why? Because $something has no value - it was never initialized prior to use. In this case, it is NULL or otherwise `undef` (undefined). Some people prefer to test `if ($something eq '')` - but that's just wrong (since '' and undef are two separate values!). Instead, do it right - call `if (defined($something) && $something eq '')`.

Last on the warnings pragma - if typing 'use warnings;' is too much for you, then prefix your perl code in one of the following manners:
    #!/usr/bin/perl -w
#!/usr/bin/perl -W
Lower-case w will import 'warnings' into your package. '-W' will import warnings into all packages.

So now you have all of these lovely warnings printed on your screen - what about the strict pragma? Add this to the top of your perl package or script:
    use strict;
This will import the strict module into your namespace and, if you have mistakes - it will tell you about them... (Sound familiar?!). This time, rather than just uninitialized variables, `strict` will help you keep the right scope in your references, variables and subroutines. Simply put, you need to make sure you properly scope your variables. For instance:

#!/usr/bin/perl -w
use strict;

my $bar = 'something';
&changeBar('else');
print $bar . "\n";
sub changeBar {
my $val = shift;
$bar = $val;
}

What does this code produce? It prints 'else' instead of 'something'. Simple enough, right? Far too many people miss the basics here, ignore that their variables need to be scoped - and then wonder why their counters aren't working. Maybe this example is a little better:
    #!/usr/bin/perl
$count = 0;
&a;
print "Count: " . $count . "\n";
sub a {
for ($x=0;$x<100;$x++) {
print "a: " . $x . "\n";
&b;
print "now: " . $x . "\n";
}
}
sub b {
for ($x=200;$x>150;$x--) {
$count++;
}
}

What does this produce? It may not be the result you desire:
    [root@delta ~]# ./nostrict.pl
a: 0
now: 150
Count: 50
[root@delta ~]#
What did the user want? Probably to have $count be 5000. How could this have been resolved? In each subroutine, scope $x by declaring them with 'my' either:
    my $x;
or
for (my $x; ....)

That's it - then, your variables are scoped a little better, and you're not banging your head on the wall for something silly.

For anyone looking to put together any code shy of the 1-liner, using 'warnings' and 'strict' is a big MUST.

In conclusion - save yourself from headache -
use warnings;
and
use strict;
- they may save your $life one day...

References:
http://search.cpan.org/perldoc?warnings
http://search.cpan.org/perldoc?strict