network/roles/firewall/templates/frr.conf.j2
Timotej Lazar 7b5980f871 exit: add routes for internal IPv4 addresses to outside VRF
Routed through and mostly dropped by the firewall, of course. So we
don’t necessarily have to do NAT for everything that comes from the
old / USI network.
2024-08-13 19:02:03 +02:00

150 lines
5 KiB
Django/Jinja

{% set addrs = interfaces | selectattr('name', '==', 'lo') |
map(attribute='ip_addresses') | first | selectattr('role') %}
{% set loopback = addrs | selectattr('role.value', '==', 'loopback') | map(attribute='address') -%}
frr defaults datacenter
service integrated-vtysh-config
log syslog
# Without this frr and kernel ECMP routes sometimes get desynced when a link is
# lost and found. Maybe related to https://github.com/FRRouting/frr/issues/12239.
zebra nexthop-group keep 1
router-id {{ loopback | ipv4 | first | ipaddr('address') }}
bfd
profile fast
receive-interval 150
transmit-interval 150
# Default VRF has two connections to each exit, one for inside and one
# for outside networks. The efault route is received from the outside
# peers and distributed back to inside peers. Routes to office
# networks and NAT IPs are distributed to outside peers.
router bgp {{ asn.asn }}
# Allow multipathing through different ASs with equal path length.
bgp bestpath as-path multipath-relax
# NAT IPs are not on any interface so disable checking for it.
no bgp network import-check
{% for group in ['inside', 'outside'] %}
neighbor {{ group }} peer-group
neighbor {{ group }} remote-as external
neighbor {{ group }} capability extended-nexthop
{% endfor %}
{% for iface in interfaces | selectattr('name', 'match', '^lan') %}
neighbor {{ iface.name }}.2 interface peer-group inside
neighbor {{ iface.name }}.2 bfd profile fast
neighbor {{ iface.name }}.4 interface peer-group outside
neighbor {{ iface.name }}.4 bfd profile fast
{% endfor %}
address-family ipv4 unicast
{% for network in nat %}
network {{ network }}
{% endfor %}
redistribute connected route-map loopback
maximum-paths 16
neighbor outside soft-reconfiguration inbound
neighbor outside route-map outside->default in
neighbor outside route-map default->outside out
neighbor inside allowas-in origin
neighbor inside default-originate
neighbor inside soft-reconfiguration inbound
neighbor inside route-map inside->default in
neighbor inside route-map default->inside out
exit-address-family
address-family ipv6 unicast
redistribute connected route-map loopback
maximum-paths 16
neighbor outside activate
neighbor outside soft-reconfiguration inbound
neighbor outside route-map outside->default in
neighbor outside route-map default->outside out
neighbor inside activate
neighbor inside allowas-in origin
neighbor inside default-originate
neighbor inside soft-reconfiguration inbound
neighbor inside route-map inside->default in
neighbor inside route-map default->inside out
exit-address-family
# Prefix lists.
ip prefix-list default permit 0.0.0.0/0
ipv6 prefix-list default permit ::/0
ip prefix-list fabric permit 10.34.0.0/24 ge 32
{% for prefix in vrf_prefixes | rejectattr('vrf.name', '==', 'outside')
| sort(attribute='family.value') %}
{% if prefix.family.value == 4 %}
ip prefix-list office permit {{ prefix.prefix }} ge {{ prefix.prefix | ipaddr('prefix') }}
{% elif prefix.family.value == 6 %}
ipv6 prefix-list office permit {{ prefix.prefix }} ge {{ prefix.prefix | ipaddr('prefix') }}
{% endif %}
{% endfor %}
{% if wg_net is defined %}
ip prefix-list vpn permit {{ wg_net | ipaddr('subnet') }}
{% endif %}
{% if wg_net6 is defined %}
ipv6 prefix-list vpn permit {{ wg_net6 | ipaddr('subnet') }}
{% endif %}
{% for network in nat %}
ip prefix-list nat permit {{ network }}
{% endfor %}
{# TODO WG endpoint should probably be in a separate prefix-list. #}
ip prefix-list nat permit {{ wg_ip }}
route-map loopback permit 1
match interface lo
route-map loopback permit 2
match interface wg
# Get routes to offices from inside peers.
route-map inside->default permit 10
match ip address prefix-list fabric
route-map inside->default permit 20
match ip address prefix-list office
route-map inside->default permit 21
match ipv6 address prefix-list office
# Send default route and VPN network to inside peers.
route-map default->inside permit 1
match interface lo
route-map default->inside permit 20
match ip address prefix-list default
route-map default->inside permit 21
match ipv6 address prefix-list default
# I don’t think these /need/ to be announced separately since we are sending the default route anyway.
#route-map default->inside permit 30
# match ip address prefix-list vpn
#route-map default->inside permit 31
# match ipv6 address prefix-list vpn
# Get default route from outside peers.
route-map outside->default permit 10
match ip address prefix-list default
route-map outside->default permit 11
match ipv6 address prefix-list default
# Send inside and NAT addresses to outside peers so inbound packets go through the firewall.
route-map default->outside permit 1
match interface lo
route-map default->outside permit 10
match ip address prefix-list office
route-map default->outside permit 11
match ipv6 address prefix-list office
route-map default->outside permit 20
match ip address prefix-list nat
route-map default->outside permit 31
match ipv6 address prefix-list vpn