userpkg — installing users from packages

Wednesday, March 10th, 2010

If you’re looking after handfuls of computers belonging to armfuls of different companies, you end up going through hoops trying to get your own user(s) installed each time you want access to a new machine.

userpkg aims to make this simpler, by using Debian package management.

Once userpkg is installed on a machine, you can introduce your new admin users as packages. userpkg will take care of choosing an available username, generating a new password, installing ssh keys and setting up sudo rights.

If you have set up your own private repository, you can now automatically upgrade ssh keys across the population of customer machines …

The initial public release of userpkg can be found at http://userpkg.inode.co.nz/. It’s feature-limited at this stage, but will grow; faster if people suggest things to me!

Debian and python setuptools easy_install — “error: Unexpected HTML page found”

Thursday, February 25th, 2010

So I’m here setting up a simple Trac environment on a Debian 5 server, and I’m about to add the essential graphviz plugin from trac-hacks.org

# easy_install http://trac-hacks.org/svn/graphvizplugin/0.11
Downloading http://trac-hacks.org/svn/graphvizplugin/0.11
error: Unexpected HTML page found at http://trac-hacks.org/svn/graphvizplugin/0.11

Wait, what? This exact same commandline works just fine on my laptop (Ubuntu, that is) … the URL is valid, I get the page I expect generated by subversion itself …

A quick Google later, it looks like the Debian packaged version can’t handle the latest subversion web pages. Thanks to coffeecoders.de we have a simple description of the problem & a workaround … upgrade easy_install underneath the Debian package.

# easy_install -U setuptools
Searching for setuptools
Reading http://pypi.python.org/simple/setuptools/
Best match: setuptools 0.6c11
Downloading http://pypi.python.org/packages/2.5/s/setuptools/setuptools-0.6c11-py2.5.egg#md5=64c94f3bf7a72a13ec83e0b24f2749b2
Processing setuptools-0.6c11-py2.5.egg
Moving setuptools-0.6c11-py2.5.egg to /usr/lib/python2.5/site-packages
Adding setuptools 0.6c11 to easy-install.pth file
Installing easy_install script to /usr/bin
Installing easy_install-2.5 script to /usr/bin

Installed /usr/lib/python2.5/site-packages/setuptools-0.6c11-py2.5.egg
Processing dependencies for setuptools
Finished processing dependencies for setuptools

This fixes the problem that easy_install has in grabbing resources from a subversion 1.5+ webserver. On the other hand it breaks the python-setuptools file …

# cd /
# md5sum -c /var/lib/dpkg/info/python-setuptools.md5sums
usr/bin/easy_install: FAILED
usr/bin/easy_install-2.5: FAILED
usr/bin/easy_install-2.4: OK
...
md5sum: WARNING: 2 of 53 computed checksums did NOT match

If you’re in the habit of verifying binaries against the package contents (e.g. with debsums), you need to know what you have just done … and look out for any upgrades of this package too (well, you could always pin this version in place, but let’s hope any future update of python-setuptools fixes this bug, eh).

Exim tls_verify_certificates …

Wednesday, February 24th, 2010

So you’re using Exim4, and you want to verify the TLS certificates of the MTA you are sending email to (especially useful if you want to use a smarthost).

Here’s my smarthost transport :-

smarthost:
driver = smtp
hosts_require_tls = my smarthost
tls_verify_certificates = /etc/exim4/tls/my_smarthost-ca.crt

I was reading Philip Hazel’s ‘The Exim SMTP mail server’, and it claimed that tls_verify_certificates could be a link to a directory instead of a single (possibly large) file.

However, there’s a gotcha … this is only possible if you are using the OpenSSL library with Exim4; the Debian 5 packaged version uses GnuTLS, and that can only accept the file version. You get a cryptic error in the logs if you try …

TLS error on connection to my_smarthost [IP Address] (setup_certs): Error while reading file.

See http://www.exim.org/exim-html-current/doc/html/spec_html/ch30.html for the clarifying documentation. To be fair, this has been ‘well known’ for many years …

Wordpress on Debian 5 with nginx, apache2 and admin under HTTPS

Saturday, January 16th, 2010

This Wordpress instance is being served by a combination of Nginx and Apache2, with the admin pages under HTTPS using the Admin SSL plugin. It’s all done with the Debian 5 packaged versions and some nifty configuration …

Nginx

The public webserver is Nginx, which is the high-performance front-end webserver you should be using. Nginx is listening for both HTTP and HTTPS. It is directly serving all static content it can, based on a regexp to detect the types.

As added complications, the /wp-uploads/ files are in a different location, and need to have the requested file name rewritten. And there’s no point wasting our time sending static content over HTTPS, we’re going to redirect all of it to HTTP. This will trigger browser warnings regarding mixed content, but that’s not a big problem.

location ~ \.(html|css|js|png|gif|jpg|svg|ico|txt)$ {
    if ($scheme = https) {
        # Refuse to serve static content under HTTPS
        rewrite ^/(.*)$ http://$host/$1 break;
    }
    # Intercept and serve static files directly
    if ($request_uri ~ /wp-uploads/.*$) {
        rewrite ^/wp-uploads/(.*)$ /$1 break;
        root /var/www/wp-uploads/inode.co.nz;
    }
    if ($request_uri !~ /wp-uploads/.*$) {
        root /var/www/inode.co.nz;
    }
}

Everything else is proxied down to an Apache running mod_php, on localhost. This is pretty straightforward, except the Apache itself is running HTTP and HTTPS (using the same certificates as Nginx), so I have to choose which proxy to talk to :-

# Choose the proxy based on the current encryption scheme
if ($scheme = http) {
    proxy_pass http://127.0.1.1:80;
}
if ($scheme = https) {
    proxy_pass https://127.0.1.1:443;
}

We are also setting up some new headers so that Apache can use mod_rpaf, enabling it to log real end-user IP addresses in its logfiles.

Apache

The application webserver is Apache, running mod_php (libapache2-mod-php5), mod_rewrite (which is not enabled by default on Debian) and mod_rpaf (libapache2-mod-rpaf). Apache is listening to both HTTP and HTTPS, but will look out for requests to /wp-admin/ and /wp-login.php and make sure that they are redirected to HTTPS. This is basically the same setup as recommended by the Wordpress Codex.

# Bounce sensitive requests to https
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^/wp-admin(.*) https://inode.co.nz/wp-admin$1 [QSA,L]
    RewriteRule ^/wp-login.php(.*) https://inode.co.nz/wp-login.php$1 [QSA,L]
</IfModule>

The HTTPS server will also rewrite non-admin page requests, and direct you back to the HTTP version.

# Bounce non-sensitive requests to http
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule !^/wp-admin(.*) - [C]
    RewriteRule !^/wp-login.php(.*) - [C]
    RewriteRule ^/(.*) http://inode.co.nz/$1 [QSA,L]
</IfModule>

Admin SSL

This is almost enough, as most of the admin URLs presented by Wordpress are relative, and will therefore be HTTPS if the requested page was HTTPS. But for Wordpress versions below 2.6 (i.e. the standard Debian version is 2.5.1) you will need to install the Admin SSL plugin. The default configuration is fine, just install and enable the plugin (specifically, we are not using Shared SSL).

Conclusion

Here is a diagram showing what we have achieved :-

Wordpress under nginx & apache

HTTPS will be automatically invoked when accessing admin pages, and will be automatically switched off at all other times. Only requests that need PHP will be passed on to Apache, everything else will be handled by nginx.