misc: WIP: vpn

This commit is contained in:
jeltz 2023-11-07 04:11:28 +01:00
parent 061b6f1049
commit 02910a8fc0
Signed by: jeltz
GPG key ID: 800882B66C0C3326
24 changed files with 231 additions and 120 deletions

View file

@ -7,9 +7,9 @@ ifupdown2__gateways:
int:
- 2a09:6840:206::1
- 10.206.0.1
pub:
- 2a09:6840:111::254
- 45.66.111.254
ext:
- 2a09:6840:211::1
- 10.211.0.1
monit:
- 2a09:6840:204::1
- 10.204.0.1

View file

@ -57,4 +57,28 @@ bird__bgp:
- pref_src: "{{ bird__pref_src_addr }}"
- accept
export: reject
wg1:
local:
address: "{{ bird__bgp_addr.vpn }}"
as: "{{ bird__as.aurore }}"
neighbor:
address:
- 2a09:6840:213::1:3
- 10.213.1.3
as: "{{ bird__as.aurore }}"
rr_cluster_client: 10.203.1.1
import: reject
export: accept
wg2:
local:
address: "{{ bird__bgp_addr.vpn }}"
as: "{{ bird__as.aurore }}"
neighbor:
address:
- 2a09:6840:213::1:4
- 10.203.1.4
as: "{{ bird__as.aurore }}"
rr_cluster_client: 10.203.1.1
import: reject
export: accept
...

View file

@ -104,7 +104,13 @@ firewall__zones:
- 10.128.0.150
firewall__input:
- src: back
- iif:
- back0 # FIXME link-local
- vpn0
verdict: accept
- src:
- back
- vpn
verdict: accept
- src: monit
protocols:

58
group_vars/vpn/bird.yml Normal file
View file

@ -0,0 +1,58 @@
---
bird__kernel:
kernel:
learn: true
import: accept
export: accept
vrf:
import: reject
export: accept
table: wg
kernel: "{{ iproute2__custom_protos.wireguard }}"
bird__ospf:
limits:
import: 4000
export: 4000
table: wg
import: accept
export:
protos:
- kernel
- wireguard
areas:
1:
broadcast:
- vpn0
bird__tables:
- wg
bird__bgp:
infra1:
local:
address: "{{ bird__bgp_addr.vpn }}"
as: "{{ bird__as.aurore }}"
neighbor:
address:
- 2a09:6840:213::1:1
- 10.213.1.1
as: "{{ bird__as.aurore }}"
table: wg
import: accept
export: reject
next_hop_self: true
infra2:
local:
address: "{{ bird__bgp_addr.vpn }}"
as: "{{ bird__as.aurore }}"
neighbor:
address:
- 2a09:6840:213::1:2
- 10.213.1.2
as: "{{ bird__as.aurore }}"
table: wg
import: accept
export: reject
next_hop_self: true
...

View file

@ -1,24 +1,15 @@
---
ifupdown2__vrf:
wg-vrf:
table: "{{ iproute2__custom_tables.wireguard }}"
ifupdown2__wireguard:
wg0:
private_key: "{{ vault_wireguard_wg0_private }}"
listen_port: 5121
goto_table: bird
vrf: wg-vrf
peer_allowed_addresses:
- 2a09:6840:212::1:1/128
- 10.212.1.1/32
peer_public_key: 0kP/XjaGOpu4p9KHTAoAhkLwXzC8wJUdPIdhdpgeKhY=
ifupdown2__interfaces:
adm0:
addresses:
- 2a09:6840:128::10:11/64
- 10.128.10.11/16
ext0:
addresses:
- 45.66.111.200/30
vpn0:
addresses:
- 2a09:6840:213::1:3/64
- 10.213.1.3/16
...

View file

@ -0,0 +1,7 @@
---
iproute2__custom_tables:
wireguard: 2000
iproute2__custom_protos:
wireguard: 2000
...

View file

@ -38,8 +38,8 @@ ifupdown2__interfaces:
ipv6_addrgen: false
vpn0:
addresses:
- 2a09:6840:213::1:1
- 10.213.1.1
- 2a09:6840:213::1:1/64
- 10.213.1.1/16
bird__router_id: 10.203.1.3
@ -47,6 +47,9 @@ bird__bgp_addr:
back:
- 2a09:6840:203::1:3
- 10.203.1.3
vpn:
- 2a09:6840:213::1:1
- 10.213.1.1
bird__pref_src_addr:
- 2a09:6840:203::1:3

View file

@ -38,8 +38,8 @@ ifupdown2__interfaces:
ipv6_addrgen: false
vpn0:
addresses:
- 2a09:6840:213::1:2
- 10.213.1.2
- 2a09:6840:213::1:2/64
- 10.213.1.2/16
bird__router_id: 10.203.1.4
@ -47,6 +47,9 @@ bird__bgp_addr:
back:
- 2a09:6840:203::1:4
- 10.203.1.4
vpn:
- 2a09:6840:213:1:2
- 10.213.1.2
bird__pref_src_addr:
- 2a09:6840:203::1:4

View file

@ -363,12 +363,12 @@ knotd__zones:
dns-2.int:
- 2a09:6840:206::1:2
- 10.206.1.2
vpn-1.back:
- 10.128.10.11
- 2a09:6840:128::10:11
vpn-2.back:
- 10.128.10.111
- 2a09:6840:128::10:111
wg-1.vpn:
- 2a09:6840:213::1:3
- 10.213.1.3
wg-2.vpn:
- 2a09:6840:213::1:4
- 10.213.1.4
infra-1.back:
- 2a09:6840:203::1:3
- 10.203.1.3

View file

@ -0,0 +1,24 @@
---
systemd_link__links:
vpn0: 02:00:00:b5:ca:c7
ext0: 02:00:00:e3:65:49
ifupdown2__interfaces:
ext0:
gateways: "{{ ifupdown2__gateways.ext }}"
addresses:
- 2a09:6840:211::1:1/64
- 10.211.1.1/16
- 45.66.111.200/30
vpn0:
addresses:
- 2a09:6840:213::1:3/64
- 10.213.1.3/16
bird__router_id: 10.213.1.3
bird__bgp_addr:
vpn:
- 2a09:6840:213::1:3
- 10.213.1.3
...

24
hosts
View file

@ -19,7 +19,7 @@ eb-1.ups.infra.auro.re
ec-1.ups.infra.auro.re
[vpn]
#vpn-[1:2].back.infra.auro.re
wg-[1:2].vpn.infra.auro.re
[dns]
dns-[1:2].int.infra.auro.re
@ -54,17 +54,17 @@ ntp-[1:2].int.infra.auro.re
[radius]
radius-[1:2].isp.infra.auro.re
[vm_network]
#vpn-[1:2].back.infra.auro.re
edge-[1:2].back.infra.auro.re
dhcp-[1:2].isp.infra.auro.re
dns-[1:2].int.infra.auro.re
radius-[1:2].isp.infra.auro.re
ntp-[1:2].int.infra.auro.re
#ldap-[1:2].int.infra.auro.re
isp-[1:2].back.infra.auro.re
infra-[1:2].back.infra.auro.re
prometheus-[1:2].monit.infra.auro.re
[vm_network:children]
vpn
edge
dhcp
dns
radius
ntp
#ldap
isp
infra
prom
[pve:children]
pve_network

View file

@ -3,6 +3,7 @@
- hosts:
- infra
- isp
- vpn
roles:
- bird

View file

@ -1,17 +1,10 @@
#!/usr/bin/env ansible-playbook
---
- hosts:
- edge-1.back.infra.auro.re
- edge-2.back.infra.auro.re
- isp-1.back.infra.auro.re
- isp-2.back.infra.auro.re
- infra-1.back.infra.auro.re
- infra-2.back.infra.auro.re
- vpn-1.back.infra.auro.re
- vpn-2.back.infra.auro.re
vars:
iproute2__custom_tables:
bird: 100
- edge
- isp
- infra
- vpn
roles:
- iproute2
...

View file

@ -11,12 +11,6 @@
- ldap
- isp
- vpn
vars:
systemd_link__hosts:
vpn-1.back.infra.auro.re:
adm0: 02:00:00:3b:74:20
vpn0: 02:00:00:b5:ca:c7
pub0: 02:00:00:e3:65:49
roles:
- systemd_link
...

View file

@ -1,7 +1,7 @@
---
bird__ospf_stub_interfaces: []
bird__ospf_stub_networks: []
bird__ospf_broadcast_interfaces: {}
bird__kernel: {}
bird__pipes: {}
bird__tables: {}
bird__ospf_hello: 2
bird__ospf_retransmit: 5
bird__ospf_wait: 10
@ -10,5 +10,5 @@ bird__radv_interfaces: {}
bird__radv_dns_servers: []
bird__radv_max_interval: 5
bird__static_unreachable: []
bird__bgp_sessions: []
bird__bgp_sessions: {}
...

View file

@ -135,7 +135,7 @@ def str_of_condition(condition: Condition, ctx: bool) -> str:
case Proto(protos=protos):
protos = [quoted(bird_name(p, ctx.ipv4)) for p in protos]
return f"proto ~ [ {', '.join(protos)} ]"
return " || ".join(f"proto = {p}" for p in protos)
case Source(sources=[source]):
return f"krt_source = {source}"

View file

@ -1,9 +1,26 @@
{{ ansible_managed | comment }}
{% macro import_export(obj, ipv4) %}
{{ obj.import | default([]) | bird_import(ipv4) }}
{% if obj.limits.import is defined %}
import limit {{ obj.limits.import }};
{% endif %}
{{ obj.export | default([]) | bird_export(ipv4) }}
{% if obj.limits.export is defined %}
export limit {{ obj.limits.export }};
{% endif %}
{% endmacro %}
log syslog all;
router id {{ bird__router_id }};
{% for table in bird__tables %}
{% for version in ["ipv4", "ipv6"] %}
{{ version }} table {{ table | bird_name(version == "ipv4") }};
{% endfor %}
{% endfor %}
protocol device {
scan time 10;
}
@ -22,45 +39,36 @@ protocol kernel {{ name | bird_name(ipv4) }} {
persist;
{% endif %}
{{ version }} {
{{ kernel.import
| default([])
| bird_import(ipv4)
| indent(8) }}
{% if kernel.limits.import is defined %}
import limit {{ kernel.limits.import }};
{% endif %}
{{ kernel.export
| default([])
| bird_export(ipv4)
| indent(8) }}
{% if kernel.limits.export is defined %}
export limit {{ kernel.limits.export }};
{% if kernel.table is defined %}
table {{ kernel.table | bird_name(ipv4) }};
{% endif %}
{{ import_export(kernel, ipv4) | indent(8) }}
};
}
{% endfor %}
{% endfor %}
{% for name, pipe in bird__pipes.items() %}
{% for version in ["ipv4", "ipv6"] %}
{% set ipv4 = version == "ipv4" %}
protocol pipe {{ name | bird_name(ipv4) }} {
table {{ pipe.table | bird_name(ipv4) }};
peer_table {{ pipe.peer_table | bird_name(ipv4) }};
{{ import_export(kernel, ipv4) | indent(8) }}
}
{% endfor %}
{% endfor %}
{% if bird__ospf is defined %}
{% for version in ["ipv4", "ipv6"] %}
{% set ipv4 = version == "ipv4" %}
{% set ospf_version = "v2" if ipv4 else "v3" %}
protocol ospf {{ ospf_version }} {{ "ospf" | bird_name(ipv4) }} {
{{ version }} {
{{ bird__ospf.import
| default([])
| bird_import(ipv4)
| indent(8) }}
{% if bird__ospf.limits.import is defined %}
import limit {{ bird__ospf.limits.import }};
{% endif %}
{{ bird__ospf.export
| default([])
| bird_export(ipv4)
| indent(8) }}
{% if bird__ospf.limits.export is defined %}
export limit {{ bird__ospf.limits.export }};
{% if bird__ospf.table is defined %}
table {{ bird__ospf.table | bird_name(ipv4) }};
{% endif %}
{{ import_export(bird__ospf, ipv4) | indent(8) }}
};
{% for id, area in bird__ospf.areas.items() %}
area {{ id }} {
@ -97,20 +105,13 @@ protocol bgp {{ name | bird_name(ipv4) }} {
rr cluster id {{ bgp.rr_cluster_client }};
{% endif %}
{{ version }} {
{{ bgp.import
| default([])
| bird_import(ipv4)
| indent(8) }}
{% if bgp.limits.import is defined %}
import limit {{ bgp.limits.import }};
{% if bgp.table is defined %}
table {{ bgp.table | bird_name(ipv4) }};
{% endif %}
{{ bgp.export
| default([])
| bird_export(ipv4)
| indent(8) }}
{% if bgp.limits.export is defined %}
export limit {{ bgp.limits.export }};
{% if bgp.next_hop_self is defined %}
next hop self;
{% endif %}
{{ import_export(bgp, ipv4) | indent(8) }}
};
}
{% endfor %}

View file

@ -155,8 +155,8 @@ class Protocols(RestrictiveBaseModel):
class Rule(RestrictiveBaseModel):
iif: str | None
oif: str | None
iif: AutoSet[str] | None
oif: AutoSet[str] | None
protocols: Protocols = Protocols()
src: AutoSet[IPvAnyNetwork | ZoneName] | None
dst: AutoSet[IPvAnyNetwork | ZoneName] | None

View file

@ -1,6 +1,7 @@
---
ifupdown2__interfaces: {}
ifupdown2__wireguard: {}
ifupdown2__vrf: {}
ifupdown2__wireguard_keepalive: 0
ifupdown2__wireguard_proto: boot
ifupdown2__prio_base: 100

View file

@ -21,6 +21,9 @@ pre-up ip rule add prio {{ prio + 1 }} iif $IFACE blackhole
post-down ip rule del prio {{ prio }} iif $IFACE table {{ iface.goto_table }}
post-down ip rule del prio {{ prio + 1 }} iif $IFACE blackhole
{% endif %}
{% if iface.vrf is defined %}
vrf {{ iface.vrf }}
{% endif %}
{% if iface.ipv6_addrgen is defined %}
ipv6-addrgen {{ iface.ipv6_addrgen
| ternary("yes", "no") }}
@ -63,5 +66,11 @@ iface {{ name }}
{% for address in iface.peer_allowed_addresses | default([]) %}
post-up ip route add {{ address }} proto {{ ifupdown2__wireguard_proto }} dev $IFACE
{% endfor %}
{% endfor %}
{% for name, iface in ifupdown2__vrf.items() | sort(attribute="0") %}
auto {{ name }}
iface {{ name }}
{{ iface_common(iface, index=loop.index) | indent(4) }}
vrf-table {{ iface.table }}
{% endfor %}

View file

@ -1,8 +1,4 @@
---
iproute2__default_tables:
local: 255
main: 254
default: 253
unspec: 0
iproute2__custom_tables: {}
iproute2__custom_protos: {}
...

View file

@ -1,17 +1,12 @@
---
- name: Ensure that default and custom tables names don't overlap
assert:
that: "not (iproute2__default_tables.keys()
| intersect(iproute2__custom_tables.keys()))"
- name: Configure rt_tables
- name: Configure custom tables and protos
template:
src: rt_tables.j2
dest: /etc/iproute2/rt_tables
src: "{{ item }}.j2"
dest: "/etc/iproute2/{{ item }}.d/custom.conf"
owner: root
group: root
mode: u=rw,g=r,o=r
vars:
iproute2__tables: "{{ iproute2__default_tables
| combine(iproute2__custom_tables) }}"
loop:
- rt_tables
- rt_protos
...

View file

@ -0,0 +1,5 @@
{{ ansible_managed | comment }}
{% for name, id in iproute2__custom_protos.items() %}
{{ id }} {{ name }}
{% endfor %}

View file

@ -1,5 +1,5 @@
{{ ansible_managed | comment }}
{% for name, id in iproute2__tables.items() %}
{% for name, id in iproute2__custom_tables.items() %}
{{ id }} {{ name }}
{% endfor %}