Ldfa Posté(e) le 18 juin 2020 Partager Posté(e) le 18 juin 2020 Derrière ce titre un poil « putaclic » se cache des heures de recherches et des litres de café. Et oui, le réseau et moi ça fait deux… Vous vous souvenez sans doute de mon dernier article portant sur openvswitch, il n’était pas écrit pour rien… généralement quand je commence à fouiller une techno c’est que j’ai une idée derrière la tête. Jusqu’à présent pour créer un réseau privé, j’utilisais tinc. Je ne vais pas m’appesantir sur ce sujet, mais c’est tout de même assez puissant. Je ne cache pas que dans une logique d’automatisation et d’industrialisation, ce n’est pas franchement sexy. Il faut installer le binaire, le configurer (en mode switch c’est mieux), créer les interfaces tun/tap, les clés, les partager… Il existe des rôles Ansible pour faire le job, vous les trouverez facilement sur Github. On va s’approcher un peu plus d’un fonctionnement type OpenStack et utiliser les possibilités offertes par OpenVSwitch. Nous allons créer un bridge interne GRE avec tunnel IPsec : Pré-requis Pour ce faire il faut au minimum deux hyperviseurs KVM bare metal, ça fonctionne aussi avec Proxmox et MacOS VMWare (ahahah), OpenStack puisque c’est intégré dans la solution, mais aussi sans rien… Il faut deux IPs joignables qui pointent vers les serveurs. Avoir installé openvswitch, sauf si ça ne vous intéresse pas mais dans ce cas, je me demande pourquoi vous lisez ces lignes. Configuration On ne va pas faire une usine à gaz, juste créer des certificats auto-signés avec la cli d’openvswitch sur le premier hôte : mkdir /etc/keys cd !$ ovs-pki req -u `hostname` ovs-pki self-sign `hostname` La même procédure sur le deuxième hôte : mkdir /etc/keys cd !$ ovs-pki req -u `hostname` ovs-pki self-sign `hostname` Il faut copier la clé d’un serveur sur l’autre : scp `hostname`-cert.pem user@hote2:/etc/keys/`hostname`-cert.pem scp `hostname`-cert.pem user@hote1:/etc/keys/`hostname`-cert.pem Ensuite on va dire à openvswitch où se trouvent ces fichiers : ovs-vsctl set Open_vSwitch . \ other_config:certificate=/etc/keys/<hostname1>-cert.pem \ other_config:private_key=/etc/keys/<hostname1>-privkey.pem A faire sur chacun des serveurs bien sûr et changeant le nom hostname du .pem. C’est terminé pour les certificats et clés. Maintenant la mise en place des bridges ipsec GRE avec openvswitch. Sur l’hôte 1: ip addr add 192.0.0.1/24 dev br-ipsec ip link set br-ipsec up ovs-vsctl add-port br-ipsec tun -- set interface tun type=gre \ options:remote_ip=<ip_de_hote2> \ options:remote_cert=/etc/keys/<hostname2>-cert.pem ovs-vsctl show Sur l’hôte 2 : ip addr add 192.0.0.2/24 dev br-ipsec ip link set br-ipsec up ovs-vsctl add-port br-ipsec tun -- set interface tun type=gre \ options:remote_ip=<ip_de_hote1> \ options:remote_cert=/etc/keys/<hostname1>-cert.pem Et maintenant sous vos yeux ébahis depuis l’hôte 2 : ping 192.0.0.1 PING 192.0.0.1 (192.0.0.1) 56(84) bytes of data. 64 bytes from 192.0.0.1: icmp_seq=1 ttl=64 time=88.9 ms 64 bytes from 192.0.0.1: icmp_seq=2 ttl=64 time=87.6 ms 64 bytes from 192.0.0.1: icmp_seq=3 ttl=64 time=87.8 ms ^C --- 192.0.0.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev = 87.587/88.097/88.926/0.591 ms Généralisation Vu que les serveurs sont des hyperviseurs KVM, on va tenter de créer des machines virtuelles qui profiteront du tunnel IPsec.Comme nous l’avons vu dans le dernier article sur openvswitch, il faut intégrer le xml du bridge pour qu’il soit interprété par libvirt : # cat /tmp/net-ipsec.xml <network> <name>net-ipsec</name> <forward mode='bridge'/> <bridge name='br-ipsec'/> <virtualport type='openvswitch'/> </network> virsh net-define /tmp/net-ipsec.xml virsh net-start net-ipsec virsh net-autostart net-ipsec Faites démarrer une vm sur chaque hyperviseur avec comme réseau net-ipsec, donnez-lui une adresse dans ce réseau et pingez. Ping de deux vms entre Paris et Beauharnois (datacenter OVH)… latence cata… Automatisation Pour travailler dans un environnement automatisé, avec Terraform et Libvirt KVM, il faudra utiliser un alias pour le provider (j’ai mis Toronto en hommage à Glenn Gould) : # cat multi_hyp.tf provider "libvirt" { uri = "qemu:///system" } provider "libvirt" { alias = "toronto" uri = "qemu+ssh://<kvm_user>@<ip_address>/system" } resource "libvirt_volume" "local-fedora-qcow2" { name = "fedora-qcow2" pool = "default" source = "https://download.fedoraproject.org/pub/fedora/linux/releases/32/Cloud/x86_64/images/Fedora-Cloud-Base-32-1.6.x86_64.qcow2" format = "qcow2" } resource "libvirt_volume" "remote-fedora-qcow2" { provider = libvirt.toronto name = "fedora-qcow2" pool = "default" source = "https://download.fedoraproject.org/pub/fedora/linux/releases/32/Cloud/x86_64/images/Fedora-Cloud-Base-32-1.6.x86_64.qcow2" format = "qcow2" } resource "libvirt_cloudinit_disk" "commoninit-local" { name = "local-commoninit.iso" pool = "default" user_data = data.template_file.user_data.rendered network_config = data.template_file.network_config_local.rendered } resource "libvirt_cloudinit_disk" "commoninit-remote" { provider = libvirt.toronto name = "remote-commoninit.iso" pool = "default" user_data = data.template_file.user_data.rendered network_config = data.template_file.network_config_remote.rendered } data "template_file" "user_data" { template = file("${path.module}/cloud_init.cfg") vars = { hostname = "fedora" fqdn = "lan" user = "matt" ssh_public_key = "ssh-rsa AAAA..." } } data "template_file" "network_config_local" { template = file("${path.module}/network_config_static.cfg") vars = { prefixIP = "192.0.0" octetIP = "6" } } data "template_file" "network_config_remote" { template = file("${path.module}/network_config_static.cfg") vars = { prefixIP = "192.0.0" octetIP = "7" } } resource "libvirt_domain" "local-domain" { name = "local" memory = "2048" vcpu = 2 disk { volume_id = libvirt_volume.local-fedora-qcow2.id } cloudinit = libvirt_cloudinit_disk.commoninit-local.id network_interface { network_name = "net-ipsec" } } resource "libvirt_domain" "remotehost-domain" { provider = libvirt.toronto name = "toronto" memory = "2048" vcpu = 2 disk { volume_id = libvirt_volume.remote-fedora-qcow2.id } cloudinit = libvirt_cloudinit_disk.commoninit-remote.id network_interface { network_name = "net-ipsec" } } terraform { required_version = ">= 0.12" } Avec les fichiers config de cloudinit qui vont bien : # cat cloud_init.cfg #cloud-config # vim: syntax=yaml hostname: ${hostname} fqdn: ${fqdn} ssh_pwauth: true manage_etc_hosts: true chpasswd: list: | root: StrongPassword expire: False users: - name: ${user} passwd: $6$rounds=4096$sWnV/iBTck9OVnMl$PcfdG7/Yjq91I7KdGJyfap23K3wvt3OFtnGhC2vXpbeK7zYC1EO4qU3toVinoYHxPPhkA3HmyKURONXv1Ezrq. lock-passwd: false ssh_authorized_keys: - ${ssh_public_key} sudo: ['ALL=(ALL) NOPASSWD:ALL'] shell: /bin/bash groups: wheel growpart: mode: auto devices: ['/'] output: init: output: "> /var/log/cloud-init.out" error: "> /var/log/cloud-init.err" config: "tee -a /var/log/cloud-config.log" final: - ">> /var/log/cloud-final.out" - "/var/log/cloud-final.err" final_message: "The system is up, after $UPTIME seconds" et pour le réseau statique : # cat network_config_static.cfg version: 2 ethernets: eth0: dhcp4: no dhcp6: no addresses: [ ${prefixIP}.${octetIP}/24 ] Et les vms se pingent, on peut également s’y connecter en SSH depuis leurs adresses privées sur 192.0.0.0/24 : Voilà pour cet article, reste maintenant à isoler à l’intérieur avec des VLANS, mais aussi des VXLAN… dans un futur… proche… si j’ai le temps… Related posts: Afficher l’article complet Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.