Projects for Spring Break
Posted Tue, 28 Feb 2006
- templating system for the stats aggregator with logwatcher
- jquery sort() plugin
- get newpsm/newmoused into FreeBSD -CURRENT
- pam_captcha code audit
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.
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.
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 credentialsOn 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 dbGoogling around will tell you that lots of people put the following in their "slapd.conf" files:
pwcheck_method: saslauthd saslauthd_path: /var/run/saslauthd/muxNow, 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 -dThe 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: OKWhew! 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.
#!/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()
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