summaryrefslogtreecommitdiff
path: root/roles/ipsec_route_based/tasks
diff options
context:
space:
mode:
Diffstat (limited to 'roles/ipsec_route_based/tasks')
-rw-r--r--roles/ipsec_route_based/tasks/main.yml113
-rw-r--r--roles/ipsec_route_based/tasks/verify.yml52
2 files changed, 165 insertions, 0 deletions
diff --git a/roles/ipsec_route_based/tasks/main.yml b/roles/ipsec_route_based/tasks/main.yml
new file mode 100644
index 0000000..a3b4c16
--- /dev/null
+++ b/roles/ipsec_route_based/tasks/main.yml
@@ -0,0 +1,113 @@
+---
+- name: Peers sharing a PSK entry use the same key
+ ansible.builtin.assert:
+ that: >-
+ ipsec_route_based_peers | selectattr('psk_name', 'defined') | selectattr('psk_name', 'equalto', _ipsec_route_based_psk_name)
+ | map(attribute='psk') | unique | length == 1
+ fail_msg: "peers with psk_name {{ _ipsec_route_based_psk_name }} have different psk values"
+ quiet: true
+ loop: "{{ ipsec_route_based_peers | selectattr('psk_name', 'defined') | map(attribute='psk_name') | unique | list }}"
+ loop_control:
+ loop_var: _ipsec_route_based_psk_name
+ no_log: true
+
+- name: Create the VTIs
+ vyos.vyos.vyos_interfaces:
+ config: "{{ lookup('ansible.builtin.template', 'vti.yml.j2') | from_yaml }}"
+ state: "{{ _ipsec_route_based_state }}"
+ register: _ipsec_route_based_r_vti
+
+- name: Clamp TCP MSS on the VTIs
+ # vyos_interfaces has no option for ip adjust-mss.
+ vyos.vyos.vyos_config:
+ lines: "{{ _ipsec_route_based_cli_lines }}"
+ register: _ipsec_route_based_r_cli
+ when:
+ - _ipsec_route_based_cli_lines | length > 0
+ - not (vyos_blueprints_render_only | default(false) | bool)
+
+- name: Address the VTIs
+ vyos.vyos.vyos_l3_interfaces:
+ config: "{{ lookup('ansible.builtin.template', 'vti_l3.yml.j2') | from_yaml }}"
+ state: "{{ _ipsec_route_based_state }}"
+ register: _ipsec_route_based_r_vti_l3
+
+- name: Configure IKE/ESP groups, pre-shared keys and options
+ vyos.vyos.vyos_vpn_ipsec:
+ config: "{{ lookup('ansible.builtin.template', 'vpn_ipsec.yml.j2') | from_yaml }}"
+ state: "{{ _ipsec_route_based_state }}"
+ register: _ipsec_route_based_r_ipsec
+ no_log: true
+
+- name: Configure the site-to-site peers
+ vyos.vyos.vyos_vpn_ipsec_s2s:
+ config: "{{ lookup('ansible.builtin.template', 'vpn_ipsec_s2s.yml.j2') | from_yaml }}"
+ state: "{{ _ipsec_route_based_state }}"
+ register: _ipsec_route_based_r_s2s
+
+- name: Add the default route towards the WAN gateway
+ vyos.vyos.vyos_static_routes:
+ config:
+ - address_families:
+ - afi: ipv4
+ routes:
+ - dest: 0.0.0.0/0
+ next_hops:
+ - forward_router_address: "{{ ipsec_route_based_default_gateway }}"
+ state: "{{ _ipsec_route_based_state }}"
+ register: _ipsec_route_based_r_route
+ when: ipsec_route_based_default_gateway | length > 0
+
+- name: Add interface routes through the VTIs (e.g. to the peer's BGP listener)
+ vyos.vyos.vyos_static_routes:
+ config:
+ - address_families:
+ - afi: ipv4
+ routes: "{{ lookup('ansible.builtin.template', 'interface_routes.yml.j2') | from_yaml }}"
+ state: "{{ _ipsec_route_based_state }}"
+ register: _ipsec_route_based_r_ifroutes
+ when: ipsec_route_based_interface_routes | length > 0
+
+- name: Run BGP over the VTIs
+ vyos.vyos.vyos_bgp_global:
+ config: "{{ lookup('ansible.builtin.template', 'bgp_global.yml.j2') | from_yaml }}"
+ state: "{{ _ipsec_route_based_state }}"
+ register: _ipsec_route_based_r_bgp
+ when: _ipsec_route_based_bgp | length > 0
+
+- name: Set BGP address-family options (networks, soft-reconfiguration)
+ vyos.vyos.vyos_bgp_address_family:
+ config: "{{ _ipsec_route_based_bgp_af }}"
+ state: "{{ _ipsec_route_based_state }}"
+ vars:
+ _ipsec_route_based_bgp_af: "{{ lookup('ansible.builtin.template', 'bgp_address_family.yml.j2') | from_yaml }}"
+ register: _ipsec_route_based_r_bgp_af
+ when:
+ - _ipsec_route_based_bgp | length > 0
+ - _ipsec_route_based_bgp_af | length > 1
+
+- name: Run OSPF over the VTIs
+ vyos.vyos.vyos_ospfv2:
+ config: "{{ lookup('ansible.builtin.template', 'ospfv2.yml.j2') | from_yaml }}"
+ state: "{{ _ipsec_route_based_state }}"
+ register: _ipsec_route_based_r_ospf
+ when: _ipsec_route_based_ospf | length > 0
+
+- name: Set OSPF interface options (point-to-point VTIs, passive LANs)
+ vyos.vyos.vyos_ospf_interfaces:
+ config: "{{ lookup('ansible.builtin.template', 'ospf_interfaces.yml.j2') | from_yaml }}"
+ state: "{{ _ipsec_route_based_state }}"
+ register: _ipsec_route_based_r_ospf_if
+ when: _ipsec_route_based_ospf | length > 0
+
+- name: Collect rendered commands # noqa: var-naming[no-role-prefix] - shared across roles by design
+ ansible.builtin.set_fact:
+ vyos_blueprints_rendered: >-
+ {{ vyos_blueprints_rendered | default([])
+ + (_ipsec_route_based_r_vti.rendered | default([]))
+ + _ipsec_route_based_cli_lines
+ + ([_ipsec_route_based_r_vti_l3, _ipsec_route_based_r_ipsec, _ipsec_route_based_r_s2s,
+ _ipsec_route_based_r_route, _ipsec_route_based_r_ifroutes, _ipsec_route_based_r_bgp,
+ _ipsec_route_based_r_bgp_af, _ipsec_route_based_r_ospf, _ipsec_route_based_r_ospf_if]
+ | selectattr('rendered', 'defined') | map(attribute='rendered') | flatten | unique) }}
+ when: vyos_blueprints_render_only | default(false) | bool
diff --git a/roles/ipsec_route_based/tasks/verify.yml b/roles/ipsec_route_based/tasks/verify.yml
new file mode 100644
index 0000000..42edd24
--- /dev/null
+++ b/roles/ipsec_route_based/tasks/verify.yml
@@ -0,0 +1,52 @@
+---
+- name: Read IPsec SAs
+ vyos.vyos.vyos_command:
+ commands:
+ - show vpn ipsec sa
+ register: _ipsec_route_based_v_sa
+
+- name: The IPsec SA of every peer is up
+ ansible.builtin.assert:
+ that: _ipsec_route_based_v_sa.stdout[0] is search('(?m)^' ~ (item.name | regex_escape) ~ '-vti\s+up\b')
+ fail_msg: "IPsec SA {{ item.name }}-vti is not up"
+ quiet: true
+ loop: "{{ ipsec_route_based_peers }}"
+ loop_control:
+ label: "{{ item.name }}"
+
+- name: Read OSPF neighbours
+ vyos.vyos.vyos_command:
+ commands:
+ - show ip ospf neighbor
+ register: _ipsec_route_based_v_ospf
+ when: ipsec_route_based_ospf | default({}, true) | length > 0
+
+- name: A Full OSPF adjacency on every VTI
+ ansible.builtin.assert:
+ that: _ipsec_route_based_v_ospf.stdout[0] is search('Full.*\s' ~ (item.vti.interface | regex_escape) ~ ':')
+ fail_msg: "no Full OSPF adjacency on {{ item.vti.interface }}"
+ quiet: true
+ loop: "{{ ipsec_route_based_peers }}"
+ loop_control:
+ label: "{{ item.vti.interface }}"
+ when: ipsec_route_based_ospf | default({}, true) | length > 0
+
+- name: Read BGP neighbours
+ vyos.vyos.vyos_command:
+ commands:
+ - show bgp summary
+ register: _ipsec_route_based_v_bgp
+ when: ipsec_route_based_bgp | default({}, true) | length > 0
+
+- name: Every BGP session is established
+ # An established neighbour shows its Up/Down time followed by a prefix count.
+ ansible.builtin.assert:
+ that: >-
+ _ipsec_route_based_v_bgp.stdout[0] is search('(?m)^' ~ (item.address | regex_escape)
+ ~ '\s.*\s(\d{2}:\d{2}:\d{2}|\d+[dwh]\S*)\s+\d+\b')
+ fail_msg: "BGP session to {{ item.address }} is not established"
+ quiet: true
+ loop: "{{ (ipsec_route_based_bgp | default({}, true)).neighbors | default([]) }}"
+ loop_control:
+ label: "{{ item.address }}"
+ when: ipsec_route_based_bgp | default({}, true) | length > 0