Search this site


Metadata

Articles

Projects

Presentations

Projects for Spring Break

The following projects stuff I'd like to put time into during spring break. These are in no particular order of preference.
  • templating system for the stats aggregator with logwatcher
  • jquery sort() plugin
  • get newpsm/newmoused into FreeBSD -CURRENT
  • pam_captcha code audit
Whether or not I actually get around to doing any of this is still in question.

precedence sorting with perl's sort()

This isn't terribly complicated, but it may be useful to you. Mostly I'm putting it here for my own future reference.
sort { $users{$b} <=> $users{$a} || $a cmp $b } keys(%users)
This will sort first numerically by the values stored in %users and then by the keys of %users. This means that the return value of sort is the keys sorted by data values first, and then alphabetically when both data values are equal.

Logwatcher + lwrecord

It's time logwatcher takes a step towards log summarization in addition to it's already (hopefully) good match-and-react system. This step is with a script I'm working on that will be distributed with logwatcher called lwrecord. lwrecord will let you record arbitrary data in a tree-like structure for later retrieval.

My logwatch.conf is as follows:

file "/var/log/auth.log" {
   type "bad username" {
      match = "pam for invalid user %USERNAME% from %IP%";
      match = "Invalid user %USERNAME% from %IP%";
      reaction = "./lwrecord 'ssh-illegal-user/%IP%' '%USERNAME%'";
   };
};
lwrecord splits the first argument (the key) by the '/' token and ends up storing the username attempted into:
$db->{"ssh-illegal-user"}->{"%IP%"} = "%USERNAME%";
This gets stored onto disk in to a database file.

After several ssh attempts, I can view the database and see that we are happily recording information:

nightfall(~/projects/logwatch) !130! % ./lwfetch
$VAR1 = {
          'ssh-illegal-user' => {
                                  '129.21.60.5' => [
                                                     {
                                                       'time' => 1140510435,
                                                       'data' => 'foo'
                                                     },
                                                     {
                                                       'time' => 1140510439,
                                                       'data' => 'testing'
                                                     },
                                                     {
                                                       'time' => 1140510444,
                                                       'data' => 'happytaps'
                                                     },
                                                     {
                                                       'time' => 1140510446,
                                                       'data' => 'happytaps'
                                                     },
                                                     {
                                                       'time' => 1140510447,
                                                       'data' => 'happytaps'
                                                     }
                                                   ]
                                }
        };
With lwrecord, we have the ability to store any arbitrary kind of data (hopefully) from simple data like who's ssh'ing in to entire log entries. Soon, I'll write up lwsummarize which will let you summarize database entries over a given time period for human parsing.

One step closer to simple log summarization. With lwrecord (and eventually lwsummarize) you will be able to easily show log summaries such as "Show me all of the IPs who attempted ssh logins with invalid users N times in the last day" - more on this as I work on it.

OpenLDAP authenticating against saslauthd

I've been doing research on the internets trying to get OpenLDAP to allow simple binds that can authenticate against Kerberos. Turns out the default SASL support is to only handle GSSAPI when talking to Kerberos V servers. This means you can only authenticate if you have a kerberos tgt.

Problem with SASL/GSSAPI is that address book clients aren't going to support much beyond simple authentication over SSL. Thusly, we need a way to use a simple bind over SSL and still authenticate against Kerberos.

The LDAP Server's slapd.conf has the following to translate between gssapi auth DNs and real user object DNs:

authz-policy from
authz-regexp "^uid=([^,]+),cn=gssapi,cn=auth" "uid=$1,ou=Users,dc=csh,dc=rit,dc=edu"
This allows GSSAPI authentication:
nightfall(~) % ldapwhoami
SASL/GSSAPI authentication started
ldap_sasl_interactive_bind_s: Local error (-2)
        additional info: SASL(-1): generic failure: GSSAPI Error:  Miscellaneous failure (see text) (open(/tmp/krb5cc_1001): No such file or directory)

nightfall(~) !1! % kinit psionic
psionic@CSH.RIT.EDU's Password: 
kinit: NOTICE: ticket renewable lifetime is 0
nightfall(~) % ldapwhoami
SASL/GSSAPI authentication started
SASL username: psionic@CSH.RIT.EDU
SASL SSF: 56
SASL installing layers
dn:uid=psionic,ou=users,dc=csh,dc=rit,dc=edu
Result: Success (0)
I have a TGT and can authenticate to LDAP over SASL (my ldap.conf defaults to sasl+ssl). However, when you try to do a simple bind:
nightfall(~) % ldapwhoami -x -D 'uid=psionic,ou=users,dc=csh,dc=rit,dc=edu' -W 
Enter LDAP Password: 
ldap_bind: Invalid credentials
On the slapd side, you'll see errors like:
==> bdb_bind: dn: uid=psionic,ou=users,dc=csh,dc=rit,dc=edu
SASL Canonicalize [conn=0]: authcid="psionic@CSH.RIT.EDU"
SASL Canonicalize [conn=0]: authcid="psionic@CSH.RIT.EDU"
SASL [conn=0] Failure: Could not open db
SASL [conn=0] Failure: Could not open db
Googling around will tell you that lots of people put the following in their "slapd.conf" files:
pwcheck_method: saslauthd
saslauthd_path: /var/run/saslauthd/mux
Now, you'll recognize that this format of "token: value" doesn't match the normal slapd.conf. There's a reason for this: This isn't OpenLDAP's slapd.conf file. It's the config file for SASL! From what I gather, saslauthd is working similarly to the way PAM works, in that it sees a service trying to use it and uses that particular service's config file. I believe saslauthd comes with a standard Sendmail.conf for example usage.

It took me several hours to find this fact out. My slapd SERVER config file is located here:
/usr/local/etc/openldap/slapd.conf

While the SASL "slapd.conf" authentication config file is located here:
/usr/local/lib/sasl2/slapd.conf

If you can't find the right place, look for 'Sendmail.conf' somewhere near where you installed sasl or saslauthd.

Anyway, once we've added this magic config file and told it to use saslauthd, the SASL library LDAP's slapd is using will now attempt communication with saslauthd over the /var/run/saslauthd/mux socket. I ran saslauthd like this:

/usr/local/sbin/saslauthd -a kerberos5 -d
The directory, /var/run/saslauthd was owned by 'cyrus' and I changed the group ownership to 'ldap' so that the slapd server (running as 'ldap') could access the socket. This is a necessary step, else you will get Permission Denied errors permissions disallow you from accessing the socket or its directory.

Now, once we have saslauthd running, the sasl library slapd.conf, and the moons aligned, we can perform a simple bind:

nightfall(~) % ldapwhoami -x -D 'uid=psionic,ou=users,dc=csh,dc=rit,dc=edu' -W 
Enter LDAP Password: 
dn:uid=psionic,ou=Users,dc=csh,dc=rit,dc=edu
Result: Success (0)
saslauthd, in debug mode, will say something meaningful such as:
saslauthd[28910] :do_auth         : auth success: [user=psionic] [service=ldap] [realm=CSH.RIT.EDU] [mech=kerberos5]
saslauthd[28910] :do_request      : response: OK
Whew! My LDAP Authentication journey is complete. I'll post my configs later once I have a full directory system implemented here. For now, I am elated that gssapi and simple binds both work for eventually authenticating against our Kerberos server.

statistic deltas using awk

Short shell script I call 'delta' - It is useful for groking 'vmstat -s' output (and possibly other commands) to view time-based deltas on each counter.
#!/bin/sh
while :; do
   $* | sed -e 's/^ *//';
   sleep 1;
done | awk '
{
   line = substr($0, length($1)+1);

   if (foo[line]) {
      printf("%10d %s\n", $1 - foo[line], line);
   }
   foo[line] = $1;
   fflush();
}'
Example usage:
delta vmstat -s | grep -E 'system calls|fork'

       792  system calls
         3   fork() calls
         0  vfork() calls
       120  pages affected by  fork()
         0  pages affected by vfork()
       680  system calls
         3   fork() calls
         0  vfork() calls
       120  pages affected by  fork()
         0  pages affected by vfork()
      1150  system calls
         3   fork() calls
         0  vfork() calls
       120  pages affected by  fork()
         0  pages affected by vfork()

logwatcher update

Logwatcher got a few significant updates today.

You can now give subnames to patterns in the form of %PATTERN:NAME%. It'll match against the named PATTERN but be referrable as %PATTERN:NAME% instead of just %PATTERN%. This is extremely useful if you have two instances of the same pattern in one match. Perl exec works again too.

I added debug levels too so it won't output anything less you want it to. Specify debug with -d, repeat for higher debug levels. You can also specify a nonstandard config file with -f path/to/file.

If you use logwatcher, let me know. I'm always up for adding new features.

Project page: projects/logwatch