lixonet-ee/bird/bird.conf.tmpl
Manevolent 69c27149da
Remove "+" from wireguard route check
This will prevent lixonet from sharing exact addresses like 172.31.1.16 (etc.), which might take precedence over actual Wireguard routes.  The plan is to have Wireguard's metric for the 1.x/24s be lower (or whatever is needed) so that it is always preferred when traffic reaches a wg-enabled host.
2022-12-17 21:54:38 -07:00

251 lines
9.5 KiB
Cheetah

# Lixonet BIRD configuration
# This is a templated file that automatically generates values at configuration time
# If you edit this file, it will be overwritten. Changes to the general structure of
# this configuration file that should be persisted should be committed to Git.
# For BIRD 2.0 configuration reference, see:
# https://bird.network.cz/?get_doc&f=bird.html&v=20
# For a great example configuration file, see:
# https://fossies.org/linux/bird/doc/bird.conf.example
# Global variables
# See: https://bird.network.cz/?get_doc&v=20&f=bird-3.html#ss3.2
log stderr all; # Using docker; defer logging to stderr (to Docker logs)
#debug protocols all; # Enable debugging (this should be switched off in prod)
router id ${tinc_peer_address};
timeformat protocol iso long; # See: https://github.com/czerwonk/bird_exporter
# Custom routing tables
# See: https://bird.network.cz/?get_doc&v=20&f=bird-2.html (recommended read)
ipv4 table ${netname:-lixonet}_v4;
roa4 table r4; # ROA RPKI
# RPKI
# See: https://brooks.sh/2019/11/11/validating-bgp-routes-with-rpki-in-bird/
protocol rpki {
roa4 { table r4; };
{{ range files "bird/rpki/hosts" }} # {{.}}
{{ file (print "bird/rpki/hosts/" .) }}
{{ end }}
# Time period in seconds between a failed query the next attempt
retry keep ${bgp_rpki_retry:-90};
# Tells how long to wait before attempting to poll the cache
refresh keep ${bgp_rpki_refresh:-900};
# How long to keep any records locally cached before they are deleted
# The "refresh" interval will control how often records are refreshed
# and not considered expired.
expire keep ${bgp_rpki_expire:-172800};
}
# Filters
# Define a series of filters for Lixonet routing policies:
# - Cannot advertise a route which is in the router subnet: typically 172.x.0.0/24
# See: https://gitlab.labs.nic.cz/labs/bird/wikis/BGP_filtering
# For syntax docs, see: https://bird.network.cz/?get_doc&v=16&f=bird-5.html
# Returns TRUE if the given prefix is found in a kept RPKI cache.
# Returns FALSE if the given prefix is either,
# - Valid in the cached RPKI list, or
# - RPKI has not yet been established and the route cannot be validated
# From BIRD documentation (https://bird.network.cz/?get_doc&v=20&f=bird-5.html):
# roa_check: Checks the current route (which should be from BGP to
# have AS_PATH argument) in the specified ROA table and returns
# ROA_UNKNOWN if there is no relevant ROA, ROA_VALID if there is
# a matching ROA, or ROA_INVALID if there are some relevant ROAs
# but none of them match.
function is_rpki_invalid_v4 () {
return roa_check(r4, net, bgp_path.last_nonaggregated) = ROA_INVALID;
}
# Returns TRUE if the given tested network is the exact global network prefix for
# Lixonet. Used to filter the "unreachable" static route we typically static.
function is_exact_lixonet_global_v4()
{
return net ~ [ ${network_address}/${global_prefix:-16} ];
}
# Returns TRUE if the given tested network is within the global network prefix for
# Lixonet. Used to filter networks outside of this range as they are not within
# the global mesh network.
function is_lixonet_global_v4()
{
return net ~ [ ${network_address}/${global_prefix:-16}+ ];
}
# Returns TRUE if the given tested network is within the router network prefix for
# Lixonet. Used to filter these routes from BGP as Tinc statically assigns them
# for us. Helps prevent a security vulnerability of hijacking another router.
function is_lixonet_router_v4()
{
return net ~ [ ${network_address}/${router_prefix:-24}+ ];
}
function is_own_route_v4()
{
{{ if len "${bgp_routes:-}" }}{{ range "$bgp_routes" | split "," }}if net ~ [ {{.}}+ ] then return true;
{{ end }}{{ end }}
return false;
}
function is_wireguard_route_v4()
{
{{ if len "${wg_routes:-}" }}{{ range "$wg_routes" | split "," }}if net ~ [ {{.}} ] then return true;
{{ end }}{{ end }}
return false;
}
filter bgp_import_filter_v4
{
if source ~ [RTS_STATIC] then reject; # Reject our own routes
if is_rpki_invalid_v4() then reject; # Reject posions
if is_lixonet_router_v4() then reject; # Reject poisons
if is_own_route_v4() then reject; # Reject poisons
if is_lixonet_global_v4() then accept; # Accept anything else
reject; # Reject anything else (non-Lixonet)
}
filter bgp_export_filter_v4
{
if is_lixonet_router_v4() then reject; # Reject poisons
if is_exact_lixonet_global_v4() then reject; # Reject the unreachable route
if is_lixonet_global_v4() then accept; # Accept anything else
reject; # Reject anything else (non-Lixonet)
}
# In some cases, like WireGuard, we can be a peer to a client which is
# available over another "adjacent" VPN layer. In these cases, allow
# importing routes that are added to the kernel which fall under the
# Wireguard layer
filter kernel_import_filter_v4
{
if is_own_route_v4() then reject; # Reject unexpected routes
if is_wireguard_route_v4() then accept; # Accept WireGuard routes
reject; # Reject anything else
}
filter kernel_export_filter_v4
{
#if is_own_route_v4() then reject; # Reject poisons
if is_lixonet_global_v4() then accept; # Accept anything else
reject; # Reject anything else (non-Lixonet)
}
# Static routes
# Define propagated routes here from the lixonet.conf "routes" variable
# Attached to the above "lixonet" routing table; "provide" these routes into it
# See how dn42 does it; we're very similar: https://dn42.net/howto/Bird
protocol static {
ipv4 {
table ${netname:-lixonet}_v4;
import all;
export none;
};
# Announce the whole network as unreachable; this returns packets that reach
# this router as unreachable (ICMP type=3, code=0) if no more specific route
# is defined for the network subnet
route ${network_address}/${global_prefix:-16} unreachable;
# Announced networks
{{ if len "${bgp_routes:-}" }}{{ range "$bgp_routes" | split "," }}route {{.}} via ${internal_gateway};
{{ end }}{{ end }}
};
# Device
# See: https://bird.network.cz/?get_doc&v=20&f=bird-6.html#ss6.4
# This controls which interfaces BGP, etc. will bind to for communication
# This prevents BGP from listening on eth0/off-network
protocol device {
scan time 10; # Scan the interfaces often
interface "${netname:-lixonet}" {
preferred ${tinc_peer_address};
};
};
# Direct (unnecessary for Lixonet)
# See: https://bird.network.cz/?get_doc&v=20&f=bird-6.html#ss6.5
# Disable automatically generating direct routes to all network interfaces.
protocol direct {
disabled; # Disable by default
};
# Kernel routing table
# See: https://bird.network.cz/?get_doc&v=20&f=bird.html#toc6.6
protocol kernel { # Primary routing table
learn; # Learn alien routes from the kernel
persist; # Don't remove routes on bird shutdown
scan time 10; # Scan kernel routing table every 10 seconds
graceful restart;
ipv4 {
table ${netname:-lixonet}_v4;
import filter kernel_import_filter_v4; # Import anything we allow from the kernel
export filter kernel_export_filter_v4; # Export everything we are told to the kernel
};
};
# BFD
protocol bfd {
interface "${netname:-lixonet}" {
min rx interval 1 s;
min tx interval 1 s;
idle tx interval 5 s;
multiplier 5;
};
};
# BGP (primary Lixonet routing protocol)
# This is a template to use when connecting to other BGP clients on the EE network
# This template is applied to ALL neighbors, so consider these global settings that
# apply to all neighbors. See "Neighbors" section of this configuration for
# individual neighbor configurations where per-neighbor configurations (such as their
# ASN) are applied.
template bgp lixonet_client {
local as ${bgp_asn}; # Local AS advertised to peers
source address ${tinc_peer_address}; # What local IP address we use for any outbound TCP
# connections on port 179
path metric ${bgp_path_metric:-1}; # 1 = Prefer routes with shorter paths (like Cisco does)
# Turn on BFD (bidirectional forwarding detection)
bfd on;
# BGP channels
# See: Channel configuration (BIRD BGP configuration) and the table shown there.
# BGP IPv4 channel settings
ipv4 {
table ${netname:-lixonet}_v4;
# Always advertise our own local address as a next hop, even in cases where the
# current Next Hop attribute should be used unchanged.
# Reason: tinc NEEDS this, otherwise Layer3 inter-routing on the mesh will be broken
next hop self ebgp;
# aigp (see: http://www.rfc-editor.org/info/rfc7311)
# Lixonet default: originate AIGP
# This not only allows AIGP attribute propagation, but also new AIGP attributes are
# automatically attached to non-BGP routes with valid IGP metric (e.g. ospf_metric1)
# as they are exported to the BGP session.
# Thank-you, BIRD <3 - mane and nurd
aigp ${bgp_aigp:-originate};
# Set filters for both exported (sent) and imported (received) BGP prefixes.
# This is explicitly required per RFC 8212, at least on export.
# See: https://gitlab.labs.nic.cz/labs/bird/commit/3831b619661d08d935fd78656732cd2f339ff811
export filter bgp_export_filter_v4;
import filter bgp_import_filter_v4;
};
};
# Neighbors
{{ range files "bird/peers" }} {{ if ne . "${tinc_peer_name}" }}
protocol bgp {{ . }} from lixonet_client {
description "Lixonet BGP link to {{ . }}";
{{ include (print "bird/peers/" .) }}
};{{ end }}{{ end }}