How to Install an SSL/TLS Certificate for WordPress with Apache Using a Nginx Reverse Proxy on a CentOS VPS

Introduction

Nginx and Apache are the most popular open source web servers used even by large-traffic generating websites. In this tutorial, we illustrate how to use both web servers but with different functionalities. The Apache web server runs the WordPress website behind the nginx server (with installed SSL certificate) which acts as a reverse proxy for apache server. In this case, Nginx is being applied as Reverse Proxy handling all SSL Connections on behalf of Apache, while Apache still remains the web server. This is one of the many uses of Nginx as a reverse proxy.

Therefore, all URL connections from users’ browsers hit the Nginx reverse proxy server first and are forced to be in HTTPS protocol using server’s installed SSL certificate. Then Nginx forwards all the requests to the Apache web server running the WordPress site. As a result, it’s very essential to configure both servers to listen on different ports to avoid conflict.

>In this tutorial, we illustrate how to install SSL certificate in Nginx reverse proxy for WordPress website hosted on Apache web server.

Pre-requisites

It’s assumed WordPress and Apache have been installed, configured and working fine on a CentOS 7 Linux Server.

Install & Configure Nginx

Run the commands to install nginx server

$ sudo yum install epel-release
$ sudo yum install nginx

Edit apache configuration file

$ sudo vim /etc/httpd/conf/httpd.conf

Change the listening port to a different port (e.g. 8080) by editing the line as follows.

Listen 8080

This is to prevent nginx from listening to the same port as Apache, therefore now nginx listens to port 80 while apache listens to port 8080.

Open the port 8080 in the firewall:

$ sudo firewall-cmd --permanent --add-port=8080/tcp
$ sudo firewall-cmd --reload

Restart apache service

$ sudo systemctl restart httpd

Start & enable nginx

$ sudo systemctl start nginx 
$ sudo systemctl enable nginx

Confirm that nginx is working fine by using curl to show its name and version in the HTTP headers

$ curl -I http://localhost

Configure Nginx for SSL

Uncomment the whole section under the https (ssl) server part i.e.

# Settings for a TLS Enabled Server

Generate SSL certificate

First of all, make the nginx and private directories as follows

$ sudo mkdir -p /etc/pki/nginx/private

Then generate keys:

$ sudo openssl req -x509 -nodes -sha256 -days 365 -newkey rsa:2048 -keyout /etc/pki/nginx/private/server.key -out /etc/pki/nginx/server.crt

Special Note: Ensure the 443 port is allowed via the firewall as follows:

$ sudo firewall-cmd --permanent --add-port=443/tcp
$ sudo firewall-cmd --reload

Edit Rhe nginx.conf Dile to Allow For a Reverse Proxy Pass to Apache

Under the server (http) part – the first section: Replace the location section with the following.

location / {
        try_files $uri @apache;
    }

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

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

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

    location ~/\. {
        deny all;
        access_log off;
        log_not_found off;
    }

Under the server (https) part – the second section: Replace the location section with the following.

location / {
        try_files $uri @apache;
    }

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

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

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

    location ~/\. {
        deny all;
        access_log off;
        log_not_found off;
    }

Go to Mozilla’s Wiki Website for the recommended cipher suites> and paste the ciphersuites into the cipher section in the second server (https) section.

ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256' ;

Then save the file:

Configure WordPress

Edit wp-config file to allow for the redirection to https by adding the code below:

define('FORCE_SSL_ADMIN', true);
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
    $_SERVER['HTTPS']='on';
$ sudo vim /var/www/html/wp-config.php

Save the file

Give permissions for httpd and nginx connections via SELinux

$ sudo setsebool -P httpd_can_network_connect 1

Go to the site’s wp-admin dashboard

Settings > General, then change the "http" to "https" for both the "WordPress Address (URL)" and "Site Address (URL)"

And save the changes

Force Redirect all traffic to https

Edit nginx.conf by adding the line under the http server section

return 301 https://$server_name$request_uri;

Restart both nginx and apache services

$ sudo systemctl restart nginx httpd

Now we have a WordPress site with self-signed SSL certificate as shown below:

https://35.225.251.235

Conclusion

Now you have a fully functional WordPress website with SSL certificate. The nginx server, although working as a reverse proxy works transparently and seamlessly with Apache web server. This makes it seem as if the requests are being served directly to the Apache web server. Indeed,  it is one of the most effective ways to secure your website and reduce vulnerability against hackers.

If you run into trouble, ask your web host's support service for assistance - they should be able to help. If they can't, HostAdvice can recommend the best VPS hosting providers,  the best WordPress hosting providers, and the best Linux hosting services (depending on what you are looking for). The top picks in each category are known for providing outstanding customer service and support.

 

Check out these top 3 WordPress hosting services:

Was this article helpful?