This setup configures Nginx as an SSL termination proxy with load balancing and sticky sessions to two IIS hosts.
- Nginx: Terminates SSL/TLS connections and load balances traffic at Layer 7 (HTTP)
- IIS Hosts: Two backend servers receiving proxied HTTPS requests
- SSL Termination: SSL/TLS is terminated at Nginx, then re-encrypted and forwarded to IIS over HTTPS
- Sticky Sessions: Uses
ip_hashto ensure the same client IP always routes to the same backend server - Domain: Configured for
*.host.comwildcard domain
This project supports two installation methods:
- Docker (Container-based) - See Docker Installation
- Local CentOS/RHEL Install - See Local CentOS/RHEL Installation
- Docker and Docker Compose installed
- SSL certificates (cert.pem and key.pem) placed in the
ssl/directory - Network access to your IIS hosts
Edit nginx.conf in the upstream iis_backend block and replace the placeholder hostnames/IPs:
iis-host1:443- Replace with your first IIS server address (port 443 for HTTPS)iis-host2:443- Replace with your second IIS server address (port 443 for HTTPS)
If your IIS hosts are on different ports or use hostnames, update accordingly.
Note: The backend servers are configured to use HTTPS (port 443). Ensure your IIS servers have SSL configured and are listening on port 443.
Place your SSL certificates in the ssl/ directory:
ssl/cert.pem- Your SSL certificatessl/key.pem- Your SSL private key
For testing, you can generate self-signed certificates:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout ssl/key.pem -out ssl/cert.pemImportant: Nginx terminates SSL, so it needs valid SSL certificates. Backend connections to IIS use HTTPS.
If your IIS hosts are on the same Docker network, ensure they're accessible. If they're external hosts, you may need to:
- Use actual IP addresses
- Configure Docker network settings
docker-compose up -ddocker-compose logs -f nginxdocker-compose downdocker-compose exec nginx nginx -s reload- CentOS Stream 9/10, RHEL 9/10, or compatible Linux distribution
- Root or sudo privileges
- SSL certificates (cert.pem and key.pem)
- Network access to your IIS hosts
-
Install Nginx:
sudo dnf install epel-release -y sudo dnf install nginx -y
-
Run Setup Script (as root or sudo):
sudo chmod +x setup-centos.sh sudo ./setup-centos.sh
-
Manual Setup (if preferred): See INSTALL_CENTOS.md for detailed instructions
Edit /etc/nginx/nginx.conf in the upstream iis_backend block and replace the placeholder hostnames/IPs.
Copy your SSL certificates to /etc/nginx/ssl/:
cert.pem- Your SSL certificatekey.pem- Your SSL private key
Set proper permissions:
sudo chmod 644 /etc/nginx/ssl/cert.pem
sudo chmod 600 /etc/nginx/ssl/key.pemEdit /etc/nginx/conf.d/default.conf and update server_name *.host.com to your actual domain.
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reloadsudo nginx -tsudo systemctl start nginx
sudo systemctl enable nginxsudo systemctl reload nginxsudo systemctl status nginxsudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.logFor detailed installation instructions, see INSTALL_CENTOS.md.
The current configuration uses ip_hash for sticky sessions. You can change this in nginx.conf in the upstream iis_backend block:
-
ip_hash(current) - Routes based on client IP address (sticky sessions)- Same client IP always goes to the same backend server
- Best for maintaining session state
- Note: Clients behind NAT/proxies will share the same IP and route to the same server
-
least_conn- Routes to server with fewest active connections -
round-robin- Default, distributes requests evenly (no sticky sessions)
Sticky sessions are enabled using ip_hash:
- Method: IP-based routing ensures session affinity
- Benefit: Same client always connects to the same backend server
- Use Case: Perfect for applications that maintain session state on the server
- Consideration: Multiple users behind the same NAT/proxy will route to the same backend server
Note: For cookie-based sticky sessions, you would need a custom Nginx build with the nginx-module-sticky module, or use a pre-built image that includes it.
The configuration includes:
max_fails=3- Mark server as down after 3 failed attemptsfail_timeout=30s- Retry after 30 seconds
A health check endpoint is available at /nginx-health.
- Check container logs:
docker-compose logs nginx - Test configuration:
docker-compose exec nginx nginx -t - Verify network connectivity: Ensure IIS hosts are reachable from the container
- Check SSL certificates: Verify certificates are correctly mounted
- Check logs:
sudo tail -50 /var/log/nginx/error.log - Test configuration:
sudo nginx -t - Verify network connectivity:
ping your-iis-server.com - Check SSL certificates: Verify certificates exist:
ls -l /etc/nginx/ssl/ - Check ports: Ensure ports are listening:
sudo ss -tlnp | grep -E ':80|:443' - Check SELinux:
getenforceand review denials if needed - Check firewall:
sudo firewall-cmd --list-all
- SSL Termination: SSL/TLS is terminated at Nginx, then re-encrypted and forwarded to IIS over HTTPS
- IIS HTTPS: IIS receives HTTPS traffic (port 443) - ensure IIS has SSL configured
- Layer 7 Proxying: Uses HTTP-level load balancing (can inspect HTTP headers and cookies)
- Sticky Sessions: Enabled via
ip_hash- same client IP routes to same backend - Domain Matching: Configured for
*.host.com- update the server_name in conf.d/default.conf if needed - SSL Certificates: Nginx requires SSL certificates for termination
- Backend SSL Verification: Set to
onfor security - verifies backend certificates (NIST compliant) - NIST Compliance: Configuration aligns with NIST SP 800-52 Rev. 2 - see NIST_COMPLIANCE.md
- Adjust timeouts and buffer sizes in the proxy settings based on your application needs
nginx.conf- Main nginx configuration (Docker/Linux/CentOS paths)conf.d/default.conf- Server configuration (Docker/Linux/CentOS paths)docker-compose.yml- Docker Compose configurationsetup-centos.sh- CentOS/RHEL setup scriptINSTALL_CENTOS.md- Detailed CentOS/RHEL installation guideNIST_COMPLIANCE.md- NIST compliance documentation