AFS, Apache, and pseudo-SuExec
2007-09-22 03:45 - ugcs security
It’s been an exceptionally busy week for me on the UGCS front, despite my being on vacation and traveling.
On Monday morning, we migrated everyone’s mail over to our nice new shiny 8-core Xeon server (hermes) and forced everyone into using our new Kerberos infrastructure to authenticate against IMAP and POP. There have been quite a large number of problems we discovered after the migration which we didn’t quite catch during initial testing, but as of Thursday we had everyone’s legacy mail converted and mail delivery was finally stable. I’ll blog separately about that when I have working configs to post should someone attempt to do an effort similar to UGCS in the future (I’m currently debugging an issue with mail forwarding at the moment). In short, we’ve set up delivery to maildirs on AFS, postfix, dovecot, GSSAPI auth (Kerberos), LDAP mail delivery settings and nss info, mailman, amavisd, clamd, and spamassassin all happily playing with each other now.
We also ended up moving over web services to the new ‘service’ machine (poseidon) on Thursday because the old webservers had finally had it and were timing out and refusing to function.
Inspired by this post by Todd Lewis from the University of North Carolina, but lacking his source code, I endeavored to create an equivalent for SuEXEC for our users. The problem is that Apache does not run with the Kerberos tokens of users, so it cannot execute sensitive read or write operations on user data, only read the data in ~/public/www. Many of our users rely on using CGI to manipulate flat file databases, etc., so this was somewhat of a priority to get them some level of control over their data using CGI without opening them up to cross-user scripting vulnerabilities from malicious users.
http://www.ugcs.caltech.edu/~elizabeth/cgi-wrapper is the result of my efforts – it’s meant to be run setuid as root and executable only by Apache when Apache matches “ScriptAliasMatch ^/~(.+)/cgi-bin/(.*) /usr/local/sbin/cgi-wrapper”. $10 security bug bounty, payable via Paypal to the first person who finds a security hole in it. The script was largely written according to Todd’s spec, and essentially pulls the tokens for a user from a root-only file, sets environment variables so the wrapped script won’t notice the aliasing, and then changes uid/gid to the user and creates a new PAG context with the tokens for that user’s cgi subuser. The cgi subuser can be assigned very limited permissions using AFS acl’s so a vulnerable cgi script can’t wipe out one’s homedir or mail (unless of course given permission to do so).
Now that our webservices are up, I’ve migrated the UGCS development wiki over to poseidon, but it currently requires a Kerberos login to view (sorry, guys). I used mod_auth_krb plus Extension:AutomaticREMOTE_USER to make it work.
All in all, a very productive week on my side project :) – we’re definitely going to make the September 29th switchover date to shut down the old cluster and convert old cluster’s servers into shell machines in the new cluster.

<- Review: But I'm a Cheerleader (1999) Reps. Frank and Pelosi throw transpeople under the bus ->

That’s a really great script.
One of the major reasons I held off from switching acm.jhu.edu to Kerberos (and AFS) was that I couldn’t think of a reasonable way to handle this exact use case.
Security warning: You use backticks to call out to other programs, but it seems to me that using system() and passing it a list prevents all shell injection attacks; here, you’re using sanitized input (except possibly the a bizarre tempfile() implementation might give you an evil $keyfile), but in general I figure it’s best to practice good habits, system(list) being one of them.
(Also, hi Elizabeth! Long time, no talk; mostly my fault, I suppose.)
— Asheesh Laroia Dec 23, 02:44 PM #