On getting lighttpd + PHP working on OS X Tuesday, Mar 2 2010 

Now playing: ♫ One More Time – Daft Punk

My first post of 2010!  I have been so busy that I just haven’t had any time to write anything in here.  But I have something special for you today; some build instructions for making an experimental dev server out of a Mac.

I use a Mac at work.  And being that I frequently have to test out our new Web stuff (some written in PHP but the majority written in Django), it’s helpful to have a working lighttpd install on it.  I’ve considered dual-booting with FreeBSD, but it seems a bit of a challenge to get all of the Apple hardware to work on FreeBSD (especially WiFi; we don’t even really use wired Ethernet at work anymore) so I’ve held that off for a while.  I could also use my desktop, but with the KVM on the fritz I just find it easier to sometimes run sites on OS X.

This isn’t a problem with Django, because it comes with a small development server that I can use.  But it is big problem with PHP; the Apache2 built in to Snow Leopard doesn’t seem to like me or PHP (or my configuration) and I prefer lighttpd anyway.  I could never find a really good guide to installing any of this online without resorting to MacPorts or Fink or even Aptitude.  I prefer to keep my system clean of the port systems (even though I’ve heard great things about MacPorts, it just seems ugh).   So, here’s how I got lighttpd and PHP to play nice on OS X with FastCGI:

Absolute prerequisites

  1. You must be absolutely comfortable with using Terminal and compiling things by hand.
  2. You must have already installed XCode, because we’re going to be using GCC and friends.

lighttpd installation

  1. Install PCRE.  This is the only lighttpd dependency that Mac OS X doesn’t ship developer libs with.
  2. I ran configure like this:
    ./configure --prefix=/usr/local --with-openssl --with-kerberos5 --with-ldap --with-zlib
    This allowed me to test SSL and Kerb5, which we use on one of our portals, and a few other miscellaneous things I feel will be useful.
  3. make and then sudo make install.
  4. Congratulations, you have an almost-working lighttpd!

PHP installation

For GD, you’ll need at least:

  1. libjpeg (Note: You’ll need to run sudo mkdir -p /usr/local/man/man1 for manpages.  If you don’t want them, you can ignore the error Make throws.)
  2. libpng (Don’t you love that they still distribute .TXZ’s?)

You can also snag FreeType and libxpm, but it isn’t necessary and building them is beyond the scope of this document.

Okay, so now we’re ready to build PHP. The configure line you supply to PHP is site-specific.  The one I used was:

./configure --prefix=/usr/local --with-openssl=/usr --with-kerberos --with-pcre-regex=/usr/local --without-sqlite --without-sqlite3 --disable-pdo --with-zlib --with-bz2 --enable-exif --with-gd --with-ldap --with-ldap-sasl --with-mcrypt --without-mysql --with-pgsql=/usr/local/pgsql

but I stress again: this is site-specific. You probably want MySQL and don’t want PostgreSQL (even though it takes a lot to squeeze even equal performance out of MySQL).  That said, the only oddity is that on OS X, PHP has a problem locating the OpenSSL lib for itself and I had to use –with-openssl=/usr to allow it to find where it was.

Also, a big disclaimer: GD is still broken with libpng>=1.3.  Since I use 1.4, I was forced to use the SVN version of 5.3.  Not even the new 5.2.13 release has the patch (even though this bug was reported in early January).

Now that we’ve gotten that out of the way, let’s get a server running!

Configuration files

The lighttpd configuration file is up to you.  Note that you have to use server.event-handler = "freebsd-kqueue" on OS X.  Mine is pretty standard, so I’m only going to paste the FastCGI configuration section here:

fastcgi.server = (
".php" => (
"php-osx" => (
"socket" => "/tmp/php5.sock",
"bin-path" => "/usr/local/bin/php-cgi",
"bin-environment" => (
"PHP_FCGI_CHILDREN" => "2"
)
)
)
)

Now, one of the most painful parts of this process was getting a LaunchDaemon configured for lighttpd properly.  Note that when under launchd, lighttpd is very sensitive to syntax; I spent about an hour trying to figure out why it wouldn’t start until I realised I had an extraneous space in the plist.  Here is my /Library/LaunchDaemons/net.lighttpd.plist file:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>net.lighttpd</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/sbin/lighttpd</string>
<string>-D</string>
<string>-f/usr/local/etc/lighttpd.conf</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>

Now run launchctl as root and type load /Library/LaunchDaemons/net.lighttpd.plist.  If you’ve come this far and you don’t get any errors, congratulations!  Your Mac is now a lighttpd+PHP/FastCGI server!

Advertisements

On getting OpenLDAP and Windows LDAP to interop Friday, Dec 18 2009 

Many Windows developers have a need of some sort to connect to OpenLDAP directory services.  Some use wldap32, others use the DirectoryServices namespace in .NET, others use custom libraries.  Myself, I’m writing an ASPX front-end to our FreeBSD LDAP directory service.

If you are one of the developers in the first two camps, you’ve probably been dumbfounded by one of these error messages:

  • An unexpected operation error occurred
  • A local error occurred
  • TLS negotiation failure

At first, I was inclined to believe this was due to the fact that MS wanted devs to stick with ADAM and not use OpenLDAP.  However, this is not the case.  Each error means something different, and I have workarounds now for all of them that fixes it.

An unexpected operations error occurred

My favourite.  This is due to an OpenLDAP bug that the developers won’t fix.  They have claimed that “Microsoft is the one that is broken by following RFC 2830″…yes, that’s right, an open-source project upset that MS is following an RFC.

Anyway, to fix it you need to apply a one-liner patch (thanks Kirill) to starttls.c, verified to work with OpenLDAP-2.4.19 and CVS HEAD as of this morning (GMT):

=============
--- orig/starttls.c	2004-01-01 21:15:32.000000000 +0200
+++ fixed/starttls.c	2004-05-27 14:14:54.000000000 +0300
@@ -94,6 +94,8 @@
     op->o_conn->c_is_tls = 1;
     op->o_conn->c_needs_tls_accept = 1;

+    rs->sr_rspoid = SLAP_STRDUP(LDAP_EXOP_START_TLS);
+
     rc = LDAP_SUCCESS;

 done:
=============

Recompile OpenLDAP with this change.  Your OpenLDAP is now RFC 2830 compliant and Microsoft APIs (and older Netscape and Novell APIs) can now connect and start TLS with it.

“But wait, Pongo,” you say.  “Now I’m getting a new error!”  Yes, because MS is strange about server certificate processing you will now receive:

A local error occurred (on the LDAP server, “TLS negotiation failure”)

You need the server certificate from the OpenLDAP server (see your slapd.conf file, under TLSCertificateFile.  Mine is in /etc/ssl/keys/ldap).

  1. Copy the file (named chicago-auth.crt in the example) to your Windows computer.
  2. Install the certificate (double-click it) to the Trusted Root Certificate Authorities store.  (I am not sure if this step is required or not.  It was for me for other reasons.)
  3. In your .NET application, add a code block similar to the following:
                lc.SessionOptions.VerifyServerCertificate = Ldap_ServCertCallback;  // Add this line BEFORE StartTLS call
                lc.SessionOptions.StartTransportLayerSecurity(null);

Your Ldap_ServCertCallback function should look something like this:

        private bool Ldap_ServCertCallback(LdapConnection connection, X509Certificate cert)
        {
            X509Certificate realchi = new X509Certificate("chicago-auth.crt");

            if (realchi.GetCertHashString() == cert.GetCertHashString())
                return true;
            else return false;
        }

That’s it. Your .NET application will now happily connect to your OpenLDAP server.

Note that I have not personally tested this workaround with wldap32 (I’m unsure how to set a VerifyServerCertificate callback and I don’t hack the Win32 API anymore anyway), but I have in .NET and it works in both Win32 and ASP.NET applications.

The case of the missing manager Monday, Dec 14 2009 

I was reading the awesome Screwed article on Rands In Repose when I finally realised what the problem I’m having at work is.

I have no manager telling me to get the hell going.

You see, like most startups, we have like…5 people on our team total.  And the problem is that most people think I’m the manager.  To outside people, it may look like it.  Well, actually, if I were to draw an org chart I’m probably the top of the development leaf.  The problem isn’t that I have no managerial experience.  The problem is nobody above me is pushing me to do anything and the developers below me don’t care about anything at all.  Things are starting to slow and stagnate.  The developers below me are pretty much not doing anything related to the project… they’re using the excuse that they are waiting on design specifications that I’m supposed to write.  The problem is I can’t write those specifications yet.  And for that we need to look at the org process and the use case specification.

Ah, the use case specification.  I slaved on that thing for 9 days getting it correct and making sure the “Product Champion” (fancy word our org. uses for product manager) had input because she’s the only person here who actually knows our users.  After it was finished I was to send it off to everyone in the team and get input.  This is part of the very little process we have; everyone has to approve a doc before we move to the next step.  And I think that’s reasonable with a 5 person dev team.  That was 19 June.

On 11 August the product champion finally read it.  Wait, what?  It took almost a month?!  She had a few corrections and additions that I added in about an hour.  I sent it off to everyone in the team again.  On 21 August (10 days later) one dev replied and had one small clarification.  There are still two people on our team that haven’t even opened the PDF.

Yes, there are two people on our team that haven’t opened the PDF after 6 months.  I will call this WTF #1.

Closely related is the fact that in the course of use case development I had to prototype two small features.  I used Visual C++ 2008 because they were related to the way Windows would handle things (it was ensuring that Windows would support multilingual support the way the product champion wanted it).  I raised a few questions and concerns to two members of the team and they went completely unnoticed.  It’s like nobody on the team but me even cares about this software.  I will call this WTF #2.

Anyway, back to the matter at hand.  I’m not supposed to write the design specification below use cases until all members of the team read the use case doc.  Obviously, it’s been 6 months and there are still members who haven’t.  I have gone ‘underground’ and started writing the other specifications actually at the request of the product champion, whom is just as concerned as I am that this is heading nowhere fast.  We don’t even have VCs or investors yet because we have nothing to invest in.  Now that’s all fine and dandy because we can get paid our half-salaries indefinitely as long as “financial” (if you can call one person who is basically investing her life in this business “financial”) continues to have money.  But the problem is I think this is giving everyone else on our team the feeling that we’re able to stagnate.  I mean, what’s the rush, we’re getting paid (even if it isn’t all of what we’re worth) and we don’t technically have to DO anything, we can just keep trodding along and never even make a product.  This is WTF #3 and it’s the biggest.  I think this team needs a HUGE shakeup.  I think it needs fire and determination.  And where do good teams get fire and determination from?

Leaders.  They get it from leaders.  And our team has none and I think that’s where the huge problem is.  We have nobody making us stay on schedule.  And do you know what’s worse than having a tight schedule where you know you won’t deliver?  We don’t have a schedule.  UM is quite content with “when it gets done, it gets done” — probably the worst schedule known to productive society because it’s far too open-ended.  We have another project… an embedded system that I can’t talk about because of NDAs.  And I see this project working and progressing and it’s almost ALMOST to the point of being able to have VCs and I am truly starting to wonder where the hell our team went on the radar of…everybody.

I should’ve left a long time ago.  And to be honest, I wish I could leave.  This is fruitless and getting nowhere fast, especially since it’s far too late to ask for new team members (and actually I know that I couldn’t get them anyway.  I’ve tried.) and I feel this is going to drag on forever.  My screw-i-tude is higher than anyone could imagine.  What I need right now is UM or a manager or ANYBODY to come and say to the entire team: “here’s a schedule, let’s take this software and GITFO the door”.

And before you tell me that I should be inspiring myself to do it, YOU inspire yourself after watching nothing happen for 6 months, no other orgs nearby to get a job with (a hick town, that’s what this is) and no schedule.  I’ve been fighting tooth and nail to get this project done since…09 December 2008 according to this document.  It’s getting increasingly harder to self-motivate, especially around other devs that don’t gaf about this software or me or themselves, it seems.

I stick around here for only two reasons: The idea itself is fantastic and this could be huge if someone would actually make it MOVE, and there’s basically nothing else around here I could do other than work for a small store being a cashier.  Yeah, I have looked but found nothing else, and I really like software dev and I do not want to work as a cashier.

And before you comment about how I should move to somewhere else where I could be useful.  Yes.  I should.  But I’m tied here due to family stuff (stuff that I wouldn’t go on about in a blog).  So that isn’t an option yet, at least not for a few years.

So I think what this team needs now is just authority.  Someone to come in and say to this team “why are you all on your asses?  Get to f—ing work.”  And I think what I’m going to go do right now is send this to my team and my managers and hope for the best.

Well, to my managers at least.  I know my team won’t care or read it.