<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://agora.nasqueron.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Yousra</id>
	<title>Nasqueron Agora - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://agora.nasqueron.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Yousra"/>
	<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/Special:Contributions/Yousra"/>
	<updated>2026-04-08T17:46:53Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.46.0-alpha</generator>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2514</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2514"/>
		<updated>2026-03-29T18:27:37Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;apps/network/carp-hyper-001-switch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by router-002 and router-003.  They are then used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP). The script authenticates to Vault using AppRole (via secretsmith) to retrieve them.&lt;br /&gt;
&lt;br /&gt;
The AppRole credentials (role_id and secret_id) used by the script are stored in:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ops/secrets/network/router/vault&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Vault secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt. &lt;br /&gt;
&lt;br /&gt;
The Vault Secrets may need to be rotated, so we need a simple way to propagate&lt;br /&gt;
updated credentials to routers. This is enabled by the mechanism&lt;br /&gt;
introduced in D4026.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2513</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2513"/>
		<updated>2026-03-29T15:11:03Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;apps/network/carp-hyper-001-switch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by router-002 and router-003.  They are then used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP). The script authenticates to Vault using AppRole (via secretsmith) to retrieve them.&lt;br /&gt;
&lt;br /&gt;
The AppRole credentials (role_id and secret_id) used by the script are stored in:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ops/secrets/network/router/vault&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Vault secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt. This done easily thanks to Linked to {{D|4026}}.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2512</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2512"/>
		<updated>2026-03-29T15:04:21Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;apps/network/carp-hyper-001-switch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by router-002 and router-003.  They are then used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP). The script authenticates to Vault using AppRole (via secretsmith) to retrieve them.&lt;br /&gt;
&lt;br /&gt;
The AppRole credentials (role_id and secret_id) used by the script are stored in:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ops/secrets/network/router/vault&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Vault secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt. This done easily thanks to Linked to {{D|4026}}.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When rotating the secrets OVH :&lt;br /&gt;
&lt;br /&gt;
* Terraform must be applied again to update the secrets in Vault&lt;br /&gt;
&lt;br /&gt;
Failing to do so may cause CARP failover to break due to invalid OVH credentials or expired Vault authentication.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2511</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2511"/>
		<updated>2026-03-29T15:02:37Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;apps/network/carp-hyper-001-switch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by router-002 and router-003.  They are then used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP). The script authenticates to Vault using AppRole (via secretsmith) to retrieve them.&lt;br /&gt;
&lt;br /&gt;
The AppRole credentials (role_id and secret_id) used by the script are stored in:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ops/secrets/network/router/vault&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Vault secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt. This done easily thanks to Linked to {{D|4026}}.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When rotating Vault secrets managed through Terraform:&lt;br /&gt;
&lt;br /&gt;
* Terraform must be applied again to update them in Vault&lt;br /&gt;
* if Vault AppRole credentials are changed, they must also be propagated to the routers using Salt&lt;br /&gt;
&lt;br /&gt;
When rotating the secrets OVH :&lt;br /&gt;
&lt;br /&gt;
* Terraform must be applied again to update the secrets in Vault&lt;br /&gt;
&lt;br /&gt;
Failing to do so may cause CARP failover to break due to invalid OVH credentials or expired Vault authentication.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2510</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2510"/>
		<updated>2026-03-29T15:01:12Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;apps/network/carp-hyper-001-switch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by router-002 and router-003.  They are then used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP). The script authenticates to Vault using AppRole (via secretsmith) to retrieve them.&lt;br /&gt;
&lt;br /&gt;
The AppRole credentials (role_id and secret_id) used by the script are stored in:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ops/secrets/network/router/vault&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Vault secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt. This done thanks to Linked to {{D|4026}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When rotating Vault secrets managed through Terraform:&lt;br /&gt;
&lt;br /&gt;
* Terraform must be applied again to update them in Vault&lt;br /&gt;
* if Vault AppRole credentials are changed, they must also be propagated to the routers using Salt&lt;br /&gt;
&lt;br /&gt;
When rotating the secrets OVH :&lt;br /&gt;
&lt;br /&gt;
* Terraform must be applied again to update the secrets in Vault&lt;br /&gt;
&lt;br /&gt;
Failing to do so may cause CARP failover to break due to invalid OVH credentials or expired Vault authentication.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2509</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2509"/>
		<updated>2026-03-29T15:00:53Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* ESXI and CARP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later implemented directly in the kernel of other BSD systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer, a counter&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the CARP priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Address Multicast CARP ==&lt;br /&gt;
&lt;br /&gt;
In the Common Address Redundancy Protocol (CARP), routers communicate with each other using a multicast address. CARP advertisements are sent to the IPv4 multicast address &#039;&#039;&#039;224.0.0.18&#039;&#039;&#039;, which allows all routers participating in the CARP group to receive the messages simultaneously. At the Ethernet level, this multicast IP address corresponds to the multicast MAC address &#039;&#039;&#039;01:00:5e:00:00:12&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Preemption ==&lt;br /&gt;
&lt;br /&gt;
In fact, after some research, I discovered that on FreeBSD, the preemption behavior of CARP (Common Address Redundancy Protocol) is controlled by the kernel parameter net.inet.carp.preempt. This parameter allows a router with a higher priority (a lower advskew) to become MASTER, even if another router is already active in that role or if the real Master was restart after. To check if preemption is enabled, you can use the command  : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;sysctl net.inet.carp.preempt&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If the returned value is 0, preemption is disabled, and the currently MASTER router will retain that role as long as it continues to send its CARP advertisements. &lt;br /&gt;
&lt;br /&gt;
To temporarily enable preemption, simply run : &#039;&#039;&#039;sysctl net.inet.carp.preempt=1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To make this behavior permanent, you must add the line &#039;&#039;&#039;net.inet.carp.preempt=1&#039;&#039;&#039; to the /etc/sysctl.conf file. &lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?carp(4)&lt;br /&gt;
&lt;br /&gt;
https://vincentdelft.be/post/post_20241115&lt;br /&gt;
&lt;br /&gt;
== Peer ==&lt;br /&gt;
&lt;br /&gt;
By default, CARP uses multicast to send advertisements. However, multicast traffic can be filtered, restricted and so unreliable. Configuring CARP to use unicast advertisements between peers can help ensure more stable and predictable high-availability operation.&lt;br /&gt;
&lt;br /&gt;
In addition to that, using CARP in unicast mode can be appropriate in a two-router topology, as communication only needs to occur between 2 specific peers.&lt;br /&gt;
&lt;br /&gt;
Above all IPsec (security added in a classic tunnel) protects unicast traffic, it does not protect (or protects very poorly) multicast traffic. So if we want CARP to be used with IPsec, peer is an excellent choice.&lt;br /&gt;
&lt;br /&gt;
Router-002 : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass seediez7ae7LooFevohshae4oot0EeR peer 178.32.70.111 alias 51.68.252.230/32&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Router-003 : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass seediez7ae7LooFevohshae4oot0EeR peer 178.32.70.110 alias 51.68.252.230/32&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We see that the Master router-003 sends advertissements to router-002.nasqueron.org/178.32.70.110 &lt;br /&gt;
[[ File:Peer.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?query=carp&lt;br /&gt;
&lt;br /&gt;
https://docs.opnsense.org/manual/how-tos/carp.html&lt;br /&gt;
&lt;br /&gt;
https://www.kernel-panic.it/openbsd/carp/carp4.html&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the Master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the Master router. When a failover occurs, the Backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2508</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2508"/>
		<updated>2026-03-29T14:34:51Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;apps/network/carp-hyper-001-switch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by router-002 and router-003.  They are then used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP). The script authenticates to Vault using AppRole (via secretsmith) to retrieve them.&lt;br /&gt;
&lt;br /&gt;
The AppRole credentials (role_id and secret_id) used by the script are stored in:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ops/secrets/network/router/vault&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Vault secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When rotating the secrets OVH :&lt;br /&gt;
&lt;br /&gt;
* Terraform must be applied again to update the secrets in Vault&lt;br /&gt;
&lt;br /&gt;
Failing to do so may cause CARP failover to break due to invalid OVH credentials or expired Vault authentication.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2507</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2507"/>
		<updated>2026-03-29T14:33:57Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;apps/network/carp-hyper-001-switch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by router-002 and router-003.  They are then used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP). The script authenticates to Vault using AppRole (via secretsmith) to retrieve them.&lt;br /&gt;
&lt;br /&gt;
The AppRole credentials (role_id and secret_id) used by the script are stored in:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ops/secrets/network/router/vault&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Vault secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When rotating the secrets Vault or OVH :&lt;br /&gt;
&lt;br /&gt;
* Terraform must be applied again to update the secrets in Vault&lt;br /&gt;
&lt;br /&gt;
Failing to do so may cause CARP failover to break due to invalid OVH credentials or expired Vault authentication.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2506</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2506"/>
		<updated>2026-03-29T14:33:11Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;apps/network/carp-hyper-001-switch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by router-002 and router-003.  They are then used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP). The script authenticates to Vault using AppRole (via secretsmith) to retrieve them.&lt;br /&gt;
&lt;br /&gt;
The AppRole credentials (role_id and secret_id) used by the script are stored in:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ops/secrets/network/router/vault&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Vault secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
When rotating the secrets:&lt;br /&gt;
&lt;br /&gt;
* Terraform must be applied again to update the secrets in Vault&lt;br /&gt;
&lt;br /&gt;
Failing to do so may cause CARP failover to break due to invalid OVH credentials or expired Vault authentication.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2505</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2505"/>
		<updated>2026-03-29T14:29:49Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;apps/network/carp-hyper-001-switch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by router-002 and router-003.  They are then used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP). The script authenticates to Vault using AppRole (via secretsmith) to retrieve them.&lt;br /&gt;
&lt;br /&gt;
The AppRole credentials (role_id and secret_id) used by the script are stored in:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ops/secrets/network/router/vault&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
When rotating the secrets:&lt;br /&gt;
&lt;br /&gt;
* Terraform must be applied again to update the secrets in Vault&lt;br /&gt;
&lt;br /&gt;
Failing to do so may cause CARP failover to break due to invalid OVH credentials or expired Vault authentication.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2504</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2504"/>
		<updated>2026-03-29T14:24:27Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;apps/network/carp-hyper-001-switch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by router-002 and router-003.  They are then used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP). The script authenticates to Vault using AppRole (via secretsmith) to retrieve them.&lt;br /&gt;
&lt;br /&gt;
The AppRole credentials (role_id and secret_id) used by the script are stored in:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ops/secrets/network/router/vault&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are provisioned via Terraform and deployed to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
Secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
When rotating these secrets:&lt;br /&gt;
&lt;br /&gt;
* Terraform must be applied again to update the secrets in Vault&lt;br /&gt;
* Salt states must be re-applied to propagate updated AppRole credentials to the routers&lt;br /&gt;
&lt;br /&gt;
Failing to do so may cause CARP failover to break due to invalid OVH credentials or expired Vault authentication.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2503</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2503"/>
		<updated>2026-03-29T14:22:45Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;apps/network/carp-hyper-001-switch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by router-002 and router-003.  &lt;br /&gt;
The script authenticates to Vault using AppRole (via secretsmith) to retrieve them.&lt;br /&gt;
&lt;br /&gt;
They are then used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP).&lt;br /&gt;
&lt;br /&gt;
The AppRole credentials (role_id and secret_id) used by the routers are stored in:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ops/secrets/network/router/vault&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are provisioned via Terraform and deployed to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
Secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
When rotating these secrets:&lt;br /&gt;
&lt;br /&gt;
* Terraform must be applied again to update the secrets in Vault&lt;br /&gt;
* Salt states must be re-applied to propagate updated AppRole credentials to the routers&lt;br /&gt;
&lt;br /&gt;
Failing to do so may cause CARP failover to break due to invalid OVH credentials or expired Vault authentication.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2502</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2502"/>
		<updated>2026-03-29T14:21:13Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;apps/network/carp-hyper-001-switch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by router-002 and router-003 using AppRole authentication (via secretsmith).  &lt;br /&gt;
They are used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP).&lt;br /&gt;
&lt;br /&gt;
The AppRole credentials (role_id and secret_id) used by the routers are stored in:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ops/secrets/network/router/vault&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are provisioned via Terraform and deployed to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
Secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
When rotating these secrets:&lt;br /&gt;
&lt;br /&gt;
* Terraform must be applied again to update the secrets in Vault&lt;br /&gt;
* Salt states must be re-applied to propagate updated AppRole credentials to the routers&lt;br /&gt;
&lt;br /&gt;
Failing to do so may cause CARP failover to break due to invalid OVH credentials or expired Vault authentication.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2501</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2501"/>
		<updated>2026-03-29T14:20:50Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
apps/network/carp-hyper-001-switch&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by router-002 and router-003 using AppRole authentication (via secretsmith).  &lt;br /&gt;
They are used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP).&lt;br /&gt;
&lt;br /&gt;
The AppRole credentials (role_id and secret_id) used by the routers are stored in:&lt;br /&gt;
&lt;br /&gt;
ops/secrets/network/router/vault&lt;br /&gt;
&lt;br /&gt;
These are provisioned via Terraform and deployed to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
Secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
When rotating these secrets:&lt;br /&gt;
&lt;br /&gt;
* Terraform must be applied again to update the secrets in Vault&lt;br /&gt;
* Salt states must be re-applied to propagate updated AppRole credentials to the routers&lt;br /&gt;
&lt;br /&gt;
Failing to do so may cause CARP failover to break due to invalid OVH credentials or expired Vault authentication.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2500</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2500"/>
		<updated>2026-03-29T14:19:11Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;apps/network/carp-hyper-001-switch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by router-002 and router-003  and are used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP, that is using AppRole authentication (via secretsmith),&lt;br /&gt;
&lt;br /&gt;
Secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
When rotating these secrets:&lt;br /&gt;
* Terraform must be applied again&lt;br /&gt;
&lt;br /&gt;
Failing to do so may cause CARP failover to break due to invalid OVH credentials.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2499</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2499"/>
		<updated>2026-03-29T14:17:06Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;apps/network/carp-hyper-001-switch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by router-002 and router-003  and are used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP, that is using AppRole authentication (via secretsmith),&lt;br /&gt;
&lt;br /&gt;
Secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
When rotating these secrets:&lt;br /&gt;
* Terraform must be applied again&lt;br /&gt;
* Salt states must be re-applied to update the configuration on routers&lt;br /&gt;
&lt;br /&gt;
Failing to do so may cause CARP failover to break due to invalid OVH credentials.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2498</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2498"/>
		<updated>2026-03-29T14:09:45Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;apps/network/carp-hyper-001-switch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by router-002 and router-003 that are using AppRole authentication (via secretsmith), and are used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP).&lt;br /&gt;
&lt;br /&gt;
Secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
When rotating these secrets:&lt;br /&gt;
* Terraform must be applied again&lt;br /&gt;
* Salt states must be re-applied to update the configuration on routers&lt;br /&gt;
&lt;br /&gt;
Failing to do so may cause CARP failover to break due to invalid OVH credentials.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2497</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2497"/>
		<updated>2026-03-29T14:08:58Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* CARP OVH secrets usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;apps/network/carp-hyper-001-switch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by routers using AppRole authentication (via secretsmith), and are used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP).&lt;br /&gt;
&lt;br /&gt;
Secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
When rotating these secrets:&lt;br /&gt;
* Terraform must be applied again&lt;br /&gt;
* Salt states must be re-applied to update the configuration on routers&lt;br /&gt;
&lt;br /&gt;
Failing to do so may cause CARP failover to break due to invalid OVH credentials.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2496</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2496"/>
		<updated>2026-03-29T14:00:31Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Propagate secrets (DRP) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CARP OVH secrets usage ===&lt;br /&gt;
&lt;br /&gt;
The OVH credentials used by the CARP failover script are stored in Vault at:&lt;br /&gt;
&lt;br /&gt;
apps/network/carp-hyper-001-switch&lt;br /&gt;
&lt;br /&gt;
These credentials are accessed by routers using AppRole authentication (via secretsmith), and are used by a script triggered by devd to update the OVH failover IP MAC address depending on the CARP state (MASTER/BACKUP).&lt;br /&gt;
&lt;br /&gt;
Secrets are provisioned using Terraform (openbao module), and must be propagated to the routers using Salt.&lt;br /&gt;
&lt;br /&gt;
When rotating these secrets:&lt;br /&gt;
* Terraform must be applied again&lt;br /&gt;
* Salt states must be re-applied to update the configuration on routers&lt;br /&gt;
&lt;br /&gt;
Failing to do so may cause CARP failover to break due to invalid OVH credentials.&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2491</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2491"/>
		<updated>2026-03-22T20:24:31Z</updated>

		<summary type="html">&lt;p&gt;Yousra: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later implemented directly in the kernel of other BSD systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer, a counter&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the CARP priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Address Multicast CARP ==&lt;br /&gt;
&lt;br /&gt;
In the Common Address Redundancy Protocol (CARP), routers communicate with each other using a multicast address. CARP advertisements are sent to the IPv4 multicast address &#039;&#039;&#039;224.0.0.18&#039;&#039;&#039;, which allows all routers participating in the CARP group to receive the messages simultaneously. At the Ethernet level, this multicast IP address corresponds to the multicast MAC address &#039;&#039;&#039;01:00:5e:00:00:12&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Preemption ==&lt;br /&gt;
&lt;br /&gt;
In fact, after some research, I discovered that on FreeBSD, the preemption behavior of CARP (Common Address Redundancy Protocol) is controlled by the kernel parameter net.inet.carp.preempt. This parameter allows a router with a higher priority (a lower advskew) to become MASTER, even if another router is already active in that role or if the real Master was restart after. To check if preemption is enabled, you can use the command  : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;sysctl net.inet.carp.preempt&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If the returned value is 0, preemption is disabled, and the currently MASTER router will retain that role as long as it continues to send its CARP advertisements. &lt;br /&gt;
&lt;br /&gt;
To temporarily enable preemption, simply run : &#039;&#039;&#039;sysctl net.inet.carp.preempt=1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To make this behavior permanent, you must add the line &#039;&#039;&#039;net.inet.carp.preempt=1&#039;&#039;&#039; to the /etc/sysctl.conf file. &lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?carp(4)&lt;br /&gt;
&lt;br /&gt;
https://vincentdelft.be/post/post_20241115&lt;br /&gt;
&lt;br /&gt;
== Peer ==&lt;br /&gt;
&lt;br /&gt;
By default, CARP uses multicast to send advertisements. However, multicast traffic can be filtered, restricted and so unreliable. Configuring CARP to use unicast advertisements between peers can help ensure more stable and predictable high-availability operation.&lt;br /&gt;
&lt;br /&gt;
In addition to that, using CARP in unicast mode can be appropriate in a two-router topology, as communication only needs to occur between 2 specific peers.&lt;br /&gt;
&lt;br /&gt;
Above all IPsec (security added in a classic tunnel) protects unicast traffic, it does not protect (or protects very poorly) multicast traffic. So if we want CARP to be used with IPsec, peer is an excellent choice.&lt;br /&gt;
&lt;br /&gt;
Router-002 : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass seediez7ae7LooFevohshae4oot0EeR peer 178.32.70.111 alias 51.68.252.230/32&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Router-003 : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass seediez7ae7LooFevohshae4oot0EeR peer 178.32.70.110 alias 51.68.252.230/32&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We see that the Master router-003 sends advertissements to router-002.nasqueron.org/178.32.70.110 &lt;br /&gt;
[[ File:Peer.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?query=carp&lt;br /&gt;
&lt;br /&gt;
https://docs.opnsense.org/manual/how-tos/carp.html&lt;br /&gt;
&lt;br /&gt;
https://www.kernel-panic.it/openbsd/carp/carp4.html&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the Master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the Master router. When a failover occurs, the Backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2482</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2482"/>
		<updated>2026-03-18T08:16:16Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Peer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later implemented directly in the kernel of other BSD systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer, a counter&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the CARP priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Address Multicast CARP ==&lt;br /&gt;
&lt;br /&gt;
In the Common Address Redundancy Protocol (CARP), routers communicate with each other using a multicast address. CARP advertisements are sent to the IPv4 multicast address &#039;&#039;&#039;224.0.0.18&#039;&#039;&#039;, which allows all routers participating in the CARP group to receive the messages simultaneously. At the Ethernet level, this multicast IP address corresponds to the multicast MAC address &#039;&#039;&#039;01:00:5e:00:00:12&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Preemption ==&lt;br /&gt;
&lt;br /&gt;
In fact, after some research, I discovered that on FreeBSD, the preemption behavior of CARP (Common Address Redundancy Protocol) is controlled by the kernel parameter net.inet.carp.preempt. This parameter allows a router with a higher priority (a lower advskew) to become MASTER, even if another router is already active in that role or if the real Master was restart after. To check if preemption is enabled, you can use the command  : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;sysctl net.inet.carp.preempt&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If the returned value is 0, preemption is disabled, and the currently MASTER router will retain that role as long as it continues to send its CARP advertisements. &lt;br /&gt;
&lt;br /&gt;
To temporarily enable preemption, simply run : &#039;&#039;&#039;sysctl net.inet.carp.preempt=1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To make this behavior permanent, you must add the line &#039;&#039;&#039;net.inet.carp.preempt=1&#039;&#039;&#039; to the /etc/sysctl.conf file. &lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?carp(4)&lt;br /&gt;
&lt;br /&gt;
https://vincentdelft.be/post/post_20241115&lt;br /&gt;
&lt;br /&gt;
== Peer ==&lt;br /&gt;
&lt;br /&gt;
By default, CARP uses multicast to send advertisements. However, multicast traffic can be filtered, restricted and so unreliable. Configuring CARP to use unicast advertisements between peers can help ensure more stable and predictable high-availability operation.&lt;br /&gt;
&lt;br /&gt;
In addition to that, using CARP in unicast mode can be appropriate in a two-router topology, as communication only needs to occur between 2 specific peers.&lt;br /&gt;
&lt;br /&gt;
Above all IPsec (security added in a classic tunnel) protects unicast traffic, it does not protect (or protects very poorly) multicast traffic. So if we want CARP to be used with IPsec, peer is an excellent choice.&lt;br /&gt;
&lt;br /&gt;
Router-002 : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass seediez7ae7LooFevohshae4oot0EeR peer 178.32.70.111 alias 51.68.252.230/32&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Router-003 : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass seediez7ae7LooFevohshae4oot0EeR peer 178.32.70.110 alias 51.68.252.230/32&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We see that the Master router-003 sends advertissements to router-002.nasqueron.org/178.32.70.110 &lt;br /&gt;
[[ File:Peer.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?query=carp&lt;br /&gt;
&lt;br /&gt;
https://docs.opnsense.org/manual/how-tos/carp.html&lt;br /&gt;
&lt;br /&gt;
https://www.kernel-panic.it/openbsd/carp/carp4.html&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the Master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the Master router. When a failover occurs, the Backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2481</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2481"/>
		<updated>2026-03-18T08:14:38Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Peer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later implemented directly in the kernel of other BSD systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer, a counter&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the CARP priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Address Multicast CARP ==&lt;br /&gt;
&lt;br /&gt;
In the Common Address Redundancy Protocol (CARP), routers communicate with each other using a multicast address. CARP advertisements are sent to the IPv4 multicast address &#039;&#039;&#039;224.0.0.18&#039;&#039;&#039;, which allows all routers participating in the CARP group to receive the messages simultaneously. At the Ethernet level, this multicast IP address corresponds to the multicast MAC address &#039;&#039;&#039;01:00:5e:00:00:12&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Preemption ==&lt;br /&gt;
&lt;br /&gt;
In fact, after some research, I discovered that on FreeBSD, the preemption behavior of CARP (Common Address Redundancy Protocol) is controlled by the kernel parameter net.inet.carp.preempt. This parameter allows a router with a higher priority (a lower advskew) to become MASTER, even if another router is already active in that role or if the real Master was restart after. To check if preemption is enabled, you can use the command  : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;sysctl net.inet.carp.preempt&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If the returned value is 0, preemption is disabled, and the currently MASTER router will retain that role as long as it continues to send its CARP advertisements. &lt;br /&gt;
&lt;br /&gt;
To temporarily enable preemption, simply run : &#039;&#039;&#039;sysctl net.inet.carp.preempt=1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To make this behavior permanent, you must add the line &#039;&#039;&#039;net.inet.carp.preempt=1&#039;&#039;&#039; to the /etc/sysctl.conf file. &lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?carp(4)&lt;br /&gt;
&lt;br /&gt;
https://vincentdelft.be/post/post_20241115&lt;br /&gt;
&lt;br /&gt;
== Peer ==&lt;br /&gt;
&lt;br /&gt;
By default, CARP uses multicast to send advertisements. However, multicast traffic can be filtered, restricted and so unreliable. Configuring CARP to use unicast advertisements between peers can help ensure more stable and predictable high-availability operation.&lt;br /&gt;
&lt;br /&gt;
In addition to that, using CARP in unicast mode can be appropriate in a two-router topology, as communication only needs to occur between 2 specific peers.&lt;br /&gt;
&lt;br /&gt;
Also IPsec (security added in a classic tunnel) protects unicast traffic, it does not protect (or protects very poorly) multicast traffic. So if we want CARP to be used with IPsec, peer is an excellent choice.&lt;br /&gt;
&lt;br /&gt;
Router-002 : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass seediez7ae7LooFevohshae4oot0EeR peer 178.32.70.111 alias 51.68.252.230/32&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Router-003 : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass seediez7ae7LooFevohshae4oot0EeR peer 178.32.70.110 alias 51.68.252.230/32&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We see that the Master router-003 sends advertissements to router-002.nasqueron.org/178.32.70.110 &lt;br /&gt;
[[ File:Peer.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?query=carp&lt;br /&gt;
&lt;br /&gt;
https://docs.opnsense.org/manual/how-tos/carp.html&lt;br /&gt;
&lt;br /&gt;
https://www.kernel-panic.it/openbsd/carp/carp4.html&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the Master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the Master router. When a failover occurs, the Backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2480</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2480"/>
		<updated>2026-03-17T08:26:47Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Master Election Process */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later implemented directly in the kernel of other BSD systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer, a counter&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the CARP priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Address Multicast CARP ==&lt;br /&gt;
&lt;br /&gt;
In the Common Address Redundancy Protocol (CARP), routers communicate with each other using a multicast address. CARP advertisements are sent to the IPv4 multicast address &#039;&#039;&#039;224.0.0.18&#039;&#039;&#039;, which allows all routers participating in the CARP group to receive the messages simultaneously. At the Ethernet level, this multicast IP address corresponds to the multicast MAC address &#039;&#039;&#039;01:00:5e:00:00:12&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Preemption ==&lt;br /&gt;
&lt;br /&gt;
In fact, after some research, I discovered that on FreeBSD, the preemption behavior of CARP (Common Address Redundancy Protocol) is controlled by the kernel parameter net.inet.carp.preempt. This parameter allows a router with a higher priority (a lower advskew) to become MASTER, even if another router is already active in that role or if the real Master was restart after. To check if preemption is enabled, you can use the command  : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;sysctl net.inet.carp.preempt&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If the returned value is 0, preemption is disabled, and the currently MASTER router will retain that role as long as it continues to send its CARP advertisements. &lt;br /&gt;
&lt;br /&gt;
To temporarily enable preemption, simply run : &#039;&#039;&#039;sysctl net.inet.carp.preempt=1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To make this behavior permanent, you must add the line &#039;&#039;&#039;net.inet.carp.preempt=1&#039;&#039;&#039; to the /etc/sysctl.conf file. &lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?carp(4)&lt;br /&gt;
&lt;br /&gt;
https://vincentdelft.be/post/post_20241115&lt;br /&gt;
&lt;br /&gt;
== Peer ==&lt;br /&gt;
&lt;br /&gt;
By default, CARP uses multicast to send advertisements. However, multicast traffic can be filtered, restricted and so unreliable. Configuring CARP to use unicast advertisements between peers can help ensure more stable and predictable high-availability operation.&lt;br /&gt;
&lt;br /&gt;
In addition to that, using CARP in unicast mode can be appropriate in a two-router topology, as communication only needs to occur between 2 specific peers.&lt;br /&gt;
&lt;br /&gt;
Router-002 : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass seediez7ae7LooFevohshae4oot0EeR peer 178.32.70.111 alias 51.68.252.230/32&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Router-003 : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass seediez7ae7LooFevohshae4oot0EeR peer 178.32.70.110 alias 51.68.252.230/32&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We see that the Master router-003 sends advertissements to router-002.nasqueron.org/178.32.70.110 &lt;br /&gt;
[[ File:Peer.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?query=carp&lt;br /&gt;
&lt;br /&gt;
https://docs.opnsense.org/manual/how-tos/carp.html&lt;br /&gt;
&lt;br /&gt;
https://www.kernel-panic.it/openbsd/carp/carp4.html&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the Master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the Master router. When a failover occurs, the Backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2479</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2479"/>
		<updated>2026-03-16T21:39:21Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Peer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later implemented directly in the kernel of other BSD systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the CARP priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Address Multicast CARP ==&lt;br /&gt;
&lt;br /&gt;
In the Common Address Redundancy Protocol (CARP), routers communicate with each other using a multicast address. CARP advertisements are sent to the IPv4 multicast address &#039;&#039;&#039;224.0.0.18&#039;&#039;&#039;, which allows all routers participating in the CARP group to receive the messages simultaneously. At the Ethernet level, this multicast IP address corresponds to the multicast MAC address &#039;&#039;&#039;01:00:5e:00:00:12&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Preemption ==&lt;br /&gt;
&lt;br /&gt;
In fact, after some research, I discovered that on FreeBSD, the preemption behavior of CARP (Common Address Redundancy Protocol) is controlled by the kernel parameter net.inet.carp.preempt. This parameter allows a router with a higher priority (a lower advskew) to become MASTER, even if another router is already active in that role or if the real Master was restart after. To check if preemption is enabled, you can use the command  : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;sysctl net.inet.carp.preempt&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If the returned value is 0, preemption is disabled, and the currently MASTER router will retain that role as long as it continues to send its CARP advertisements. &lt;br /&gt;
&lt;br /&gt;
To temporarily enable preemption, simply run : &#039;&#039;&#039;sysctl net.inet.carp.preempt=1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To make this behavior permanent, you must add the line &#039;&#039;&#039;net.inet.carp.preempt=1&#039;&#039;&#039; to the /etc/sysctl.conf file. &lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?carp(4)&lt;br /&gt;
&lt;br /&gt;
https://vincentdelft.be/post/post_20241115&lt;br /&gt;
&lt;br /&gt;
== Peer ==&lt;br /&gt;
&lt;br /&gt;
By default, CARP uses multicast to send advertisements. However, multicast traffic can be filtered, restricted and so unreliable. Configuring CARP to use unicast advertisements between peers can help ensure more stable and predictable high-availability operation.&lt;br /&gt;
&lt;br /&gt;
In addition to that, using CARP in unicast mode can be appropriate in a two-router topology, as communication only needs to occur between 2 specific peers.&lt;br /&gt;
&lt;br /&gt;
Router-002 : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass seediez7ae7LooFevohshae4oot0EeR peer 178.32.70.111 alias 51.68.252.230/32&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Router-003 : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass seediez7ae7LooFevohshae4oot0EeR peer 178.32.70.110 alias 51.68.252.230/32&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We see that the Master router-003 sends advertissements to router-002.nasqueron.org/178.32.70.110 &lt;br /&gt;
[[ File:Peer.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?query=carp&lt;br /&gt;
&lt;br /&gt;
https://docs.opnsense.org/manual/how-tos/carp.html&lt;br /&gt;
&lt;br /&gt;
https://www.kernel-panic.it/openbsd/carp/carp4.html&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the Master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the Master router. When a failover occurs, the Backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2478</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2478"/>
		<updated>2026-03-16T21:35:40Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Peer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later implemented directly in the kernel of other BSD systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the CARP priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Address Multicast CARP ==&lt;br /&gt;
&lt;br /&gt;
In the Common Address Redundancy Protocol (CARP), routers communicate with each other using a multicast address. CARP advertisements are sent to the IPv4 multicast address &#039;&#039;&#039;224.0.0.18&#039;&#039;&#039;, which allows all routers participating in the CARP group to receive the messages simultaneously. At the Ethernet level, this multicast IP address corresponds to the multicast MAC address &#039;&#039;&#039;01:00:5e:00:00:12&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Preemption ==&lt;br /&gt;
&lt;br /&gt;
In fact, after some research, I discovered that on FreeBSD, the preemption behavior of CARP (Common Address Redundancy Protocol) is controlled by the kernel parameter net.inet.carp.preempt. This parameter allows a router with a higher priority (a lower advskew) to become MASTER, even if another router is already active in that role or if the real Master was restart after. To check if preemption is enabled, you can use the command  : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;sysctl net.inet.carp.preempt&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If the returned value is 0, preemption is disabled, and the currently MASTER router will retain that role as long as it continues to send its CARP advertisements. &lt;br /&gt;
&lt;br /&gt;
To temporarily enable preemption, simply run : &#039;&#039;&#039;sysctl net.inet.carp.preempt=1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To make this behavior permanent, you must add the line &#039;&#039;&#039;net.inet.carp.preempt=1&#039;&#039;&#039; to the /etc/sysctl.conf file. &lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?carp(4)&lt;br /&gt;
&lt;br /&gt;
https://vincentdelft.be/post/post_20241115&lt;br /&gt;
&lt;br /&gt;
== Peer ==&lt;br /&gt;
&lt;br /&gt;
By default, CARP uses multicast to send advertisements. However, multicast traffic can be filtered, restricted and so unreliable. Configuring CARP to use unicast advertisements between peers can help ensure more stable and predictable high-availability operation.&lt;br /&gt;
&lt;br /&gt;
In addition to that, using CARP in unicast mode can be appropriate in a two-router topology, as communication only needs to occur between 2 specific peers.&lt;br /&gt;
&lt;br /&gt;
Router-002 : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass seediez7ae7LooFevohshae4oot0EeR peer 178.32.70.111 alias 51.68.252.230/32&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Router-003 : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass seediez7ae7LooFevohshae4oot0EeR peer 178.32.70.110 alias 51.68.252.230/32&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We see that the Master router-003 sends advertissements to router-002.nasqueron.org/178.32.70.110 &lt;br /&gt;
[[ File:Peer.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?query=carp&lt;br /&gt;
&lt;br /&gt;
https://docs.opnsense.org/manual/how-tos/carp.html&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the Master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the Master router. When a failover occurs, the Backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=File:Peer.png&amp;diff=2477</id>
		<title>File:Peer.png</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=File:Peer.png&amp;diff=2477"/>
		<updated>2026-03-16T21:33:07Z</updated>

		<summary type="html">&lt;p&gt;Yousra: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2476</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2476"/>
		<updated>2026-03-16T21:28:14Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Preemption */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later implemented directly in the kernel of other BSD systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the CARP priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Address Multicast CARP ==&lt;br /&gt;
&lt;br /&gt;
In the Common Address Redundancy Protocol (CARP), routers communicate with each other using a multicast address. CARP advertisements are sent to the IPv4 multicast address &#039;&#039;&#039;224.0.0.18&#039;&#039;&#039;, which allows all routers participating in the CARP group to receive the messages simultaneously. At the Ethernet level, this multicast IP address corresponds to the multicast MAC address &#039;&#039;&#039;01:00:5e:00:00:12&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Preemption ==&lt;br /&gt;
&lt;br /&gt;
In fact, after some research, I discovered that on FreeBSD, the preemption behavior of CARP (Common Address Redundancy Protocol) is controlled by the kernel parameter net.inet.carp.preempt. This parameter allows a router with a higher priority (a lower advskew) to become MASTER, even if another router is already active in that role or if the real Master was restart after. To check if preemption is enabled, you can use the command  : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;sysctl net.inet.carp.preempt&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If the returned value is 0, preemption is disabled, and the currently MASTER router will retain that role as long as it continues to send its CARP advertisements. &lt;br /&gt;
&lt;br /&gt;
To temporarily enable preemption, simply run : &#039;&#039;&#039;sysctl net.inet.carp.preempt=1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To make this behavior permanent, you must add the line &#039;&#039;&#039;net.inet.carp.preempt=1&#039;&#039;&#039; to the /etc/sysctl.conf file. &lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?carp(4)&lt;br /&gt;
&lt;br /&gt;
https://vincentdelft.be/post/post_20241115&lt;br /&gt;
&lt;br /&gt;
== Peer ==&lt;br /&gt;
&lt;br /&gt;
By default, CARP uses multicast to send advertisements. However, multicast traffic can be filtered, restricted and so unreliable. Configuring CARP to use unicast advertisements between peers can help ensure more stable and predictable high-availability operation.&lt;br /&gt;
&lt;br /&gt;
In addition to that, using CARP in unicast mode can be appropriate in a two-router topology, as communication only needs to occur between 2 specific peers.&lt;br /&gt;
&lt;br /&gt;
Router-002 : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass seediez7ae7LooFevohshae4oot0EeR peer 178.32.70.111 alias 51.68.252.230/32&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Router-003 : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass seediez7ae7LooFevohshae4oot0EeR peer 178.32.70.110 alias 51.68.252.230/32&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?query=carp&lt;br /&gt;
&lt;br /&gt;
https://docs.opnsense.org/manual/how-tos/carp.html&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the Master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the Master router. When a failover occurs, the Backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2475</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2475"/>
		<updated>2026-03-16T13:41:59Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Preemption */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later implemented directly in the kernel of other BSD systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the CARP priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Address Multicast CARP ==&lt;br /&gt;
&lt;br /&gt;
In the Common Address Redundancy Protocol (CARP), routers communicate with each other using a multicast address. CARP advertisements are sent to the IPv4 multicast address &#039;&#039;&#039;224.0.0.18&#039;&#039;&#039;, which allows all routers participating in the CARP group to receive the messages simultaneously. At the Ethernet level, this multicast IP address corresponds to the multicast MAC address &#039;&#039;&#039;01:00:5e:00:00:12&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Preemption ==&lt;br /&gt;
&lt;br /&gt;
In fact, after some research, I discovered that on FreeBSD, the preemption behavior of CARP (Common Address Redundancy Protocol) is controlled by the kernel parameter net.inet.carp.preempt. This parameter allows a router with a higher priority (a lower advskew) to become MASTER, even if another router is already active in that role or if the real Master was restart after. To check if preemption is enabled, you can use the command  : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;sysctl net.inet.carp.preempt&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If the returned value is 0, preemption is disabled, and the currently MASTER router will retain that role as long as it continues to send its CARP advertisements. &lt;br /&gt;
&lt;br /&gt;
To temporarily enable preemption, simply run : &#039;&#039;&#039;sysctl net.inet.carp.preempt=1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To make this behavior permanent, you must add the line &#039;&#039;&#039;net.inet.carp.preempt=1&#039;&#039;&#039; to the /etc/sysctl.conf file. &lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?carp(4)&lt;br /&gt;
&lt;br /&gt;
https://vincentdelft.be/post/post_20241115&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the Master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the Master router. When a failover occurs, the Backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2474</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2474"/>
		<updated>2026-03-16T13:35:27Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Preemption */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later implemented directly in the kernel of other BSD systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the CARP priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Address Multicast CARP ==&lt;br /&gt;
&lt;br /&gt;
In the Common Address Redundancy Protocol (CARP), routers communicate with each other using a multicast address. CARP advertisements are sent to the IPv4 multicast address &#039;&#039;&#039;224.0.0.18&#039;&#039;&#039;, which allows all routers participating in the CARP group to receive the messages simultaneously. At the Ethernet level, this multicast IP address corresponds to the multicast MAC address &#039;&#039;&#039;01:00:5e:00:00:12&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Preemption ==&lt;br /&gt;
&lt;br /&gt;
In fact, after some research, I discovered that on FreeBSD, the preemption behavior of CARP (Common Address Redundancy Protocol) is controlled by the kernel parameter net.inet.carp.preempt. This parameter allows a router with a higher priority (a lower advskew) to become MASTER, even if another router is already active in that role or if the real Master was restart after. To check if preemption is enabled, you can use the command  : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;sysctl net.inet.carp.preempt&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If the returned value is 0, preemption is disabled, and the currently MASTER router will retain that role as long as it continues to send its CARP advertisements. &lt;br /&gt;
&lt;br /&gt;
To temporarily enable preemption, simply run : &#039;&#039;&#039;sysctl net.inet.carp.preempt=1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To make this behavior permanent, you must add the line &#039;&#039;&#039;net.inet.carp.preempt=1&#039;&#039;&#039; to the /etc/sysctl.conf file. &lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?carp(4)&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the Master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the Master router. When a failover occurs, the Backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2473</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2473"/>
		<updated>2026-03-16T13:34:28Z</updated>

		<summary type="html">&lt;p&gt;Yousra: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later implemented directly in the kernel of other BSD systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the CARP priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Address Multicast CARP ==&lt;br /&gt;
&lt;br /&gt;
In the Common Address Redundancy Protocol (CARP), routers communicate with each other using a multicast address. CARP advertisements are sent to the IPv4 multicast address &#039;&#039;&#039;224.0.0.18&#039;&#039;&#039;, which allows all routers participating in the CARP group to receive the messages simultaneously. At the Ethernet level, this multicast IP address corresponds to the multicast MAC address &#039;&#039;&#039;01:00:5e:00:00:12&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Preemption ==&lt;br /&gt;
&lt;br /&gt;
In fact, after some research, I discovered that on FreeBSD, the preemption behavior of CARP (Common Address Redundancy Protocol) is controlled by the kernel parameter net.inet.carp.preempt. This parameter allows a router with a higher priority (a lower advskew) to become MASTER, even if another router is already active in that role. To check if preemption is enabled, you can use the command  : &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;sysctl net.inet.carp.preempt&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If the returned value is 0, preemption is disabled, and the currently MASTER router will retain that role as long as it continues to send its CARP advertisements. &lt;br /&gt;
&lt;br /&gt;
To temporarily enable preemption, simply run : &#039;&#039;&#039;sysctl net.inet.carp.preempt=1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To make this behavior permanent, you must add the line &#039;&#039;&#039;net.inet.carp.preempt=1&#039;&#039;&#039; to the /etc/sysctl.conf file. &lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://man.freebsd.org/cgi/man.cgi?carp(4)&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the Master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the Master router. When a failover occurs, the Backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2472</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2472"/>
		<updated>2026-03-13T11:30:11Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Introduction and history */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later implemented directly in the kernel of other BSD systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the CARP priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Address Multicast CARP ==&lt;br /&gt;
&lt;br /&gt;
In the Common Address Redundancy Protocol (CARP), routers communicate with each other using a multicast address. CARP advertisements are sent to the IPv4 multicast address &#039;&#039;&#039;224.0.0.18&#039;&#039;&#039;, which allows all routers participating in the CARP group to receive the messages simultaneously. At the Ethernet level, this multicast IP address corresponds to the multicast MAC address &#039;&#039;&#039;01:00:5e:00:00:12&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the Master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the Master router. When a failover occurs, the Backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2471</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2471"/>
		<updated>2026-03-12T10:03:21Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Master Election Process */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the CARP priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Address Multicast CARP ==&lt;br /&gt;
&lt;br /&gt;
In the Common Address Redundancy Protocol (CARP), routers communicate with each other using a multicast address. CARP advertisements are sent to the IPv4 multicast address &#039;&#039;&#039;224.0.0.18&#039;&#039;&#039;, which allows all routers participating in the CARP group to receive the messages simultaneously. At the Ethernet level, this multicast IP address corresponds to the multicast MAC address &#039;&#039;&#039;01:00:5e:00:00:12&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the Master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the Master router. When a failover occurs, the Backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2470</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2470"/>
		<updated>2026-03-09T20:49:49Z</updated>

		<summary type="html">&lt;p&gt;Yousra: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Address Multicast CARP ==&lt;br /&gt;
&lt;br /&gt;
In the Common Address Redundancy Protocol (CARP), routers communicate with each other using a multicast address. CARP advertisements are sent to the IPv4 multicast address &#039;&#039;&#039;224.0.0.18&#039;&#039;&#039;, which allows all routers participating in the CARP group to receive the messages simultaneously. At the Ethernet level, this multicast IP address corresponds to the multicast MAC address &#039;&#039;&#039;01:00:5e:00:00:12&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the Master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the Master router. When a failover occurs, the Backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2469</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2469"/>
		<updated>2026-03-09T20:40:01Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* ESXI and CARP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the Master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the Master router. When a failover occurs, the Backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2468</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2468"/>
		<updated>2026-03-09T20:32:17Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* ESXI and CARP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the master router. When a failover occurs, the backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2467</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2467"/>
		<updated>2026-03-09T20:30:39Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* ESXI and CARP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the master router. When a failover occurs, the backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2466</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2466"/>
		<updated>2026-03-09T20:30:23Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* ESXI and CARP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the master router. When a failover occurs, the backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2465</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2465"/>
		<updated>2026-03-09T20:06:20Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* ESXI and CARP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the master router. When a failover occurs, the backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;br /&gt;
&lt;br /&gt;
Source documentation: &lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2464</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2464"/>
		<updated>2026-03-09T20:06:08Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Automatic blue/green deployment */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the master router. When a failover occurs, the backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Source documentation: &lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2463</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2463"/>
		<updated>2026-03-09T20:05:45Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* ESXI and CARP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
When using Common Address Redundancy Protocol in a virtualized environment such as VMware ESXi, specific security settings must be adjusted on the virtual switch. CARP relies on the use of a virtual MAC address that can move between routers depending on which device is currently the master. However, ESXi applies strict security policies by default to prevent virtual machines from sending or receiving traffic with unexpected MAC addresses. To ensure that CARP functions correctly, three settings must be enabled on the vSwitch or port group.&lt;br /&gt;
&lt;br /&gt;
First, &#039;&#039;&#039;Promiscuous Mode&#039;&#039;&#039; must be enabled. This allows a virtual machine to receive all frames circulating on the virtual network, even if the destination MAC address does not match the interface’s MAC address. This is important for CARP because routers must receive multicast advertisements sent to the CARP group.&lt;br /&gt;
&lt;br /&gt;
Second, &#039;&#039;&#039;MAC Address Changes&#039;&#039;&#039; must be allowed. CARP dynamically assigns a virtual MAC address to the master router. When a failover occurs, the backup router must adopt this same virtual MAC address. If ESXi blocks MAC address changes, the router will not be able to assume the virtual MAC address and the failover mechanism will fail.&lt;br /&gt;
&lt;br /&gt;
Finally, &#039;&#039;&#039;Forged Transmits&#039;&#039;&#039; must also be permitted. This option allows a virtual machine to send frames with a source MAC address different from the one originally assigned to the virtual network interface. Since CARP advertisements and ARP responses are sent using the virtual MAC address rather than the physical interface MAC address, this setting is required to allow those frames to be transmitted correctly.&lt;br /&gt;
&lt;br /&gt;
Together, these three settings ensure that CARP redundancy mechanisms operate properly in a virtualized ESXi network environment.&lt;br /&gt;
&lt;br /&gt;
Configuration to enable &amp;quot;Promiscuous Mode&amp;quot;, “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Source documentation: &lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2462</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2462"/>
		<updated>2026-03-09T19:51:06Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Distribute traffic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;br /&gt;
&lt;br /&gt;
== ESXI and CARP ==&lt;br /&gt;
&lt;br /&gt;
The current infrastructure relies on two distinct networks at the ESXI hypervisor level:&lt;br /&gt;
&lt;br /&gt;
 - An internal network 172.27.27.0/28, referred to as IntraNought, used for internal communication and management.&lt;br /&gt;
&lt;br /&gt;
 - A public network used for public IP addresses exposed to the Internet.&lt;br /&gt;
&lt;br /&gt;
The objective now is to evaluate the possibility of implementing an active/active model so that both routers would receive traffic during normal operation, while still maintaining high availability through CARP. &lt;br /&gt;
&lt;br /&gt;
On the internal network (IntraNought), configuring CARP does not introduce a significant complexity. One router can operate as master and the other as backup. We will configure a first VHID.&lt;br /&gt;
&lt;br /&gt;
However, on the public network, a constraint exists. Public IP addresses (IPFO) provided by OVH are associated with a specific MAC address. If both routers need to use the same public IP address, they must present the same MAC address.&lt;br /&gt;
&lt;br /&gt;
By default, the ESXi vSwitch blocks situations where two virtual machines use the same MAC address. This requires enabling specific settings such as Promiscuous Mode, MAC Address Changes and Forged Transmits. It is technically feasible, but this adds complexity and may require network isolation by using a dedicated vSwitch for the routers.&lt;br /&gt;
&lt;br /&gt;
Finally, even if both routers are active, they run on the same hypervisor. This means the hypervisor is a Single Point of Failure (SPOF). If the physical host fails, both routers would go down at the same time, so the redundancy only exists at the virtual level, not at the hardware level.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;But at this point, a key question remains: If two VMs share the same MAC address, how does the vSwitch decide which VM should receive the traffic? Could it send the frame to the wrong VM? Or both ?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In our setup, two routers share the same virtual public IP and therefore the same virtual MAC address using CARP. However, only one router is active (the master) at a time.&lt;br /&gt;
&lt;br /&gt;
When the master sends traffic, the ESXi vSwitch learns the virtual MAC address from the source MAC of the frames it receives. It then associates that MAC address with the master’s port. As a result, any incoming traffic destined for that MAC is forwarded only to the active router.&lt;br /&gt;
&lt;br /&gt;
The backup router has the same virtual MAC configured, but it does not actively use it while in backup state. It does not respond to ARP requests and does not send traffic using that MAC. Therefore, the vSwitch does not associate the MAC with the backup’s port.&lt;br /&gt;
&lt;br /&gt;
If a failover occurs, the backup router becomes master and starts sending traffic with the same virtual MAC. The vSwitch detects that the MAC now appears on a different port and updates its table. Traffic is then forwarded to the new master.&lt;br /&gt;
&lt;br /&gt;
Security settings such as “MAC Address Changes” and “Forged Transmits” must be set to Accept to allow this MAC movement between ports and prevent ESXi from blocking the traffic as a potential MAC spoofing attempt.&lt;br /&gt;
&lt;br /&gt;
Regarding Promiscuous Mode, VMware documentation states: “Promiscuous mode eliminates any reception filtering that the virtual machine adapter performs so that the guest operating system receives all traffic observed on the wire.” This means that the filtering normally performed by the virtual network adapter based on the destination MAC address is disabled. As a result, the guest operating system can receive all traffic visible on that VLAN. However, this setting does not modify the forwarding logic of the vSwitch itself. The vSwitch continues to perform standard Layer 2 MAC learning and forwards unicast traffic to a single port at a time. Therefore, even with Promiscuous Mode enabled, the vSwitch does not behave like a hub. Promiscuous mode is mainly used for traffic monitoring or packet sniffing, it is not required in our case.&lt;br /&gt;
&lt;br /&gt;
Also, VMware documentation explicitly mentions legitimate scenarios where multiple adapters share the same MAC address, such as Microsoft NLB in unicast mode. This confirms that using a shared virtual MAC with CARP is a supported and valid design pattern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Configuration to enable “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
Source documentation: &lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2461</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2461"/>
		<updated>2026-03-09T19:49:07Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Priority vs advskew. */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the Master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the Master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the Master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in Backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the Master or Backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;br /&gt;
&lt;br /&gt;
== Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
The current infrastructure relies on two distinct networks at the ESXI hypervisor level:&lt;br /&gt;
&lt;br /&gt;
 - An internal network 172.27.27.0/28, referred to as IntraNought, used for internal communication and management.&lt;br /&gt;
&lt;br /&gt;
 - A public network used for public IP addresses exposed to the Internet.&lt;br /&gt;
&lt;br /&gt;
The objective now is to evaluate the possibility of implementing an active/active model so that both routers would receive traffic during normal operation, while still maintaining high availability through CARP. &lt;br /&gt;
&lt;br /&gt;
On the internal network (IntraNought), configuring CARP does not introduce a significant complexity. One router can operate as master and the other as backup. We will configure a first VHID.&lt;br /&gt;
&lt;br /&gt;
However, on the public network, a constraint exists. Public IP addresses (IPFO) provided by OVH are associated with a specific MAC address. If both routers need to use the same public IP address, they must present the same MAC address.&lt;br /&gt;
&lt;br /&gt;
By default, the ESXi vSwitch blocks situations where two virtual machines use the same MAC address. This requires enabling specific settings such as Promiscuous Mode, MAC Address Changes and Forged Transmits. It is technically feasible, but this adds complexity and may require network isolation by using a dedicated vSwitch for the routers.&lt;br /&gt;
&lt;br /&gt;
Finally, even if both routers are active, they run on the same hypervisor. This means the hypervisor is a Single Point of Failure (SPOF). If the physical host fails, both routers would go down at the same time, so the redundancy only exists at the virtual level, not at the hardware level.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;But at this point, a key question remains: If two VMs share the same MAC address, how does the vSwitch decide which VM should receive the traffic? Could it send the frame to the wrong VM? Or both ?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In our setup, two routers share the same virtual public IP and therefore the same virtual MAC address using CARP. However, only one router is active (the master) at a time.&lt;br /&gt;
&lt;br /&gt;
When the master sends traffic, the ESXi vSwitch learns the virtual MAC address from the source MAC of the frames it receives. It then associates that MAC address with the master’s port. As a result, any incoming traffic destined for that MAC is forwarded only to the active router.&lt;br /&gt;
&lt;br /&gt;
The backup router has the same virtual MAC configured, but it does not actively use it while in backup state. It does not respond to ARP requests and does not send traffic using that MAC. Therefore, the vSwitch does not associate the MAC with the backup’s port.&lt;br /&gt;
&lt;br /&gt;
If a failover occurs, the backup router becomes master and starts sending traffic with the same virtual MAC. The vSwitch detects that the MAC now appears on a different port and updates its table. Traffic is then forwarded to the new master.&lt;br /&gt;
&lt;br /&gt;
Security settings such as “MAC Address Changes” and “Forged Transmits” must be set to Accept to allow this MAC movement between ports and prevent ESXi from blocking the traffic as a potential MAC spoofing attempt.&lt;br /&gt;
&lt;br /&gt;
Regarding Promiscuous Mode, VMware documentation states: “Promiscuous mode eliminates any reception filtering that the virtual machine adapter performs so that the guest operating system receives all traffic observed on the wire.” This means that the filtering normally performed by the virtual network adapter based on the destination MAC address is disabled. As a result, the guest operating system can receive all traffic visible on that VLAN. However, this setting does not modify the forwarding logic of the vSwitch itself. The vSwitch continues to perform standard Layer 2 MAC learning and forwards unicast traffic to a single port at a time. Therefore, even with Promiscuous Mode enabled, the vSwitch does not behave like a hub. Promiscuous mode is mainly used for traffic monitoring or packet sniffing, it is not required in our case.&lt;br /&gt;
&lt;br /&gt;
Also, VMware documentation explicitly mentions legitimate scenarios where multiple adapters share the same MAC address, such as Microsoft NLB in unicast mode. This confirms that using a shared virtual MAC with CARP is a supported and valid design pattern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Configuration to enable “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
Source documentation: &lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2460</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2460"/>
		<updated>2026-03-09T19:48:16Z</updated>

		<summary type="html">&lt;p&gt;Yousra: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the master or backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;br /&gt;
&lt;br /&gt;
== Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
The current infrastructure relies on two distinct networks at the ESXI hypervisor level:&lt;br /&gt;
&lt;br /&gt;
 - An internal network 172.27.27.0/28, referred to as IntraNought, used for internal communication and management.&lt;br /&gt;
&lt;br /&gt;
 - A public network used for public IP addresses exposed to the Internet.&lt;br /&gt;
&lt;br /&gt;
The objective now is to evaluate the possibility of implementing an active/active model so that both routers would receive traffic during normal operation, while still maintaining high availability through CARP. &lt;br /&gt;
&lt;br /&gt;
On the internal network (IntraNought), configuring CARP does not introduce a significant complexity. One router can operate as master and the other as backup. We will configure a first VHID.&lt;br /&gt;
&lt;br /&gt;
However, on the public network, a constraint exists. Public IP addresses (IPFO) provided by OVH are associated with a specific MAC address. If both routers need to use the same public IP address, they must present the same MAC address.&lt;br /&gt;
&lt;br /&gt;
By default, the ESXi vSwitch blocks situations where two virtual machines use the same MAC address. This requires enabling specific settings such as Promiscuous Mode, MAC Address Changes and Forged Transmits. It is technically feasible, but this adds complexity and may require network isolation by using a dedicated vSwitch for the routers.&lt;br /&gt;
&lt;br /&gt;
Finally, even if both routers are active, they run on the same hypervisor. This means the hypervisor is a Single Point of Failure (SPOF). If the physical host fails, both routers would go down at the same time, so the redundancy only exists at the virtual level, not at the hardware level.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;But at this point, a key question remains: If two VMs share the same MAC address, how does the vSwitch decide which VM should receive the traffic? Could it send the frame to the wrong VM? Or both ?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In our setup, two routers share the same virtual public IP and therefore the same virtual MAC address using CARP. However, only one router is active (the master) at a time.&lt;br /&gt;
&lt;br /&gt;
When the master sends traffic, the ESXi vSwitch learns the virtual MAC address from the source MAC of the frames it receives. It then associates that MAC address with the master’s port. As a result, any incoming traffic destined for that MAC is forwarded only to the active router.&lt;br /&gt;
&lt;br /&gt;
The backup router has the same virtual MAC configured, but it does not actively use it while in backup state. It does not respond to ARP requests and does not send traffic using that MAC. Therefore, the vSwitch does not associate the MAC with the backup’s port.&lt;br /&gt;
&lt;br /&gt;
If a failover occurs, the backup router becomes master and starts sending traffic with the same virtual MAC. The vSwitch detects that the MAC now appears on a different port and updates its table. Traffic is then forwarded to the new master.&lt;br /&gt;
&lt;br /&gt;
Security settings such as “MAC Address Changes” and “Forged Transmits” must be set to Accept to allow this MAC movement between ports and prevent ESXi from blocking the traffic as a potential MAC spoofing attempt.&lt;br /&gt;
&lt;br /&gt;
Regarding Promiscuous Mode, VMware documentation states: “Promiscuous mode eliminates any reception filtering that the virtual machine adapter performs so that the guest operating system receives all traffic observed on the wire.” This means that the filtering normally performed by the virtual network adapter based on the destination MAC address is disabled. As a result, the guest operating system can receive all traffic visible on that VLAN. However, this setting does not modify the forwarding logic of the vSwitch itself. The vSwitch continues to perform standard Layer 2 MAC learning and forwards unicast traffic to a single port at a time. Therefore, even with Promiscuous Mode enabled, the vSwitch does not behave like a hub. Promiscuous mode is mainly used for traffic monitoring or packet sniffing, it is not required in our case.&lt;br /&gt;
&lt;br /&gt;
Also, VMware documentation explicitly mentions legitimate scenarios where multiple adapters share the same MAC address, such as Microsoft NLB in unicast mode. This confirms that using a shared virtual MAC with CARP is a supported and valid design pattern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Configuration to enable “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
Source documentation: &lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2459</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2459"/>
		<updated>2026-03-09T19:47:09Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Priority vs advskew. */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the master or backup role. However, advskew can also be called &amp;quot;CARP priority&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;br /&gt;
&lt;br /&gt;
== Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
The current infrastructure relies on two distinct networks at the ESXI hypervisor level:&lt;br /&gt;
&lt;br /&gt;
 - An internal network 172.27.27.0/28, referred to as IntraNought, used for internal communication and management.&lt;br /&gt;
&lt;br /&gt;
 - A public network used for public IP addresses exposed to the Internet.&lt;br /&gt;
&lt;br /&gt;
The objective now is to evaluate the possibility of implementing an active/active model so that both routers would receive traffic during normal operation, while still maintaining high availability through CARP. &lt;br /&gt;
&lt;br /&gt;
On the internal network (IntraNought), configuring CARP does not introduce a significant complexity. One router can operate as master and the other as backup. We will configure a first VHID.&lt;br /&gt;
&lt;br /&gt;
However, on the public network, a constraint exists. Public IP addresses (IPFO) provided by OVH are associated with a specific MAC address. If both routers need to use the same public IP address, they must present the same MAC address.&lt;br /&gt;
&lt;br /&gt;
By default, the ESXi vSwitch blocks situations where two virtual machines use the same MAC address. This requires enabling specific settings such as Promiscuous Mode, MAC Address Changes and Forged Transmits. It is technically feasible, but this adds complexity and may require network isolation by using a dedicated vSwitch for the routers.&lt;br /&gt;
&lt;br /&gt;
Finally, even if both routers are active, they run on the same hypervisor. This means the hypervisor is a Single Point of Failure (SPOF). If the physical host fails, both routers would go down at the same time, so the redundancy only exists at the virtual level, not at the hardware level.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;But at this point, a key question remains: If two VMs share the same MAC address, how does the vSwitch decide which VM should receive the traffic? Could it send the frame to the wrong VM? Or both ?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In our setup, two routers share the same virtual public IP and therefore the same virtual MAC address using CARP. However, only one router is active (the master) at a time.&lt;br /&gt;
&lt;br /&gt;
When the master sends traffic, the ESXi vSwitch learns the virtual MAC address from the source MAC of the frames it receives. It then associates that MAC address with the master’s port. As a result, any incoming traffic destined for that MAC is forwarded only to the active router.&lt;br /&gt;
&lt;br /&gt;
The backup router has the same virtual MAC configured, but it does not actively use it while in backup state. It does not respond to ARP requests and does not send traffic using that MAC. Therefore, the vSwitch does not associate the MAC with the backup’s port.&lt;br /&gt;
&lt;br /&gt;
If a failover occurs, the backup router becomes master and starts sending traffic with the same virtual MAC. The vSwitch detects that the MAC now appears on a different port and updates its table. Traffic is then forwarded to the new master.&lt;br /&gt;
&lt;br /&gt;
Security settings such as “MAC Address Changes” and “Forged Transmits” must be set to Accept to allow this MAC movement between ports and prevent ESXi from blocking the traffic as a potential MAC spoofing attempt.&lt;br /&gt;
&lt;br /&gt;
Regarding Promiscuous Mode, VMware documentation states: “Promiscuous mode eliminates any reception filtering that the virtual machine adapter performs so that the guest operating system receives all traffic observed on the wire.” This means that the filtering normally performed by the virtual network adapter based on the destination MAC address is disabled. As a result, the guest operating system can receive all traffic visible on that VLAN. However, this setting does not modify the forwarding logic of the vSwitch itself. The vSwitch continues to perform standard Layer 2 MAC learning and forwards unicast traffic to a single port at a time. Therefore, even with Promiscuous Mode enabled, the vSwitch does not behave like a hub. Promiscuous mode is mainly used for traffic monitoring or packet sniffing, it is not required in our case.&lt;br /&gt;
&lt;br /&gt;
Also, VMware documentation explicitly mentions legitimate scenarios where multiple adapters share the same MAC address, such as Microsoft NLB in unicast mode. This confirms that using a shared virtual MAC with CARP is a supported and valid design pattern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Configuration to enable “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
Source documentation: &lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2458</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2458"/>
		<updated>2026-03-09T19:39:11Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Virtual Mac Address */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the vhid2 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the master or backup role.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;br /&gt;
&lt;br /&gt;
== Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
The current infrastructure relies on two distinct networks at the ESXI hypervisor level:&lt;br /&gt;
&lt;br /&gt;
 - An internal network 172.27.27.0/28, referred to as IntraNought, used for internal communication and management.&lt;br /&gt;
&lt;br /&gt;
 - A public network used for public IP addresses exposed to the Internet.&lt;br /&gt;
&lt;br /&gt;
The objective now is to evaluate the possibility of implementing an active/active model so that both routers would receive traffic during normal operation, while still maintaining high availability through CARP. &lt;br /&gt;
&lt;br /&gt;
On the internal network (IntraNought), configuring CARP does not introduce a significant complexity. One router can operate as master and the other as backup. We will configure a first VHID.&lt;br /&gt;
&lt;br /&gt;
However, on the public network, a constraint exists. Public IP addresses (IPFO) provided by OVH are associated with a specific MAC address. If both routers need to use the same public IP address, they must present the same MAC address.&lt;br /&gt;
&lt;br /&gt;
By default, the ESXi vSwitch blocks situations where two virtual machines use the same MAC address. This requires enabling specific settings such as Promiscuous Mode, MAC Address Changes and Forged Transmits. It is technically feasible, but this adds complexity and may require network isolation by using a dedicated vSwitch for the routers.&lt;br /&gt;
&lt;br /&gt;
Finally, even if both routers are active, they run on the same hypervisor. This means the hypervisor is a Single Point of Failure (SPOF). If the physical host fails, both routers would go down at the same time, so the redundancy only exists at the virtual level, not at the hardware level.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;But at this point, a key question remains: If two VMs share the same MAC address, how does the vSwitch decide which VM should receive the traffic? Could it send the frame to the wrong VM? Or both ?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In our setup, two routers share the same virtual public IP and therefore the same virtual MAC address using CARP. However, only one router is active (the master) at a time.&lt;br /&gt;
&lt;br /&gt;
When the master sends traffic, the ESXi vSwitch learns the virtual MAC address from the source MAC of the frames it receives. It then associates that MAC address with the master’s port. As a result, any incoming traffic destined for that MAC is forwarded only to the active router.&lt;br /&gt;
&lt;br /&gt;
The backup router has the same virtual MAC configured, but it does not actively use it while in backup state. It does not respond to ARP requests and does not send traffic using that MAC. Therefore, the vSwitch does not associate the MAC with the backup’s port.&lt;br /&gt;
&lt;br /&gt;
If a failover occurs, the backup router becomes master and starts sending traffic with the same virtual MAC. The vSwitch detects that the MAC now appears on a different port and updates its table. Traffic is then forwarded to the new master.&lt;br /&gt;
&lt;br /&gt;
Security settings such as “MAC Address Changes” and “Forged Transmits” must be set to Accept to allow this MAC movement between ports and prevent ESXi from blocking the traffic as a potential MAC spoofing attempt.&lt;br /&gt;
&lt;br /&gt;
Regarding Promiscuous Mode, VMware documentation states: “Promiscuous mode eliminates any reception filtering that the virtual machine adapter performs so that the guest operating system receives all traffic observed on the wire.” This means that the filtering normally performed by the virtual network adapter based on the destination MAC address is disabled. As a result, the guest operating system can receive all traffic visible on that VLAN. However, this setting does not modify the forwarding logic of the vSwitch itself. The vSwitch continues to perform standard Layer 2 MAC learning and forwards unicast traffic to a single port at a time. Therefore, even with Promiscuous Mode enabled, the vSwitch does not behave like a hub. Promiscuous mode is mainly used for traffic monitoring or packet sniffing, it is not required in our case.&lt;br /&gt;
&lt;br /&gt;
Also, VMware documentation explicitly mentions legitimate scenarios where multiple adapters share the same MAC address, such as Microsoft NLB in unicast mode. This confirms that using a shared virtual MAC with CARP is a supported and valid design pattern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Configuration to enable “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
Source documentation: &lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2457</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2457"/>
		<updated>2026-03-09T19:17:27Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Virtual Mac Address */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the VIP 51.68.252.230 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the master or backup role.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;br /&gt;
&lt;br /&gt;
== Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
The current infrastructure relies on two distinct networks at the ESXI hypervisor level:&lt;br /&gt;
&lt;br /&gt;
 - An internal network 172.27.27.0/28, referred to as IntraNought, used for internal communication and management.&lt;br /&gt;
&lt;br /&gt;
 - A public network used for public IP addresses exposed to the Internet.&lt;br /&gt;
&lt;br /&gt;
The objective now is to evaluate the possibility of implementing an active/active model so that both routers would receive traffic during normal operation, while still maintaining high availability through CARP. &lt;br /&gt;
&lt;br /&gt;
On the internal network (IntraNought), configuring CARP does not introduce a significant complexity. One router can operate as master and the other as backup. We will configure a first VHID.&lt;br /&gt;
&lt;br /&gt;
However, on the public network, a constraint exists. Public IP addresses (IPFO) provided by OVH are associated with a specific MAC address. If both routers need to use the same public IP address, they must present the same MAC address.&lt;br /&gt;
&lt;br /&gt;
By default, the ESXi vSwitch blocks situations where two virtual machines use the same MAC address. This requires enabling specific settings such as Promiscuous Mode, MAC Address Changes and Forged Transmits. It is technically feasible, but this adds complexity and may require network isolation by using a dedicated vSwitch for the routers.&lt;br /&gt;
&lt;br /&gt;
Finally, even if both routers are active, they run on the same hypervisor. This means the hypervisor is a Single Point of Failure (SPOF). If the physical host fails, both routers would go down at the same time, so the redundancy only exists at the virtual level, not at the hardware level.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;But at this point, a key question remains: If two VMs share the same MAC address, how does the vSwitch decide which VM should receive the traffic? Could it send the frame to the wrong VM? Or both ?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In our setup, two routers share the same virtual public IP and therefore the same virtual MAC address using CARP. However, only one router is active (the master) at a time.&lt;br /&gt;
&lt;br /&gt;
When the master sends traffic, the ESXi vSwitch learns the virtual MAC address from the source MAC of the frames it receives. It then associates that MAC address with the master’s port. As a result, any incoming traffic destined for that MAC is forwarded only to the active router.&lt;br /&gt;
&lt;br /&gt;
The backup router has the same virtual MAC configured, but it does not actively use it while in backup state. It does not respond to ARP requests and does not send traffic using that MAC. Therefore, the vSwitch does not associate the MAC with the backup’s port.&lt;br /&gt;
&lt;br /&gt;
If a failover occurs, the backup router becomes master and starts sending traffic with the same virtual MAC. The vSwitch detects that the MAC now appears on a different port and updates its table. Traffic is then forwarded to the new master.&lt;br /&gt;
&lt;br /&gt;
Security settings such as “MAC Address Changes” and “Forged Transmits” must be set to Accept to allow this MAC movement between ports and prevent ESXi from blocking the traffic as a potential MAC spoofing attempt.&lt;br /&gt;
&lt;br /&gt;
Regarding Promiscuous Mode, VMware documentation states: “Promiscuous mode eliminates any reception filtering that the virtual machine adapter performs so that the guest operating system receives all traffic observed on the wire.” This means that the filtering normally performed by the virtual network adapter based on the destination MAC address is disabled. As a result, the guest operating system can receive all traffic visible on that VLAN. However, this setting does not modify the forwarding logic of the vSwitch itself. The vSwitch continues to perform standard Layer 2 MAC learning and forwards unicast traffic to a single port at a time. Therefore, even with Promiscuous Mode enabled, the vSwitch does not behave like a hub. Promiscuous mode is mainly used for traffic monitoring or packet sniffing, it is not required in our case.&lt;br /&gt;
&lt;br /&gt;
Also, VMware documentation explicitly mentions legitimate scenarios where multiple adapters share the same MAC address, such as Microsoft NLB in unicast mode. This confirms that using a shared virtual MAC with CARP is a supported and valid design pattern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Configuration to enable “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
Source documentation: &lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2456</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2456"/>
		<updated>2026-03-09T19:17:11Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Virtual Mac Address */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the VIP 51.68.252.230 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the master or backup role.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;br /&gt;
&lt;br /&gt;
== Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
The current infrastructure relies on two distinct networks at the ESXI hypervisor level:&lt;br /&gt;
&lt;br /&gt;
 - An internal network 172.27.27.0/28, referred to as IntraNought, used for internal communication and management.&lt;br /&gt;
&lt;br /&gt;
 - A public network used for public IP addresses exposed to the Internet.&lt;br /&gt;
&lt;br /&gt;
The objective now is to evaluate the possibility of implementing an active/active model so that both routers would receive traffic during normal operation, while still maintaining high availability through CARP. &lt;br /&gt;
&lt;br /&gt;
On the internal network (IntraNought), configuring CARP does not introduce a significant complexity. One router can operate as master and the other as backup. We will configure a first VHID.&lt;br /&gt;
&lt;br /&gt;
However, on the public network, a constraint exists. Public IP addresses (IPFO) provided by OVH are associated with a specific MAC address. If both routers need to use the same public IP address, they must present the same MAC address.&lt;br /&gt;
&lt;br /&gt;
By default, the ESXi vSwitch blocks situations where two virtual machines use the same MAC address. This requires enabling specific settings such as Promiscuous Mode, MAC Address Changes and Forged Transmits. It is technically feasible, but this adds complexity and may require network isolation by using a dedicated vSwitch for the routers.&lt;br /&gt;
&lt;br /&gt;
Finally, even if both routers are active, they run on the same hypervisor. This means the hypervisor is a Single Point of Failure (SPOF). If the physical host fails, both routers would go down at the same time, so the redundancy only exists at the virtual level, not at the hardware level.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;But at this point, a key question remains: If two VMs share the same MAC address, how does the vSwitch decide which VM should receive the traffic? Could it send the frame to the wrong VM? Or both ?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In our setup, two routers share the same virtual public IP and therefore the same virtual MAC address using CARP. However, only one router is active (the master) at a time.&lt;br /&gt;
&lt;br /&gt;
When the master sends traffic, the ESXi vSwitch learns the virtual MAC address from the source MAC of the frames it receives. It then associates that MAC address with the master’s port. As a result, any incoming traffic destined for that MAC is forwarded only to the active router.&lt;br /&gt;
&lt;br /&gt;
The backup router has the same virtual MAC configured, but it does not actively use it while in backup state. It does not respond to ARP requests and does not send traffic using that MAC. Therefore, the vSwitch does not associate the MAC with the backup’s port.&lt;br /&gt;
&lt;br /&gt;
If a failover occurs, the backup router becomes master and starts sending traffic with the same virtual MAC. The vSwitch detects that the MAC now appears on a different port and updates its table. Traffic is then forwarded to the new master.&lt;br /&gt;
&lt;br /&gt;
Security settings such as “MAC Address Changes” and “Forged Transmits” must be set to Accept to allow this MAC movement between ports and prevent ESXi from blocking the traffic as a potential MAC spoofing attempt.&lt;br /&gt;
&lt;br /&gt;
Regarding Promiscuous Mode, VMware documentation states: “Promiscuous mode eliminates any reception filtering that the virtual machine adapter performs so that the guest operating system receives all traffic observed on the wire.” This means that the filtering normally performed by the virtual network adapter based on the destination MAC address is disabled. As a result, the guest operating system can receive all traffic visible on that VLAN. However, this setting does not modify the forwarding logic of the vSwitch itself. The vSwitch continues to perform standard Layer 2 MAC learning and forwards unicast traffic to a single port at a time. Therefore, even with Promiscuous Mode enabled, the vSwitch does not behave like a hub. Promiscuous mode is mainly used for traffic monitoring or packet sniffing, it is not required in our case.&lt;br /&gt;
&lt;br /&gt;
Also, VMware documentation explicitly mentions legitimate scenarios where multiple adapters share the same MAC address, such as Microsoft NLB in unicast mode. This confirms that using a shared virtual MAC with CARP is a supported and valid design pattern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Configuration to enable “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
Source documentation: &lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2455</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2455"/>
		<updated>2026-03-09T19:16:16Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Virtual Mac Address */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
We can see here that the virtual mac address associated to the VIP 51.68.252.230 is : 00:00:5e:00:01:02 (02 at the end for vhid2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -e -ni vmx1 proto 112&#039;&#039;&#039;&lt;br /&gt;
[[ File:Virtual-mac.png ]]&lt;br /&gt;
&lt;br /&gt;
✔ The CARP virtual MAC address is visible.&lt;br /&gt;
❌ The virtual IP address (VIP) is not visible as the source.&lt;br /&gt;
&lt;br /&gt;
In CARP advertisements, the Ethernet source address corresponds to the virtual CARP MAC address derived from the VHID. However, the IP source address is the physical IP address of the router sending the advertisement. The virtual IP address (VIP) is not used as the source IP in these control packets. Instead, the VIP is used for normal traffic between clients and the virtual gateway.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the master or backup role.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;br /&gt;
&lt;br /&gt;
== Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
The current infrastructure relies on two distinct networks at the ESXI hypervisor level:&lt;br /&gt;
&lt;br /&gt;
 - An internal network 172.27.27.0/28, referred to as IntraNought, used for internal communication and management.&lt;br /&gt;
&lt;br /&gt;
 - A public network used for public IP addresses exposed to the Internet.&lt;br /&gt;
&lt;br /&gt;
The objective now is to evaluate the possibility of implementing an active/active model so that both routers would receive traffic during normal operation, while still maintaining high availability through CARP. &lt;br /&gt;
&lt;br /&gt;
On the internal network (IntraNought), configuring CARP does not introduce a significant complexity. One router can operate as master and the other as backup. We will configure a first VHID.&lt;br /&gt;
&lt;br /&gt;
However, on the public network, a constraint exists. Public IP addresses (IPFO) provided by OVH are associated with a specific MAC address. If both routers need to use the same public IP address, they must present the same MAC address.&lt;br /&gt;
&lt;br /&gt;
By default, the ESXi vSwitch blocks situations where two virtual machines use the same MAC address. This requires enabling specific settings such as Promiscuous Mode, MAC Address Changes and Forged Transmits. It is technically feasible, but this adds complexity and may require network isolation by using a dedicated vSwitch for the routers.&lt;br /&gt;
&lt;br /&gt;
Finally, even if both routers are active, they run on the same hypervisor. This means the hypervisor is a Single Point of Failure (SPOF). If the physical host fails, both routers would go down at the same time, so the redundancy only exists at the virtual level, not at the hardware level.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;But at this point, a key question remains: If two VMs share the same MAC address, how does the vSwitch decide which VM should receive the traffic? Could it send the frame to the wrong VM? Or both ?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In our setup, two routers share the same virtual public IP and therefore the same virtual MAC address using CARP. However, only one router is active (the master) at a time.&lt;br /&gt;
&lt;br /&gt;
When the master sends traffic, the ESXi vSwitch learns the virtual MAC address from the source MAC of the frames it receives. It then associates that MAC address with the master’s port. As a result, any incoming traffic destined for that MAC is forwarded only to the active router.&lt;br /&gt;
&lt;br /&gt;
The backup router has the same virtual MAC configured, but it does not actively use it while in backup state. It does not respond to ARP requests and does not send traffic using that MAC. Therefore, the vSwitch does not associate the MAC with the backup’s port.&lt;br /&gt;
&lt;br /&gt;
If a failover occurs, the backup router becomes master and starts sending traffic with the same virtual MAC. The vSwitch detects that the MAC now appears on a different port and updates its table. Traffic is then forwarded to the new master.&lt;br /&gt;
&lt;br /&gt;
Security settings such as “MAC Address Changes” and “Forged Transmits” must be set to Accept to allow this MAC movement between ports and prevent ESXi from blocking the traffic as a potential MAC spoofing attempt.&lt;br /&gt;
&lt;br /&gt;
Regarding Promiscuous Mode, VMware documentation states: “Promiscuous mode eliminates any reception filtering that the virtual machine adapter performs so that the guest operating system receives all traffic observed on the wire.” This means that the filtering normally performed by the virtual network adapter based on the destination MAC address is disabled. As a result, the guest operating system can receive all traffic visible on that VLAN. However, this setting does not modify the forwarding logic of the vSwitch itself. The vSwitch continues to perform standard Layer 2 MAC learning and forwards unicast traffic to a single port at a time. Therefore, even with Promiscuous Mode enabled, the vSwitch does not behave like a hub. Promiscuous mode is mainly used for traffic monitoring or packet sniffing, it is not required in our case.&lt;br /&gt;
&lt;br /&gt;
Also, VMware documentation explicitly mentions legitimate scenarios where multiple adapters share the same MAC address, such as Microsoft NLB in unicast mode. This confirms that using a shared virtual MAC with CARP is a supported and valid design pattern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Configuration to enable “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
Source documentation: &lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=File:Virtual-mac.png&amp;diff=2454</id>
		<title>File:Virtual-mac.png</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=File:Virtual-mac.png&amp;diff=2454"/>
		<updated>2026-03-09T17:38:58Z</updated>

		<summary type="html">&lt;p&gt;Yousra: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2453</id>
		<title>Protocol CARP</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Protocol_CARP&amp;diff=2453"/>
		<updated>2026-03-09T17:26:46Z</updated>

		<summary type="html">&lt;p&gt;Yousra: /* Basic configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction and history ==&lt;br /&gt;
&lt;br /&gt;
« CARP stands for Common Address Redundancy Protocol and its basic functionality is to allow multiple hosts to share a set of IP addresses ».&lt;br /&gt;
&lt;br /&gt;
CARP was developed by the OpenBSD project in 2003 as an alternative to VRRP due to patent concerns related to Cisco&#039;s HSRP technology. To avoid potential legal issues and remain compatible with open-source principles, OpenBSD implemented its own redundancy protocol with added cryptographic features. CARP was later adopted by other systems such as FreeBSD and NetBSD. A userland implementation of CARP, named ucarp, made the protocol usable on Linux without requiring kernel integration.&lt;br /&gt;
&lt;br /&gt;
These patent concerns originated from the development of VRRP by the Internet Engineering Task Force (IETF). Indeed, when the Internet Engineering Task Force (IETF) developed the Virtual Router Redundancy Protocol (VRRP), Cisco Systems indicated that it owned patents related to router redundancy mechanisms used in the protocol Hot Standby Router Protocol (HSRP). This created a legal risk for developers, particularly for open-source projects that wanted to implement VRRP freely.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master host and backup hosts ==&lt;br /&gt;
&lt;br /&gt;
CARP creates a redundancy group, meaning several hosts are configured to share a virtual IP address. However, at any given time, only one host uses the shared IP address. This host is called the Master host and it receives and handles all traffic destined to that virtual IP.&lt;br /&gt;
&lt;br /&gt;
When the Master host becomes unavailable (it crashed, turned off, or lost its network connection), the other hosts in the same redundancy group detect the failure. Immediately, one of the Backup hosts is elected as the new Master host. That means that it will take over the shared IP address.&lt;br /&gt;
&lt;br /&gt;
This switch happens automatically, ensuring service continuity without clients noticing any interruption.&lt;br /&gt;
&lt;br /&gt;
[[File:Schema redondance routeurs.png]]&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
== CARP advertisements ==&lt;br /&gt;
&lt;br /&gt;
- The Master host periodically broadcasts CARP advertisements to the backup hosts.&lt;br /&gt;
&lt;br /&gt;
- The Backup hosts listen but do not send any packets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Each CARP advertisement contains :&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1. The CARP version and packet type (CARP Header).&lt;br /&gt;
&lt;br /&gt;
2. The VHID (Virtual Host ID), which identifies the redundancy group (CARP Header).&lt;br /&gt;
&lt;br /&gt;
3. The advertisement parameters (advbase and advskew), which determine the host’s priority CARP (CARP Header).&lt;br /&gt;
&lt;br /&gt;
4. The counter&lt;br /&gt;
&lt;br /&gt;
5. The signature in SHA-1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CARP Advertisement Packet Format :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Each line represent 32 bits, 4 bytes&lt;br /&gt;
&lt;br /&gt;
Length : 36 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * The CARP header layout is as follows:&lt;br /&gt;
 *&lt;br /&gt;
 *     0                   1                   2                   3&lt;br /&gt;
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |    Demotion   |     AdvBase   |          Checksum             |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (1)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                         Counter (2)                           |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (1)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (2)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (3)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (4)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *    |                        SHA-1 HMAC (5)                         |&lt;br /&gt;
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;commande : tcpdump -i &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[ File:Carp-advertissement.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://github.com/openbsd/src/blob/master/sys/netinet/ip_carp.h&lt;br /&gt;
&lt;br /&gt;
== Cryptography ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All CARP advertisements are cryptographically signed :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Steps : &lt;br /&gt;
&lt;br /&gt;
1. The Master host creates an advertisement.&lt;br /&gt;
&lt;br /&gt;
2. It calculates a cryptographic signature, a SHA-1 hash using:&lt;br /&gt;
&lt;br /&gt;
* the shared secret,&lt;br /&gt;
&lt;br /&gt;
* the VHID,&lt;br /&gt;
&lt;br /&gt;
* the virtual IP address,&lt;br /&gt;
&lt;br /&gt;
* the advertisement parameters (advbase and advskew),&lt;br /&gt;
&lt;br /&gt;
* the counter&lt;br /&gt;
&lt;br /&gt;
* and other header fields.&lt;br /&gt;
&lt;br /&gt;
3. It then sends the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
4. The Backup hosts receives the signed advertisement.&lt;br /&gt;
&lt;br /&gt;
5. Each Backup host recalculates the signature using the same shared secret : &lt;br /&gt;
&lt;br /&gt;
 - If the calculated signature matches the received signature → the packet is considered valid because authentication and integrity are insured.&lt;br /&gt;
&lt;br /&gt;
 - If it does not match → the packet is rejected.&lt;br /&gt;
&lt;br /&gt;
It protects against spoofing attacks : without cryptographic authentication, an attacker could send fake CARP advertisements and attempt to pretend to be or to become the Master host.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;command : tcpdump -X -ni &amp;lt;interface&amp;gt; proto 112&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We can observe the complete packet in the capture. Each hexadecimal value represents two bytes. The first 20 bytes correspond to the IP header, while the last 20 bytes correspond to the SHA-1 authentication hash included in the CARP advertisement.&lt;br /&gt;
&lt;br /&gt;
[[ File:Sha1-signature.png ]]&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.giac.org/paper/gsec/4031/carp-free-fail-over-protocol/106433&lt;br /&gt;
&lt;br /&gt;
== IP protocol number  ==&lt;br /&gt;
&lt;br /&gt;
CARP uses the same IP protocol number as VRRP (112). As a result, packet capture tools such as tcpdump interpret CARP packets as VRRP advertisements like we see above, even though the packets actually belong to the CARP protocol.&lt;br /&gt;
&lt;br /&gt;
Why ??&lt;br /&gt;
The OpenBSD developers initially requested unique identifiers from the Internet Assigned Numbers Authority (IANA), but the request was denied because they had not followed the IETF standardization process. As a result, they chose to use protocol number 112, which was already assigned to VRRP. Despite this overlap, VRRP and CARP can coexist on the same network as long as their identifiers (VRRP group ID and CARP VHID) are different.&lt;br /&gt;
&lt;br /&gt;
Sources : &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Common_Address_Redundancy_Protocol&lt;br /&gt;
&lt;br /&gt;
== Multiple VHID : Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
Using multiple VHIDs in CARP allows several virtual IP addresses to be managed separately. This means different hosts can be Master for different services. For example, one host can manage the web service, while another manages the DNS service. Thanks to this, the hosts can be used efficiently while still ensuring high availability. It would not be practical to use a machine only when the other machine is not responding.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Split-brain ==&lt;br /&gt;
&lt;br /&gt;
Normally:&lt;br /&gt;
* one Master&lt;br /&gt;
&lt;br /&gt;
* one or several Backups&lt;br /&gt;
&lt;br /&gt;
If the Master host stops sending advertisements, the Backup hosts know that the master is no longer reachable. However, a problem can occur if the Backup hosts stop receiving each other&#039;s advertisements because the link between them is broken. In that case, each node may assume it is the Master.&lt;br /&gt;
&lt;br /&gt;
When communication is restored, CARP resolves the problem:&lt;br /&gt;
&lt;br /&gt;
 1. The Masters can see each other&lt;br /&gt;
 2. The real Master send the packet&lt;br /&gt;
 3. The hosts compare CARP priority&lt;br /&gt;
 4. The hosts with lower priority automatically switch back to Backup&lt;br /&gt;
&lt;br /&gt;
sources :&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
== Master Election Process ==&lt;br /&gt;
&lt;br /&gt;
1. All hosts start&lt;br /&gt;
&lt;br /&gt;
  All hosts begin in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
2. Each host starts a timer&lt;br /&gt;
&lt;br /&gt;
* The delay depends on the CARP priority (advskew).&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the shorter the delay.&lt;br /&gt;
&lt;br /&gt;
* The lower the advskew, the higher the priority.&lt;br /&gt;
&lt;br /&gt;
3. The higher-priority host’s timer expires first&lt;br /&gt;
&lt;br /&gt;
   That host sends CARP advertisements when the timer expires.&lt;br /&gt;
&lt;br /&gt;
   It assigns the virtual IP (VIP) to its interface.&lt;br /&gt;
&lt;br /&gt;
   It becomes the MASTER host.&lt;br /&gt;
&lt;br /&gt;
4. The other hosts receive the advertisement&lt;br /&gt;
&lt;br /&gt;
   They detect that a higher-priority host is active.&lt;br /&gt;
&lt;br /&gt;
   They remain in BACKUP state.&lt;br /&gt;
&lt;br /&gt;
   They do not send CARP advertisements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In CARP, we usually choose the preferred Master by giving it a higher priority (lower advskew).&lt;br /&gt;
&lt;br /&gt;
== Virtual Mac Address ==&lt;br /&gt;
&lt;br /&gt;
The protocol automatically generates a virtual MAC address based on the VHID, ending with the VHID&#039;s value (00:00:5e:00:01:XX). This MAC address is identical on both hosts and is used by the MASTER node.&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;br /&gt;
&lt;br /&gt;
== Basic configuration ==&lt;br /&gt;
&lt;br /&gt;
We want : &lt;br /&gt;
&lt;br /&gt;
 router-002 to act as the  master, while router-003 should operate as the backup for Intranought network.&lt;br /&gt;
&lt;br /&gt;
 router-003 to act as the  master, while router-002 should operate as the backup for Public network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Enable CARP Support&lt;br /&gt;
&lt;br /&gt;
On the file &#039;&#039;/boot/loader.conf&#039;&#039;, you need to add : &#039;&#039;&#039;carp_load=&amp;quot;YES&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You are telling FreeBSD:&lt;br /&gt;
&lt;br /&gt;
“Load the CARP kernel module automatically at boot time.”&lt;br /&gt;
&lt;br /&gt;
If you  want to load it now, but not permanently : &#039;&#039;&#039;kldload carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If someone has build a custom FreeBSD kernel, they can include CARP directly by adding this line to the kernel configuration file: &#039;&#039;&#039;device carp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) CARP configuration&lt;br /&gt;
&lt;br /&gt;
In each router, on the new appropriate file &#039;&#039;&#039;/etc/rc.conf.d/netif/carp&#039;&#039;&#039;, we will have the CARP configuration &lt;br /&gt;
&lt;br /&gt;
router-002 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 0 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 100 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router-003 : &lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx0_alias0=&amp;quot;inet vhid 1 advskew 100 pass xxxxxxx alias 172.27.27.13/27&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ifconfig_vmx1_alias0=&amp;quot;inet vhid 2 advskew 0 pass xxxxxxx alias 51.68.252.230/32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So we gave a lower advskew (default is 0) to become the master router.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In older versions of FreeBSD (9 and earlier), CARP required creating a separate virtual interface such as carp0, and the shared IP address was attached to that interface. Starting with FreeBSD 10, this was simplified. CARP can now be configured directly on the physical interface using an alias with a VHID. The newer method is easier to configure and maintain, so it is recommended to use it in modern versions of FreeBSD.&lt;br /&gt;
&lt;br /&gt;
commands : &lt;br /&gt;
&lt;br /&gt;
 ifconfig carp0 create&lt;br /&gt;
 ifconfig carp0 vhid 1 pass xxxxxx&lt;br /&gt;
 ifconfig carp0 inet 172.27.27.X/28&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
sources : &lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
== Automatic blue/green deployment ==&lt;br /&gt;
&lt;br /&gt;
In this context, “automatic Blue-Green” does not refer to a traditional application deployment strategy. Instead, it describes a network-level behavior enabled by CARP.&lt;br /&gt;
&lt;br /&gt;
With CARP, two routers are deployed in parallel:&lt;br /&gt;
&lt;br /&gt;
 - One acts as the active router (MASTER)&lt;br /&gt;
&lt;br /&gt;
 - The other remains in standby (BACKUP)&lt;br /&gt;
&lt;br /&gt;
Both routers are fully operational and connected to the network. Traffic is sent to a shared virtual IP address. At any given time, only the MASTER processes the traffic. However, if the MASTER fails, the BACKUP automatically takes over the virtual IP address without manual intervention.&lt;br /&gt;
&lt;br /&gt;
This behavior resembles Blue-Green deployment because:&lt;br /&gt;
&lt;br /&gt;
 1. Two environments exist simultaneously&lt;br /&gt;
&lt;br /&gt;
 2. Only one actively handles traffic&lt;br /&gt;
&lt;br /&gt;
 3. Traffic can switch from one to the other&lt;br /&gt;
&lt;br /&gt;
 4. The switch is transparent to users&lt;br /&gt;
&lt;br /&gt;
The difference is that in traditional Blue-Green deployment, the switch is usually performed manually during an update. With CARP, the switch happens automatically in case of failure.&lt;br /&gt;
&lt;br /&gt;
== Priority vs advskew. ==&lt;br /&gt;
&lt;br /&gt;
In the CARP protocol, the master router is not directly determined by priority, but rather by a value called advskew. Advskew is a numerical parameter between 0 and 255: the lower its value, the more likely the router is to become the master. Priority, on the other hand, is a more intuitive abstraction used in automation tools or logical configurations: the higher the priority, the higher the router&#039;s expected priority. To link the two, we use the formula: advskew = 255 − priority. Thus, a router with a priority of 200 will have a low advskew (55) and will become the master, while a router with a priority of 0 will have a maximum advskew (255) and will remain in backup mode. In short, priority is a value that is easily understood and logical for humans, while advskew is the value actually used by CARP&#039;s internal mechanism to determine the master or backup role.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Linked to {{T|2227}}&lt;br /&gt;
&lt;br /&gt;
== Distribute traffic ==&lt;br /&gt;
&lt;br /&gt;
The current infrastructure relies on two distinct networks at the ESXI hypervisor level:&lt;br /&gt;
&lt;br /&gt;
 - An internal network 172.27.27.0/28, referred to as IntraNought, used for internal communication and management.&lt;br /&gt;
&lt;br /&gt;
 - A public network used for public IP addresses exposed to the Internet.&lt;br /&gt;
&lt;br /&gt;
The objective now is to evaluate the possibility of implementing an active/active model so that both routers would receive traffic during normal operation, while still maintaining high availability through CARP. &lt;br /&gt;
&lt;br /&gt;
On the internal network (IntraNought), configuring CARP does not introduce a significant complexity. One router can operate as master and the other as backup. We will configure a first VHID.&lt;br /&gt;
&lt;br /&gt;
However, on the public network, a constraint exists. Public IP addresses (IPFO) provided by OVH are associated with a specific MAC address. If both routers need to use the same public IP address, they must present the same MAC address.&lt;br /&gt;
&lt;br /&gt;
By default, the ESXi vSwitch blocks situations where two virtual machines use the same MAC address. This requires enabling specific settings such as Promiscuous Mode, MAC Address Changes and Forged Transmits. It is technically feasible, but this adds complexity and may require network isolation by using a dedicated vSwitch for the routers.&lt;br /&gt;
&lt;br /&gt;
Finally, even if both routers are active, they run on the same hypervisor. This means the hypervisor is a Single Point of Failure (SPOF). If the physical host fails, both routers would go down at the same time, so the redundancy only exists at the virtual level, not at the hardware level.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;But at this point, a key question remains: If two VMs share the same MAC address, how does the vSwitch decide which VM should receive the traffic? Could it send the frame to the wrong VM? Or both ?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In our setup, two routers share the same virtual public IP and therefore the same virtual MAC address using CARP. However, only one router is active (the master) at a time.&lt;br /&gt;
&lt;br /&gt;
When the master sends traffic, the ESXi vSwitch learns the virtual MAC address from the source MAC of the frames it receives. It then associates that MAC address with the master’s port. As a result, any incoming traffic destined for that MAC is forwarded only to the active router.&lt;br /&gt;
&lt;br /&gt;
The backup router has the same virtual MAC configured, but it does not actively use it while in backup state. It does not respond to ARP requests and does not send traffic using that MAC. Therefore, the vSwitch does not associate the MAC with the backup’s port.&lt;br /&gt;
&lt;br /&gt;
If a failover occurs, the backup router becomes master and starts sending traffic with the same virtual MAC. The vSwitch detects that the MAC now appears on a different port and updates its table. Traffic is then forwarded to the new master.&lt;br /&gt;
&lt;br /&gt;
Security settings such as “MAC Address Changes” and “Forged Transmits” must be set to Accept to allow this MAC movement between ports and prevent ESXi from blocking the traffic as a potential MAC spoofing attempt.&lt;br /&gt;
&lt;br /&gt;
Regarding Promiscuous Mode, VMware documentation states: “Promiscuous mode eliminates any reception filtering that the virtual machine adapter performs so that the guest operating system receives all traffic observed on the wire.” This means that the filtering normally performed by the virtual network adapter based on the destination MAC address is disabled. As a result, the guest operating system can receive all traffic visible on that VLAN. However, this setting does not modify the forwarding logic of the vSwitch itself. The vSwitch continues to perform standard Layer 2 MAC learning and forwards unicast traffic to a single port at a time. Therefore, even with Promiscuous Mode enabled, the vSwitch does not behave like a hub. Promiscuous mode is mainly used for traffic monitoring or packet sniffing, it is not required in our case.&lt;br /&gt;
&lt;br /&gt;
Also, VMware documentation explicitly mentions legitimate scenarios where multiple adapters share the same MAC address, such as Microsoft NLB in unicast mode. This confirms that using a shared virtual MAC with CARP is a supported and valid design pattern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Configuration to enable “MAC Address Changes” and “Forged Transmits”  : &lt;br /&gt;
&lt;br /&gt;
https://knowledge.broadcom.com/external/article/324520/configuring-promiscuous-mode-on-a-virtua.html&lt;br /&gt;
Source documentation: &lt;br /&gt;
&lt;br /&gt;
https://wxcafe.net/posts/redondance-routeurs-openbsd-freebsd/&lt;br /&gt;
&lt;br /&gt;
https://freebsdfoundation.org/wp-content/uploads/2022/11/zaborski_CARP.pdf&lt;br /&gt;
&lt;br /&gt;
https://docs-archive.freebsd.org/doc/11.0-RELEASE/usr/local/share/doc/freebsd/en/books/handbook/carp.html&lt;br /&gt;
&lt;br /&gt;
https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-vsphere-networking/securing-vsphere-standard-switches.html&lt;br /&gt;
&lt;br /&gt;
https://dynfi.com/documentations/dynfi-firewall/configuration_firewall_VIP.html&lt;/div&gt;</summary>
		<author><name>Yousra</name></author>
	</entry>
</feed>