Setting Up a Reverse Proxy with Nginx on RHEL
A reverse proxy accepts requests from clients and forwards them to an application server on a private network. With Nginx in front of a web application, the proxy can handle TLS, logging, access control, compression, and static files while the backend listens on localhost or an internal address. Learn more about Writing Your First Magik Extension A Step By Step In Emacs 0518e.
This arrangement suits RHEL servers running Python, Node.js, PHP, Java, or containerised workloads. It also gives administrators a consistent public endpoint, even when the application port or internal host changes later.
For an Australian deployment, placing the proxy near users in Sydney, Melbourne, Brisbane, or Perth can reduce latency. A local NBN connection may be adequate for a small office service, while a production site should use a properly hosted server, reliable DNS, and a monitored network path.
Prepare The RHEL Host
Update package metadata and install Nginx with the supporting SELinux utilities:
sudo dnf install -y nginx policycoreutils-python-utils
sudo systemctl enable --now nginx
Confirm that the service is running and that the host has the expected address:
sudo systemctl status nginx
ip addr
Create a simple backend for testing. If an application already listens on port 8080, use that service instead. For a quick check, Python can serve a temporary directory:
python3 -m http.server 8080 --bind 127.0.0.1
The Fedora LAMP guide is useful background when the backend is a PHP and database application rather than a standalone service.
Configure The Nginx Server Block
Create a dedicated configuration file rather than placing every virtual host in the main file:
sudo nano /etc/nginx/conf.d/app.example.com.conf
Add a server block that forwards traffic to the application:
server {
listen 80;
listen [::]:80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
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;
}
}
The Host and forwarding headers allow the application to identify the original request. This matters for redirects, audit records, client IP reporting, and frameworks that generate absolute URLs. If the backend runs on another machine, replace 127.0.0.1 with its private address and ensure routing is available.
Check the syntax before reloading:
sudo nginx -t
sudo systemctl reload nginx
A DNS record for app.example.com must point to the proxy’s public address. For Australian users, a short DNS time-to-live can help during migration between a local data centre and a provider in Sydney or Melbourne, although DNS changes still depend on resolver caching.
Allow Traffic Through Firewalld And SELinux
RHEL commonly uses firewalld, so open HTTP and HTTPS without exposing the backend port:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Port 8080 should remain inaccessible from the internet. If the application is on a separate internal host, allow only the proxy’s address through that host’s firewall. Restricting the backend in this way reduces the chance of bypassing Nginx access rules and TLS protection.
SELinux can prevent Nginx from making outbound connections to an application, even when the Linux permissions appear correct. Enable the appropriate boolean:
sudo setsebool -P httpd_can_network_connect 1
For a backend on a labelled non-standard port, inspect the current policy and label the port where necessary:
sudo semanage port -l | grep http_port_t
sudo semanage port -a -t http_port_t -p tcp 8080
If the port already has a different SELinux type, use -m instead of -a. Review audit records with ausearch -m AVC -ts recent when access is denied, rather than disabling SELinux.
Add TLS And Application Safeguards
A public reverse proxy should normally terminate HTTPS. Obtain a certificate from a trusted authority, configure Nginx to listen on port 443, and redirect plain HTTP to HTTPS. Keep private keys readable only by root and renew certificates before expiry. Australian organisations handling customer information should also consider the Privacy Act 1988 and the Notifiable Data Breaches scheme when designing logs, retention, and incident procedures.
Useful proxy settings can be added inside the location block:
proxy_connect_timeout 10s;
proxy_read_timeout 60s;
client_max_body_size 20m;
proxy_buffering on;
Adjust these values for the application. File uploads, WebSocket connections, long-running reports, and streaming responses may need different limits. Never trust an incoming X-Forwarded-For header from an untrusted network; configure trusted proxy handling in the application and preserve only headers supplied by your own Nginx instance.
Test, Monitor, And Maintain The Proxy
Test from the server and from an external network:
curl -I http://app.example.com
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080
sudo journalctl -u nginx --since "15 minutes ago"
sudo tail -f /var/log/nginx/access.log /var/log/nginx/error.log
A 502 Bad Gateway usually means the backend is stopped, listening on another address, blocked by SELinux, or unreachable through the firewall. A 404 may instead indicate an application route or incorrect server_name.
Keep RHEL and Nginx patched through a controlled maintenance process. The DNF update automation reference explains how scheduled updates can reduce manual work, but production systems still need testing, change records, backups, and a rollback plan. This is especially important when services support customers across Australian time zones.
A reverse proxy is working correctly when DNS reaches Nginx, firewalld exposes only the intended public services, SELinux permits the required connection, and the backend remains private. Remember to validate every configuration change, protect the application port, preserve the original request details, and monitor both Nginx and the service behind it.