How to host WordPress admin on a seperate domain and subfolder

Introduction

So why would you want to do this when most posts on the Internet indicate that this is security by obscurity and a bad idea. Well, first and most important, at least for me – I wan’t my wordpress admin to be protected by HTTPS encryption but SSL certificates are expensive so I don’t want to buy one for each new site I host.

Secondly, while I don’t believe in relying on security by obscurity, I see no reason to make life easy for a potential attacker.

This setup is tested on WordPress 3 and 4.

Setup

This post is based on the following setup:

  • One Apache reverse proxy host that only redirects traffic to other virtual servers that run the actual sites. Lets call it the Proxy server and assign it IP 10.0.0.2
  • One existing site for which I have valid TLS certificate. Lets call this server web1, IP 10.0.0.3
  • One or more wordpress servers, lets call it wordpress and assign it IP 10.0.0.4
  • On the wordpress server there is a blog called blog, which is publicly accessible through blog.example.com.

Although I believe this setup makes sense for a lot of reasons, most of this guide will work even if you have everything on one server.

The challenges

If you are familiar with Apache’s mod_proxy, you may think this is as easy as forwarding a sub folder on your existing HTTPS-enabled site to a wordpress instance but unfortunately, WordPress is very sensitive to whether it is installed on a specific domain, in a subfolder etc. and trying this you will notice a lot of broken links. Also, WordPress cookies have a path that must match for the login to work.

If you have domain-name based virtual hosts to have several WordPress sites on the same server, you need to pass on the proper host name of the WordPress site, blog.example.com in this case.

The Solution

We use mod_proxy to forward traffic to the different sites’ admin urls.

We ensure ProxyPreserveHost is Off, set the internal IP of the blog in the hosts file of the proxy server, allowing us to use the domain name in the ProxyPass statement.

We can use mod_substitute (ensure it’s enabled on the proxy host) to fix the broken links that come back from the wordpress server which thinks the client is accessing the site through http://blog.example.com

Finally we leverage ProxyPassReverseCookiePath to fix the cookies.

So, where’s the code? Here we go…

In the virtual host of the HTTPS-enabled site on the proxy server:

<Location /wp-admins/blog/>

  AddOutputFilterByType SUBSTITUTE text/html
  AddOutputFilterByType SUBSTITUTE text/css
  AddOutputFilterByType SUBSTITUTE application/javascript
  AddOutputFilterByType SUBSTITUTE application/json
  Substitute "s|http://blog.example.com|https://ssl.example.com/wp-admins/blog|i"
  Substitute "s|blog.example.com\\\/|blog.example.com\\/wp-admins\\/blog\\/|i"
  Substitute "s|'/wp-admin|'/wp-admins/blog/wp-admin|i"
  Substitute "s|\"/wp-admin|\"/wp-admins/blog/wp-admin|i"
  Substitute "s|'/wp-includes|'/wp-admins/blog/wp-includes|i"
  ProxyPassReverseCookiePath / /wp-admins/blog/

</Location>

ProxyPass /wp-admins/blog/ http://blog.example.com/
ProxyPassReverse /wp-admins/blog/ http://blog.example.com/

In the hosts file add:

10.0.0.4 blog.example.com

With this configuration in place, you should be able to login at:

https://ssl.example.com/wp-admins/blog/wp-login.php

If you also want to block the admin from working when going to the direct URL, i.e. http://blog.example.com/wp-login.php you can add the following to the Apache virtual host for the blog itself:

RewriteEngine On
RewriteCond %{REQUEST_URI} wp-login|wp-admin
RewriteRule .   "-" [F]

Let me know in the comments if you’re facing any issues with this.

Join the Conversation

4 Comments

  1. Thanks for the post! Would you have any ideas on how this would work on a sub folder based multi site? my idea is for the wp-admin to run from one server while my other varnish based servers run the front site. I apologize if this is outside of the scope of your article.

  2. Dear sir,
    I tried to access wp-admin by subdomain as admin.mysite.com, and I stucked.
    I used nginx instead of apache.
    Please help

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.