# Protecting Wordpress Admin interface on an alternate port

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:

1. one serving blog.domain.com port 80 which returned 404 if you tried to get to anything under /wp-admin
2. 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.

-

  define('FORCE_SSL_LOGIN', true);


Sometimes, you want your whole wp-admin to run over a secure connection using the https protocol. Conceptually, the procedure works like this:

Set up two virtual hosts with the same url (the blog url), one secure, the other not. On the secure virtual host, set up a rewrite rule that shuttles all non-wp-admin traffic to the insecure site. On the insecure virtual host, set up a rewrite rule that shuttles all traffic to wp-admin to the secure host. Put in a filter (via a plugin) that filters the links in wp-admin so that once activated, administrative links are rewritten to use https and that edits cookies to work only over encrypted connections.

The plugin they mention is called admin ssl.

-
I played with this a bit; unfortunately it doesn't do precisely what I want because turning on FORCE_SSL_ADMIN implies FORCE_SSL_LOGIN. That means that my registered user logins also go to the SSL site, where the server asks for and attempts to verify their X.509 cert (which they don't have). So I can get halfway there (encryption for the sensitive bits) but my username/password is still the only thing required to get to the admin panel (instead of both + a keyed X.509 cert). –  James F Jul 21 '09 at 23:55

I'm facing a similar problem, I'm using wordpress since a quite long time and want to force /wp-admin/ to work over SSL.

So I did :

RewriteEngine On
RewriteCond %{HTTPS} !=on


This is almost working. When I go to http://website/wp-admin/ I'm redirected to wp-login.php over SSL but after loggin process I'm getting redirected to https://website/http://website/wp-admin/ (this is not a typo) because wordpress use internal redirection that doesn't work well with rewrite rule.

But before recent Wordpress release there was another issue, on the wp-login.php page, the login form action was set to http://website/wp-login.php. So login information was sent in clear. (So patching wp-login.php was needed)

Recent (since 2.6.0) Wordpress release add a FORCE_SSL_LOGIN setting. Putting define ('FORCE_SSL_LOGIN','true'); in wp-config.php will make the form action on wp-login.php to https://website/wp-login.php (With a little change in wp-login.php you can add :8443)

So with FORCE_SSL_LOGIN + rewrite it's safe, but I still have to reload the wp-admin url after login process.

2.6.0 also add FORCE_SSL_ADMIN`, but When I set this to true (with or with my rewrite configured) I for indefinitely redirected to http://website/wp-admin/ So you may try to set FORCE_SSL_LOGIN to true and patch wp-login.php to use port 8443 and you may also try FORCE_SSL_ADMIN (I don't know yet why it's not working for me, may be it will for you)

-

Mhhh... I have a suspicion this would require mangling wordpress to separate the wp-admin section from the main site, which as far as I know it isn't designed to be.

Can you not set up a secure SSL vhost (with the same docroot) and then via .htaccess magic (which I've done before) force all /wp-admin requests to go through https rather than http?

This obviously doesn't separate the whole admin section off, but at least it mean unencrypted traffic is stopped.

-
The problem is that the main site runs on the default http port; when you redirect it to https, it attempts to go to the default https port (it's careful enough to check that it doesn't redirect https to http). The default https port on my server is a completely different site, so to make this work, I'd need to give wordpress the default SSL site and move what's curently there to an alternate port. I was hoping to avoid that. –  James F Jul 21 '09 at 18:28