Proxmox
HAProxy
Réseau
7 min
Mis en ligne le 03/02/2023

Configurer un serveur proxmox avec une seule ip publique

Par défaut, Proxmox est livré avec une configuration bridge (pont) qui se nomme vmbr0, ce pont est connecté à la première carte Ethernet. Chaque VM peut ensuite partager ce pont, elles se comportent alors comme si elles étaient directement connectées au réseau physique.

Le problème est que cette configuration réseau ne fonctionne pas chez la plupart des hébergeurs pour des raisons de sécurité. Ils désactivent la mise en réseau dès que plusieurs adresses MAC sont détectées sur une seule interface réseau.

Ce que nous allons faire ici d'après les mots de la documentation de Proxmox :

Le masquage permet aux invités n'ayant qu'une adresse IP privée d'accéder au réseau en utilisant l'adresse IP de l'hôte pour le trafic sortant. Chaque paquet sortant est réécrit par iptables pour apparaître comme provenant de l'hôte, et les réponses sont réécrites en conséquence pour être acheminées vers l'expéditeur d'origine.

Prérequis

  • Avoir un serveur avec un Proxmox d'installé (pour moi il sera chez OVH et ce sera un Proxmox VE 7.2)
  • Connaître l'IP de son serveur et sa passerelle (chez OVH il est possible de récupérer ces informations dans l'onglet Bare Metal -> Serveur dédié -> choisissez ensuite votre serveur -> Interfaces réseau)

Configuration de l'hôte proxmox

Nous allons modifier la configuration de la carte réseau eno1 associée au Proxmox. Ensuite, nous allons créer un sous-réseau privé qui servira pour nos machines virtuelles.

Pour configurer le réseau sur l'hôte Proxmox, nous allons modifier le fichier /etc/network/interfaces

1auto lo
2iface lo inet loopback
3 
4# Configuration de l'ip réel du serveur
5auto eno1
6iface eno1 inet static
7 address ip-de-votre-serveur/24 # /24 si le netmask est 255.255.255.0
8 gateway passerelle-de-votre-serveur
9 
10iface eno2 inet manual
11 
12# Configuration du sous-réseau privé
13auto vmbr0
14iface vmbr0 inet static
15 address 192.168.1.1/24
16 bridge-ports none
17 bridge-stp off
18 bridge-fd 0
19 
20 post-up echo 1 > /proc/sys/net/ipv4/ip_forward
21 post-up iptables -t nat -A POSTROUTING -s '192.168.1.0/24' -o eno1 -j MASQUERADE
22 post-down iptables -t nat -D POSTROUTING -s '192.168.1.0/24' -o eno1 -j MASQUERADE

Attention à bien remplacer ip-de-votre-serveur et passerelle-de-votre-serveur dans l'interface eno1.

Nous avons ensuite créé un pont vmbr0 qui nous servira de réseau privé pour nos machines virtuelles. Ici j'ai choisi de le mettre sur la plage d'IP 192.168.1.X.

L'IP 192.168.1.1 est attribuée à notre pont, c'est l'IP qui servira de passerelle pour nos machines virtuelles.

Chacune de mes machines virtuelles pourra avoir une IP comme par exemple :

  • 192.168.1.5
  • 192.168.1.10
  • 192.168.1.12
  • 192.168.1.20
  • et ça jusqu'à 255.

Nous redirigeons ensuite le trafic à l'aide d'iptables.

Pour que la nouvelle configuration soit prise en compte, il faut redémarrer le service networking

1systemctl restart networking

Configuration d'une machine virtuelle

Création d'une nouvelle VM

Dans votre interface d'administration Proxmox, créez une nouvelle machine virtuelle (pour mes besoins je me suis créé une Debian), en prenant soin lors de la configuration réseau de choisir notre pont vmbr0

Lors de l'installation de Debian, la configuration automatique du réseau échoue. Nous allons le configurer manuellement :

  • Pour l'adresse IP, choisissez-en une disponible dans la plage d'IP de notre réseau privé, ici je vais choisir 192.168.1.10.
  • Le masque de sous-réseau est 255.255.255.0
  • La passerelle est l'adresse IP que nous avons attribué à notre carte vmbr0, ici 192.168.1.1
  • Pour les serveurs de noms, j'utilise ceux de Cloudflare et Google, je vais donc mettre 1.1.1.1 8.8.8.8 mais vous pouvez utiliser ceux que vous préférez.

Bravo, votre VM est maintenant connectée à Interne

Modification de la configuration réseau d'une VM existante

Voici à quoi ressemble le fichier /etc/network/interfaces si le besoin est de modifier une VM déjà installée

1source /etc/network/interfaces.d/*
2 
3# The loopback network interface
4auto lo
5iface lo inet loopback
6 
7allow-hotplug ens18
8iface ens18 inet static
9 address 192.168.1.10/24
10 gateway 192.168.1.1
11 dns-namesservers 1.1.1.1 8.8.8.8

Vérifier l'accès internet de la VM

Pour vérifier que la VM soit bien connectée à Internet, il suffit de faire une requête ping.

1ping google.fr

La réponse devrait ressembler à quelque chose comme ci-dessous :

1PING google.fr (142.250.201.163) 56(84) bytes of data.
264 bytes from par21s23-in-f3.1e100.net (142.250.201.163): icmp_seq=1 ttl=113 time=4.14 ms
364 bytes from par21s23-in-f3.1e100.net (142.250.201.163): icmp_seq=2 ttl=113 time=4.18 ms
464 bytes from par21s23-in-f3.1e100.net (142.250.201.163): icmp_seq=3 ttl=113 time=4.17 ms

Accéder à la VM en SSH

Notre VM est maintenant connectée à Internet, cependant elle ne dispose pas d'IP publique à elle seule. Il n'est donc pas possible de se connecter directement en SSH sur l'IP de la machine, car elle est dans un sous-réseau privé

Nous allons donc mettre en place un reverse proxy avec HAProxy pour rediriger le trafic d'un port spécifique de notre serveur hôte vers le port 22 de notre machine virtuelle.

Il faudra pour cela avoir un serveur SSH installé sur la machine virtuelle. Si vous ne l'avez pas fait lors de l'installation, allez dans la console de votre VM sur Proxmox et installez-le avec la commande suivante :

1apt install openssh-server

Configuration de l'hôte proxmox

Installer Haproxy sur le serveur hôte :

1apt install haproxy

Toutes les configurations se passent dans le fichier /etc/haproxy/haproxy.cfg. Par défaut, la configuration devrait ressembler à ceci :

1global
2 log /dev/log local0
3 log /dev/log local1 notice
4 chroot /var/lib/haproxy
5 stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
6 stats timeout 30s
7 user haproxy
8 group haproxy
9 daemon
10 
11 # Default SSL material locations
12 ca-base /etc/ssl/certs
13 crt-base /etc/ssl/private
14 
15 # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
16 ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CH>
17 ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
18 ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
19 
20defaults
21 log global
22 mode http
23 option httplog
24 option dontlognull
25 timeout connect 5000
26 timeout client 50000
27 timeout server 50000
28 errorfile 400 /etc/haproxy/errors/400.http
29 errorfile 403 /etc/haproxy/errors/403.http
30 errorfile 408 /etc/haproxy/errors/408.http
31 errorfile 500 /etc/haproxy/errors/500.http
32 errorfile 502 /etc/haproxy/errors/502.http
33 errorfile 503 /etc/haproxy/errors/503.http
34 errorfile 504 /etc/haproxy/errors/504.http

Ajoutons le frontend pour capturer le trafic SSH et le rediriger vers les machines virtuelles. Il faut avoir un port spécifique par serveur SSH

1frontend sshd
2 mode tcp
3 option tcplog
4 timeout client 180000
5 bind *:200 # Binding du port 200
6 bind *:300 # Bindig du port 300
7 
8 # Ajout des règles de routages
9 acl sshd-200 dst_port 200
10 acl sshd-300 dst_port 300
11 
12 # Redirection sur le backend en fonction de la règle de routage
13 # Pour le port 200, on redirige sur le backend sshd_ma_vm1, pour le 300 sur sshd_ma_vm2
14 use_backend sshd_ma_vm1 if sshd-200
15 use_backend sshd_ma_vm2 if sshd-300

Créons les backends pour les connexions SSH aux machines virtuelles

1backend sshd_ma_vm1
2 mode tcp
3 server ssh 192.168.1.10:22
4 
5backend sshd_ma_vm2
6 mode tcp
7 server ssh 192.168.1.10:22

Pour vérifier et prendre en compte les modifications du fichier de configuration, tapez la commande suivante :

1haproxy -f /etc/haproxy/haproxy.cfg -c

Attention à bien remplacer l'IP de la VM dans le backend par l'IP de votre machine virtuelle.

Les noms sshd_ma_vm1 et sshd_ma_vm2 sont ici totalement arbitraires. Il faut qu'ils concordent dans la propriété default_backend avec le nom choisi pour la déclaration du backend

Pour se connecter en SSH, il suffit maintenant d'ouvrir une connexion vers notre serveur hôte sur le port choisi dans le frontend, ici 200 ou 300 en fonction de la machine virtuelle à laquelle nous souhaitons nous connecter.

Il faudra faire de même pour chaque VM ayant besoin d'avoir un accès SSH, mais sur un port différent.

Voici à quoi ressemble le fichier de configuration complet :

1# Cliquez ci-dessous pour déplier
2 ...
3global
4 log /dev/log local0
5 log /dev/log local1 notice
6 chroot /var/lib/haproxy
7 stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
8 stats timeout 30s
9 user haproxy
10 group haproxy
11 daemon
12 
13 # Default SSL material locations
14 ca-base /etc/ssl/certs
15 crt-base /etc/ssl/private
16 
17 # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
18 ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CH>
19 ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
20 ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
21 
22defaults
23 log global
24 mode http
25 option httplog
26 option dontlognull
27 timeout connect 5000
28 timeout client 50000
29 timeout server 50000
30 errorfile 400 /etc/haproxy/errors/400.http
31 errorfile 403 /etc/haproxy/errors/403.http
32 errorfile 408 /etc/haproxy/errors/408.http
33 errorfile 500 /etc/haproxy/errors/500.http
34 errorfile 502 /etc/haproxy/errors/502.http
35 errorfile 503 /etc/haproxy/errors/503.http
36 errorfile 504 /etc/haproxy/errors/504.http
37 
38frontend sshd
39 mode tcp
40 option tcplog
41 timeout client 180000
42 bind *:200 # Binding du port 200
43 bind *:300 # Exemple pour une seconde VM, bindig du port 300
44 
45 # Ajout des règles de routages
46 acl sshd-200 dst_port 200
47 acl sshd-300 dst_port 300 # Exemple pour une seconde VM qui utilise le port 300 pour le ssh
48 
49 # Redirection sur le backend en fonction de la règle de routage
50 # Pour le port 200, on redirige sur le backend sshd_ma_vm1, pour le 300 sur sshd_ma_vm2
51 use_backend sshd_ma_vm1 if sshd-200
52 use_backend sshd_ma_vm2 if sshd-300 # Exemple pour une seconde VM qui utilise le port 300 pour le ssh
53 
54backend sshd_ma_vm1
55 mode tcp
56 server ssh 192.168.1.10:22
57 
58# Exemple pour une seconde VM qui utilise le port 300 pour le ssh
59backend sshd_ma_vm2
60 mode tcp
61 server ssh 192.168.1.10:22

Attention à bien remplacer l'IP de la VM dans le backend par l'IP de votre machine virtuelle.

Il faudra écrire les règles pour chaque connexion entrante vers une des VM. Par exemple, il faudra router les ports 80 et 443 dans le cas d'une installation d'un serveur web.

Pour aller plus loin

Pour aller plus loin et ajouter un peu de sécurité à cette installation, vous pouvez configurer un pare-feu UFW pour autoriser uniquement les ports que vous avez routés dans votre configuration HAProxy.

Sources

Ludovic Meurot

Développeur web, PHP Laravel, interessé par l'admin sys et du réseau.