Question

NGINX reverse proxy to Apache with Wordpress bad gateway

I have followed the guide here (https://www.digitalocean.com/community/tutorials/how-to-configure-nginx-as-a-web-server-and-reverse-proxy-for-apache-on-one-ubuntu-16-04-server)

While they are using Ubuntu we are using Centos 7.2.

Going directly to apache on port 8080 or 8443 (ssl) works. Pulling static files from Nginx works as well on port 80 and 443. However once the configuration is updated to use pass php traffic to apache I get 502 Bad Gateway. I

Nginx Config

server {
    listen 80;
    listen 443 ssl;
    server_name www.domain.com domain.com;	

    ssl on;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM;
    ssl_session_cache   shared:SSL:5m;
    ssl_session_timeout 10m;
    ssl_prefer_server_ciphers on;
    ssl_certificate /etc/nginx/ssl/domain_com.pem;
    ssl_certificate_key /etc/nginx/ssl/domain_com.key;

    root /data/web/corp/domain;
    index index.php index.htm index.html;

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

    location ~ \.php$ {
        proxy_pass https://127.0.0.1:8443;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location ~ /\. {
        deny all;
    }
}

I have tried to set the proxy_pass to the internal IP, Public IP, domain name, and loopback ip. Seems to all be the same issue.

Apache is set to listen on 8080 and 443.

The Nginx error logs show this:

2017/03/14 23:07:52 [error] 24934#0: *306 upstream prematurely closed connection while reading response header from upstream, client: 71.25.9.17, server: www.domain.com, request: "GET / HTTP/1.1", upstream: "https://127.0.0.1:8443/index.php", host: "www.domain.com"

Apache SSL error log:

[Tue Mar 14 23:12:36.955268 2017] [ssl:error] [pid 63873] [client 127.0.0.1:45822] AH02261: Re-negotiation handshake failed: Not accepted by client!?, referer: https://www.domain.com/favicon.ico

Apache SSL access log:

127.0.0.1 - - [14/Mar/2017:23:12:16 +0000] "GET /index.php HTTP/1.0" 403 211

I am not sure where to start as I am new to Nginx but from my reading it seems to be much better/faster at serving up static content than Apache. While our development group currently requires .htaccess we have to keep using Apache.

Show comments

Submit an answer

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in Q&A, subscribe to topics of interest, and get courses and tools that will help you grow as a developer and scale your project or business.

I was having the same problem. The solution was to pass everything to apache, not just .php files

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

If you append $request_uri to your proxy_pass, e.g. https://127.0.0.1:8080$request_uri; then install mod_rpaf as per https://www.digitalocean.com/community/tutorials/how-to-configure-nginx-as-a-web-server-and-reverse-proxy-for-apache-on-one-ubuntu-18-04-server, then Apache and thus PHP will see the right URL, and you won’t need SSL on Apache. You can also tweak the standard WordPress rewrite rules because by the time the request gets to Apache, you already know it’s for a .php file.

Did you ever get this resolved? After hours of tinkering I have been able to get this working because of 1 simple missing “s”… yes an S… If anyone else is having this issue, I’ll post my configs for review… Once I added that s, it worked like a charm… One issue I am stil having is with .htaccess files… Apparently the proxy to apache from nginx does not include the ip traffic is originally coming from and this causes deny,allow issues… I have not resolved this yet but the site is now accessible!! Anything in bold you should probably be changing to your own settings… :)

**-------------- NGINX -> ** /etc/nginx/sites-available/domainx.conf

server { listen 80; server_name xxxxx.domainx.com; return 301 https://$host$request_uri; }

server { listen 443 ssl; server_name xxxxx.domainx.com; ssl_certificate /etc/nginx/ssl/cert_domainx.crt; ssl_certificate_key /etc/nginx/ssl/cert_domainx.key; location / { proxy_pass https://192.168.0.100:6443; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-Port 443; proxy_set_header Host $host; } }

**-------------- APACHE -> ** ports.conf

Listen 8085

<IfModule ssl_module> Listen 6443 </IfModule>

<IfModule mod_gnutls.c> Listen 6443 </IfModule>

**-------------- APACHE -> ** 000-default.conf

<VirtualHost *:8085> ServerName xxxxx.domainx.com Redirect permanent / https://xxxxx.domainx.com/ </VirtualHost>

<VirtualHost *:6443> # The ServerName directive sets the request scheme, hostname and port that # the server uses to identify itself. This is used when creating # redirection URLs. In the context of virtual hosts, the ServerName # specifies what hostname must appear in the request’s Host: header to # match this virtual host. For the default virtual host (this file) this # value is not decisive as it is used as a last resort host regardless. # However, you must set it for any further virtual host explicitly. ServerName xxxxx.domainx.com

    ServerAdmin **webmaster@localhost**
    DocumentRoot /var/www/html

    SSLEngine on
    SSLCertificateFile **/etc/apache2/ssl/cert_domainx.crt**
    SSLCertificateKeyFile **/etc/apache2/ssl/cert_domainx.key**
    SSLCACertificateFile **/etc/apache2/ssl/cert_intermediate.crt**

    # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
    # error, crit, alert, emerg.
    # It is also possible to configure the loglevel for particular
    # modules, e.g.
    #LogLevel info ssl:warn

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    # For most configuration files from conf-available/, which are
    # enabled or disabled at a global level, it is possible to
    # include a line for only one particular virtual host. For example the
    # following line enables the CGI configuration for this host only
    # after it has been globally disabled with "a2disconf".
    #Include conf-available/serve-cgi-bin.conf

</VirtualHost>