Proxmox 6.0 sur un serveur dédié (3/3) : Ajout d’un conteneur LXC faisant office de Routeur/Firewall

Maintenant que nous avons installé, configuré et sécurisé Proxmox, nous devons mettre en place une machine qui fera office routeur/ firewall (passerelle) afin de sécuriser les machines qui seront derrières. Nous allons mettre en place un conteneur LXC. C’est un système de virtualisation léger permettant de faire fonctionner des environnements Linux isolés les uns des autres, tout en utilisant le même noyau Linux.

Création du conteneur

Avant de pouvoir créer un conteneur, nous devons récupérer l’image qui servira à la création de ce dernier. Pour cela dans un premier temps, nous allons mettre à jour la liste des images disponibles :

1
# pveam update

Nous pouvons maintenant afficher la liste des images systèmes disponibles :

1
# pveam available --section system

Nous allons télécharger l’image CentOS 7. Pour cela, on tape la commande suivante :

1
# pveam download proxmox centos-7-default_20171212_amd64.tar.xz

Nous pouvons nous assurez que le template est bien présent, via la commande suivante :

1
# pveam list proxmox

Maintenant que nous avons télécharger le template, nous allons pouvoir créer le conteneur. Pour cela on tape la commande suivante :

1
# pct create 100 proxmox:vztmpl/centos-7-default_20171212_amd64.tar.xz --hostname Firewall --cores 1 --memory 512 --swap 512 --rootfs proxmox:5 --net0 name=eth0,bridge=vmbr1,ip=10.0.0.2/30,gw=10.0.0.1 --net1 name=eth1,bridge=vmbr2,ip=192.168.0.2/24 --onboot 1 --startup 'order=1,up=5,down=5'

Maintenant que nous avons créer notre conteneur LXC, je vais vous expliquer à quoi correspondent les différentes options :

  • –100 : Correspond à l’ID du conteneur. Celui-ci doit-être unique
  • proxmox:vztmpl/centos-7-default_20171212_amd64.tar.xz : Correspond à l’ID du stockage ou se trouve le template ainsi que le nom du template à utiliser séparé par « : »
  • –hostname Firewall : Nom du conteneur LXC (/etc/hostname). Il servira aussi à identifier le conteneur dans l’interface web de Proxmox
  • –cores 1 : Indique le nombre de cœur qui sera alloué au conteneur
  • –memory 512 : Indique la quantité de mémoire vive allouée au conteneur. La taille doit être indiquée en MB
  • –swap 512 : Indique la quantité de mémoire swap allouée au conteneur. La taille doit être indiquée en MB
  • –rootfs proxmox:5 : Correspond à l’ID du stockage ou se sera créé le disque dur conteneur ainsi que la taille de ce dernier séparé par « : ». La taille doit être indiquée en GB
  • –net0 name=eth0,bridge=vmbr1,ip=10.0.0.2/30,gw=10.0.0.1 : Correspond à la configuration réseau du conteneur. Dans notre cas l’interface eth0 sera connecté au bridge vmbr1, aura pour adresse IP 10.0.0.1 avec un masque de sous réseau autorisant 2 ip et comme passerelle 10.0.0.1
  • –net1 name=eth1,bridge=vmbr2,ip=192.168.0.2/24 : Nous configurons une seconde interface réseau « eth1 » qui aura pour adresse IP 192.168.0.2 avec un masque de sous réseau autorisant 254 IPs
  • –onboot 1 : On indique à Proxmox qu’il faudra démarrer automatiquement le conteneur une fois que le système aura démarré pour ne pas avoir à le faire manuellement
  • –startup ‘order=1,up=5,down=5’ : On indique l’ordre de démarrage du conteneur ainsi que le temps à observer entre chaque démarrage ou extinction de conteneur

Notre conteneur étant créé, nous allons maintenant le démarrer. Pour cela, on tape la commande suivante :

1
# pct start 100

Nous pouvons nous assurer que notre conteneur est bien démarré en tapant la commande suivante :

1
2
# pct status 100
status: running

Nous allons maintenant nous connecter au conteneur pour ajouter les scripts contenant les règles iptables pour le routage des paquets et du firewall. Pour cela, on tape la commande suivante :

1
# pct enter 100

Nous sommes maintenant dans le conteneur. La première chose que nous allons faire, c’est de mettre à jour le système. Pour cela, on tape les commandes suivantes :

1
# yum upgrade

Nous allons créer un script qui sera exécuté lorsque que l’interface sera monté. Pour cela, on tape les commandes suivantes :

1
2
# mkdir /root/scripts/
# vi /root/scripts/add_iptables_rules.sh

Voici le contenu du scripts :

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/bin/bash

        ##### Port forwarding activation #####

echo 1 > /proc/sys/net/ipv4/ip_forward

        ##### Variables definitions #####

## WAN Router Interface
WanInt="eth0"
## LAN Router Interface
LanInt="eth1"
## Network LAN
LanNet="192.168.0.0/24"

## WAN Router IP
WanIP="10.0.0.2"
## LAN Router IP
LanIP="192.168.0.2"
## HAProxy IP
HAProxyIP="192.168.0.3"

DNSPort="53"
HTTPPort="80"
HTTPSPort="443"

DNS1="XXX.XXX.XXX.XXX"
DNS2="XXX.XXX.XXX.XXX"

        ##### CLEAN ALL RULES & DROP IPV4 AND IPV6 PACKETS #####

## Delete all existing rules.
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X

ip6tables -F
ip6tables -X
ip6tables -t nat -F
ip6tables -t nat -X
ip6tables -t mangle -F
ip6tables -t mangle -X

## Block ALL IPV4 and IPV6 INPUT and OUTPUT
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

ip6tables -P INPUT DROP
ip6tables -P OUTPUT DROP
ip6tables -P FORWARD DROP

        ##### CHAINS #####

## Creating chains
iptables -N TCP
iptables -N UDP
iptables -N udp-flood

## UDP = ACCEPT / SEND TO THIS CHAIN
iptables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP
## TCP = ACCEPT / SEND TO THIS CHAIN
iptables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP

        ##### GLOBAL RULES #####

## Allow localhost
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
## Don't break the current/active connections
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
## Allow response to ping request on interface eth1
iptables -A INPUT -i $LanInt -p icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT

        ##### OUTPUT IPV4 RULES FOR Router #####

## Allow ping out
iptables -A OUTPUT -p icmp -j ACCEPT

## Routeur as CLIENT
## Allow DNS
iptables -A OUTPUT -o $WanInt -s $WanIP -p udp --dport $DNSPort -d $DNS1,$DNS2 -j ACCEPT
## Block All Other UDP
#iptables -A OUTPUT -p udp -j DROP
## Allow HTTP/HTTPS
iptables -A OUTPUT -o $WanInt -s $WanIP -p tcp --match multiport --dports $HTTPPort,$HTTPSPort -j ACCEPT

        ##### FORWARD IPV4 RULES #####

## Allow request forwarding from WAN to Router LAN interface
iptables -A FORWARD -i $WanInt -d $WanIP -o $LanInt -p tcp -j ACCEPT
iptables -A FORWARD -i $WanInt -d $WanIP -o $LanInt -p udp -j ACCEPT
## Allow request forwarding from LAN
iptables -A FORWARD -i $LanInt -s $LanNet -j ACCEPT
## Forward HTTP/HTTPS to HAProxy
iptables -A FORWARD -i $WanInt -p tcp --match multiport --dports $HTTPPort,$HTTPSPort -d $HAProxyIP -j ACCEPT

        ##### MASQUERADE MANDATORY #####

## Allow WAN network to use WanInt public adress to go out
iptables -t nat -A POSTROUTING -s $LanNet -o $WanInt -j MASQUERADE

        ##### Redirect IPV4 (NAT) traffic from internet #####

## All tcp to Router WAN
iptables -t nat -A PREROUTING -i $WanInt -p tcp --match multiport --dports $HTTPPort,$HTTPSPort -j DNAT --to $HAProxyIP
## All udp to Router WAN
iptables -t nat -A PREROUTING -i $WanInt -p udp -j DNAT --to $LanIP

	##### OUTPUT FLOOD PROTECTION #####

iptables -A OUTPUT -p udp -j udp-flood
iptables -A udp-flood -p udp -m limit --limit 10/s -j RETURN
iptables -A udp-flood -j LOG --log-level 4 --log-prefix 'UDP-flood attempt: '
iptables -A udp-flood -j DROP
iptables -A OUTPUT -p udp -j DROP

Maintenant, on le rend executable via la commande suivante :

1
# chmod +x /root/scripts/add_iptables_rules.sh

Sur CentOS, nous ne pouvons pas procéder de la même façon que sur Debian. Nous devons installer le package « iptables-services » afin de pouvoir lancer iptables au démarrage du conteneur. Pour cela, on tape la commande suivante :

1
# yum install iptables-services

Nous devons lancer une première fois le script contenant nos règles pour le sauvegarder à l’aide de la commande « iptables-save ». Pour cela, on tape les commandes suivantes :

1
2
# /root/scripts/add_iptables_rules.sh
# iptables-save > /etc/sysconfig/iptables

Maintenant que nous avons sauvegardé les règles iptables, nous devons activer et démarrer le service iptables pour qu’il se lance au démarrage de la machine. Pour cela, on tape les commandes suivantes :

1
2
# systemctl enable iptables
# systemctl start iptables

Lors du démarrage du conteneur, le service iptables ira lire les règles contenu dans le fichier /etc/sysconfig/iptables et les exécutera. Si vous éditez son contenu, vous vous apercevrez que c’est beaucoup moins lisible que le script que je vous ai fourni Vous pouvez maintenant créer un conteneur LXC ou une machine virtuelle. Ils devront avoir :

  • une adresse IP : de 192.168.0.3 à 192.168.0.254
  • un masque de sous réseau : 255.255.255.0
  • une passerelle : 192.168.0.2