Auto-update blog content from Obsidian: 2025-11-20 20:44:04
All checks were successful
Blog Deployment / Merge (push) Successful in 6s
Blog Deployment / Deploy-Production (push) Successful in 9s
Blog Deployment / Test-Production (push) Successful in 2s
Blog Deployment / Clean (push) Has been skipped
Blog Deployment / Notify (push) Successful in 2s
Blog Deployment / Check-Rebuild (push) Successful in 7s
Blog Deployment / Build (push) Has been skipped
Blog Deployment / Deploy-Staging (push) Successful in 9s
Blog Deployment / Test-Staging (push) Successful in 2s

This commit is contained in:
Gitea Actions
2025-11-20 20:44:04 +00:00
parent e495593cc1
commit c27bd9f906
2 changed files with 210 additions and 207 deletions

View File

@@ -1,7 +1,7 @@
--- ---
slug: migration-opnsense-proxmox-highly-available slug: migration-opnsense-proxmox-highly-available
title: Migration to my OPNsense Highly Available Cluster in Proxmox VE title: Migration vers mon cluster OPNsense hautement disponible dans Proxmox VE
description: The detailed steps of the migration from my OPNsense physical box to a highly available cluster of VM in Proxmox VE. description: La démarche détaillée de la migration de ma box OPNsense physique vers un cluster de VM hautement disponible dans Proxmox VE.
date: 2025-11-20 date: 2025-11-20
draft: true draft: true
tags: tags:
@@ -13,285 +13,288 @@ categories:
--- ---
## Intro ## Intro
This is the final stage of my **OPNsense** virtualization journey. C'est la dernière étape de l'aventure de la virtualisation d'**OPNsense**.
A few months ago, my physical [OPNsense box crashed]({{< ref "post/10-opnsense-crash-disk-panic" >}}) because of a hardware failure. This leads my home in the dark, literally. No network, no lights. Il y a quelques mois, ma [box OPNsense physique a crash]({{< ref "post/10-opnsense-crash-disk-panic" >}}) à cause d'une défaillance matérielle. Cela a plongé ma maison dans le noir, litralement. Pas de réseau, pas de lumières.
💡 To avoid being in that situation again, I imagine a way to virtualize my OPNsense firewall into my **Proxmox VE** cluster. The last time, I've set up a [proof of concept]({{< ref "post/12-opnsense-virtualization-highly-available" >}}) to validate this solution: create a cluster of two **OPNsense** VMs in Proxmox and make the firewall highly available. 💡 Pour éviter de me retrouver à nouveau dans cette situation, j'ai imaginé un plan pour virtualiser mon pare-feu OPNsense dans mon cluster **Proxmox VE**. La dernière fois, j'avais mis en place un [proof of concept]({{< ref "post/12-opnsense-virtualization-highly-available" >}}) pour valider cette solution : créer un cluster de deux VM **OPNsense** dans Proxmox et rendre le firewall hautement disponible.
This time, I will cover the creation of my future OPNsense cluster from scratch, plan the cut over and finally migrate from my current physical box. Let's go! Cette fois, je vais couvrir la création de mon futur cluster OPNsense depuis zéro, planifier la bascule et finalement migrer depuis ma box physique actuelle. C'est parti !
--- ---
## The VLAN Configuration ## La Configuration VLAN
For my plans, I'll have to connect the WAN, coming from my ISP box, to my main switch. For that I create a dedicated VLAN to transport this flow to my Proxmox nodes. Pour mes plans, je dois connecter le WAN, provenant de ma box FAI, à mon switch principal. Pour cela je crée un VLAN dédié pour transporter ce flux jusqu'à mes nœuds Proxmox.
### UniFi ### UniFi
First, I configure my layer 2 network which is managed by UniFi. There I need to create two VLANs: D'abord, je configure mon réseau de couche 2 qui est géré par UniFi. Là, je dois créer deux VLANs :
- *WAN* (20): transport the WAN between my ISP box and my Proxmox nodes.
- *pfSync* (44), communication between my OPNsense nodes.
In the UniFi controller, in `Settings` > `Networks`, I add a `New Virtual Network`. I name it `WAN` and give it the VLAN ID 20: - _WAN_ (20) : transporte le WAN entre ma box FAI et mes nœuds Proxmox.
- _pfSync_ (44), communication entre mes nœuds OPNsense.
Dans le contrôleur UniFi, dans `Paramètres` > `Réseaux`, j'ajoute un `New Virtual Network`. Je le nomme `WAN` et lui donne l'ID VLAN 20 :
![Creation of the WAN VLAN in the UniFi Controller](img/unifi-add-vlan-for-wan.png) ![Creation of the WAN VLAN in the UniFi Controller](img/unifi-add-vlan-for-wan.png)
I do the same thing again for the `pfSync` VLAN with the VLAN ID 44. Je fais la même chose pour le VLAN `pfSync` avec l'ID VLAN 44.
I plan to plug my ISP box on the port 15 of my switch, which is disabled for now. I set it as active, set the native VLAN on the newly created one `WAN (20)` and disable trunking: Je prévois de brancher ma box FAI sur le port 15 de mon switch, qui est désactivé pour l'instant. Je l'active, définis le VLAN natif sur le nouveau `WAN (20)` et désactive le trunking :
![Configuration of the UniFi switch port for the WAN uplink](img/unifi-enable-port-wan-vlan.png) ![Configuration du port du switch UniFi pour la liaison WAN](img/unifi-enable-port-wan-vlan.png)
Once this setting applied, I make sure that only the ports where are connected my Proxmox nodes propagate these VLAN on their trunk. Une fois ce réglage appliqué, je m'assure que seules les ports où sont connectés mes nœuds Proxmox propagent ces VLANs sur leur trunk.
I'm done with UniFi configuration. J'ai fini la configuration UniFi.
### Proxmox SDN ### Proxmox SDN
Now that the VLAN can reach my nodes, I want to handle it in the Proxmox SDN. I've configured the SDN in [that article]({{< ref "post/11-proxmox-cluster-networking-sdn" >}}). Maintenant que le VLAN peut atteindre mes nœuds, je veux le gérer dans le SDN de Proxmox. J'ai configuré le SDN dans [cet article]({{< ref "post/11-proxmox-cluster-networking-sdn" >}}).
In `Datacenter` > `SDN` > `VNets`, I create a new VNet, call it `vlan20` to follow my own naming convention, give it the *WAN* alias and use the tag (VLAN ID) 20: Dans `Datacenter` > `SDN` > `VNets`, je crée un nouveau VNet, je l'appelle `vlan20` pour suivre ma propre convention de nommage, je lui donne l'alias _WAN_ et j'utilise le tag (ID VLAN) 20 :
![Creation of the VNet for the WAN in the Proxmox SDN](img/proxmox-sdn-new-vnet-wan.png) ![Creation of the VNet for the WAN in the Proxmox SDN](img/proxmox-sdn-new-vnet-wan.png)
I also create the `vlan44` for the *pfSync* VLAN, then I apply this configuration and we are done with the SDN. Je crée aussi le `vlan44` pour le VLAN _pfSync_, puis j'applique cette configuration et nous avons terminé avec le SDN.
--- ---
## Create the VMs ## Création des VMs
Now that the VLAN configuration is done, I can start buiding the virtual machines on Proxmox. Maintenant que la configuration VLAN est faite, je peux commencer à construire les machines virtuelles sur Proxmox.
The first VM is named `cerbere-head1` (I didn't tell you? My current firewall is named `cerbere`, it makes even more sense now!). Here are the settings: La première VM s'appelle `cerbere-head1` (je ne vous l'ai pas dit ? Mon firewall actuel s'appelle `cerbere`, ça a encore plus de sens maintenant !). Voici les réglages :
- **OS type**: Linux (even if OPNsense is based on FreeBSD) - **Type d'OS** : Linux (même si OPNsense est basé sur FreeBSD)
- **Machine type**: `q35` - **Type de machine** : `q35`
- **BIOS**: `OVMF (UEFI)` - **BIOS** : `OVMF (UEFI)`
- **Disk**: 20 GiB on Ceph distributed storage - **Disque** : 20 Go sur stockage Ceph distribué
- **RAM**: 4 GiB RAM, ballooning disabled - **RAM** : 4 Go, ballooning désactivé
- **CPU**: 2 vCPU - **CPU** : 2 vCPU
- **NICs**, firewall disabled: - **NICs**, pare-feu désactivé :
1. `vmbr0` (*Mgmt*) 1. `vmbr0` (_Mgmt_)
2. `vlan20` (*WAN*) 2. `vlan20` (_WAN_)
3. `vlan13` *(User)* 3. `vlan13` _(User)_
4. `vlan37` *(IoT)* 4. `vlan37` _(IoT)_
5. `vlan44` *(pfSync)* 5. `vlan44` _(pfSync)_
6. `vlan55` *(DMZ)* 6. `vlan55` _(DMZ)_
7. `vlan66` *(Lab)* 7. `vlan66` _(Lab)_
![Hardware settings of the OPNsense VM in Proxmox](img/proxmox-cerbere-vm-settings.png) ![Hardware settings of the OPNsense VM in Proxmox](img/proxmox-cerbere-vm-settings.png)
Now I clone that VM to create `cerbere-head2`, then I proceed with OPNsense installation. I don't want to go into much details about OPNsense installation, I already documented it in the [proof of concept]({{< ref "post/12-opnsense-virtualization-highly-available" >}}). Maintenant je clone cette VM pour créer `cerbere-head2`, puis je procède à l'installation d'OPNsense. Je ne veux pas entrer trop dans les détails de l'installation d'OPNsense, je l'ai déjà documentée dans le [proof of concept]({{< ref "post/12-opnsense-virtualization-highly-available" >}}).
After the installation of both OPNsense instances, I give to each of them their IP in the *Mgmt* network: Après l'installation des deux instances OPNsense, j'attribue à chacune leur IP sur le réseau _Mgmt_ :
- `cerbere-head1`: `192.168.88.2/24` - `cerbere-head1` : `192.168.88.2/24`
- `cerbere-head2`: `192.168.88.3/24` - `cerbere-head2` : `192.168.88.3/24`
While these routers are not managing the networks, I give them my current OPNsense routeur as gateway (`192.168.88.1`) to allow me to reach them from my laptop in another VLAN. Tant que ces routeurs ne gèrent pas encore les réseaux, je leur donne comme passerelle mon routeur OPNsense actuel (`192.168.88.1`) pour me permettre de les atteindre depuis mon portable dans un autre VLAN.
--- ---
## Configure OPNsense ## Configuration d'OPNsense
Initially, I considered restoring my existing OPNsense configuration and adapt it to the setup. Initialement, j'envisageais de restaurer ma configuration OPNsense existante et de l'adapter à l'installation.
Then I decided to start over to document and share it. This part was getting so long that I prefered create a dedicated post instead. Puis j'ai décidé de repartir de zéro pour documenter et partager la procédure. Cette partie devenant trop longue, j'ai préféré créer un article dédié.
📖 You can find the details of the full OPNsense configuration in that [article]({{< ref "post/13-opnsense-full-configuration" >}}), covering HA, DNS, DHCP, VPN and reverse proxy. 📖 Vous pouvez trouver les détails de la configuration complète d'OPNsense dans cet [article]({{< ref "post/13-opnsense-full-configuration" >}}), couvrant HA, DNS, DHCP, VPN et reverse proxy.
--- ---
## Proxmox VM High Availability ## VM Proxmox Hautement Disponible
Resources (VM or LXC) in Proxmox VE can be tagged as highly available, let see how to set it up. Les ressources (VM ou LXC) dans Proxmox VE peuvent être marquées comme hautement disponibles, voyons comment les configurer.
### Proxmox HA Requirements ### Prérequis pour la HA Proxmox
First, your Proxmox cluster must allow it. There are some requirements: D'abord, votre cluster Proxmox doit le permettre. Il y a quelques exigences :
- At least 3 nodes to have quorum
- Shared storage for your resources
- Time synchronized
- Reliable network
A fencing mechanism must be enabled. Fencing is the process of isolating a failed cluster node to ensure it no longer accesses shared resources. This prevents split-brain situations and allows Proxmox HA to safely restart affected VMs on healthy nodes. By default, it is using Linux software watchdog, *softdog*, good enough for me. - Au moins 3 nœuds pour avoir le quorum
- Stockage partagé pour vos ressources
- Horloge synchronisée
- Réseau fiable
In Proxmox VE 8, It was possible to create HA groups, depending of their resources, locations, etc. This has been replaced, in Proxmox VE 9, by HA affinity rules. This is actually the main reason behind my Proxmox VE cluster upgrade, which I've detailed in that [post]({{< ref "post/14-proxmox-cluster-upgrade-8-to-9-ceph" >}}). Un mécanisme de fencing doit être activé. Le fencing est le processus d'isoler un nœud de cluster défaillant pour s'assurer qu'il n'accède plus aux ressources partagées. Cela évite les situations de split-brain et permet à Proxmox HA de redémarrer en toute sécurité les VM affectées sur des nœuds sains. Par défaut, il utilise le watchdog logiciel Linux, _softdog_, suffisant pour moi.
### Configure VM HA Dans Proxmox VE 8, il était possible de créer des groupes HA, en fonction de leurs ressources, emplacements, etc. Cela a été remplacé, dans Proxmox VE 9, par des règles d'affinité HA. C'est la raison principale derrière la mise à niveau de mon cluster Proxmox VE, que j'ai détaillée dans ce [post]({{< ref "post/14-proxmox-cluster-upgrade-8-to-9-ceph" >}}).
The Proxmox cluster is able to provide HA for the resources, but you need to define the rules. ### Configurer la HA pour les VM
In `Datacenter` > `HA`, you can see the status and manage the resources. In the `Resources` panel I click on `Add`. I need to pick the resource to configure as HA in the list, here `cerbere-head1` with ID 122. Then in the tooltip I can define the maximum of restart and relocate, I keep `Failback` enabled and the requested state to `started`: Le cluster Proxmox est capable de fournir de la HA pour les ressources, mais vous devez définir les règles.
Dans `Datacenter` > `HA`, vous pouvez voir le statut et gérer les ressources. Dans le panneau `Resources` je clique sur `Add`. Je dois choisir la ressource à configurer en HA dans la liste, ici `cerbere-head1` avec l'ID 122. Puis dans l'infobulle je peux définir le maximum de redémarrages et de relocations, je laisse `Failback` activé et l'état demandé à `started` :
![Create HA resource in Proxmox](img/proxmox-add-vm-ha.png) ![Create HA resource in Proxmox](img/proxmox-add-vm-ha.png)
The Proxmox cluster will now make sure this VM is started. I do the same for the other OPNsense VM, `cerbere-head2`. Le cluster Proxmox s'assurera maintenant que cette VM est démarrée. Je fais de même pour l'autre VM OPNsense, `cerbere-head2`.
### HA Affinity Rules ### Règles d'affinité HA
Great, but I don't want them on the same node. This is when the new feature HA affinity rules, of Proxmox VE 9, come in. Proxmox allows to create node affinity and resource affinity rules. I don't mind on which node they run, but I don't want them together. I need a resource affinity rule. Super, mais je ne veux pas qu'elles tournent sur le même nœud. C'est là qu'intervient la nouvelle fonctionnalité des règles d'affinité HA de Proxmox VE 9. Proxmox permet de créer des règles d'affinité de nœud et de ressource. Peu m'importe sur quel nœud elles tournent, mais je ne veux pas qu'elles soient ensemble. J'ai besoin d'une règle d'affinité de ressource.
In `Datacenter` > `HA` > `Affinity Rules`, I add a new HA resource affinity rule. I select both VMs and pick the option `Keep Separate`: Dans `Datacenter` > `HA` > `Affinity Rules`, j'ajoute une nouvelle règle d'affinité de ressource HA. Je sélectionne les deux VMs et choisis l'option `Keep Separate` :
![Create HA resource affinity in Proxmox](img/proxmox-ha-resource-affinity-rule.png) ![Create HA resource affinity in Proxmox](img/proxmox-ha-resource-affinity-rule.png)
✅ My OPNsense VMs are now fully ready! ✅ Mes VMs OPNsense sont maintenant entièrement prêtes !
--- ---
## Migration ## Migration
🚀 Time to make it real! 🚀 Il est temps de rendre cela réel !
I'm not gonna lie, I'm quite excited. I'm working for this moment for days. Je ne vais pas mentir, je suis assez excité. Je travaille pour ce moment depuis des jours.
### The Migration Plan ### Le Plan de Migration
I have my physical OPNsense box directly connected to my ISP box. I want to swap it for the VM cluster. To avoid writing the word OPNsense on each line, I'll simply name it the box and the VM. Ma box OPNsense physique est directement connectée à ma box FAI. Je veux la remplacer par le cluster de VM. (Pour éviter d'écrire le mot OPNsense à chaque ligne, j'appellerai simplement l'ancienne instance "la box" et la nouvelle "la VM" )
Here is the plan: Voici le plan :
1. Backup of the box configuration. 1. Sauvegarde de la configuration de la box.
2. Disable DHCP server on the box. 2. Désactiver le serveur DHCP sur la box.
3. Change IP addresses of the box. 3. Changer les adresses IP de la box.
4. Change VIP on the VM. 4. Changer les VIP sur la VM.
5. Disable gateway on VM. 5. Désactiver la passerelle sur la VM.
6. Configure DHCP on both VMs. 6. Configurer le DHCP sur les deux VMs.
7. Enable mDNS repeater on VM. 7. Activer le répéteur mDNS sur la VM.
8. Replicate services on VM. 8. Répliquer les services sur la VM.
9. Ethernet cable swap. 9. Déplacement du câble Ethernet.
### Rollback Strategy
None. 😎 ### Stratégie de Retour Arrière
I'm kidding, the rollback consists of restoring the box configuration, shutdown the OPNsense VMs and plug back the Ethernet cable into the box. Aucune. 😎
### Verification Plan Je plaisante, le retour arrière consiste à restaurer la configuration de la box, arrêter les VMs OPNsense et rebrancher le câble Ethernet dans la box.
To validate the migration, I'm drawing up a checklist: ### Plan de vérification
1. WAN DHCP lease in the VM.
2. Ping from my PC to the VIP of the User VLAN. Pour valider la migration, je dresse une checklist :
3. Ping cross VLAN. 1. Bail DHCP WAN dans la VM.
4. SSH into my machines. 2. Ping depuis mon PC vers le VIP du VLAN User.
5. Renew DHCP lease. 3. Ping entre les VLANs.
6. Check `ipconfig` 4. SSH vers mes machines.
7. Test internet website. 5. Renouveler le bail DHCP.
8. Check firewall logs. 6. Vérifier `ipconfig`
9. Check my webservices. 7. Tester l'accès à des sites internet.
10. Verify if my internal webservices are not accessible from outside. 8. Vérifier les logs du pare-feu.
11. Test VPN. 9. Vérifier mes services web.
12. Check all IoT devices. 10. Vérifier que mes services internes ne sont pas accessibles depuis l'extérieur.
13. Check Home Assistant features. 11. Tester le VPN.
14. Check if the TV works. 12. Vérifier tous les appareils IoT.
15. Test the Chromecast. 13. Vérifier les fonctionnalités Home Assistant.
16. Print something. 14. Vérifier que la TV fonctionne.
17. Verify DNS blocklist. 15. Tester le Chromecast.
16. Imprimer quelque chose.
17. Vérifier la blocklist DNS.
18. Speedtest. 18. Speedtest.
19. Switchover. 19. Bascule.
20. Failover. 20. Failover.
21. Disaster Recovery. 21. Reprise après sinistre.
22. Champaign! 22. Champagne !
Will it work? Let's find out! Est-ce que ça va marcher ? On verra bien !
### Migration Steps ### Étapes de Migration
1. **Backup of the box configuration.** 1. **Sauvegarde de la configuration de la box.**
On my physical OPNsense instance, in `System` > `Configuration` > `Backups`, I click the `Download configuration` button which give me the precious XML file. The one that saved my ass the [last time]({{< ref "post/10-opnsense-crash-disk-panic" >}}). Sur mon instance OPNsense physique, dans `System` > `Configuration` > `Backups`, je clique sur le bouton `Download configuration` qui me donne le précieux fichier XML. Celui qui m'a sauvé la mise la [dernière fois]({{< ref "post/10-opnsense-crash-disk-panic" >}}).
2. **Disable DHCP server on the box.** 2. **Désactiver le serveur DHCP sur la box.**
In `Services` > `ISC DHCPv4`, and for all my interfaces, I disable the DHCP server. I only serve DHCPv4 in my network. Dans `Services` > `ISC DHCPv4`, et pour toutes mes interfaces, je désactive le serveur DHCP. Je ne fournis que du DHCPv4 dans mon réseau.
3. **Change IP addresses of the box.** 3. **Changer les adresses IP de la box.**
In `Interfaces`, and for all my interfaces, I modify the IP of the firewall, from `.1` to `.253`. I want to reuse the same IP address as VIP, and have this instance still reachable if needed. Dans `Interfaces`, et pour toutes mes interfaces, je modifie l'IP du firewall, de `.1` à `.253`. Je veux réutiliser la même adresse IP comme VIP, et garder cette instance encore joignable si besoin.
As soon as I click on `Apply`, I lost the communication, which is expected. Dès que je clique sur `Apply`, je perds la communication, ce qui est attendu.
4. **Change VIP on the VM.** 4. **Changer les VIP sur la VM.**
On my master VM, In `Interfaces` > `Virtual IPs` > `Settings`, I change the VIP address for each interface and set it to `.1`. Sur ma VM maître, dans `Interfaces` > `Virtual IPs` > `Settings`, je change l'adresse VIP pour chaque interface et la mets en `.1`.
5. **Disable gateway on VM.** 5. **Désactiver la passerelle sur la VM.**
In `System` > `Gateways` > `Configuration`, I disable the `LAN_GW` which is not needed anymore. Dans `System` > `Gateways` > `Configuration`, je désactive `LAN_GW` qui n'est plus nécessaire.
6. **Configure DHCP on both VMs.** 6. **Configurer le DHCP sur les deux VMs.**
In both VM, in `Services` > `Dnsmasq DNS & DHCP`, I enable the service on my 5 interfaces. Sur les deux VMs, dans `Services` > `Dnsmasq DNS & DHCP`, j'active le service sur mes 5 interfaces.
7. **Enable mDNS repeater on VM.** 7. **Activer le répéteur mDNS sur la VM.**
In `Services` > `mDNS Repeater`, I enable the service and also enable CARP Failover. Dans `Services` > `mDNS Repeater`, j'active le service et j'active aussi le `CARP Failover`.
The service does not start. I'll see that problem later. Le service ne démarre pas. Je verrai ce problème plus tard.
8. **Replicate services on VM.** 8. **Répliquer les services sur la VM.**
In `System` > `High Availability` > `Status`, I click the button to `Synchronize and reconfigure all`. Dans `Système` > `High Availability` > `Status`, je clique sur le bouton `Synchronize and reconfigure all`.
9. **Ethernet cable swap.** 9. **Déplacement du câble Ethernet.**
Physically in my rack, I unplug the Ethernet cable from the WAN port (`igc0`) of my physical OPNsense box and plug it into the port 15 of my UniFi switch. Physiquement dans mon rack, je débranche le câble Ethernet du port WAN (`igc0`) de ma box OPNsense physique et je le branche sur le port 15 de mon switch UniFi.
--- ---
## Verification ## Vérification
😮‍💨 I take a deep breath and start the verification phase. 😮‍💨 Je prends une grande inspiration et commence la phase de vérification.
### Checklist ### Checklist
-WAN DHCP lease in the VM. -Bail DHCP WAN dans la VM.
- ✅ Ping from my PC to the VIP of the User VLAN. - ✅ Ping depuis mon PC vers le VIP du VLAN User.
- ⚠️ Ping cross VLAN. - ⚠️ Ping entre VLANs.
Pings are working, but I observe some drops, about 10%. Les pings fonctionnent, mais j'observe quelques pertes, environ 10 %.
- ✅ SSH into my machines. - ✅ SSH vers mes machines.
- ✅ Renew DHCP lease. - ✅ Renouvellement du bail DHCP.
-Check `ipconfig` -Vérifier `ipconfig`
- ❌ Test internet website. → ✅ - ❌ Tester un site internet. → ✅
A few websites are working, everything is incredibly slow... It must be the DNS. I try to lookup a random domain, it is working. But I can't lookup google.com. I restart the Unbound DNS service, everything works now. It is always the DNS. Quelques sites fonctionnent, tout est incroyablement lent... Ça doit être le DNS. J'essaie de résoudre un domaine au hasard, ça marche. Mais je ne peux pas résoudre `google.com`. Je redémarre le service Unbound DNS, tout fonctionne maintenant. C'est toujours le DNS...
- ⚠️ Check firewall logs. - ⚠️ Vérifier les logs du pare-feu.
Few flows are blocks, not mandatory. Quelques flux sont bloqués, pas critique.
-Check my webservices. - Vérifier mes services web.
-Verify if my internal webservices are not accessible from outside. - Vérifier que mes services internes ne sont pas accessibles depuis l'extérieur.
- ✅ Test VPN. - ✅ Tester le VPN.
-Check all IoT devices. -Vérifier tous les appareils IoT.
-Check Home Assistant features. -Vérifier les fonctionnalités Home Assistant.
-Check if the TV works. - Vérifier que la TV fonctionne.
- ❌ Test the Chromecast. - ❌ Tester le Chromecast.
It is related to the mDNS service not able to start. I can start it if I uncheck the `CARP Failover` option. the Chromecast is visible now. → ⚠️ C'est lié au service mDNS qui ne parvient pas à démarrer. Je peux le démarrer si je décoche l'option `CARP Failover`. Le Chromecast est visible maintenant. → ⚠️
-Print something. - Imprimer quelque chose.
-Verify DNS blocklist. - Vérifier la blocklist DNS.
- ✅ Speedtest. - ✅ Speedtest.
I observe roughly 15% of decrease bandwidth (from 940Mbps to 825Mbps). J'observe environ 15 % de diminution de bande passante (de 940Mbps à 825Mbps).
-Switchover. -Bascule.
The switchover barely works, a lot of dropped packets during the switch. The service provided is not great: no more internet and my webservices are not reachable. La bascule fonctionne difficilement, beaucoup de paquets perdus pendant la bascule. Le service rendu n'est pas génial : plus d'accès internet et mes services web sont inaccessibles.
- ⌛ Failover. - ⌛ Failover.
-Disaster Recovery. -Reprise après sinistre.
To be tested later. À tester plus tard.
📝 Well, the results are pretty good, not perfect, but satisfying! 📝 Bon, les résultats sont plutôt bons, pas parfaits, mais satisfaisants !
### Problem Solving ### Résolution des Problèmes
I focus on resolving remaining problems experienced during the tests. Je me concentre sur la résolution des problèmes restants rencontrés lors des tests.
1. **DNS** 1. **DNS**
During the switchover, the internet connection is not working. No DNS, it is always DNS. Lors de la bascule, la connexion internet ne fonctionne pas. Pas de DNS, c'est toujours le DNS.
It's because the backup node does not have a gateway while passive. No gateway prevents the DNS to resolve. After the switchover, it still has unresolved domains in its cache. This problem also lead to another issue, while passive, I can't update the system. C'est parce que le nœud de secours n'a pas de passerelle lorsqu'il est en mode passif. L'absence de passerelle empêche le DNS de résoudre. Après la bascule, il conserve des domaines non résolus dans son cache. Ce problème conduit aussi à un autre souci : quand il est passif, je ne peux pas mettre à jour le système.
**Solution**: Set a gateway in the *Mgmt* interface pointing to the other node, with a higher priority number than the WAN gateway (higher number means lower priority). This way, that gateway is not active while the node is master. **Solution** : Définir une passerelle sur l'interface _Mgmt_ pointant vers l'autre nœud, avec un numéro de priorité plus élevé que la passerelle WAN (un numéro plus élevé signifie une priorité plus basse). Ainsi, cette passerelle n'est pas active tant que le nœud est maître.
2. **Reverse Proxy** 2. **Reverse Proxy**
During the switchover, every webservices which I host (reverse proxy/layer 4 proxy) give this error: `SSL_ERROR_INTERNAL_ERROR_ALERT`. After checking the services synchronized throught XMLRPC Sync, Caddy and mDNS-repeater were not selected. It is because these services were installed after the initial configuration of the HA. Lors de la bascule, tous les services web que j'héberge (reverse proxy/proxy couche 4) renvoient cette erreur : `SSL_ERROR_INTERNAL_ERROR_ALERT`. Après vérification des services synchronisés via XMLRPC Sync, Caddy et mDNS repeater n'étaient pas sélectionnés. C'est parce que ces services ont été installés après la configuration initiale du HA.
**Solution**: Add Caddy to XMLRPC Sync. **Solution** : Ajouter Caddy à XMLRPC Sync.
3. **Packet Drops** 3. **Pertes de paquets**
I observe about 10% packet drops for pings from any VLAN to the *Mgmt* VLAN. I don't have this problem for the other VLANs. J'observe environ 10 % de pertes de paquets pour les pings depuis n'importe quel VLAN vers le VLAN _Mgmt_. Je n'ai pas ce problème pour les autres VLANs.
The *Mgmt* VLAN is the native one in my network, it might be the reason behind this issue. This is the only network not defined in the Proxmox SDN. I don't want to have to tag this VLAN. Le VLAN _Mgmt_ est le VLAN natif dans mon réseau, cela pourrait être la raison de ce problème. C'est le seul réseau non défini dans le SDN Proxmox. Je ne veux pas avoir à tagger ce VLAN.
**Solution**: Disable the Proxmox firewall of this interface for the VM. I actually disable them all and update the documentation above. I'm not sure why this cause that kind of problem, but disabling it fixed my issue (I could reproduce the behavior while activating the firewall again). **Solution** : Désactiver le pare-feu Proxmox de cette interface pour la VM. En réalité, je les ai tous désactivés et mis à jour la documentation ci-dessus. Je ne sais pas exactement pourquoi cela causait ce type de problème, mais la désactivation a résolu mon souci (j'ai pu reproduire le comportement en réactivant le pare-feu).
4. **CARP Script** 4. **Script CARP**
During a switchover, the CARP event script is triggered as many times as the number of interfaces. I have 5 virtual IPs, the script reconfigure my WAN interface 5 times. Lors de la bascule, le script d'événement CARP est déclenché autant de fois qu'il y a d'interfaces. J'ai 5 IPs virtuelles, le script reconfigure mon interface WAN 5 fois.
**Solution**: Rework the script to get the WAN interface state and only reconfigure the inteface when needed: **Solution** : Retravailler le script pour récupérer l'état de l'interface WAN et ne reconfigurer l'interface que lorsque c'est nécessaire :
```php ```php
#!/usr/local/bin/php #!/usr/local/bin/php
<?php <?php
@@ -355,65 +358,65 @@ if ($type === "MASTER") {
5. **mDNS Repeater** 5. **mDNS Repeater**
The mDNS repeater does not want to start when I select the option for `CARP Failover`. Le répéteur mDNS ne veut pas démarrer quand je sélectionne l'option `CARP Failover`.
**Solution**: The machine requires a reboot to start this service CARP aware. **Solution** : La machine nécessite un redémarrage pour démarrer ce service compatible CARP.
6. **IPv6 Address** 6. **Adresse IPv6**
My `cerbere-head1` node is crying in the log file while the other does not. Here are the messages spit every seconds while it is master: Mon nœud `cerbere-head1` crie dans le fichier de logs tandis que l'autre ne le fait pas. Voici les messages affichés chaque seconde quand il est maître :
```plaintext ```plaintext
Warning rtsold <interface_up> vtnet1 is disabled. in the logs (OPNsense) Warning rtsold <interface_up> vtnet1 is disabled. in the logs (OPNsense)
``` ```
Another one I'm having several times after a switchback: Un autre message que j'ai plusieurs fois après un switchback :
```plaintext ```plaintext
Error dhcp6c transmit failed: Can't assign requested address Error dhcp6c transmit failed: Can't assign requested address
``` ```
This is related to IPv6. I observe that my main node does not have a global IPv6 address, only a link-local. Also, it does not have a IPv6 gateway. My secondary node, in the other hand, has both addresses and the gateway. Ceci est lié à IPv6. J'observe que mon nœud principal n'a pas d'adresse IPv6 globale, seulement une link-local. De plus, il n'a pas de passerelle IPv6. Mon nœud secondaire, en revanche, a à la fois l'adresse globale et la passerelle.
I'm no IPv6 expert, after searching for a couple of hours, I give up the IPv6. If someone out here can help, it would be really appreciated! Je ne suis pas expert IPv6, après quelques heures de recherche, j'abandonne IPv6. Si quelqu'un peut m'aider, ce serait vraiment apprécié !
**Workaround**: Remove DHCPv6 for my WAN interface. **Contournement** : Supprimer DHCPv6 pour mon interface WAN.
### Confirmation ### Confirmation
Now that everything is fixed, I can evaluate the failover performance. Maintenant que tout est corrigé, je peux évaluer les performances du failover.
1. **Switchover** 1. **Basculement**
When manually entering CARP maintenance mode from the WebGUI interface, no packet drop is observed. Impressive. En entrant manuellement en mode maintenance CARP depuis l'interface WebGUI, aucune perte de paquets n'est observée. Impressionnant.
2. Failover 2. **Failover**
To simulate a failover, I kill the active OPNsense VM. Here I observe only one packet dropped. Awesome. Pour simuler un failover, je tue la VM OPNsense active. Ici j'observe une seule perte de paquet. Génial.
![Ping test during OPNsense CARP failover](img/opnsense-ping-failover.png) ![Ping test during OPNsense CARP failover](img/opnsense-ping-failover.png)
3. Disaster Recovery 3. **Reprise après sinistre**
A disaster recovery is what would happen after a full Proxmox cluster stop, after an electrical outage for example. I didn't have the time (or the courage) to do that, I'd prefer to prepare a bit better to avoid collateral damages. But surely, this kind of scenario must be evaluated. Une reprise après sinistre est ce qui se produirait après un arrêt complet d'un cluster Proxmox, suite à une coupure de courant par exemple. Je n'ai pas eu le temps (ni le courage) de m'en occuper, je préfère mieux me préparer pour éviter les dommages collatéraux. Mais il est certain que ce genre de scénario doit être évalué.
### Extras #### Avantages Supplémentaires
Leaving aside the fact that this new setup is more resilient, I have few more bonuses. Outre le fait que cette nouvelle configuration est plus résiliente, j'ai constaté quelques autres avantages.
My rack is tiny and the space is tight. The whole thing is heating quite much, exceeding 40°C on top of the rack in summer. Reducing the number of machines powered up lower the temperature. I've gained **1,5°C** after shutting down the old OPNsense box, cool! Mon rack est minuscule et l'espace est restreint. L'ensemble chauffe beaucoup, dépassant les 40 °C au sommet du rack en été. Réduire le nombre de machines allumées a permis de faire baisser la température. J'ai gagné 1,5 °C après avoir éteint l'ancien boîtier OPNsense, c'est super !
Power consumption is also a concern, my tiny datacenter was drawing 85W on average. Here again I could observe a small decrease, about 8W lower. Considering that this run 24/7, not negligible. La consommation électrique est également un point important, mon petit datacenter consommait en moyenne 85 W. Là encore, j'ai constaté une légère baisse, d'environ 8 W. Sachant que le système fonctionne 24/7, ce n'est pas négligeable.
Finally I also removed the box itself and the power cable. Slots are very limited, another good point. Enfin, j'ai également retiré le boîtier lui-même et le câble d'alimentation. Les places sont très limitées, ce qui est un autre point positif.
--- ---
## Conclusion ## Conclusion
🎉 I did it guys! I'm very proud of the results, proud of myself. 🎉 J'ai réussi les gars ! Je suis très fier du résultat, et fier de moi.
From my [first OPNsense box crash]({{< ref "post/10-opnsense-crash-disk-panic" >}}), the thinking about a solution, the HA [proof of concept]({{< ref "post/12-opnsense-virtualization-highly-available" >}}), to this migration. This has been a quite long project, but extremly interesting. De mon [premier crash de ma box OPNsense]({{< ref "post/10-opnsense-crash-disk-panic" >}}), à la recherche d'une solution, en passant par la [proof of concept]({{< ref "post/12-opnsense-virtualization-highly-available" >}}) de haute disponibilité, jusqu'à cette migration, ce fut un projet assez long, mais extrêmement intéressant.
🎯 This is great to set objectives, but this is even better when you reach them. 🎯 Se fixer des objectifs, c'est bien, mais les atteindre, c'est encore mieux.
Now I'm going to leave OPNsense aside for a bit, to be able to re-focus on my Kubernetes journey! Je vais maintenant mettre OPNsense de côté un petit moment pour me recentrer sur mon apprentissage de Kubernetes !
As always, if you have questions, remarks or a solution for my IPv6 problem, I'll be really happy to share with you. Comme toujours, si vous avez des questions, des remarques ou une solution à mon problème d'IPv6, je serai ravi de vous aider.

View File

@@ -17,7 +17,7 @@ This is the final stage of my **OPNsense** virtualization journey.
A few months ago, my physical [OPNsense box crashed]({{< ref "post/10-opnsense-crash-disk-panic" >}}) because of a hardware failure. This leads my home in the dark, literally. No network, no lights. A few months ago, my physical [OPNsense box crashed]({{< ref "post/10-opnsense-crash-disk-panic" >}}) because of a hardware failure. This leads my home in the dark, literally. No network, no lights.
💡 To avoid being in that situation again, I imagined a way to virtualize my OPNsense firewall into my **Proxmox VE** cluster. The last time, I've set up a [proof of concept]({{< ref "post/12-opnsense-virtualization-highly-available" >}}) to validate this solution: create a cluster of two **OPNsense** VMs in Proxmox and make the firewall highly available. 💡 To avoid being in that situation again, I imagined a plan to virtualize my OPNsense firewall into my **Proxmox VE** cluster. The last time, I've set up a [proof of concept]({{< ref "post/12-opnsense-virtualization-highly-available" >}}) to validate this solution: create a cluster of two **OPNsense** VMs in Proxmox and make the firewall highly available.
This time, I will cover the creation of my future OPNsense cluster from scratch, plan the cut over and finally migrate from my current physical box. Let's go! This time, I will cover the creation of my future OPNsense cluster from scratch, plan the cut over and finally migrate from my current physical box. Let's go!
@@ -38,7 +38,7 @@ In the UniFi controller, in `Settings` > `Networks`, I add a `New Virtual Networ
I do the same thing again for the `pfSync` VLAN with the VLAN ID 44. I do the same thing again for the `pfSync` VLAN with the VLAN ID 44.
I plan to plug my ISP box on the port 15 of my switch, which is disabled for now. I set it as active, set the native VLAN on the newly created one `WAN (20)` and disable trunking: I plan to plug my ISP box on the port 15 of my switch, which is disabled for now. I set it as active, set the native VLAN on the newly created one `WAN (20)` and disable trunking:
![Configuration of the UniFi switch port for the WAN uplink](img/unifi-enable-port-wan-vlan.png) ![Configuration du port du switch UniFi pour la liaison WAN](img/unifi-enable-port-wan-vlan.png)
Once this setting applied, I make sure that only the ports where are connected my Proxmox nodes propagate these VLAN on their trunk. Once this setting applied, I make sure that only the ports where are connected my Proxmox nodes propagate these VLAN on their trunk.
@@ -62,8 +62,8 @@ The first VM is named `cerbere-head1` (I didn't tell you? My current firewall is
- **OS type**: Linux (even if OPNsense is based on FreeBSD) - **OS type**: Linux (even if OPNsense is based on FreeBSD)
- **Machine type**: `q35` - **Machine type**: `q35`
- **BIOS**: `OVMF (UEFI)` - **BIOS**: `OVMF (UEFI)`
- **Disk**: 20 GiB on Ceph distributed storage - **Disk**: 20 GB on Ceph distributed storage
- **RAM**: 4 GiB RAM, ballooning disabled - **RAM**: 4 GB RAM, ballooning disabled
- **CPU**: 2 vCPU - **CPU**: 2 vCPU
- **NICs**, firewall disabled: - **NICs**, firewall disabled:
1. `vmbr0` (*Mgmt*) 1. `vmbr0` (*Mgmt*)
@@ -81,7 +81,7 @@ After the installation of both OPNsense instances, I give to each of them their
- `cerbere-head1`: `192.168.88.2/24` - `cerbere-head1`: `192.168.88.2/24`
- `cerbere-head2`: `192.168.88.3/24` - `cerbere-head2`: `192.168.88.3/24`
While these routers are not managing the networks, I give them my current OPNsense routeur as gateway (`192.168.88.1`) to allow me to reach them from my laptop in another VLAN. I give them the other OPNsense node as gateway (`192.168.88.1`) to allow me to reach them from my laptop in another VLAN.
--- ---
## Configure OPNsense ## Configure OPNsense
@@ -136,7 +136,7 @@ I'm not gonna lie, I'm quite excited. I'm working for this moment for days.
### The Migration Plan ### The Migration Plan
I have my physical OPNsense box directly connected to my ISP box. I want to swap it for the VM cluster. To avoid writing the word OPNsense on each line, I'll simply name it the box and the VM. I have my physical OPNsense box directly connected to my ISP box. I want to swap it for the VM cluster. (To avoid writing the word OPNsense on each line, I'll simply name it "the box" and "the VM")
Here is the plan: Here is the plan:
1. Backup of the box configuration. 1. Backup of the box configuration.
@@ -147,7 +147,7 @@ Here is the plan:
6. Configure DHCP on both VMs. 6. Configure DHCP on both VMs.
7. Enable mDNS repeater on VM. 7. Enable mDNS repeater on VM.
8. Replicate services on VM. 8. Replicate services on VM.
9. Ethernet cable swap. 9. Move of the Ethernet cable.
### Rollback Strategy ### Rollback Strategy
None. 😎 None. 😎
@@ -220,7 +220,7 @@ The service does not start. I'll see that problem later.
In `System` > `High Availability` > `Status`, I click the button to `Synchronize and reconfigure all`. In `System` > `High Availability` > `Status`, I click the button to `Synchronize and reconfigure all`.
9. **Ethernet cable swap.** 9. **Move of the Ethernet cable.**
Physically in my rack, I unplug the Ethernet cable from the WAN port (`igc0`) of my physical OPNsense box and plug it into the port 15 of my UniFi switch. Physically in my rack, I unplug the Ethernet cable from the WAN port (`igc0`) of my physical OPNsense box and plug it into the port 15 of my UniFi switch.
@@ -239,7 +239,7 @@ Pings are working, but I observe some drops, about 10%.
- ✅ Renew DHCP lease. - ✅ Renew DHCP lease.
- ✅ Check `ipconfig` - ✅ Check `ipconfig`
- ❌ Test internet website. → ✅ - ❌ Test internet website. → ✅
A few websites are working, everything is incredibly slow... It must be the DNS. I try to lookup a random domain, it is working. But I can't lookup google.com. I restart the Unbound DNS service, everything works now. It is always the DNS. A few websites are working, everything is incredibly slow... It must be the DNS. I try to lookup a random domain, it is working. But I can't lookup `google.com`. I restart the Unbound DNS service, everything works now. It is always the DNS...
- ⚠️ Check firewall logs. - ⚠️ Check firewall logs.
Few flows are blocks, not mandatory. Few flows are blocks, not mandatory.
- ✅Check my webservices. - ✅Check my webservices.
@@ -275,7 +275,7 @@ It's because the backup node does not have a gateway while passive. No gateway p
2. **Reverse Proxy** 2. **Reverse Proxy**
During the switchover, every webservices which I host (reverse proxy/layer 4 proxy) give this error: `SSL_ERROR_INTERNAL_ERROR_ALERT`. After checking the services synchronized throught XMLRPC Sync, Caddy and mDNS-repeater were not selected. It is because these services were installed after the initial configuration of the HA. During the switchover, every webservices which I host (reverse proxy/layer 4 proxy) give this error: `SSL_ERROR_INTERNAL_ERROR_ALERT`. After checking the services synchronized throught XMLRPC Sync, Caddy and mDNS repeater were not selected. It is because these services were installed after the initial configuration of the HA.
**Solution**: Add Caddy to XMLRPC Sync. **Solution**: Add Caddy to XMLRPC Sync.
@@ -385,17 +385,17 @@ Now that everything is fixed, I can evaluate the failover performance.
When manually entering CARP maintenance mode from the WebGUI interface, no packet drop is observed. Impressive. When manually entering CARP maintenance mode from the WebGUI interface, no packet drop is observed. Impressive.
2. Failover 2. **Failover**
To simulate a failover, I kill the active OPNsense VM. Here I observe only one packet dropped. Awesome. To simulate a failover, I kill the active OPNsense VM. Here I observe only one packet dropped. Awesome.
![Ping test during OPNsense CARP failover](img/opnsense-ping-failover.png) ![Ping test during OPNsense CARP failover](img/opnsense-ping-failover.png)
3. Disaster Recovery 3. **Disaster Recovery**
A disaster recovery is what would happen after a full Proxmox cluster stop, after an electrical outage for example. I didn't have the time (or the courage) to do that, I'd prefer to prepare a bit better to avoid collateral damages. But surely, this kind of scenario must be evaluated. A disaster recovery is what would happen after a full Proxmox cluster stop, after an electrical outage for example. I didn't have the time (or the courage) to do that, I'd prefer to prepare a bit better to avoid collateral damages. But surely, this kind of scenario must be evaluated.
### Extras ### Extras Benefits
Leaving aside the fact that this new setup is more resilient, I have few more bonuses. Leaving aside the fact that this new setup is more resilient, I have few more bonuses.