Monday, July 19, 2010

CIS Apache Web Server Scoring Tool

The Apache Benchmark Tool assesses target systems for conformance with the CIS Benchmark for Apache Web Servers.

Here’s the link to the code:

CIS Apache Web Server Scoring Tool for the 2.1.0 Benchmark v1.0.0

This is free but unsupported software from the nonprofit Center for Internet Security.
[Read More…]

Monday, March 1, 2010

An alternative to custom objectclasses: the extensibleobject

I’ve spent a decade designing and implementing LDAP directories, but only recently had the opportunity to reflect on the big picture. For example, the basic structure of the environment originally put in place at the company I work for by the consultants who started things is still there, but as time marched on things like access controls and custom object classes have become much more complex than the relatively simple setup I was handed at the beginning.

One missed opportunity was in failing to avoid the inevitable proliferation of custom objectclasses in our schema. Although I was merely following the lead of not only our consultants, but also the major part of the LDAP community, I now think that much of that effort was not entirely necessary.

Objectclasses are in reality only containers for attributes. While there is some utility in being able to group related attributes in distinct objectclasses (e.g., the fact that all people entries on a directory were created with the inetorgperson objectclass makes it easy to get a dump of them all by using the search filter “(objectclass=inetorgperson)”) , this practice can become unwieldy: particularly when the directory objects involved are user entries.

Most experienced directory administrators will almost instinctively create a user entry by first inserting the person, organizationalperson, and inetorgperson objectclasses. It’s just how things are done.

But I’ve begun to wonder about that next step, the creation and maintenance of custom objectclasses for attributes that aren’t included in the standard objectclasses but may be desired in user entries. For example, none of those standard person objectclasses permit you to add the attribute ‘c’ to entries for holding a two-character country code. To add ‘c’ you either have to extend one of those existing objectclasses or create a new custom objectclass and make sure it is part of every user entry you want to add ‘c’ to.

There is a middle way though. If an entry has the extensibleobject objectclass you can add any attribute you’d like to it. Section 7.1 of RFC 2252 states:

The extensibleObject object class, if present in an entry, permits that entry to optionally hold any attribute. The MAY attribute list of this class is implicitly the set of all attributes.

There’s no guarantee that extensibleobject will be supported by all LDAP servers, although it is by the major products used today.

As part of a project to put my personal address book in LDAP I recently added the evolutionperson objectclass and its constituent attributes, including the very useful birthDate and anniversary, to my home directory server. Rather than use this new objectclass or create a custom class, I’ve decided to simply add the extensibleobject objectclass to each of my entries so that I can add the attributes I need without running afoul of schema checking. It’s a practical solution to a practical problem that has the enormous benefit of keeping things as simple as possible. And that’s always a good thing.

Wednesday, January 6, 2010

Ntpd on Solaris 10

This is easy.

Here are the steps (all done as root):

1. Copy /etc/inet/ntp.server to /etc/inet/ntp.conf, and then edit ntp.conf to comment out the “server” and “fudge” lines. Add a line to the bottom of the file,

server timeservername

Like,

server tick.usno.navy.mil

2. Create a drift file,

touch /var/ntp/ntp.drift

3. Initialize the ntpd service,

svcadm enable svc:/network/ntp

Monday, September 21, 2009

static-routes in RHEL

“Where do I define any needed static routes for a Red Hat Enterprise Linux (RHEL) system?”

I’m glad you asked. In /etc/sysconfig/static-routes, of course, right where anyone who had the courage to take (and the skill to pass) either the RHCT (Red Hat Certified Technician) or RHCE (Red Hat Certified Engineer) test would expect to find them.

Example syntax of the file:

any net 10.0.0.0 netmask 255.0.0.0 gw 192.168.1.1
any net 192.168.0.0 netmask 255.252.0.0 gw 192.168.1.1
any net 172.16.0.0 netmask 255.255.0.0 gw 192.168.1.1

An official Red Hat pronouncement is here.

Thursday, September 10, 2009

More fun with hashed and encoded strings

Most of us who have worked with LDAP directories know that the better systems out there don’t actually store passwords in user entries.

Paragraph 5.36 of RFC 2256 specified that the userpassword attribute be stored using the octet string syntax and not encrypted.

Early on it became the practice to have the directory server itself hash an incoming password and commit that hashed value to the directory. By far the most popular method is to hash using the SHA-1 or SSHA algorithm and encode the result as a Base64 string. Further obfuscation is provided by Base64 re-encoding the string again. Subsequent authentication attempts are handled by comparing the stored hash to the text submitted by applying the same hashing and encoding algorithm to that text and seeing if it matches the stored value.

As with all things, it helps to see this illustrated. The following bit of perl code will let you take a text string of your choice and see the results of hashing and Base64 encoding that string.

#!/usr/bin/perl
use strict;
use Digest::SHA qw(sha1_base64);
use MIME::Base64;
	
my $data = "purple";
	
print "Original text: ", $data, "n";
	
my $hashed = sha1_base64($data);
print "Hashed text: ", $hashed, "n";
	
my $shatext = '{SHA}' . $hashed . '=';
print "Formatted hash: ", $shatext, "n";
	
my $encoded = encode_base64($shatext);
print "Base64 re-encoded: ", $encoded, "n";
	
my $decoded = decode_base64($encoded);
print "Decoded: ", $decoded, "n";
	
__END__;

Here’s the output:

Original text: purple
Hashed text: r67XVAa9QUggzqSlEZ+QwlnAV1U
Formatted hash: {SHA}r67XVAa9QUggzqSlEZ+QwlnAV1U=
Base64 re-encoded: e1NIQX1yNjdYVkFhOVFVZ2d6cVNsRVorUXdsbkFWMVU9
Decoded: {SHA}r67XVAa9QUggzqSlEZ+QwlnAV1U=

What you’ll find is that when you query a directory as a privileged user (e.g. “cn=Directory Manager”) for the userpassword in an entry, most LDAP utilities will return either the formatted hash (e.g. with the “{SHA}” prepended and an equals sign at the end), or the Base64 re-encoded value.

As you can see from the code above, translating a string into a Base64 encoded SHA hash and then further Base64 encoding the result isn’t difficult using a combination of the Digest::SHA and MIME::Base64 perl modules. Decoding the Base64 encoded result back into the formatted Base64 SHA hash is also pretty straightforward. Note that the Digest::SHA module doesn’t automatically add the “{SHA}” prefix or “=” suffix to the hash value, so that needs to be done “manually” inside the script.

The hashed text is as far back in the process as you can go, since this is a one-way hash by design. But with the value in either formatted or Base64 re-encoded form you will be able to compare it to existing values stored in entry userpassword attributes. One application for this is a script that goes out and compares userpassword values to the kinds of insecure password strings that we always warn users to avoid. A “dictionary” of values can be built by hashing a list of words and then comparing the results with the hash values in entry userpassword attributes.

Note: Using Gisle Aas’s Digest::SHA1 module will give the same results demonstrated here. The major difference between Gisle’s module and Mark Shelor’s Digest::SHA is that the latter allows the use of some stronger SHA-based algorithms.