Nginx reverse proxy

🗂 IP / Port Map

ServiceIPPortNotes
Websites (Apache only)51.210.247.10280,443Main IP; public HTTP + HTTPS
ISPConfig admin panel51.210.247.102443Admin HTTPS on same IP as Apache → must use reverse proxy
stunnel (OpenVPN)5.135.106.93443Secondary IP; separate port, no conflicts

1️⃣ How this works conceptually

Main IP: 51.210.247.102

  • Both Apache websites and ISPConfig admin panel HTTPS share the same IP and port 443.

  • This requires reverse proxying: a single service listens on 443 (nginx recommended) and routes traffic based on:

    • Host: header in HTTP (for websites vs panel)

    • TLS SNI if needed

  • Apache itself can remain listening on 127.0.0.1:8080 (websites) and 127.0.0.1:8081 (ISPConfig), so no port conflicts.

Secondary IP: 5.135.106.93

  • stunnel listens only on this IP:443.

  • Forwards traffic internally to OpenVPN (127.0.0.1:1195).

  • Completely isolated — no conflicts with Main IP.


2️⃣ Practical architecture diagram

 
Public Internet
| |
51.210.247.102:443
v [Nginx reverse proxy]
|-- Host: panel.example.com --> ISPConfig 127.0.0.1:8081
|-- Host: www.example.com --> Apache 127.0.0.1:8080
| |
51.210.247.102:80 --> Apache 127.0.0.1:8080 (HTTP)
| 5.135.106.93:443 --> stunnel --> OpenVPN 127.0.0.1:1195

3️⃣ Steps to implement

a) Websites

  • Apache listens only on 127.0.0.1:8080 (internal)

  • Nginx reverse proxy handles 443 and 80 for main IP

b) ISPConfig admin

  • Install ISPConfig panel on 127.0.0.1:8081

  • Nginx reverse proxy maps panel.example.com to 127.0.0.1:8081

  • Use SSL certificate (Let’s Encrypt or self-signed) in Nginx

c) stunnel

  • Configure stunnel on secondary IP:443 to forward TCP → OpenVPN (127.0.0.1:1195)

d) Firewall

  • Main IP: allow 80,443

  • Secondary IP: allow 443 only for stunnel/OpenVPN


4️⃣ Advantages

  • No port conflicts

  • Clear separation of services

  • ISPConfig is fully HTTPS on main IP

  • Websites continue to run normally

  • stunnel/OpenVPN fully isolated on secondary IP

 

1️⃣ Why nginx

 ISPConfig admin panel and websites share the same IP (51.210.247.102) and port 443.

  • Apache alone cannot easily serve two different services on the same IP:443 because it can only listen on a port and serve one set of virtual hosts.

  • Nginx (or any reverse proxy) can listen on 443 and route requests based on the hostname (Host header / SNI) to different backends:

    • panel.example.com → ISPConfig

    • www.example.com → Apache websites

This is called reverse proxying.

 

Full working stack for your scenario:

  • Main IP: 51.210.247.102

    • Websites → Apache (HTTP/HTTPS)

    • ISPConfig → HTTPS on same IP, via nginx reverse proxy

  • Additional IP: 5.135.106.93

    • stunnel → OpenVPN

1️⃣ Install required packages

 
sudo apt update sudo apt install -y apache2 nginx stunnel4 openvpn ufw curl

2️⃣ Configure Apache (websites backend)

/etc/apache2/ports.conf

 
Listen 127.0.0.1:8080

/etc/apache2/sites-available/000-default.conf

 
<VirtualHost 127.0.0.1:8080>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Enable site & restart:

 
sudo a2ensite 000-default.conf sudo systemctl restart apache2

Test locally:

 
curl http://127.0.0.1:8080

3️⃣ Configure ISPConfig backend

  • Install ISPConfig normally, but set admin panel port to 8081:

  • Install ISPConfig normally, but set admin panel port to 8081:

 
# During installation, set admin port = 8081
  • Ensure ISPConfig listens only on 127.0.0.1:8081

  • Test:

 
curl http://127.0.0.1:8081

4️⃣ Configure nginx as reverse proxy

/etc/nginx/sites-available/main-proxy.conf

 

# Main IP: 51.210.247.102
# Serves both websites and ISPConfig on HTTPS

# Websites (www.example.com)
server {
    listen 51.210.247.102:80;
    server_name www.example.com example.com;

    root /var/www/html;
    index index.php index.html;
}

server {
    listen 51.210.247.102:443 ssl;
    server_name www.example.com example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
    }
}

# ISPConfig admin panel (panel.example.com)
server {
    listen 51.210.247.102:443 ssl;
    server_name panel.example.com;

    ssl_certificate     /etc/letsencrypt/live/panel.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/panel.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8081;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
    }
}

 

Enable site:

 
sudo ln -s /etc/nginx/sites-available/main-proxy.conf /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginx

 

2026Stable CORE