Nginx-Proxy-Server für IPv4-Anbindung von IPv6-only-Servern: Anleitung

etron770

Member
Da ich keine neuen, teuren IPv4-Adressen kaufen wollte oder möglicherweise einmal keine mehr bekommen würde, habe ich Folgendes konfiguriert, um reine IPv6-LXC-Container oder VMs mit IPv4 versorgen zu können. Es ist zwar meine Idee, aber nicht ganz allein meine Arbeit. ChatGPT hat mir dabei geholfen. Die Zusammenfassung hat mir auch ChatGPT erstellt. Es funktioniert, die Zugriffe sind drastisch schneller geworden, weil nun ein Nginx Proxy davor ist, der die Architektur in mehreren Punkten optimiert. Allerdings sind jedoch im DNS einige VMs/LXC Container unter einer IPV4 und einer IPV6 zusammengefasst. Ob man einen Mailserver auch einbindet, sollte man sich gut überlegen. Spamt ein Container, ist auch der Mailserver auf der Blacklist, weil er dieselbe IP hat.
Ich hoffe, es sind alle Schritte zusammengefasst.
Dies ist der aktuelle Status:
(Englisch unten)

Technische Systembeschreibung – Edge-Proxy und WireGuard unter Debian 12 mit ISPConfig​

1. Systemübersicht​

Dieses Setup beschreibt eine Debian-12-Installation mit ISPConfig, die als kombinierter Reverse-Proxy (TLS-Passthrough) und WireGuard-Server für IPv4-Egress dient. „Edge-Proxy“ = öffentlicher Dual-Stack-Server, „Client 1“ = internes IPv6-only-System mit IPv4-Tunnel.

2. Paketinstallation​

Code:
apt update
apt install nginx-full libnginx-mod-stream wireguard iptables

Falls Apache durch ISPConfig aktiv ist, sicherstellen, dass dieser nicht auf den Ports 80/443 lauscht, um Portkonflikte zu vermeiden.

3. Netzwerkkonzept​

Der Edge-Proxy ist Dual-Stack-fähig mit öffentlicher IPv4- und IPv6-Adresse. Backends (inklusive Client 1) nutzen native IPv6; IPv4-Datenverkehr wird über WireGuard getunnelt. DNS-A/AAAA-Einträge verweisen auf den Edge-Proxy; SSH erfolgt direkt über IPv6.

4. Nginx-Reverse-Proxy-Konfiguration​

Datei: /etc/nginx/stream-enabled/443-sni-map.conf (SNI-Mapping und TLS-Passthrough)

Code:
map $ssl_preread_server_name $sni_upstream {
site1.example.net [IPv6-Backend1]:443;
site2.example.net [IPv6-Backend2]:443;
default [IPv6-Default]:443;
}

server {
listen 0.0.0.0:443;
ssl_preread on;
proxy_pass $sni_upstream;
proxy_connect_timeout 5s;
proxy_timeout 60s;
}

Datei: /etc/nginx/conf.d/80-acme-proxy.conf (HTTP-ACME-Challenge-Proxy und Redirect)

Code:
map $host $acme_upstream {
hostnames;
site1.example.net [IPv6-Backend1]:80;
#Wildcard:
.example2.net [IPv6-Backend2]:80;
default [IPv6-Backend3]:80;
}

server {
listen 80;
listen [::]:80;
location ^~ /.well-known/acme-challenge/ {
proxy_pass http://$acme_upstream;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
location / { return 301 https://$host$request_uri; }
}

Änderung in Apache-Konfiguration (Datei: /etc/apache2/conf-available/10-remoteip-proxyproto.conf):

Code:
RemoteIPProxyProtocol On
RemoteIPTrustedProxy <EDGE_PROXY_IPV4>
RemoteIPTrustedProxy <EDGE_PROXY_IPV6>
LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined_realip
CustomLog ${APACHE_LOG_DIR}/access.log combined_realip

Hinweise:
- <EDGE_PROXY_IPV4> und <EDGE_PROXY_IPV6> mit tatsächlichen Adressen des Edge-Proxy ersetzen.
- Der Edge-Proxy muss das PROXY-Protokoll aktiv übergeben.
- Keine gleichzeitige Verwendung von RemoteIPHeader.
- Aktivierung: a2enmod remoteip && a2enconf 10-remoteip-proxyproto && systemctl reload apache2.

5. WireGuard-Konfiguration​

Schlüsselgenerierung (pro System eindeutige Dateinamen verwenden, z. B. für Edge-Proxy und jeden Client separat):

Code:
# Edge-Proxy
umask 077
wg genkey > /etc/wireguard/edgeproxy.key
wg pubkey < /etc/wireguard/edgeproxy.key > /etc/wireguard/edgeproxy.key.pub

# Client 1
umask 077
wg genkey > /etc/wireguard/client1.key
wg pubkey < /etc/wireguard/client1.key > /etc/wireguard/client1.key.pub

# Für weitere Clients jeweils eindeutige Namen verwenden (client2.key, client3.key, ...)
wg genkey > /etc/wireguard/client2.key
wg pubkey < /etc/wireguard/client2.key > /etc/wireguard/client2.key.pub

Konfigurationsdatei Edge-Proxy: /etc/wireguard/wg0.conf

Code:
[Interface]
Address = 10.10.10.1/24
PrivateKey = <EdgeProxyPrivateKey>
ListenPort = 51820
PostUp = iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o <PublicInterface> -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s 10.10.10.0/24 -o <PublicInterface> -j MASQUERADE

[Peer]
PublicKey = <Client1PublicKey>
AllowedIPs = 10.10.10.2/32

# Beispiel: zweiter Peer (Client 2)
[Peer]
PublicKey = <Client2PublicKey>
AllowedIPs = 10.10.10.3/32

Konfigurationsdatei Client 1: /etc/wireguard/wg0.conf

Code:
[Interface]
Address = 10.10.10.2/32
PrivateKey = <Client1PrivateKey>
MTU = 1420

[Peer]
PublicKey = <EdgeProxyPublicKey>
Endpoint = [IPv6-Adresse-EdgeProxy]:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

# Optional: zweiter Peer (z. B. Backup-Edge-Proxy)
[Peer]
PublicKey = <EdgeProxyBackupPublicKey>
Endpoint = [IPv6-Adresse-EdgeProxy-Backup]:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

=================================
English Version
==================================


Technical Setup Description – Edge Proxy and WireGuard on Debian 12 with ISPConfig​

1. System Overview​

This setup describes a Debian 12 installation with ISPConfig, acting as a combined reverse proxy (TLS passthrough) and WireGuard server for IPv4 egress. 'Edge Proxy' = public dual-stack host, 'Client 1' = internal IPv6-only system.

2. Package Installation​

Code:
apt update
apt install nginx-full libnginx-mod-stream wireguard iptables

Ensure Apache (if installed) does not bind to ports 80 or 443.

3. Network Design​

The Edge Proxy runs dual-stack (IPv4 + IPv6). Backends (e.g., Client 1) use native IPv6; IPv4 traffic is tunneled through WireGuard. DNS A/AAAA entries point to the Edge Proxy, SSH uses direct IPv6 access.

4. Nginx Reverse Proxy Configuration​

File: /etc/nginx/stream-enabled/443-sni-map.conf (SNI mapping and TLS passthrough)

Code:
map $ssl_preread_server_name $sni_upstream {
site1.example.net [IPv6-of-backend1]:443;
site2.example.net [IPv6-of-backend2]:443;
default [IPv6-default-backend]:443;
}

server {
listen 0.0.0.0:443;
ssl_preread on;
proxy_pass $sni_upstream;
proxy_connect_timeout 5s;
proxy_timeout 60s;
}

File: /etc/nginx/conf.d/80-acme-proxy.conf (HTTP ACME challenge proxy and redirect)

Code:
map $host $acme_upstream {
hostnames;
site1.example.net [IPv6-Backend1]:80;
#Wildcard:
.example2.net [IPv6-Backend2]:80;
default [IPv6-Backend3]:80;
}

server {
listen 80;
listen [::]:80;
location ^~ /.well-known/acme-challenge/ {
proxy_pass http://$acme_upstream;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
location / { return 301 https://$host$request_uri; }
}

Changes for Apache configuration (File: /etc/apache2/conf-available/10-remoteip-proxyproto.conf):

Code:
RemoteIPProxyProtocol On
RemoteIPTrustedProxy <EDGE_PROXY_IPV4>
RemoteIPTrustedProxy <EDGE_PROXY_IPV6>
LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined_realip
CustomLog ${APACHE_LOG_DIR}/access.log combined_realip

Notes:
- Replace <EDGE_PROXY_IPV4> and <EDGE_PROXY_IPV6> with actual addresses of the Edge Proxy.
- The Edge Proxy must forward using the PROXY protocol.
- Do not use RemoteIPHeader together with RemoteIPProxyProtocol.
- To enable: a2enmod remoteip && a2enconf 10-remoteip-proxyproto && systemctl reload apache2.

5. WireGuard Configuration​

Key generation (use distinct filenames per system, e.g., for the Edge Proxy and each client separately):

Code:
# Edge Proxy
umask 077
wg genkey > /etc/wireguard/edgeproxy.key
wg pubkey < /etc/wireguard/edgeproxy.key > /etc/wireguard/edgeproxy.key.pub

# Client 1
umask 077
wg genkey > /etc/wireguard/client1.key
wg pubkey < /etc/wireguard/client1.key > /etc/wireguard/client1.key.pub

# For additional clients use unique names (client2.key, client3.key, ...)
wg genkey > /etc/wireguard/client2.key
wg pubkey < /etc/wireguard/client2.key > /etc/wireguard/client2.key.pub

Edge Proxy configuration file: /etc/wireguard/wg0.conf

Code:
[Interface]
Address = 10.10.10.1/24
PrivateKey = <EdgeProxyPrivateKey>
ListenPort = 51820
PostUp = iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o <PublicInterface> -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s 10.10.10.0/24 -o <PublicInterface> -j MASQUERADE

[Peer]
PublicKey = <Client1PublicKey>
AllowedIPs = 10.10.10.2/32

# Example: second peer (Client 2)
[Peer]
PublicKey = <Client2PublicKey>
AllowedIPs = 10.10.10.3/32

Client 1 configuration file: /etc/wireguard/wg0.conf

Code:
[Interface]
Address = 10.10.10.2/32
PrivateKey = <Client1PrivateKey>
MTU = 1420

[Peer]
PublicKey = <EdgeProxyPublicKey>
Endpoint = [IPv6-of-EdgeProxy]:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

# Optional: second peer (e.g., backup Edge Proxy)
[Peer]
PublicKey = <EdgeProxyBackupPublicKey>
Endpoint = [IPv6-of-EdgeProxy-Backup]:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
 

etron770

Member
Derzeit suche ich eine Lösung für Letsencryp Zertifikate.
Wenn man ein Zertifikat erstellen möchte, so wird die Proxyserver-IP genommen, und damit erhält die zertifizierende Stelle eine falsche oder keine Antwort.
Das habe ich gestern bemerkt, als ein Zertifikat abgelaufen war.
Die Erstellung von Zertifikaten auf dem Default-Server (Eintrag beim Prox Server) funktioniert aber.Die Lösung, wenn ich sie gefunden habe, teile ich hier mit.
 

etron770

Member
@Till
Kann ich bei ISPConfig einen Pre- und Post-Hook angeben, bevor Zertifikate erstellt werden?

Code:
cat /usr/local/sbin/proxyproto-off.sh
#!/bin/bash
set -euo pipefail
a2disconf 10-remoteip-proxyproto.conf >/dev/null 2>&1 || true
a2enconf 10-remoteip-proxyproto-off.conf >/dev/null 2>&1 || true
apache2ctl configtest
systemctl reload apache2
cat /usr/local/sbin/proxyproto-on.sh
#!/bin/bash
set -euo pipefail
a2disconf 10-remoteip-proxyproto-off.conf >/dev/null 2>&1 || true
a2enconf 10-remoteip-proxyproto.conf >/dev/null 2>&1 || true
apache2ctl configtest
systemctl reload apache2
Ich müsste vor der Zertifikaterstellung je ein Skript ausführen.
Es gibt doch ein /usr/local/ispconfig/server/conf-custom/ Verzeicnis.
Die automatische Erneuerung funktioniert damit.
 
Zuletzt bearbeitet:

etron770

Member
Kann ich einstellen, dass die Apache Direktive
<IfModule mod_remoteip.c>
RemoteIPProxyProtocol On
</IfModule>
für jede Webseite eingefügt wird, anstatt bei jeder Webseite das manuell einzufügen?
 

Werbung

Top