Labo 3 Benzonana
Aussi disponible sur mon git (https://gitedu.hesge.ch/alexandr.benzonan/lab3_ansible)
1 - Commandes ad-hoc
-
Expliquez ce que fait cette commande ? utilisez la commande
ansible-doc
pour répondre à la question.- finalement le -m ping est le module ansible à exécuter
- le -i liste un inventaire
- et le all exécute sur tout les éléments de l’inventaire
-
Donner la commande ad-hoc qui permet d’afficher l’uptime de toutes les machines, sans écrire de fichier inventaire. Démontrez que cette commande est correcte en l’exécutant sur la topologie.
ansible all -m command -a "uptime" -i "H1,H2,R1,R2"
-
Donner la commande ad-hoc qui va créer le fichier
/tmp/hello.txt
sur toutes les machines. Montrez sa sortie par une capture d’écran.ansible all -m command -a "touch /tmp/hello.txt" -i "H1,H2,R1,R2"
- ou
ansible all -m file -a "path=/tmp/hello.txt state=touch" -i "H1,H2,R1,R2"
-
Quelle est la différente entre les modules
command
,shell
etraw
? Expliquez et donner des exemples.- Command n’interprète pas les variables d’environnement ni caractères spéciaux
- Shell est exactement le contraire, il interprète les variables d’environnement et les caractères spéciaux
- Raw est utilisé pour les commandes qui ne sont pas interprétées, en général utilisé pour les commandes qui ne fonctionne ni avec
command
ni avecshell
- en résumé :
2 - Routage et adressage
pour lancer cette partie, il faut utiliser la commande ansible-playbook playbook.yaml
On cherche à recréer une typologie comme celle décrite sur l’image
Nous allons commencer par configurer nos hotes (H1 et H2)
Nos allons créer un template jinja2 pour ce faire (le même template sera utilisé pour les 4 devices)
la première ligne de notre template sera
auto eth0
on indique ici que l’interface redémarre automatiquement au démarrage de l’appareil
on va maintenant configurer cette même interface
on commence par indiquer que l’adressage est statique
iface eth0 inet static
puis on lui indique son adresse et son masque de sous réseau (ici pour H1)
address 1.0.0.3
netmask 255.255.255.0
on lui indique ensuite comment rejoindre l’autre sous réseau
post-up ip route add default via 1.0.0.1
on lui indique ici que tout ses paquets devront passer par 1.0.0.1 qui est l’adresse du routeur qui lui est directement lié
Maintenant notre config au complet
auto eth0
iface eth0 inet static
address 1.0.0.3
netmask 255.255.255.0
post-up ip route add default via 1.0.0.1
nous voulons pouvoir utiliser le même template pour nos différents appareils nous allons donc utiliser des variables
auto {{all[group_names[0]].ifname}}
iface {{all[group_names[0]].ifname}} inet static
address {{all[inventory_hostname].ip}}
netmask {{all.netmask}}
post-up ip route add default via {{all[inventory_hostname].gateway}}
la config de H2 est identique mais avec 3.0.0.3 comme ip et 3.0.0.2 comme gateway
Passons maintenant à la config de nos routeurs (ici R1)
nos commençons avec une configuration similaire à celle de H1
auto eth0
iface eth0 inet static
address 2.0.0.1
netmask 255.255.255.0
post-up ip route add 3.0.0.0/24 via 2.0.0.2
ici on indique que pour accéder au sous réseau 3.0.0.0 il faut passer par l’ip 2.0.0.2, le reste de la config n’est pas très différent
il nous faut cependant configurer l’autre interface également
auto eth1
iface eth1 inet static
address 1.0.0.1
netmask 255.255.255.0
configuration identique ici aussi mais nous n’avons pas besoin du post-up
maintenant la configuration entière
auto eth1
iface eth1 inet static
address 1.0.0.1
netmask 255.255.255.0
auto eth0
iface eth0 inet static
address 2.0.0.1
netmask 255.255.255.0
post-up ip route add 3.0.0.0/24 via 2.0.0.2
comme précédemment il nous faut des variables
auto {{all[group_names[0]].ifname}}
iface {{all[group_names[0]].ifname}} inet static
address {{all[inventory_hostname].ip}}
netmask {{all.netmask}}
auto {{all['routers'].ifname2}}
iface {{all['routers'].ifname2}} inet static
address {{all[inventory_hostname].ip2}}
netmask {{all.netmask}}
post-up ip route add 3.0.0.0/24 nexthop via {{all[inventory_hostname].gateway}}
J’avais indiqué que notre config serait utilisée pour tout les appareils nous allons donc ajouter des conditions
auto {{all[group_names[0]].ifname}}
iface {{all[group_names[0]].ifname}} inet static
address {{all[inventory_hostname].ip}}
netmask {{all.netmask}}
{% if group_names[0] == "hosts" %}
post-up ip route add default via {{all[inventory_hostname].gateway}}
{% endif %}
{% if group_names[0] == "routers" %}
auto {{all['routers'].ifname2}}
iface {{all['routers'].ifname2}} inet static
address {{all[inventory_hostname].ip2}}
netmask {{all.netmask}}
{% if inventory_hostname == "R1" %}
post-up ip route add 3.0.0.0/24 nexthop via {{all[inventory_hostname].gateway}}
{% else %}
post-up ip route add 1.0.0.0/24 nexthop via {{all[inventory_hostname].gateway}}
{% endif %}
{% endif %}
Le premier post-up est nécessaire uniquement pour les hosts tandis que la 2eme partie de la config est destinée au routers uniquement
la configuration est sauvegardée dans /etc/network/interfaces.d/ansible.conf
pour être persistante (il serait mieux de la stocker dans deux fichiers différents nommés eth0 et eth1)
Voici le résultat du playbook, la commande ping est effectivement exécutée
On peut voir grâce à la commande traceroute que le paquet utilise le bon chemin
3 - Tunnel wireguard et serveur web
On commence par installer wireguard sur nos 2 hosts et nginx sur H2
j’ai choisi de faire cette action à la main
on utilise l’interface de management pour accéder à internet (ce qui n’est généralement pas re commandé mais c’était la solution la plus simple)
dhclient -v mgmt0
apt instal wiregurad-tools
apt install nginx
delete default route
Ici l’installation sur H2, sur H1 on supprime seulement la 3eme ligne
la dernière ligne nous sert à supprimer cet accès après son utilisation
il faudra ensuite à nouveau exécuter la commande
post-up ip route add default via {{gateway}}
pour revenir dans notre état précédent
passons maintenant à la configuration de notre serveur nginx
nous allons conserver la configuration par défaut
server{
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}
Nous allons simplement ajouter deux lignes pour empêcher toutes les connexions sauf depuis 10.0.0.0/24
allow {{allowed_ips}};
deny all;
notre configuration finale sera donc
server{
listen 80 default_server;
listen [::]:80 default_server;
allow {{allowed_ips}};
deny all;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}
elle est aussi stockée dans un fichier template jinja2
on se contente ensuite de la copier dans le bon dossier /etc/nginx/sites-available/default
on vient ensuite créer un page web simple grâce à un template jinja2
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
</head>
<body>
<h1>{{content}}</h1>
</body>
</html>
on peut changer la valeur de title et content depuis le playbook
maintenant passons à la configuration de wireguard
le plus simple est de le configurer en ligne de commande puis d’utiliser la commande wg showconf wg0
pour récupérer une config prête à être utilisée
on commence par créer un interface pour wireguard
ip link add wg0 type wireguard
ip addr add 10.0.0.1/24 dev wg0
ip link set up dev wg0
il nous faut ensuite une clef privée et un clef publique pour communiquer
wg genkey | tee private.key | wg pubkey > public.key
et on configure wireguard pour l’utiliser
wg seet private-key private.key
maintenant il faut ajouter notre client
wg set wg0 peer <client pub key> allowed-ips 10.0.0.2/32 endpoint 3.0.0.3:<port>
on récupère la config et on l’utilise dans un template jinja2
[Interface]
Address = {{all[inventory_hostname].ip}}
ListenPort = {{all[inventory_hostname].port}}
PrivateKey = {{pk[inventory_hostname].private_key}}
[Peer]
PublicKey = {{all[inventory_hostname].other_public_key}}
AllowedIPs = {{all[inventory_hostname].AllowedIPs}}
Endpoint = {{all[inventory_hostname].endpoint}}:{{all[inventory_hostname].other_port}}
ici aussi la config est la même pour H1 et H2
pour ne pas stocker la clef privée dans la playbook mais la stocker en sécurité elle est dans un vault ansible crée à partir de la commande
ansible-vault create vault.yml
il faut entrer un mot de passe à la création
que l’on peut ensuite modifier grâce à la commande
ansible-vault edit vault.yml
pour le modifier ou l’afficher il est nécessaire d’indiquer le mot de passe
on ajoute donc nos 2 clef privé comme variable et on peut lancer notre playbook
il faudra juste créer un autre fichier qui contient le mot de passe
je l’ai appelé vaultpassword
on le spécifie lorsque lance le playbook
ansible-playbook --vault-password-file vaultpassword playbook_2.yaml
Résultat du playbook avec notre curl sur 10.0.0.2 pour vérifier que wireguard est bien configuré
preuve que l’on peut accéder au serveur uniquement depuis 10.0.0.0/24
le serveur nous indique bien que nous n’avons pas le droit d’y accéder avec une erreur 403
tandis que sur 10.0.0.2 nous avons bien notre page