I have a self-hosted Wordpress blog. Whenever possible, I try to protect admin interfaces to web apps using SSL and X.509 client certificate authentication. I have all of this working properly for things like phpMyAdmin, so the technical bits with the web server are all in place.
My hosting setup is:
- nginx 0.7.x
- PHP 5.2.10 with the fpm patch
- MySQL 5.x
I'm running all of this on a VPS, so I just have one external IP. I have several other SSL websites running on the box: one on the default port and all the others on alternate ports (so that each can have a different certificate matched to their hostname).
My intent was to have two server configuration blocks:
- one serving blog.domain.com port 80 which returned 404 if you tried to get to anything under /wp-admin
- another running on port 8443 with SSL with no URL restrictions but which required that a valid X.509 client certificate be presented.
The problem I'm facing is that Wordpress doesn't like being accessed on two different ports. Whenever I attempt to go to https://blog.domain.com:8443, it redirects me to https://blog.domain.com, which is a different vhost entirely (the main site on the server, running on the default port). I then get a certificate name error in the browser, and even if I override the warning, I'm no longer talking to the wordpress site.
The main URL of the blog is stored in the wp_options table:
mysql> select option_value from wp_options where option_name = 'siteurl';
+------------------------------+
| option_value |
+------------------------------+
| http://blog.domain.com |
+------------------------------+
1 row in set (0.00 sec)
mysql>
so it's not like I could just make a second copy of the blog files with the main URL set to https://blog.domain.com:8443 and access the admin interface that way.
Any ideas?
UPDATE
Ater playing for some time with the suggested answers, I've come to the conclusion that it isn't possible to do precisely what I want. Enabling the features in wordpress result in users making SSL requests to /wp-(admin|login|register), which they can't do if I require X.509 client certs on the SSL side.
The best solution I came up with was to set up an SSL frontend with certificate authentication that just proxied requests back to the non-SSL nginx. Even then, I can't entirely cut off non-SSL access to /wp-admin because much of the CSS and Javascript used in user registration and profile management come from that directory.
I can allow access to the CSS, images and Javascript under /wp-admin over HTTP and just require SSL access for the PHP scripts, but then users can't modify their profile (colour schemes, display names, etc.) The next step would be to identify the subset of PHP scripts required for normal users and let those pass over HTTP while rejecting the rest, but then I'm a slave to the wordpress development team should they reorganize things.
I guess this one comes down to training myself to only manage the blog over SSL, even though the server will allow me to do so over plain HTTP.