3

I am trying to setup a fresh Wordpress installation on an nginx + apache reverse proxy configuration. My installation process was as follows:

  1. Installed nginx and apache servers
  2. Configured nginx (conf below) to proxy apache server (listening on port 8080)
  3. Generated let's encrypt SSL certificate using certbot with nginx plugin
  4. Extracted fresh wordpress installation to apache /var/www/mysite.com, setup file ownership/permissions
  5. Ran wordpress install, generated config and added HTTPS details (conf below)

I intend to only allow access over HTTPS to this site, so I have setup the nginx conf to redirect all traffic to port 443.

/etc/nginx/mysite.com:

server {

    root /var/www/mysite.com;
    index index.php index.html index.htm;

    server_name mysite.com;

    location / {
    try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {

    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Proto $scheme; # scheme: https
    proxy_set_header Host $host;
    proxy_pass http://127.0.0.1:8080;

     }

     location ~ /\.ht {
            deny all;
    }

listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/mysite.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/mysite.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
if ($host = mysite.com) {
    return 301 https://$host$request_uri;
} # managed by Certbot


    listen   80;

    server_name mysite.com;
return 404; # managed by Certbot


}

wp-config.php:

<?php

define( 'DB_NAME', 'x' );
...
define( 'NONCE_SALT',       'x' );

$table_prefix = 'wp_';

define( 'WP_DEBUG', false );

if ( $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' )
{
    $_SERVER['HTTPS']       = 'on';
    $_SERVER['SERVER_PORT'] = '443';
    define('FORCE_SSL_ADMIN', true);
}

if ( isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
    $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}

if ( ! defined( 'ABSPATH' ) ) {
    define( 'ABSPATH', dirname( __FILE__ ) . '/' );
}

require_once( ABSPATH . 'wp-settings.php' );

Using this installation, I can access /wp-admin/ without any issues, however when I try to access the main site I run into a redirect loop. Chrome network console shows this: Wordpress front page produces endless redirect loop

Anyone have any solutions to this issue? I have tried many solutions I've seen across various websites, including some plugins, which claim to manage the SSL page settings for you, to no avail. If you need any more details, please don't hesitate to ask!

EDIT: Raw response from each redirect:

HTTP/1.1 301 Moved Permanently
Server: nginx/1.14.0 (Ubuntu)
Date: Sun, 10 Mar 2019 16:35:06 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 0
Connection: keep-alive
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
X-Redirect-By: WordPress
Location: https://example.com/

When I try to request / I get a 301 Moved Permanently response telling me the resource has moved to /, causing the redirect loop.

7
  • Did you install some kind of SSL plugin? I very much doubt they'll be able to handle your reverse proxy unless explicitly coded with that. Have you figured out if it's WordPress generating the redirect or Apache/Nginx? There's still some debugging that needs to be done here
    – Tom J Nowell
    Mar 10, 2019 at 15:45
  • Additionally, if ($host = mysite.com) { return 301 https://$host$request_uri; looks suspicious, are you sure it's WordPress knowledge you need to understand what's going on and not Nginx expertise? I suspect you asked here because it's a WP site but it could well be that this would be the same on a Joomla or a Drupal site, are you absolutely sure it's WordPress doing the 301 redirect, not Nginx? If it's an Nginx redirect not a WP redirect, then this isn't the place to ask, you should ask on one of the other stacks
    – Tom J Nowell
    Mar 10, 2019 at 15:49
  • The responses in the redirect all have the header "X-Redirect-By: WordPress". I just removed the force https configuration from my nginx installation to verify that the site still works, and all seems to be working fine over http. It's just getting Wordpress specifically to work over https which I am struggling with, which is why I posted on this stack. I have added the full response to the original post.
    – Capy
    Mar 10, 2019 at 16:39
  • Is your site and all your sites URLs using https then? Or are you relying totally on an SSL plugin to do all of that for you?
    – Tom J Nowell
    Mar 10, 2019 at 20:13
  • I'm not using any SSL plugin. Site url is set to https in settings. I'm pretty sure this is an nginx config issue so I'll try another stack.
    – Capy
    Mar 10, 2019 at 21:29

1 Answer 1

5

Issue was caused by nginx serving example.com/index.php while Wordpress was redirecting to example.com/, thus causing a redirect loop.

This is the working config I used to fixed the redirect loop:

server {
server_name example.com;
root /var/www/example.com;

index index.php;

listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

location / {
        try_files $uri @apache;
}

location ~[^?]*/$ { # proxy directories
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
        proxy_pass http://127.0.0.1:8080;
}

location ~ \.php$ { # serve php files
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
        proxy_pass http://127.0.0.1:8080;
}

location @apache { # used by location /
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
        proxy_pass http://127.0.0.1:8080;
}

location ~ /\.ht { # Deny access to .htaccess, .htpassword 
        deny all;
}
}
server {
    listen 80;
    server_name _;
    return 301 https://$host$request_uri;
}

Another thread with more details.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.