WordPress and Apache kung-fu
November 12, 2010 8:52 PM   Subscribe

WordPressFilter: Is there a way to host the public site on one domain (bar.example.com) and the admin interface on another (foo.example.com/bar)? Some serious Apache/WP wizardry needed.

The Background: I have a user who insists that foo.example.com/bar will not fit the purpose of their blog and they want it hosted at their own domain, bar.example.com. The logins for posting to this blog must be secure, so I have to have SSL on the admin interface.

The Attempt: create a CNAME for bar.example.com that points to foo.example.com. Then setup apache with a new VirtualHost directive for bar.example.com:80. Setup the whole blog unsecured (safe because I'm on the local ethernet segment).

Then, after everything is tested and working, add this rewrite rule to the VirtualHost for bar.example.com:80

RewriteRule ^(/[a-z0-9-]+)?/wp-(admin|login|register)(.*) https://foo.example.com/bar$1/wp-$2$3 [R,L]

And setup the VirtualHost for foo.example.com:443 with all the information (Alias/Directory) to make the WP install accessable at /bar.

The Result: going to the admin interface from bar.example.com just redirects you to back to the home page of bar.example.com. RewriteLog shows that the redirect is happening, but I strongly suspect that WP doesn't know what it's doing at foo.example.com/bar and tries to fix "the problem". - - [12/Nov/2010:22:34:00 --0600] [bar.example.com/sid#1009dd520][rid#100aa8ca8/initial] (2) init rewrite engine with requested uri /sbutler/wp-login.php - - [12/Nov/2010:22:34:00 --0600] [bar.example.com/sid#1009dd520][rid#100aa8ca8/initial] (3) applying pattern '^(/[a-z0-9-]+)?/wp-(admin|login|register)(.*)' to uri '/sbutler/wp-login.php' - - [12/Nov/2010:22:34:00 --0600] [bar.example.com/sid#1009dd520][rid#100aa8ca8/initial] (2) rewrite '/sbutler/wp-login.php' -> 'https://foo.example.com/bar/sbutler/wp-login.php' - - [12/Nov/2010:22:34:00 --0600] [bar.example.com/sid#1009dd520][rid#100aa8ca8/initial] (2) explicitly forcing redirect with https://foo.example.com/bar/sbutler/wp-login.php - - [12/Nov/2010:22:34:00 --0600] [bar.example.com/sid#1009dd520][rid#100aa8ca8/initial] (1) escaping https://foo.example.com/bar/sbutler/wp-login.php for redirect - - [12/Nov/2010:22:34:00 --0600] [bar.example.com/sid#1009dd520][rid#100aa8ca8/initial] (1) redirect to https://foo.example.com/bar/sbutler/wp-login.php [REDIRECT/302]
The Problem: I know what the best way to fix this. What I should do is add a second IP to the server with bar.example.com and setup apache with both a bar.example.com:80 and bar.example.com:443 VirtualHosts + SSL certificate. But I can't (so don't suggest I do this). The server also runs some vendor kerberos enabled applications, and previous attempts with multiple IPs have caused nothing but headaches and downtime. The applications get confused about which domain they are running on and start to request/offer the wrong kerberos information.

My Hope: is there some hidden WordPress configuration or (mu-)plugin that lets me do what I want? I have a feeling that the answer is no, but I want to tell the client I've tried everything I can think of first. (And I don't want them to come back with "But site X is doing it!")

This is a WordPress 3.0.1 install with Network enabled. Apache 2.2
posted by sbutler to Computers & Internet (5 answers total)
Hm, two ideas:

1) in your Apache SSL configs, you could try a ProxyPass of foo.example.com/bar to bar.example.com, adding some header with a connection string that your port 80 Apache configs for foo.example.com/bar require for accessing wp-(admin|login|register). Since that connection will never really go over the wire, having it be unencrypted is typically fine.

2) the redirection is likely using WordPress's home_url function (as do all URLs on the site), but writing your own plugin to perform surgery on home_url is pretty easy:
add_filter('home_url', 'your_function', 0, 1);
function your_function ( $url ) {
   if (... some interesting $_SERVER var ...) {
      $url = preg_replace( '/bar.example.com/', 'foo.example.com/bar', $url );
   return $url;
Not sure that's a complete solution ... Good luck.
posted by Monsieur Caution at 8:34 AM on November 13, 2010

Force the whole site to be https, all the time?
posted by artlung at 10:26 AM on November 13, 2010

@Monsieur Caution: hmmm... (1) is a very interesting idea. I might have to give that a try.

@artlung: SSL won't work on Name based Virtual Hosts. It wouldn't ever offer the certificate for bar.example.com, always choosing foo.example.com
posted by sbutler at 11:05 AM on November 13, 2010

Hmm... poking around in the source there is an admin_url() function/filter. If it's used consistently that might be exactly what I need!
posted by sbutler at 11:16 AM on November 13, 2010

So I found a plugin that will do what I want and more (even if it is a little funny with the login cookie)! Domain mapping.
posted by sbutler at 11:28 AM on November 23, 2010

« Older i don't want to be a lifelong journalist   |   How can I find a better sense of direction? Newer »
This thread is closed to new comments.