diff --git a/docs/vyos.vyos.vyos_vpn_ipsec_module.rst b/docs/vyos.vyos.vyos_vpn_ipsec_module.rst index b28e0165..79ca84b8 100644 --- a/docs/vyos.vyos.vyos_vpn_ipsec_module.rst +++ b/docs/vyos.vyos.vyos_vpn_ipsec_module.rst @@ -1,1573 +1,1553 @@ .. _vyos.vyos.vyos_vpn_ipsec_module: ************************ vyos.vyos.vyos_vpn_ipsec ************************ **Manages global IPsec (ike-group, esp-group, profile, authentication, options) attributes of VyOS network devices.** Version added: 1.0.0 .. contents:: :local: :depth: 1 Synopsis -------- - This module manages global VPN IPsec configuration on VyOS devices -- IKE groups, ESP groups, PSK/PPK authentication, IPsec profiles, and global options. Site-to-site peers and IKEv2 remote-access connections are handled by separate modules. Parameters ---------- .. raw:: html
Parameter Choices/Defaults Comments
config
dictionary
IPsec global configuration.
authentication
dictionary
Global pre-shared-key and post-quantum pre-shared-key definitions.
ppk
list / elements=dictionary
List of post-quantum pre-shared keys.
id
list / elements=string
ID(s) for PPK.
name
string / required
Post-quantum pre-shared key name.
secret
string
Post-quantum pre-shared secret key.
secret_type
string
    Choices:
  • base64
  • hex
  • plaintext
Secret encoding type.
psk
list / elements=dictionary
List of pre-shared keys.
dhcp_interface
list / elements=string
DHCP interface(s) supplying next-hop IP address.
id
list / elements=string
ID(s) for authentication.
name
string / required
Pre-shared key name.
secret
string
IKE pre-shared secret key.
secret_type
string
    Choices:
  • base64
  • hex
  • plaintext
Secret encoding type.
disable_uniqreqids
boolean
    Choices:
  • no
  • yes
Disable requirement for unique IDs in the Security Database.
esp_group
list / elements=dictionary
List of ESP groups.
compression
boolean
    Choices:
  • no
  • yes
Enable ESP compression.
disable_rekey
boolean
    Choices:
  • no
  • yes
Do not locally initiate a re-key of the SA; remote peer must re-key before expiration.
life_bytes
integer
Security Association byte count to expire.
life_packets
integer
Security Association packet count to expire.
lifetime
integer
Security Association time to expire, in seconds.
mode
string
    Choices:
  • tunnel
  • transport
ESP mode.
name
string / required
The name of the ESP group.
pfs
string
ESP Perfect Forward Secrecy. See VyOS/strongSwan documentation for the full set of valid values -- validated device-side, not enumerated here since the set is version-dependent.
proposal
list / elements=dictionary
List of ESP proposals.
encryption
string
Encryption algorithm. See VyOS/strongSwan documentation for the full set of valid values -- validated device-side, not enumerated here since the set is version-dependent.
hash
string
Hash algorithm. See VyOS/strongSwan documentation for the full set of valid values -- validated device-side.
proposal_id
integer
The proposal identifier.
ike_group
list / elements=dictionary
List of IKE groups.
close_action
string
    Choices:
  • none
  • trap
  • start
Action to take if a child SA is unexpectedly closed.
dead_peer_detection
dictionary
Dead Peer Detection (DPD).
action
string
    Choices:
  • trap
  • clear
  • restart
Keep-alive failure action.
interval
integer
Keep-alive interval in seconds.
timeout
integer
Dead Peer Detection keep-alive timeout (IKEv1 only), in seconds.
disable_mobike
boolean
    Choices:
  • no
  • yes
Disable MOBIKE support (IKEv2 only).
ikev2_reauth
boolean
    Choices:
  • no
  • yes
Re-authentication of the remote peer during an IKE re-key (IKEv2 only).
key_exchange
string
    Choices:
  • ikev1
  • ikev2
IKE version.
lifetime
integer
IKE lifetime in seconds.
mode
string
    Choices:
  • main
  • aggressive
IKEv1 phase 1 mode.
name
string / required
The name of the IKE group.
proposal
list / elements=dictionary
List of IKE proposals.
dh_group
integer
Diffie-Hellman group. See VyOS/strongSwan documentation for the full set of valid values -- validated device-side, not enumerated here since the set is version-dependent.
encryption
string
Encryption algorithm. See VyOS/strongSwan documentation for the full set of valid values -- validated device-side, not enumerated here since the set is version-dependent.
hash
string
Hash algorithm. See VyOS/strongSwan documentation for the full set of valid values -- validated device-side.
prf
string
Pseudo-Random Function. See VyOS/strongSwan documentation for the full set of valid values -- validated device-side.
proposal_id
integer
The proposal identifier.
interface
list / elements=string
Interface(s) IPsec listens on. If omitted, listens on all interfaces.
log
dictionary
IPsec logging settings.
level
integer
Global IPsec logging level.
subsystem
list / elements=string
Per-subsystem logging levels to enable.
options
dictionary
Global IPsec options.
disable_route_autoinstall
boolean
    Choices:
  • no
  • yes
Do not automatically install routes to remote networks.
flexvpn
boolean
    Choices:
  • no
  • yes
Allow FlexVPN vendor ID payload (IKEv2 only).
interface
string
Single interface for IPsec options scope (distinct from top-level interface list).
retransmission
dictionary
IPsec retransmission settings.
attempts
integer
Maximum number of retransmissions.
base
float
Base of exponential backoff.
timeout
integer
Timeout in seconds before the first retransmission.
virtual_ip
boolean
    Choices:
  • no
  • yes
Allow install of virtual-ip addresses.
profile
list / elements=dictionary
List of VPN IPsec profiles (used for e.g. DMVPN/GRE tunnel binding).
authentication
dictionary
Authentication settings for this profile.
mode
string
    Choices:
  • pre-shared-secret
Authentication mode.
pre_shared_secret
string
Pre-shared secret key.
bind_tunnel
list / elements=string
Tunnel interface(s) associated with this profile.
disable
boolean
    Choices:
  • no
  • yes
Disable this profile.
esp_group
string
ESP group name to use for this profile.
ike_group
string
IKE group name to use for this profile.
name
string / required
Profile name.
running_config
string
This option is used only with state parsed.
The value of this option should be the output received from the VyOS device by executing the command show configuration commands | match "vpn ipsec".
The states replaced and overridden have identical behaviour for this module with respect to named collections (ike_group, esp_group, profile, authentication), but differ in scope -- see the module description for detail.
The state parsed reads the configuration from the running_config option and transforms it into Ansible structured data as per the resource module's argspec, returned in the parsed key within the result.
state
string
    Choices:
  • merged ←
  • replaced
  • overridden
  • deleted
  • gathered
  • rendered
  • parsed
The state the configuration should be left in.

Notes ----- .. note:: - Tested against VyOS 1.4 and 1.5. - Source of truth for field types/choices: device node.def templates under /opt/vyatta/share/vyatta-cfg/templates/vpn/ipsec/. + - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide ` Examples -------- .. code-block:: yaml - # ------------------- - # Using merged - # ------------------- + - name: Merge provided configuration with device configuration + vyos.vyos.vyos_vpn_ipsec: + config: + esp_group: + - name: ESP-TEST + proposal: + - proposal_id: 1 + encryption: aes256 + hash: sha256 + ike_group: + - name: IKE-TEST + key_exchange: ikev2 + proposal: + - proposal_id: 1 + encryption: aes256 + hash: sha256 + dh_group: 14 + state: merged - # Before state: - # ------------- - # vyos@vyos:~$ show configuration commands | match "vpn ipsec" - # (empty) + - name: Replace one named esp-group, leaving all other groups untouched + vyos.vyos.vyos_vpn_ipsec: + config: + esp_group: + - name: ESP-TEST + proposal: + - proposal_id: 1 + encryption: aes128 + hash: sha256 + state: replaced - # Task - # ------------- - # - name: Merge provided configuration with device configuration - # vyos.vyos.vyos_vpn_ipsec: - # config: - # esp_group: - # - name: ESP-TEST - # proposal: - # - proposal_id: 1 - # encryption: aes256 - # hash: sha256 - # ike_group: - # - name: IKE-TEST - # key_exchange: ikev2 - # proposal: - # - proposal_id: 1 - # encryption: aes256 - # hash: sha256 - # dh_group: 14 - # state: merged + - name: Override the whole configuration -- anything not listed here is removed + vyos.vyos.vyos_vpn_ipsec: + config: + esp_group: + - name: ESP-TEST + proposal: + - proposal_id: 1 + encryption: aes256 + hash: sha256 + state: overridden - # Task output: - # ------------- - # "commands": [ - # "set vpn ipsec esp-group ESP-TEST", - # "set vpn ipsec esp-group ESP-TEST proposal 1", - # "set vpn ipsec esp-group ESP-TEST proposal 1 encryption aes256", - # "set vpn ipsec esp-group ESP-TEST proposal 1 hash sha256", - # "set vpn ipsec ike-group IKE-TEST", - # "set vpn ipsec ike-group IKE-TEST key-exchange ikev2", - # "set vpn ipsec ike-group IKE-TEST proposal 1", - # "set vpn ipsec ike-group IKE-TEST proposal 1 encryption aes256", - # "set vpn ipsec ike-group IKE-TEST proposal 1 hash sha256", - # "set vpn ipsec ike-group IKE-TEST proposal 1 dh-group 14" - # ] + - name: Delete one named esp-group, leaving all other groups untouched + vyos.vyos.vyos_vpn_ipsec: + config: + esp_group: + - name: ESP-TEST + state: deleted - # ------------------- - # Using gathered - # ------------------- + - name: Remove all vpn_ipsec configuration + vyos.vyos.vyos_vpn_ipsec: + state: deleted - # Task - # ------------- - # - name: Gather current vpn_ipsec configuration - # vyos.vyos.vyos_vpn_ipsec: - # state: gathered + - name: Gather current vpn_ipsec configuration + vyos.vyos.vyos_vpn_ipsec: + state: gathered - # ------------------- - # Using deleted - # ------------------- + - name: Render configuration without touching the device + vyos.vyos.vyos_vpn_ipsec: + config: + esp_group: + - name: ESP-TEST + proposal: + - proposal_id: 1 + encryption: aes256 + hash: sha256 + state: rendered - # Task - # ------------- - # - name: Remove all vpn_ipsec configuration - # vyos.vyos.vyos_vpn_ipsec: - # state: deleted - - # ------------------- - # Using rendered - # ------------------- - - # Task - # ------------- - # - name: Render configuration without touching the device - # vyos.vyos.vyos_vpn_ipsec: - # config: - # esp_group: - # - name: ESP-TEST - # proposal: - # - proposal_id: 1 - # encryption: aes256 - # hash: sha256 - # state: rendered - - # ------------------- - # Using parsed - # ------------------- - - # Task - # ------------- - # - name: Parse raw config text into structured facts - # vyos.vyos.vyos_vpn_ipsec: - # running_config: "{{ lookup('file', './vpn_ipsec.cfg') }}" - # state: parsed + - name: Parse raw config text into structured facts + vyos.vyos.vyos_vpn_ipsec: + running_config: "{{ lookup('file', './vpn_ipsec.cfg') }}" + state: parsed Return Values ------------- Common return values are documented `here `_, the following are the fields unique to this module: .. raw:: html
Key Returned Description
after
dictionary
when changed
The resulting configuration after module execution.

Sample:
This output will always be in the same format as the module argspec.
before
dictionary
when state is merged, replaced, overridden or deleted
The configuration prior to the module execution.

Sample:
This output will always be in the same format as the module argspec.
commands
list
when state is merged, replaced, overridden or deleted
The set of commands pushed to the remote device.

Sample:
['set vpn ipsec esp-group ESP-TEST proposal 1 encryption aes256', 'set vpn ipsec ike-group IKE-TEST key-exchange ikev2']
gathered
dictionary
when state is gathered
Facts about the network resource gathered from the remote device as structured data.

Sample:
This output will always be in the same format as the module argspec.
parsed
dictionary
when state is parsed
The device native config provided in running_config option parsed into structured data as per module argspec.

Sample:
This output will always be in the same format as the module argspec.
rendered
list
when state is rendered
The provided configuration in the task rendered in device-native format (offline).

Sample:
['set vpn ipsec esp-group ESP-TEST proposal 1 encryption aes256']


Status ------ Authors ~~~~~~~ - Evgeny Molotkov (@omnom62) diff --git a/docs/vyos.vyos.vyos_vpn_ipsec_s2s_module.rst b/docs/vyos.vyos.vyos_vpn_ipsec_s2s_module.rst index 087ecbc5..8da5dc8a 100644 --- a/docs/vyos.vyos.vyos_vpn_ipsec_s2s_module.rst +++ b/docs/vyos.vyos.vyos_vpn_ipsec_s2s_module.rst @@ -1,1218 +1,1232 @@ .. _vyos.vyos.vyos_vpn_ipsec_s2s_module: **************************** vyos.vyos.vyos_vpn_ipsec_s2s **************************** **Manages IPsec site-to-site VPN peers on VyOS network devices.** Version added: 1.0.0 .. contents:: :local: :depth: 1 Synopsis -------- - This module manages VPN IPsec site-to-site peer configuration on VyOS devices -- policy-based tunnels and route-based (VTI) connections. IKE/ESP groups, PSK/PPK authentication, and IPsec profiles are managed by the separate vyos_vpn_ipsec module; peers here reference those by name. Parameters ---------- .. raw:: html
Parameter Choices/Defaults Comments
config
dictionary
IPsec site-to-site configuration.
peer
list / elements=dictionary
List of site-to-site peers.
authentication
dictionary
Peer authentication settings.
local_id
string
Local ID for peer authentication.
mode
string
    Choices:
  • pre-shared-secret
  • rsa
  • x509
Authentication mode.
ppk
dictionary
Post-quantum preshared key reference for this peer.
id
string
Post-quantum preshared key ID for this connection.
required
boolean
    Choices:
  • no
  • yes
Require a valid PPK for the connection to establish.
remote_id
string
ID for remote authentication.
rsa
dictionary
RSA key authentication.
local_key
string
Name of the PKI key-pair with the local private key.
passphrase
string
Local private key passphrase.
remote_key
string
Name of the PKI key-pair with the remote public key.
use_x509_id
boolean
    Choices:
  • no
  • yes
Use certificate common name as ID.
x509
dictionary
X.509 certificate authentication.
ca_certificate
list / elements=string
Certificate Authority chain in PKI configuration.
certificate
string
Certificate in PKI configuration.
passphrase
string
Private key passphrase.
childless
string
    Choices:
  • allow
  • prefer
  • force
  • never
Childless IKE SA initiation support.
connection_type
string
    Choices:
  • initiate
  • trap
  • none
Connection type.
default_esp_group
string
Default ESP group name for tunnels under this peer that don't specify their own.
description
string
Description.
dhcp_interface
string
DHCP interface supplying the next-hop IP address.
disable
boolean
    Choices:
  • no
  • yes
Disable this peer.
force_udp_encapsulation
boolean
    Choices:
  • no
  • yes
Force UDP encapsulation.
ike_group
string
IKE group name.
ikev2_reauth
string
    Choices:
  • yes
  • no
  • inherit
Re-authentication of the remote peer during an IKE re-key (IKEv2 only).
local_address
string
IPv4 or IPv6 address of a local interface to use for the VPN, or "any".
name
string / required
Connection name of the peer.
remote_address
list / elements=string
IPv4 or IPv6 address(es) of the remote peer, or "any".
replay_window
integer
IPsec replay window to configure for this CHILD_SA.
tunnel
list / elements=dictionary
Policy-based tunnel definitions for this peer.
disable
boolean
    Choices:
  • no
  • yes
Disable this tunnel.
esp_group
string
ESP group name for this tunnel (overrides the peer's default_esp_group).
local
dictionary
Local traffic selector for this tunnel.
port
integer
Local port to match.
prefix
list / elements=string
Local IPv4 or IPv6 prefix(es) to match.
priority
integer
Priority for this IPsec policy (lowest value is most preferred).
protocol
string
Protocol to match for this tunnel's traffic selector.
remote
dictionary
Remote traffic selector for this tunnel.
port
integer
Remote port to match.
prefix
list / elements=string
Remote IPv4 or IPv6 prefix(es) to match.
tunnel_id
integer / required
The tunnel identifier.
virtual_address
list / elements=string
Initiator-requested virtual address(es) from the peer.
vti
dictionary
Route-based (VTI) connection settings for this peer.
bind
string
VTI tunnel interface associated with this connection.
esp_group
string
ESP group name for this VTI connection.
traffic_selector
dictionary
Traffic selector for the VTI connection.
local
dictionary
Local traffic-selector parameters.
prefix
list / elements=string
Local IPv4 or IPv6 prefix(es).
remote
dictionary
Remote traffic-selector parameters.
prefix
list / elements=string
Remote IPv4 or IPv6 prefix(es).
running_config
string
This option is used only with state parsed.
The value of this option should be the output received from the VyOS device by executing the command show configuration commands | match "vpn ipsec site-to-site".
The state parsed reads the configuration from the running_config option and transforms it into Ansible structured data as per the resource module's argspec, returned in the parsed key within the result.
state
string
    Choices:
  • merged ←
  • replaced
  • overridden
  • deleted
  • gathered
  • rendered
  • parsed
The state the configuration should be left in.

Notes ----- .. note:: - Tested against VyOS 1.4 and 1.5. - Source of truth: vyos-1x's interface-definitions/vpn_ipsec.xml.in, resolved and drafted via this collection's fetch_vyos_xml_definition.py / parse_xml_definitions.py helper scripts, then hand-reviewed. + - The argspec only requires *name* on a peer, but VyOS itself enforces several more requirements at commit time -- confirmed via real device testing, not visible in the argspec: every peer needs ``authentication``, a real ``remote_address`` (not just omitted), a ``local_address`` or ``dhcp_interface``, and at least one of ``tunnel`` or ``vti``. A peer missing any of these will pass Ansible's own argument validation but fail the device commit with a specific error naming what's missing. + - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide ` Examples -------- .. code-block:: yaml - name: Merge a site-to-site peer vyos.vyos.vyos_vpn_ipsec_s2s: config: peer: - name: PEER-TEST ike_group: IKE-TEST default_esp_group: ESP-TEST remote_address: - 203.0.113.1 state: merged Return Values ------------- Common return values are documented `here `_, the following are the fields unique to this module: .. raw:: html
Key Returned Description
after
dictionary
when changed
The resulting configuration after module execution.

+
Sample:
+
This output will always be in the same format as the module argspec.
before
dictionary
when state is merged, replaced, overridden or deleted
The configuration prior to the module execution.

+
Sample:
+
This output will always be in the same format as the module argspec.
commands
list
when state is merged, replaced, overridden or deleted
The set of commands pushed to the remote device.

+
Sample:
+
["set vpn ipsec site-to-site peer PEER-TEST ike-group 'IKE-TEST'", "set vpn ipsec site-to-site peer PEER-TEST default-esp-group 'ESP-TEST'"]
gathered
dictionary
when state is gathered
Facts about the network resource gathered from the remote device as structured data.

+
Sample:
+
This output will always be in the same format as the module argspec.
parsed
dictionary
when state is parsed
The device native config provided in running_config option parsed into structured data as per module argspec.

+
Sample:
+
This output will always be in the same format as the module argspec.
rendered
list
when state is rendered
The provided configuration in the task rendered in device-native format (offline).

+
Sample:
+
["set vpn ipsec site-to-site peer PEER-TEST ike-group 'IKE-TEST'"]


Status ------ Authors ~~~~~~~ - Evgeny Molotkov (@omnom62) diff --git a/plugins/modules/vyos_vpn_ipsec.py b/plugins/modules/vyos_vpn_ipsec.py index d70e81cc..9af12ff7 100644 --- a/plugins/modules/vyos_vpn_ipsec.py +++ b/plugins/modules/vyos_vpn_ipsec.py @@ -1,473 +1,454 @@ #!/usr/bin/python # -*- coding: utf-8 -*- # Copyright 2026 Red Hat # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) """ The module file for vyos_vpn_ipsec """ from __future__ import absolute_import, division, print_function __metaclass__ = type DOCUMENTATION = """ module: vyos_vpn_ipsec short_description: Manages global IPsec (ike-group, esp-group, profile, authentication, options) attributes of VyOS network devices. description: This module manages global VPN IPsec configuration on VyOS devices -- IKE groups, ESP groups, PSK/PPK authentication, IPsec profiles, and global options. Site-to-site peers and IKEv2 remote-access connections are handled by separate modules. version_added: 1.0.0 author: Evgeny Molotkov (@omnom62) +extends_documentation_fragment: + - vyos.vyos.vyos notes: - Tested against VyOS 1.4 and 1.5. - "Source of truth for field types/choices: device node.def templates under /opt/vyatta/share/vyatta-cfg/templates/vpn/ipsec/." options: config: description: IPsec global configuration. type: dict suboptions: ike_group: description: List of IKE groups. type: list elements: dict suboptions: name: description: The name of the IKE group. type: str required: true close_action: description: Action to take if a child SA is unexpectedly closed. type: str choices: [none, trap, start] dead_peer_detection: description: Dead Peer Detection (DPD). type: dict suboptions: action: description: Keep-alive failure action. type: str choices: [trap, clear, restart] interval: description: Keep-alive interval in seconds. type: int timeout: description: Dead Peer Detection keep-alive timeout (IKEv1 only), in seconds. type: int disable_mobike: description: Disable MOBIKE support (IKEv2 only). type: bool ikev2_reauth: description: Re-authentication of the remote peer during an IKE re-key (IKEv2 only). type: bool key_exchange: description: IKE version. type: str choices: [ikev1, ikev2] lifetime: description: IKE lifetime in seconds. type: int mode: description: IKEv1 phase 1 mode. type: str choices: [main, aggressive] proposal: description: List of IKE proposals. type: list elements: dict suboptions: proposal_id: description: The proposal identifier. type: int dh_group: description: Diffie-Hellman group. See VyOS/strongSwan documentation for the full set of valid values -- validated device-side, not enumerated here since the set is version-dependent. type: int encryption: description: Encryption algorithm. See VyOS/strongSwan documentation for the full set of valid values -- validated device-side, not enumerated here since the set is version-dependent. type: str hash: description: Hash algorithm. See VyOS/strongSwan documentation for the full set of valid values -- validated device-side. type: str prf: description: Pseudo-Random Function. See VyOS/strongSwan documentation for the full set of valid values -- validated device-side. type: str esp_group: description: List of ESP groups. type: list elements: dict suboptions: name: description: The name of the ESP group. type: str required: true compression: description: Enable ESP compression. type: bool disable_rekey: description: Do not locally initiate a re-key of the SA; remote peer must re-key before expiration. type: bool life_bytes: description: Security Association byte count to expire. type: int life_packets: description: Security Association packet count to expire. type: int lifetime: description: Security Association time to expire, in seconds. type: int mode: description: ESP mode. type: str choices: [tunnel, transport] pfs: description: ESP Perfect Forward Secrecy. See VyOS/strongSwan documentation for the full set of valid values -- validated device-side, not enumerated here since the set is version-dependent. type: str proposal: description: List of ESP proposals. type: list elements: dict suboptions: proposal_id: description: The proposal identifier. type: int encryption: description: Encryption algorithm. See VyOS/strongSwan documentation for the full set of valid values -- validated device-side, not enumerated here since the set is version-dependent. type: str hash: description: Hash algorithm. See VyOS/strongSwan documentation for the full set of valid values -- validated device-side. type: str authentication: description: Global pre-shared-key and post-quantum pre-shared-key definitions. type: dict suboptions: psk: description: List of pre-shared keys. type: list elements: dict suboptions: name: description: Pre-shared key name. type: str required: true id: description: ID(s) for authentication. type: list elements: str dhcp_interface: description: DHCP interface(s) supplying next-hop IP address. type: list elements: str secret: description: IKE pre-shared secret key. type: str secret_type: description: Secret encoding type. type: str choices: [base64, hex, plaintext] ppk: description: List of post-quantum pre-shared keys. type: list elements: dict suboptions: name: description: Post-quantum pre-shared key name. type: str required: true id: description: ID(s) for PPK. type: list elements: str secret: description: Post-quantum pre-shared secret key. type: str secret_type: description: Secret encoding type. type: str choices: [base64, hex, plaintext] profile: description: List of VPN IPsec profiles (used for e.g. DMVPN/GRE tunnel binding). type: list elements: dict suboptions: name: description: Profile name. type: str required: true authentication: description: Authentication settings for this profile. type: dict suboptions: mode: description: Authentication mode. type: str choices: [pre-shared-secret] pre_shared_secret: description: Pre-shared secret key. type: str bind_tunnel: description: Tunnel interface(s) associated with this profile. type: list elements: str disable: description: Disable this profile. type: bool esp_group: description: ESP group name to use for this profile. type: str ike_group: description: IKE group name to use for this profile. type: str interface: description: Interface(s) IPsec listens on. If omitted, listens on all interfaces. type: list elements: str log: description: IPsec logging settings. type: dict suboptions: level: description: Global IPsec logging level. type: int subsystem: description: Per-subsystem logging levels to enable. type: list elements: str options: description: Global IPsec options. type: dict suboptions: disable_route_autoinstall: description: Do not automatically install routes to remote networks. type: bool flexvpn: description: Allow FlexVPN vendor ID payload (IKEv2 only). type: bool interface: description: Single interface for IPsec options scope (distinct from top-level interface list). type: str retransmission: description: IPsec retransmission settings. type: dict suboptions: attempts: description: Maximum number of retransmissions. type: int base: description: Base of exponential backoff. type: float timeout: description: Timeout in seconds before the first retransmission. type: int virtual_ip: description: Allow install of virtual-ip addresses. type: bool disable_uniqreqids: description: Disable requirement for unique IDs in the Security Database. type: bool running_config: description: - This option is used only with state I(parsed). - The value of this option should be the output received from the VyOS device by executing the command B(show configuration commands | match "vpn ipsec"). - The states I(replaced) and I(overridden) have identical behaviour for this module with respect to named collections (ike_group, esp_group, profile, authentication), but differ in scope -- see the module description for detail. - The state I(parsed) reads the configuration from the C(running_config) option and transforms it into Ansible structured data as per the resource module's argspec, returned in the I(parsed) key within the result. type: str state: description: The state the configuration should be left in. type: str choices: [merged, replaced, overridden, deleted, gathered, rendered, parsed] default: merged """ EXAMPLES = """ -# ------------------- -# Using merged -# ------------------- - -# Before state: -# ------------- -# vyos@vyos:~$ show configuration commands | match "vpn ipsec" -# (empty) - -# Task -# ------------- -# - name: Merge provided configuration with device configuration -# vyos.vyos.vyos_vpn_ipsec: -# config: -# esp_group: -# - name: ESP-TEST -# proposal: -# - proposal_id: 1 -# encryption: aes256 -# hash: sha256 -# ike_group: -# - name: IKE-TEST -# key_exchange: ikev2 -# proposal: -# - proposal_id: 1 -# encryption: aes256 -# hash: sha256 -# dh_group: 14 -# state: merged - -# Task output: -# ------------- -# "commands": [ -# "set vpn ipsec esp-group ESP-TEST", -# "set vpn ipsec esp-group ESP-TEST proposal 1", -# "set vpn ipsec esp-group ESP-TEST proposal 1 encryption aes256", -# "set vpn ipsec esp-group ESP-TEST proposal 1 hash sha256", -# "set vpn ipsec ike-group IKE-TEST", -# "set vpn ipsec ike-group IKE-TEST key-exchange ikev2", -# "set vpn ipsec ike-group IKE-TEST proposal 1", -# "set vpn ipsec ike-group IKE-TEST proposal 1 encryption aes256", -# "set vpn ipsec ike-group IKE-TEST proposal 1 hash sha256", -# "set vpn ipsec ike-group IKE-TEST proposal 1 dh-group 14" -# ] - -# ------------------- -# Using gathered -# ------------------- +- name: Merge provided configuration with device configuration + vyos.vyos.vyos_vpn_ipsec: + config: + esp_group: + - name: ESP-TEST + proposal: + - proposal_id: 1 + encryption: aes256 + hash: sha256 + ike_group: + - name: IKE-TEST + key_exchange: ikev2 + proposal: + - proposal_id: 1 + encryption: aes256 + hash: sha256 + dh_group: 14 + state: merged -# Task -# ------------- -# - name: Gather current vpn_ipsec configuration -# vyos.vyos.vyos_vpn_ipsec: -# state: gathered +- name: Replace one named esp-group, leaving all other groups untouched + vyos.vyos.vyos_vpn_ipsec: + config: + esp_group: + - name: ESP-TEST + proposal: + - proposal_id: 1 + encryption: aes128 + hash: sha256 + state: replaced -# ------------------- -# Using deleted -# ------------------- +- name: Override the whole configuration -- anything not listed here is removed + vyos.vyos.vyos_vpn_ipsec: + config: + esp_group: + - name: ESP-TEST + proposal: + - proposal_id: 1 + encryption: aes256 + hash: sha256 + state: overridden -# Task -# ------------- -# - name: Remove all vpn_ipsec configuration -# vyos.vyos.vyos_vpn_ipsec: -# state: deleted +- name: Delete one named esp-group, leaving all other groups untouched + vyos.vyos.vyos_vpn_ipsec: + config: + esp_group: + - name: ESP-TEST + state: deleted -# ------------------- -# Using rendered -# ------------------- +- name: Remove all vpn_ipsec configuration + vyos.vyos.vyos_vpn_ipsec: + state: deleted -# Task -# ------------- -# - name: Render configuration without touching the device -# vyos.vyos.vyos_vpn_ipsec: -# config: -# esp_group: -# - name: ESP-TEST -# proposal: -# - proposal_id: 1 -# encryption: aes256 -# hash: sha256 -# state: rendered +- name: Gather current vpn_ipsec configuration + vyos.vyos.vyos_vpn_ipsec: + state: gathered -# ------------------- -# Using parsed -# ------------------- +- name: Render configuration without touching the device + vyos.vyos.vyos_vpn_ipsec: + config: + esp_group: + - name: ESP-TEST + proposal: + - proposal_id: 1 + encryption: aes256 + hash: sha256 + state: rendered -# Task -# ------------- -# - name: Parse raw config text into structured facts -# vyos.vyos.vyos_vpn_ipsec: -# running_config: "{{ lookup('file', './vpn_ipsec.cfg') }}" -# state: parsed +- name: Parse raw config text into structured facts + vyos.vyos.vyos_vpn_ipsec: + running_config: "{{ lookup('file', './vpn_ipsec.cfg') }}" + state: parsed """ RETURN = """ before: description: The configuration prior to the module execution. returned: when I(state) is C(merged), C(replaced), C(overridden) or C(deleted) type: dict sample: > This output will always be in the same format as the module argspec. after: description: The resulting configuration after module execution. returned: when changed type: dict sample: > This output will always be in the same format as the module argspec. commands: description: The set of commands pushed to the remote device. returned: when I(state) is C(merged), C(replaced), C(overridden) or C(deleted) type: list sample: - set vpn ipsec esp-group ESP-TEST proposal 1 encryption aes256 - set vpn ipsec ike-group IKE-TEST key-exchange ikev2 rendered: description: The provided configuration in the task rendered in device-native format (offline). returned: when I(state) is C(rendered) type: list sample: - set vpn ipsec esp-group ESP-TEST proposal 1 encryption aes256 gathered: description: Facts about the network resource gathered from the remote device as structured data. returned: when I(state) is C(gathered) type: dict sample: > This output will always be in the same format as the module argspec. parsed: description: The device native config provided in I(running_config) option parsed into structured data as per module argspec. returned: when I(state) is C(parsed) type: dict sample: > This output will always be in the same format as the module argspec. """ from ansible.module_utils.basic import AnsibleModule from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.vpn_ipsec.vpn_ipsec import ( Vpn_ipsecArgs, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.vpn_ipsec.vpn_ipsec import ( Vpn_ipsec, ) def main(): """ Main entry point for module execution :returns: the result form module invocation """ module = AnsibleModule( argument_spec=Vpn_ipsecArgs.argument_spec, mutually_exclusive=[["config", "running_config"]], required_if=[ ["state", "merged", ["config"]], ["state", "replaced", ["config"]], ["state", "overridden", ["config"]], ["state", "rendered", ["config"]], ["state", "parsed", ["running_config"]], ], supports_check_mode=True, ) result = Vpn_ipsec(module).execute_module() module.exit_json(**result) if __name__ == "__main__": main() diff --git a/plugins/modules/vyos_vpn_ipsec_s2s.py b/plugins/modules/vyos_vpn_ipsec_s2s.py index 73f8dc4b..7458381e 100644 --- a/plugins/modules/vyos_vpn_ipsec_s2s.py +++ b/plugins/modules/vyos_vpn_ipsec_s2s.py @@ -1,311 +1,337 @@ #!/usr/bin/python # -*- coding: utf-8 -*- # Copyright 2026 Red Hat # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) """ The module file for vyos_vpn_ipsec_s2s """ from __future__ import absolute_import, division, print_function __metaclass__ = type DOCUMENTATION = """ module: vyos_vpn_ipsec_s2s short_description: Manages IPsec site-to-site VPN peers on VyOS network devices. description: This module manages VPN IPsec site-to-site peer configuration on VyOS devices -- policy-based tunnels and route-based (VTI) connections. IKE/ESP groups, PSK/PPK authentication, and IPsec profiles are managed by the separate vyos_vpn_ipsec module; peers here reference those by name. version_added: 1.0.0 author: Evgeny Molotkov (@omnom62) +extends_documentation_fragment: + - vyos.vyos.vyos notes: - Tested against VyOS 1.4 and 1.5. - "Source of truth: vyos-1x's interface-definitions/vpn_ipsec.xml.in, resolved and drafted via this collection's fetch_vyos_xml_definition.py / parse_xml_definitions.py helper scripts, then hand-reviewed." + - "The argspec only requires I(name) on a peer, but VyOS itself enforces + several more requirements at commit time -- confirmed via real device + testing, not visible in the argspec: every peer needs C(authentication), + a real C(remote_address) (not just omitted), a C(local_address) or + C(dhcp_interface), and at least one of C(tunnel) or C(vti). A peer + missing any of these will pass Ansible's own argument validation but + fail the device commit with a specific error naming what's missing." options: config: description: IPsec site-to-site configuration. type: dict suboptions: peer: description: List of site-to-site peers. type: list elements: dict suboptions: name: description: Connection name of the peer. type: str required: true disable: description: Disable this peer. type: bool authentication: description: Peer authentication settings. type: dict suboptions: local_id: description: Local ID for peer authentication. type: str remote_id: description: ID for remote authentication. type: str mode: description: Authentication mode. type: str choices: [pre-shared-secret, rsa, x509] use_x509_id: description: Use certificate common name as ID. type: bool ppk: description: Post-quantum preshared key reference for this peer. type: dict suboptions: id: description: Post-quantum preshared key ID for this connection. type: str required: description: Require a valid PPK for the connection to establish. type: bool rsa: description: RSA key authentication. type: dict suboptions: local_key: description: Name of the PKI key-pair with the local private key. type: str remote_key: description: Name of the PKI key-pair with the remote public key. type: str passphrase: description: Local private key passphrase. type: str x509: description: X.509 certificate authentication. type: dict suboptions: certificate: description: Certificate in PKI configuration. type: str passphrase: description: Private key passphrase. type: str ca_certificate: description: Certificate Authority chain in PKI configuration. type: list elements: str childless: description: Childless IKE SA initiation support. type: str choices: [allow, prefer, force, never] connection_type: description: Connection type. type: str choices: [initiate, trap, none] default_esp_group: description: Default ESP group name for tunnels under this peer that don't specify their own. type: str description: description: Description. type: str dhcp_interface: description: DHCP interface supplying the next-hop IP address. type: str force_udp_encapsulation: description: Force UDP encapsulation. type: bool ike_group: description: IKE group name. type: str ikev2_reauth: description: Re-authentication of the remote peer during an IKE re-key (IKEv2 only). type: str choices: ["yes", "no", inherit] local_address: description: IPv4 or IPv6 address of a local interface to use for the VPN, or "any". type: str remote_address: description: IPv4 or IPv6 address(es) of the remote peer, or "any". type: list elements: str replay_window: description: IPsec replay window to configure for this CHILD_SA. type: int virtual_address: description: Initiator-requested virtual address(es) from the peer. type: list elements: str tunnel: description: Policy-based tunnel definitions for this peer. type: list elements: dict suboptions: tunnel_id: description: The tunnel identifier. type: int required: true disable: description: Disable this tunnel. type: bool esp_group: description: ESP group name for this tunnel (overrides the peer's default_esp_group). type: str protocol: description: Protocol to match for this tunnel's traffic selector. type: str priority: description: Priority for this IPsec policy (lowest value is most preferred). type: int local: description: Local traffic selector for this tunnel. type: dict suboptions: port: description: Local port to match. type: int prefix: description: Local IPv4 or IPv6 prefix(es) to match. type: list elements: str remote: description: Remote traffic selector for this tunnel. type: dict suboptions: port: description: Remote port to match. type: int prefix: description: Remote IPv4 or IPv6 prefix(es) to match. type: list elements: str vti: description: Route-based (VTI) connection settings for this peer. type: dict suboptions: bind: description: VTI tunnel interface associated with this connection. type: str esp_group: description: ESP group name for this VTI connection. type: str traffic_selector: description: Traffic selector for the VTI connection. type: dict suboptions: local: description: Local traffic-selector parameters. type: dict suboptions: prefix: description: Local IPv4 or IPv6 prefix(es). type: list elements: str remote: description: Remote traffic-selector parameters. type: dict suboptions: prefix: description: Remote IPv4 or IPv6 prefix(es). type: list elements: str running_config: description: - This option is used only with state I(parsed). - The value of this option should be the output received from the VyOS device by executing the command B(show configuration commands | match "vpn ipsec site-to-site"). - The state I(parsed) reads the configuration from the C(running_config) option and transforms it into Ansible structured data as per the resource module's argspec, returned in the I(parsed) key within the result. type: str state: description: The state the configuration should be left in. type: str choices: [merged, replaced, overridden, deleted, gathered, rendered, parsed] default: merged """ EXAMPLES = """ - name: Merge a site-to-site peer vyos.vyos.vyos_vpn_ipsec_s2s: config: peer: - name: PEER-TEST ike_group: IKE-TEST default_esp_group: ESP-TEST remote_address: - 203.0.113.1 state: merged """ RETURN = """ before: description: The configuration prior to the module execution. returned: when I(state) is C(merged), C(replaced), C(overridden) or C(deleted) type: dict + sample: > + This output will always be in the same format as the + module argspec. after: description: The resulting configuration after module execution. returned: when changed type: dict + sample: > + This output will always be in the same format as the + module argspec. commands: description: The set of commands pushed to the remote device. returned: when I(state) is C(merged), C(replaced), C(overridden) or C(deleted) type: list + sample: + - set vpn ipsec site-to-site peer PEER-TEST ike-group 'IKE-TEST' + - set vpn ipsec site-to-site peer PEER-TEST default-esp-group 'ESP-TEST' rendered: description: The provided configuration in the task rendered in device-native format (offline). returned: when I(state) is C(rendered) type: list + sample: + - set vpn ipsec site-to-site peer PEER-TEST ike-group 'IKE-TEST' gathered: description: Facts about the network resource gathered from the remote device as structured data. returned: when I(state) is C(gathered) type: dict + sample: > + This output will always be in the same format as the + module argspec. parsed: description: The device native config provided in I(running_config) option parsed into structured data as per module argspec. returned: when I(state) is C(parsed) type: dict + sample: > + This output will always be in the same format as the + module argspec. """ from ansible.module_utils.basic import AnsibleModule from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.vpn_ipsec_s2s.vpn_ipsec_s2s import ( Vpn_ipsec_s2sArgs, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.vpn_ipsec_s2s.vpn_ipsec_s2s import ( Vpn_ipsec_s2s, ) def main(): """ Main entry point for module execution :returns: the result form module invocation """ module = AnsibleModule( argument_spec=Vpn_ipsec_s2sArgs.argument_spec, mutually_exclusive=[["config", "running_config"]], required_if=[ ["state", "merged", ["config"]], ["state", "replaced", ["config"]], ["state", "overridden", ["config"]], ["state", "rendered", ["config"]], ["state", "parsed", ["running_config"]], ], supports_check_mode=True, ) result = Vpn_ipsec_s2s(module).execute_module() module.exit_json(**result) if __name__ == "__main__": main()