Proxmox, n Container, 1 (netcup) Root-Server, 1 IPv4

Siehe hierzu auch folgende Follow-Up Artikel
Proxmox voll-verschlüsselt
Proxmox auf verschlüsseltem Software RAID

Du bist aktuell auf der Suche nach einem (virtuellen) Server? Ich bin seit Jahren von netcup begeistert und hätte da ein paar Gutscheine.

Im August hatte ich noch versprochen, dass ich Details von „meinem Netzwerk“ hier mal genauer ausführen möchte. Mache ich an sich auch nach wie vor gerne, aber die Zeit ist halt oft das Problem. Peters Kommentar war aber dann direkt Motivation genug, damit ich das nun endlich mal anfange:

Das war das Problem

Ich habe einen Root-Server bei netcup (ist kein physikalischer Server, sondern ein vollvirtualisierter vServer), der hat eine öffentliche IPv4. Trotzdem sollen darauf aber mehrere LXC-Container unter Proxmox laufen.

Funktioniert performancetechnisch übrigens einwandfrei, Container sind ja keine „echten“ VMs, von daher recht schlank, Hardware-Virtualisierung in einer VM wäre meiner Meinung nach auch relativ sinnlos, obwohl das technisch natürlich sogar möglich wäre (man kann sich gegen Aufpreis bei netcup die nötigen VT-x-Flags des physikalischen Prozessors „durchreichen“ lassen).

Nehmen wir also folgendes, echtes, Beispiel:

  • Der Proxmox-Host hat die öffentliche IPv4 188.68.32.249
  • Es gibt einen Container apphost-public-web, dort laufen Webanwendung, z. B. dieser Blog
  • Es gibt einen Container apphost-external, dort laufen ebenfalls Webanwendungen

Problem ist nun, wir haben eine externe IPv4, aber zwei Container die Webanwendungen bereitstellen, also am besten über Port 80 und 443 erreichbar sein sollten.

Proxmox Status-Infos meines Hosts "vmhost-external-major"

Und so habe ich das gelöst

  • Auf dem Host gibt es erst einmal ein privates Netz, aus dem die Container interne IPv4-Adressen zugeteilt bekommen
  • Dann gibt es einen weiteren Container reverse-proxy-external-major, der bekommt von extern kommend die Ports 80 und 443 weitergeleitet und dort läuft dann nginx und leitet als Reverse-Proxy die Anfragen über das interne Netzwerk an die anderen Container weiter

Internes Netz definieren/erstellen

Als internes Netz wollte ich den Bereich 192.168.0.0/24 verwenden, folgendes muss dazu in /etc/network/interfaces eingetragen werden, damit man erstmal einen neuen Netzwerkadapter für Proxmox hat.

auto vmbr1
iface vmbr1 inet static
    address 192.168.0.254
    netmask 255.255.255.0
    bridge_ports none
    bridge_stp off
    bridge_fd 0
    post-up echo 1 > /proc/sys/net/ipv4/ip_forward
    post-up iptables -t nat -A POSTROUTING -s '192.168.0.0/24' -o vmbr0 -j MASQUERADE
    post-down iptables -t nat -D POSTROUTING -s '192.168.0.0/24' -o vmbr0 -j MASQUERADE

Den Containern weist man dann den neuen Netzwerkadapter vmbr1 zu und vergibt jeweils eine feste interne IP aus dem definierten Bereich, gehen wir im Weiteren von folgender Konfiguration aus:

  • Container apphost-public-web hat die interne IP 192.168.0.106
  • Container apphost-external die 192.168.0.103
  • Und Container reverse-proxy-external-major die 192.168.0.105
Proxmox Netzwerkeinstellungen eines Containers - Zuweisung einer internen IP

Weiterleitung der Ports

Als nächstes müssen die Ports 80 und 443 an den Container reverse-proxy-external-major weitergeleitet werden, dazu trägt man ebenfalls auf dem Host in /etc/network/interfaces folgendes ein (auf dem Interface vmbr0 ist per Default die öffentliche IPv4 konfiguriert).

# HTTP 80:192.168.0.105:80
post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 80 -j DNAT --to 192.168.0.105:80
post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp --dport 80 -j DNAT --to 192.168.0.105:80

# HTTPS 443:192.168.0.105:443
post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 443 -j DNAT --to 192.168.0.105:443
post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp --dport 443 -j DNAT --to 192.168.0.105:443

nginx als Reverse-Proxy

Auf dem Container reverse-proxy-external-major läuft nginx und auf apphost-public-web z. B. dieser Blog. Die Konfiguration für diese Seite sieht damit beispielhaft so aus, damit alle Anfragen für die Domain blog.berrnd.de an den Container mit interner IP .106 weitergeleitet werden.

server {
	listen 443 ssl http2;
	server_name blog.berrnd.de;

	ssl on;
	ssl_certificate /etc/letsencrypt/live/blog.berrnd.de/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/blog.berrnd.de/privkey.pem;

	location / {
		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;
		proxy_buffering off;
		proxy_pass http://192.168.0.106/;
	}
}

server {
	server_name blog.berrnd.de;	
	return 301 https://$host$request_uri;
}

Wichtig zu erwähnen ist hierbei evtl. noch, dass der nginx auf dem von extern erreichbaren Container natürlich nun der SSL-Endpunkt ist. Heißt SSL-Zertifikate müssen hier konfiguriert werden.

Könnte man mit einem TCP-Reverse-Proxy wie HAProxy auch anders machen, dann könnte auch die SSL-Konfiguration auf dem eigentlichen Anwendungs-Container stattfinden. Habe ich z. B. auf meinem Proxmox-Host Zuhause so, da sich Exchange schlecht bis gar nicht über nginx Tunneln lässt (HTTP Digest-Authentication ist hier das Problem). Darauf kann ich bei Gelegenheit ja mal auch noch eingehen.

Du möchtest mir hierzu Feedback hinterlassen? Dann schreib mir gerne eine Nachricht.