Nginx https reverse proxy to WordPress with Apache, http and different port

Today I had to hide a WordPress 3.8.1 blog behind an Nginx reverse proxy configured to use only https. Nginx was behind an external firewall which forwarded to Nginx using https (port 4443). The difficulty was that whe WordPress blog was installed in an Apache HTTP server in port 80 and it worked using http!. Lets say that my site was and I had to put the blog in Thus my list of burdens was the following:

  1. Configure Nginx to use only https and redirect http to https.
  2. Reverse proxy in Nginx from to in Apache.
  3. Force WordPress links to use port 8080

The following is the diagram summarised my server configuration:

    |  Firewall    |
    | | 
     +–––––––––+                  +––––––––––––––+
     |  Nginx  |      http        |  WordPress   |
     | (https) |+---------------->| Apache HTTP  |
     |         |                  | (port 80)    |
     +–––––––––+                  +––––––––––––––+ 

So you will say: “Are you completely insane ??!!”

I was asked to do it! That is my answer!

Finally after one hour of searching I used a combination of two support articles (post1, post2), some PHP knowledge and experience and a little of imagination, I created a solution:

  1. Configure Nginx to reverse proxy all requests to /blog

    This is a fragment of my /etc/nginx/sites-available/default-ssl Nginx configuration file:

    upstream blog-webservers {
    # redirect http to https
    server {
        listen 80;
        rewrite ^(.*) https://$host$1 permanent;
    server {
        listen *:443;
        ssl on;
        ssl_certificate     /etc/nginx/crypto/server.crt;
        ssl_certificate_key /etc/nginx/crypto/server.key;
        ssl_client_certificate /etc/nginx/crypto/ca.crt;
        ssl_verify_client optional;
        ssl_verify_depth 10;
        # pem key asking for password problem
        access_log  /var/log/nginx/ssl.access.log;
        error_log   /var/log/nginx/ssl.error.log;
        error_page  404 /404.html;
        # reverse proxy to blog web servers
        location /blog { 
            proxy_pass http://blog-webservers/wordpress/;
            proxy_redirect https://server_name http://blog-webservers/wordpress;
            proxy_read_timeout       3500;
            proxy_connect_timeout    3250;
            proxy_set_header   X-Real-IP          $remote_addr;
            proxy_set_header   Host               $host;
            proxy_set_header   X-Forwarded-For    $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto  https;
            proxy_set_header   SSL_PROTOCOL $ssl_protocol;
            proxy_set_header   SSL_CLIENT_CERT $ssl_client_cert;
            proxy_set_header   SSL_CLIENT_VERIFY $ssl_client_verify;
            proxy_set_header   SSL_SERVER_S_DN $ssl_client_s_dn;

  2. Configure WordPress wp-config.php
    I added the following lines on top of wp-config.php file:

    // If WordPress is behind reverse proxy 
    // which proxies https to http
    if ( (!empty( $_SERVER['HTTP_X_FORWARDED_HOST'])) ||
         (!empty( $_SERVER['HTTP_X_FORWARDED_FOR'])) ) { 
        define('WP_HOME', '');
        define('WP_SITEURL', '');
        // rewrite blog word with wordpress
        $_SERVER['REQUEST_URI'] = str_replace("wordpress", "blog",
        $_SERVER['HTTPS'] = 'on';

If you want to debug the former PHP code fragment you can print $_SERVER variables before and after configuration changing command inside the if block:

echo '<br>Before:';
echo '<br>$_SERVER[\'HTTP_HOST\'] : ' . $_SERVER['HTTP_HOST'];
echo '<br>$_SERVER[\'REQUEST_URI\']: ' . $_SERVER['REQUEST_URI'];
echo '<br>$_SERVER[\'HTTPS\']: ' . $_SERVER['HTTPS'];
echo '<br>$_SERVER[\'REMOTE_ADDR\']: ' . $_SERVER['REMOTE_ADDR'];    
echo '<br>$_SERVER[\'SERVER_NAME\']: ' . $_SERVER['SERVER_NAME'];
echo '<br>WP_HOME: ' . WP_HOME;
echo '<br>WP_SITEURL : ' . WP_SITEURL;

I am exhausted, just writting it down! Be patient!


About cmanios

This entry was posted in Linux, Nginx, Server and tagged , , , , , , , , . Bookmark the permalink.

19 Responses to Nginx https reverse proxy to WordPress with Apache, http and different port

  1. If some one needs expert view concerning running a blog then i recommend him/her
    to go to see this website, Keep up the pleasant work.

  2. This paragraph will help the internet users forr
    building up new webpage or even a weblog from staft to end.

  3. You are a fucking legend.

    Thanks for posting this solution.

  4. seb says:

    your post is gold thanks!

  5. bao nguyen says:

    Thanks, I sent several hours with colleagues !!!

  6. minijus says:

    Hi Christos,
    we have a similar issue and our administrator is unable to solve this problem. Our setup: Apache server with WP installation under (no SSL) and server running with NGINX (SSL). And goal is to access blog through If you are interested and could consult us, please get back to me 🙂

  7. Alexandre FRANTZ says:

    I searched for hours , you’re a genius !

  8. Hi I am using Nginx and I did exactly what you asked, my configuration is some like this:

    main website:
    blog is hosted at: some-ip-address

    location ^~ /blog {
    proxy_read_timeout 3500;
    proxy_connect_timeout 3250;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    rewrite ^/(.*)/$ /$1 last;
    rewrite ^/blog/?(.*)$ /$1 break;
    proxy_pass http://some-ip-address:80/;
    proxy_redirect http://some-ip-address:80;

    • Jay Petallar says:

      i have this same setup. However, how do you lockdown wp-admin/wp-login.php from external network? /blog only knows the front end servers where the traffic request came from.

  9. geekonweb says:

    saved my day … thanks 🙂

  10. Pingback: The trick to get your wordpress behind a reverse proxy – Chmouel's Blog

  11. blakeimeson says:

    Great write-up! Just now stumbled on this researching AFTER we hassled through a similar issue.

    We did something very similar if anyone wants to check it out.

    WordPress Multisite Reverse Proxy Setup on WPENGINE

  12. Claudio says:

    Thanks so much! I was spending Hours trying to make this exact setup works!

  13. Pingback: Nginx https reverse proxy to WordPress with Apache, http and different port | Blog của Yên

  14. Pingback: Hosting WordPress on NixOS – 0x9b

  15. Mathias Aschhoff says:

    Thanks!!!! thats the solution!! great!

  16. Rex says:

    The man! This helped a bunch!

  17. Rajendra says:

    Hi, I have tried with the above configuration in my environment with plain http connection for apache/wordpress, it is not working for me. My configuration details are as below.
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;

    apache .htaccess:
    # BEGIN WordPress

    RewriteEngine On
    RewriteBase /blog/
    RewriteRule ^index\.php$ – [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /blog/index.php [L]

    if ( (!empty( $_SERVER[‘HTTP_X_FORWARDED_HOST’])) || (!empty( $_SERVER[‘HTTP_X_FORWARDED_FOR’])) ) {
    $_SERVER[‘HTTPS’] = ‘on’;


    When I am hitting nginx URL, apache/wordpress port is appearing in the browser URL. https://host-one:8080/blog/ instead https://host-one:9443/blog (My Nginx https port is 9443). Can you please advise, what is missing in my configuration. Thanks.

    • cmanios says:

      Hello Rajendra and Happy New year!

      Can you provide us with the full Nginx configuration? Furthermore we have noticed that you perform redirection in Apache which is quite different from the solution in this post.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s