Reverse Proxy

 

Edit /etc/nginx/nginx.conf, and make sure below line is uncommented:

include /etc/nginx/conf.d/*.conf;
Create a  configuration

 

sudo vi /etc/nginx/conf.d/yourdomainname.com.conf

 server {
    listen [::]:80;
    listen 80;

    server_name www.yourdomainname.com;

    root /var/www/html/yourdomainname.com/public;
    index index.php;

    location / {
        try_files $uri @apache;
    }

    location ~ ^/\.user\.ini {
        deny all;
    }

    location ~*  \.(svg|svgz)$ {
        types {}
        default_type image/svg+xml;
    }

    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    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://192.168.10.80:80;
    }

    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://192.168.10.80:80;
    }

    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://192.168.10.80:80;
    }

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

Note the bold line “proxy_set_header X-Forwarded-Proto $scheme; ” is for http, if you want to use Nginx as the ssl termination point, you will need to modify this line.

Now you can logon your DNS service provider, and mapping your domain name to the Nginx server.

Open your website, and check the log on the apache server, the requester should be only from the Nginx server:

sudo tail -50 /var/log/httpd/access_log

The log should be something like below:

192.168.10.1 - - [07/Aug/2020:21:57:44 +1000] "GET / HTTP/1.0" 200 18261 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15"

Note the requester’s IP is your Nginx Reverse proxy.

So you can add below line in /etc/httpd/conf/httpd.conf to restrict the requester’s IP.

Allow from 192.168.10.1/32

On the Nginx check the log for this request:

sudo tail -50 /var/log/nginx/access.log

You should see the request with the real IP address.

 

SSL terminator

 

Since Nginx has the capability of acting as a load balancer, you can give it additional work as well.

Essentially, the idea of an SSL termination that the request will come to the load balancer on a secure channel but will be sent to the other web servers without SSL. This way, your web server acts faster and eventually your requests go out to the clients in a secure manner as well.

 

Manual configure

 

First remove the first two listen lines in above configuration, and add below configure:

 

listen 443 ssl; 

ssl_certificate /path/to/cert_file; 

ssl_certificate_key /Path/to/private_key_file;

#SSL options

ssl_session_cache shared:le_nginx_SSL:10m;

ssl_session_timeout 1440m;

ssl_session_tickets off;

ssl_protocols TLSv1.2 TLSv1.3;

ssl_prefer_server_ciphers off;

ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHAC

HA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";


Then add below block to force the https redirect:

server {
    if ($host = www.yourdomainname.com) {
        return 301 https://$host$request_uri;
    }
    if ($host = yourdomainname.com) {
        return 301 https://$host$request_uri;
    }
    server_name www.yourdomainname.com yourdomainname.com;

    listen 80;

    return 404;

}

Change the header into correct protocol:

Find the line proxy_set_header X-Forwarded-Proto $scheme; change the $scheme into https.

proxy_set_header X-Forwarded-Proto https;
Other considerations

You may want to force redirect from non-www to www, so you only need to request for one SSL certificate. Simply add below server block, and change the yourdomainname.com.au into your domain name

server {

    listen       80;
    server_name  yourdomainname.com.au;
    return       301 http://www.yourdomainname.com.au$request_uri;

}
Automatic configure with certbot

It’s always good to know what parameters are required for SSL termination, but certbot can do the job for us:

First install certbot

sudo yum install epel-release -y
sudo yum install certbot -y

Second, create a cert for nginx:

sudo certbot --nginx

Select the website you want the reverse proxy to install ssl cert for.

Then you should see the congratulations message.

If you are using wordpress and found the website could not open now, which is due to the mix of http and https, don’t panic, see below fix .

 

Issue with wordpress

 

WordPress will not work due to mixed content (HTTP and HTTPS) – you won’t be able to login.

In order to fix this you first have to add this at the very start of your wp-config.php.

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

Then in the end of the file add the following, replacing “website.com” with your own URL.

define('WP_HOME','https://website.com');
define('WP_SITEURL','https://website.com');

Finally you have to add the following to your NGINX-config in the site’s location block on your reverse proxy.

proxy_set_header X-Forwarded-Proto https;
Without this, you may get the mixed content error.
Buffer and  cache

 

To enable buffer on Nginx:

server{

    proxy_buffering     on;

#Buffer for header data

    proxy_buffer_size   16k;

#Response data from backend server

    proxy_buffers 8 4k;

    proxy_busy_buffers_size 16k;

}

Enable cache:

Only two directives are needed to enable basic caching: proxy_cache_pathand proxy_cache. The proxy_cache_pathdirective sets the path and configuration of the cache, and the proxy_cachedirective activates it. Note that these two directives need to be in one configuration file.

proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g 
                 inactive=60m use_temp_path=off;

server {
    # ...
    location / {
        proxy_cache my_cache;
        proxy_pass http://192.168.10.80;
    }
}

A powerful feature of NGINX content cachingis that NGINX can be configured to deliver stale content from its cache when it can’t get fresh content from the origin servers. This can happen if all the origin servers for a cached resource are down or temporarily busy. Rather than relay the error to the client, NGINX delivers the stale version of the file from its cache. This provides an extra level of fault tolerance for the servers that NGINX is proxying, and ensures uptime in the case of server failures or traffic spikes. To enable this functionality, include the proxy_cache_use_staledirective:

location

location @apache{

….

proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;

….

}

Reference

 

A Guide to Caching with NGINX and NGINX Plus