Monday, March 30, 2009

RAID 5 on an Leopard Xserve

This seems too trivial to merit a posting, but there are other posts that might lead one to believe that Leopard doesn't support RAID-5 on an Xserve, which it does, provided you've got a RAID card installed. When booting the installation DVD, just look for "RAID utility" under the "Utilities" menu. Just be sure to create the RAID before you pick an installation disk.

Update: Jashugan's right; I've updated appropriately. Though I still like the sound of "Xserver." One last thought: why ever does the RAID 5 volume build process take something like 2 hours / 100G? I understand the time required to rebuild parity after replacing a failed disk on a live array, but the initial build should be faster than that. Unless the OS is doing a bad block scan on the disks or somesuch, but ... why do that for a RAID and not under other circumstances?

Tuesday, March 24, 2009

Regarding encryption ...

Not encryption in general, but one very specific instance of it: Apache SSL on my Ubuntu/8.10 box.

Ubuntu ships with two SSL modules available -- the canonical, OpenSSL-based Apache mod_ssl, and the newer mod_gnults (pronounced "noodles?"). I decided to try mod_gnutls for no good reason, and it seemed to work -- I could serve content via an encrypted connection! Except for the silent redirects. I'd point my browser to /, get redirected to my SSL login page as expected ... and then wind up on the login page over vanilla HTTP.

In situations like this, HttpFox is your friend. As are netcat and OpenSSL itself, which, if you'll pardon the tangent, has it's own netcat-like behavior indispensable for debugging encrypted network services:
   openssl s_client -connect myserver.com:443
Via openssl, here's the offending HTTP transaction:
GET /ri/account/login?next=/ri/ HTTP/1.1
Host: myserver.com

HTTP/1.1 301 Moved Permanently
Date: Tue, 24 Mar 2009 15:26:47 GMT
Server: Apache/2.2.9 (Ubuntu) DAV/2 mod_gnutls/0.5.1 PHP/5.2.6-2ubuntu4 with Suhosin-Patch mod_python/3.3.1 Python/2.5.2
Content-Type: text/html; charset=utf-8
Location: http://myserver.com/ri/account/login/?next=/ri/
Vary: Accept-Encoding
Content-Length: 0
I ask, over HTTPS, for the login page, and it redirects me back to the unencrypted version. And I never quite figured it out, either -- I just switched to mod_ssl and the problem went away.

I can't even say this is a GNUtls bug, but it's certainly some strange behavior.

Monday, March 23, 2009

python-ldap authentication and you

Or me, at least.

Here's how I managed to make my python client code running on a Debian/Ubuntu box authenticate against a Windows Active Directory LDAP server:
  1. Obtain the server's cert: openssl s_client -showcerts -connect myserver.com:636 > their_server.pem

  2. Edit the resulting file to isolate just the cert you want. In my case, the file had two certs embedded in it, plus some identifying cruft. Preceding the first, desired cert was a block that looked like this: 0 s:/C=US/ST=MyState/L=MyCity/O=My Company Inc./OU=Information Technology/OU=For Intranet Use Only/CN=my.host.com, followed by -----BEGIN CERTIFICATE-----. Next came VeriSign's cert. Delete everything but the CERTIFICATE block for your server, including the BEGIN and END lines, and save to /etc/ssl/certs/myserver.pem -- you can save to any location, really.


And here's the code:
#!/usr/bin/env python

import ldap
#ldap.set_option(ldap.OPT_DEBUG_LEVEL,4095)
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
ldap.set_option(ldap.OPT_X_TLS_CACERTFILE,"/etc/ssl/certs/myserver.pem")
l = ldap.initialize("ldaps://myserver.com:636")
l.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
l.simple_bind_s("username@DOMAIN","password")

Wednesday, March 11, 2009

The trouble with DRM

Cory Doctorow's brilliant denunciation of DRM, as delivered at a Google Author talk a couple years ago:
If you deliver to an attacker the cipher-text, the cipher, and
the key, and rely on the attacker not combining those except
under circumstances you dictate, you're living in a fool's paradise.
I was reminded of this by Roger Gregory, who directed me to a youtube video about cold-boot attacks.

Thursday, March 5, 2009

Timing out an arbitrary Python function

Update:

The problem with the signal.alarm approach described below is that the alarm WILL happen, thus interrupting a hung function in the failure mode we're trying to account for. But it will ALSO SIGNAL if that function returned as expected, thus throwing an exception at some random point in later code.

The solution is to disable the alarm, as described below:


Occasionally, child processes die. If you don't want your script to hang, you do something like this:

TIMEOUT = 10
process = subprocess.Popen(...)
(o, _, _) = select.select( [process.stdout], [], [], TIMEOUT )
if o:
return process.stdout.readline()
else:
os.kill(process.pid, signal.SIGKILL)
os.waitpid(-1, os.WNOHANG)

This works perfectly well (and mimics the C version pretty closely), but what if the process is already wrapped in a python module and you don't have direct access to the process?

This guy has a good solution:
  def raiseTimeout(a,b):
raise Exception()
signal.signal(signal.SIGALRM, raiseTimeout) # bind a signal handler
signal.alarm(1) # raise the alarm sig in 1 s
some_hang_prone_function() # this is the problem function
signal.alarm(0) # disable the previously set alarm


My original version used a lambda in place of a proper function, but it turns out that lambda a,b: raise Exception() isn't proper syntax.