diff --git a/10-remoteip-proxyproto-off.conf b/10-remoteip-proxyproto-off.conf new file mode 100644 index 0000000..8593dba --- /dev/null +++ b/10-remoteip-proxyproto-off.conf @@ -0,0 +1,6 @@ +# PROXY protocol ausgeschaltet (global) + + RemoteIPTrustedProxy aaaa:bbb:ccc:dddd::111 + RemoteIPTrustedProxy aa.bb.cc.32 + RemoteIPProxyProtocol Off + diff --git a/10-remoteip-proxyproto.conf b/10-remoteip-proxyproto.conf new file mode 100644 index 0000000..ae5d237 --- /dev/null +++ b/10-remoteip-proxyproto.conf @@ -0,0 +1,9 @@ + + # PROXY protocol nur von 'fury' akzeptieren (sicher!): + RemoteIPTrustedProxy aaaa:bbb:ccc:ddde::111 + # falls fury ggf. auch von 46.4.5.32 (IPv4) kommt, zusätzlich: + RemoteIPTrustedProxy aa.bb.cc.32 + # + # PROXY protocol global zulassen (gilt nur für TrustedProxy-Quellen) + RemoteIPProxyProtocol On + diff --git a/INSTALLATION.md b/INSTALLATION.md new file mode 100644 index 0000000..7aaef2c --- /dev/null +++ b/INSTALLATION.md @@ -0,0 +1,202 @@ +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: + + +# 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 + +```bash +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 + +### 4.1 Host-Mapping + +**Datei:** `/etc/nginx/maps/host_upstreams.inc` (Webseitenzuordnung) + +```text +site1.example.net [IPv6-Backend1]; +site2.example.net [IPv6-Backend2]; +default [IPv6-Default]:443; +``` + +### 4.2 TLS SNI-Mapping und TLS-Passthrough + +**Datei:** `/etc/nginx/stream-enabled/443-sni-map.conf` + +```nginx +# TLS SNI → Zielbackend:443, basierend auf /etc/nginx/maps/host_upstreams.inc (ohne Port) + +# 1) SNI → IP (ohne Port) laden +map $ssl_preread_server_name $upstream_ip_v6 { + hostnames; + # Zuordnung von URL zu Server-IP für 443 und 80 + include /etc/nginx/maps/host_upstreams.inc; +} + +# 2) IP → IP:443 zusammensetzen +map $upstream_ip_v6 $sni_upstream { + "~^(.*)$" $1:443; +} + +server { + listen 0.0.0.0:443; + listen [::]:443; + + ssl_preread on; + proxy_protocol on; + + proxy_pass $sni_upstream; + proxy_connect_timeout 10s; + proxy_timeout 180s; + + access_log /var/log/nginx/stream_access.log stream_fmt; + error_log /var/log/nginx/stream_error.log warn; +} +``` + +### 4.3 HTTP-ACME-Proxy und Redirect + +**Datei:** `/etc/nginx/conf.d/80-acme-proxy.conf` + +```nginx +# 1) Host → IP (ohne Port) aus gemeinsamer Include-Datei +map $host $upstream_ip_v6 { + hostnames; + # Zuordnung für 80 und 443 + include /etc/nginx/maps/host_upstreams.inc; +} + +server { + listen 0.0.0.0:80 default_server; + listen [::]:80 default_server; + server_name _; + + # 2) ACME-Challenges zum Zielserver auf Port 80 + location ^~ /.well-known/acme-challenge/ { + proxy_pass http://$upstream_ip_v6:80; + + 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 http; + + proxy_redirect off; + proxy_connect_timeout 5s; + proxy_send_timeout 10s; + proxy_read_timeout 10s; + } + + # 3) Alles andere auf HTTPS + location / { + return 301 https://$host$request_uri; + } +} +``` + +### 4.4 Apache-Konfiguration (Backend-Server) + +**Datei:** `/etc/apache2/conf-available/10-remoteip-proxyproto.conf` + +```apache +RemoteIPProxyProtocol On +RemoteIPTrustedProxy +RemoteIPTrustedProxy +LogFormat "%a %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined_realip +CustomLog ${APACHE_LOG_DIR}/access.log combined_realip +``` + +**Hinweise:** + +- `` und `` mit tatsächlichen Adressen des Edge-Proxy ersetzen. +- Der Edge-Proxy muss das PROXY-Protokoll aktiv übergeben. +- Keine gleichzeitige Verwendung von `RemoteIPHeader`. +- Aktivierung: + ```bash + a2enmod remoteip + a2enconf 10-remoteip-proxyproto + systemctl reload apache2 + ``` + +## 5. WireGuard-Konfiguration (Deutsch) + +### 5.1 Schlüsselgenerierung + +Schlüsselgenerierung (pro System eindeutige Dateinamen verwenden, z. B. für Edge-Proxy und jeden Client separat): + +```bash +# 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 +``` + +### 5.2 Konfiguration Edge-Proxy + +**Datei:** `/etc/wireguard/wg0.conf` + +```ini +[Interface] +Address = 10.10.10.1/24 +PrivateKey = +ListenPort = 51820 +PostUp = iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o -j MASQUERADE +PostDown = iptables -t nat -D POSTROUTING -s 10.10.10.0/24 -o -j MASQUERADE + +[Peer] +PublicKey = +AllowedIPs = 10.10.10.2/32 + +# Beispiel: zweiter Peer (Client 2) +[Peer] +PublicKey = +AllowedIPs = 10.10.10.3/32 +``` + +### 5.3 Konfiguration Client 1 + +**Datei:** `/etc/wireguard/wg0.conf` + +```ini +[Interface] +Address = 10.10.10.2/32 +PrivateKey = +MTU = 1420 + +[Peer] +PublicKey = +Endpoint = [IPv6-Adresse-EdgeProxy]:51820 +AllowedIPs = 0.0.0.0/0 +PersistentKeepalive = 25 + +# Optional: zweiter Peer (z. B. Backup-Edge-Proxy) +[Peer] +PublicKey = +Endpoint = [IPv6-Adresse-EdgeProxy-Backup]:51820 +AllowedIPs = 0.0.0.0/0 +PersistentKeepalive = 25 +``` diff --git a/INSTALLATION_en.md b/INSTALLATION_en.md new file mode 100644 index 0000000..27944ec --- /dev/null +++ b/INSTALLATION_en.md @@ -0,0 +1,201 @@ +Since I did not want to buy new, expensive IPv4 addresses, or possibly not be able to obtain any in the future, I configured the following setup to provide IPv4 connectivity to pure IPv6 LXC containers or VMs. The concept is mine, but the work is not entirely mine alone; ChatGPT helped me with it and also created the summary. The setup works; access has become significantly faster because there is now an Nginx proxy in front that optimizes the architecture in several ways. However, in DNS some VMs/LXC containers are combined under a single IPv4 and a single IPv6 address. You should carefully consider whether to integrate a mail server into this setup. If one container sends spam, the mail server will also end up on a blacklist because it shares the same IP address. +I hope all steps are covered. +This is the current state: + +# Technical system description – edge proxy and WireGuard on Debian 12 with ISPConfig + +## 1. System overview + +This setup describes a Debian 12 installation with ISPConfig that acts as a combined reverse proxy (TLS passthrough) and WireGuard server for IPv4 egress. +"Edge proxy" = public dual-stack server, "Client 1" = internal IPv6-only system with IPv4 tunnel. + +## 2. Package installation + +```bash +apt update +apt install nginx-full libnginx-mod-stream wireguard iptables +``` + +If Apache is active via ISPConfig, ensure that it does not listen on ports 80/443 to avoid port conflicts. + +## 3. Network concept + +The edge proxy is dual-stack capable with public IPv4 and IPv6 addresses. Backends (including Client 1) use native IPv6; IPv4 traffic is tunneled via WireGuard. DNS A/AAAA records point to the edge proxy; SSH is performed directly over IPv6. + +## 4. Nginx reverse proxy configuration + +### 4.1 Host mapping + +File: `/etc/nginx/maps/host_upstreams.inc` (website mapping) + +```text +site1.example.net [IPv6-Backend1]; +site2.example.net [IPv6-Backend2]; +default [IPv6-Default]:443; +``` + +### 4.2 TLS SNI mapping and TLS passthrough + +File: `/etc/nginx/stream-enabled/443-sni-map.conf` + +```nginx +# TLS SNI → target backend:443, based on /etc/nginx/maps/host_upstreams.inc (without port) + +# 1) Load SNI → IP (without port) +map $ssl_preread_server_name $upstream_ip_v6 { + hostnames; + # Map URL to server IP for 443 and 80 + include /etc/nginx/maps/host_upstreams.inc; +} + +# 2) Build IP → IP:443 +map $upstream_ip_v6 $sni_upstream { + "~^(.*)$" $1:443; +} + +server { + listen 0.0.0.0:443; + listen [::]:443; + + ssl_preread on; + proxy_protocol on; + + proxy_pass $sni_upstream; + proxy_connect_timeout 10s; + proxy_timeout 180s; + + access_log /var/log/nginx/stream_access.log stream_fmt; + error_log /var/log/nginx/stream_error.log warn; +} +``` + +### 4.3 HTTP ACME proxy and redirect + +File: `/etc/nginx/conf.d/80-acme-proxy.conf` + +```nginx +# 1) Host → IP (without port) from common include file +map $host $upstream_ip_v6 { + hostnames; + # Mapping for ports 80 and 443 + include /etc/nginx/maps/host_upstreams.inc; +} + +server { + listen 0.0.0.0:80 default_server; + listen [::]:80 default_server; + server_name _; + + # 2) Forward ACME challenges to target server on port 80 + location ^~ /.well-known/acme-challenge/ { + proxy_pass http://$upstream_ip_v6:80; + + 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 http; + + proxy_redirect off; + proxy_connect_timeout 5s; + proxy_send_timeout 10s; + proxy_read_timeout 10s; + } + + # 3) Redirect everything else to HTTPS + location / { + return 301 https://$host$request_uri; + } +} +``` + +### 4.4 Apache configuration (backend server) + +File: `/etc/apache2/conf-available/10-remoteip-proxyproto.conf` + +```apache +RemoteIPProxyProtocol On +RemoteIPTrustedProxy +RemoteIPTrustedProxy +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 `` and `` with the actual addresses of the edge proxy. +- The edge proxy must actively send the PROXY protocol. +- Do not use `RemoteIPHeader` at the same time. +- Activation: + ```bash + a2enmod remoteip + a2enconf 10-remoteip-proxyproto + systemctl reload apache2 + ``` + +## 5. WireGuard configuration + +### 5.1 Key generation + +Generate keys (use unique filenames per system, e.g. for the edge proxy and each client separately): + +```bash +# 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 +``` + +### 5.2 Edge proxy configuration + +File: `/etc/wireguard/wg0.conf` + +```ini +[Interface] +Address = 10.10.10.1/24 +PrivateKey = +ListenPort = 51820 +PostUp = iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o -j MASQUERADE +PostDown = iptables -t nat -D POSTROUTING -s 10.10.10.0/24 -o -j MASQUERADE + +[Peer] +PublicKey = +AllowedIPs = 10.10.10.2/32 + +# Example: second peer (Client 2) +[Peer] +PublicKey = +AllowedIPs = 10.10.10.3/32 +``` + +### 5.3 Client 1 configuration + +File: `/etc/wireguard/wg0.conf` + +```ini +[Interface] +Address = 10.10.10.2/32 +PrivateKey = +MTU = 1420 + +[Peer] +PublicKey = +Endpoint = [IPv6-of-EdgeProxy]:51820 +AllowedIPs = 0.0.0.0/0 +PersistentKeepalive = 25 + +# Optional: second peer (e.g. backup edge proxy) +[Peer] +PublicKey = +Endpoint = [IPv6-of-EdgeProxy-Backup]:51820 +AllowedIPs = 0.0.0.0/0 +PersistentKeepalive = 25 +``` diff --git a/README.md b/README.md index e69de29..8a213a7 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,47 @@ +# README + +## Haftungsausschluss (Deutsch) + +Die Nutzung dieser Software erfolgt auf eigenes Risiko. +Der Autor bzw. Rechteinhaber übernimmt keinerlei Gewähr für die Richtigkeit, Vollständigkeit oder Aktualität der bereitgestellten Software und Dokumentation. + +Es wird insbesondere keine Haftung übernommen für: +- direkte oder indirekte Schäden, +- Folgeschäden oder entgangenen Gewinn, +- Datenverlust oder Systemausfälle, + +die aus der Nutzung oder Nichtnutzbarkeit der Software entstehen, soweit gesetzlich zulässig. + +Vor dem Einsatz in produktiven Umgebungen ist die Software in einer geeigneten Testumgebung zu prüfen. +Anpassungen an Systemkonfigurationen, Sicherheitsrichtlinien oder Drittsoftware erfolgen eigenverantwortlich. + +Diese Hinweise stellen keine Rechtsberatung dar. Bei Bedarf ist eine qualifizierte rechtliche Beratung einzuholen. + +## Installationshinweise + +Installations- und Konfigurationshinweise befinden sich in der Datei +`INSTALLATION.md` im Wurzelverzeichnis dieses Projekts. + +--- + +## Disclaimer (English) + +Use of this software is at your own risk. +The author or copyright holder provides no warranty of any kind regarding the correctness, completeness, or up-to-dateness of the software and documentation. + +In particular, there is no liability for: +- direct or indirect damages, +- consequential damages or loss of profit, +- loss of data or system outages, + +resulting from the use or inability to use the software, to the extent permitted by applicable law. + +The software must be tested in an appropriate test environment before being used in any production system. +Any changes to system configurations, security policies, or third-party software are made at the user’s own responsibility. + +This information does not constitute legal advice. If required, appropriate legal counsel should be obtained. + +## Installation Notes + +Installation and configuration instructions are provided in +the `INSTALLATION_en.md` file located in the root directory of this project. diff --git a/acme_wrapper.sh b/acme_wrapper.sh new file mode 100755 index 0000000..c68a5f6 --- /dev/null +++ b/acme_wrapper.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# --- FÜHRT DIE BEFEHLE VOR DER ACME-ERSTELLUNG AUS (Proxy OFF) --- +stop_challenge() { + echo "Stopping normal proxy operation and preparing for ACME challenge (Proxy OFF)..." + a2disconf 10-remoteip-proxyproto.conf + a2enconf 10-remoteip-proxyproto-off.conf + systemctl reload apache2 + echo "Preparation complete." +} + +# --- FÜHRT DIE BEFEHLE NACH DER ACME-ERSTELLUNG AUS (Proxy ON) --- +start_normal() { + echo "Starting normal proxy operation after ACME challenge (Proxy ON)..." + a2disconf 10-remoteip-proxyproto-off.conf + a2enconf 10-remoteip-proxyproto.conf + systemctl reload apache2 + echo "Normal operation restored." +} + +case "$1" in + stop) + # Führt die Befehle VOR der Zertifikatserstellung aus + stop_challenge + ;; + start) + # Führt die Befehle NACH der Zertifikatserstellung aus + start_normal + ;; + *) + # Fallback: Führt das komplette Skript wie ursprünglich aus + echo "Usage: $0 {stop|start|full}" + echo "Defaulting to full run for compatibility." + stop_challenge + + echo "" + echo "--- Executing ACME Certificate Renewal ---" + /usr/bin/certbot renew --no-self-upgrade + /root/.acme.sh/acme.sh --cron --force --home /root/.acme.sh + + start_normal + ;; +esac + diff --git a/post_achme_challenge.sh b/post_achme_challenge.sh new file mode 100755 index 0000000..2ee7d4a --- /dev/null +++ b/post_achme_challenge.sh @@ -0,0 +1,6 @@ +!/bin/bash +#Script to reactivate the ipv6-only web server after calling acme or certbot, to communicate via the ipv4/ipv6 proxy +a2disconf 10-remoteip-proxyproto-off.conf +a2enconf 10-remoteip-proxyproto.conf +#Since Apache is only restarted by ISPConfig when the creation of the certificates is successful, we must always restart it as a precaution. +systemctl reload apache2 diff --git a/pre_achme_challenge.sh b/pre_achme_challenge.sh new file mode 100755 index 0000000..ea3205b --- /dev/null +++ b/pre_achme_challenge.sh @@ -0,0 +1,7 @@ +#!/bin/bash +#Script to prepare the IPv6-only web server so that certificates can be created +#The ipv6-only web server can then issue certificates, but communication via the ipv4/ipv6 proxy is interrupted +echo "###################### pre Challenge ###############################" +a2disconf 10-remoteip-proxyproto.conf +a2enconf 10-remoteip-proxyproto-off.conf +systemctl reload apache2