[TUTORIAL] Nginx as simple reverse proxy with web application firewall and SSL

Started by rene_, September 25, 2020, 09:02:11 PM

Previous topic - Next topic
Hello everyone,

as some of you requested this, I will write down, how I configured my Nginx, as a simple reverse Proxy (including HTTPS with letsencrypt, and Web Application Firewall enabled).


Step 1: Installation
You need to install the nginx and lets-encrypt plugins.

After that, configure you're letsencrypt so that you get a valid SSL certificate for your service.
You need to use DNS-01 validation method, because nginx will use the port 80, and the lets-encrypt plugin is not able to use the modify the Nginx configuration for a successful validation.
When youre done, you can continue to Step 2.
(You can also use official paid certificates, if you have one, you need to import the CA, Cert and Key unter System → Trust)


Step 2: Configure Nginx

You need to be sure, that your OPNsense is not using port 80 or 443.
So you need to change the default port of your OPNsense webgui.
This can be done under "System → Settings → Administration".
You also need to disable the HTTP Redirect.
Restart your firewall when done.

From now on, all steps are meant to configure under Services →Nginx → Configuration

2.1 Configure the upstream server

First of all, you need to configure your upstream server, this is the real server, where your web application runs on.
This could be any host on your LAN, DMZ or whatever.

To do so, navigate to Upstream → Upstream Server and click on the + in the right bottom corner.
Now enter a description, IP and port (80 – HTTP in most cases).
Use 1 as Server priority.

2.2 Configure the upstream

Next you need to configure the upstream, where you link your created upstream server.
You need to do that, because you could also configure multiple servers, for the same upstream for load balancing.
So what we configure, is a "load balancer" with just one host.

Therefore navigate to Upstream → Upstream and create one.
Chose a description, and link the upstream server you just created.
As load balancing algorithm, use weighted round robin.
Leave the rest as it is, if you don't use HTTPS directly on your upstream server.


2.3 Configure the Location

As the next step, you need to configure the Location (URL) of your web application.
Navigate to HTTP(S) → Location and click on Add.
As URL Pattern, just use slash (/) and match type none.
URL rewriting should be nothing.
Define the Upstream server you created before and leave the rest as it is for now.

Later, you can configure the Web Application Firewall rule here.


2.4 Configure HTTP Server

The last step, to bring your web application online, is to configure the HTTP Server.
Navigate to HTTP(s) → HTTP Server and click on Add.
This should match your need in most cases:

HTTP Listen Port: 80
HTTPS Listen Port: 443
Server Name: The URL your applications listens to (for example: cloud.domain.com)
Locations: the location created in step 2.3
URL Rewriting: Nothing selected
TLS Certificate: The issued Lets-Encrypt or imported certificate for this host

Leave the rest as it is for now.

2.5 Apply changes
When your done, click on General Settings and then on Apply
Your nginx should now be ready to server your web application.
Be sure to have correct firewall rules (from wan to this device, port 80 & 443)


This tutorial is not finished yet, i will explain some steps more detailed and attach some screenshots the next days.
Hope this is helpful :-)


Got exactly the same results. I will add here my WAF policy for Nextcloud. If you have something else, please post it.
OPNsense on:
Intel(R) Xeon(R) E-2278G CPU @ 3.40GHz (4 cores)
8 GB RAM
50 GB HDD
and plenty of vlans ;-)



Quote from: mimugmail on November 04, 2020, 07:33:06 AM
Search in config for X-Forward
I choose X-Forward-for at Real IP and apply it.But it's still not show real IP.

no. with this setting you direct nginx where to look for real client IP (in case its another proxy in front of nginx).
nginx already sends real client IP with X-Forwarded-For header.
you just need to enable this field on upstream log

Quote from: Fright on November 04, 2020, 05:15:43 PM
no. with this setting you direct nginx where to look for real client IP (in case its another proxy in front of nginx).
nginx already sends real client IP with X-Forwarded-For header.
you just need to enable this field on upstream log
So besides enabling X-Forward-For, should I set something on the web server? Or should I set other things on nginx?

no need to enable anything on opnsense\nginx

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

already in location template by default
just check log fields on upstream server, enable logging for X-Real-IP and/or X-Forwarded-For headers and check results

I already enable X-Forward-For but web server access.log also show nginx server IP

Attachment is web server access.log

have you disable "Real IP Source option" in GUI? (it changes client IP )
and..$proxy_add_x_forwarded_for is pretty tricky variable
what if you add X-Real-IP header to apache log and look at it for client IP? (again. dont use "Real IP Source" option in GUI)



OK,I restart opnsense nginx but also show opnsense IP.Could I need setup any option?

have you try to add X-Real-IP to appache log?
is there any chance that its another proxy in front of opnsense\nginx?
what "Remote IP" shows nginx logs?