Benutzer-Werkzeuge

Webseiten-Werkzeuge


infrastruktur:host:dobby-setup

Dobby Setup

Case/Proxmox container setup

  • General:
    • (Node: case)
    • (CT ID: 113)
    • Hostname: dobby
    • Unprivileged container: yes
    • Nesting: yes
    • SSH public key(s): T_X
  • Template:
    • Storage: local
    • Template: debian-12-standard_12.2-1_amd64.tar.zst
  • Disk(s):
    • rootfs:
      • Disk Size: 4 GiB
      • Storage: disks
  • CPU:
    • Cores: 1
  • Memory:
    • Memory: 2048 MiB
    • Swap: 512 MiB
  • Network:
    • Name: eth0
    • MAC address: auto (→ BC:24:11:0F:A6:06)
    • bridge: vmbr0
    • VLAN tag: no VLAN
    • Firewall: no
    • IPv4: static
      • IPv4/CIDR: 172.23.208.8/23
      • Gateway: 172.23.208.1
    • IPv6: static
      • IPv6/CIDR: 2a01:170:1112::8/64
      • Gateway: 2a01:170:1112::1

Basic Network Settings

/etc/systemd/network/lan0.network:

[Match]
Name=eth0

[Network]
DHCP=no
IPv6AcceptRA=no
Address=172.23.208.8/23
Address=2a01:170:1112::8/64
Address=fd20:bdda:5df0::8/64
Gateway=172.23.208.1
Gateway=2a01:170:1112::1
apt-get remove ifupdown
systemctl enable systemd-networkd
systemctl enable systemd-networkd
reboot
root@dobby:~# cat /etc/resolv.conf 
# --- BEGIN PVE ---
search nobreakspace.org
nameserver 172.23.208.1
nameserver 2a01:170:1112::1
# --- END PVE ---

Apt Unattended updates

https://wiki.debian.org/UnattendedUpgrades

$ apt-get update && apt-get dist-upgrade
$ apt-get install unattended-upgrades apt-listchanges

/etc/apt/apt.conf.d/52unattended-upgrades:

$ echo 'Unattended-Upgrade::Automatic-Reboot "true";' > /etc/apt/apt.conf.d/52unattended-upgrades-local
$ echo 'Unattended-Upgrade::Automatic-Reboot-Time "03:42";' >> /etc/apt/apt.conf.d/52unattended-upgrades-local
$ reboot

Netfilter Firewall

Ansatz:

  • zwischen dn42 peers immer routen/forwarden erlauben
  • eingehend unicast ins nbsp Netz nur bei established/related erlauben
  • Routebares IPv6 multicast zwischen dn42 und nbsp erlauben
nft add table inet filter
nft add chain inet filter input { type filter hook input priority 0\; policy accept\; }
nft add chain inet filter output { type filter hook output priority 0\; policy accept\; }
nft add chain inet filter forward { type filter hook forward priority 0\; policy drop\; }
nft add rule inet filter forward iifname "dn42_*" oifname "dn42_*" accept
nft add rule inet filter forward iifname "eth0" oifname "dn42_*" accept
nft add rule inet filter forward iifname "dn42_*" oifname "eth0" ct state established,related accept
nft add rule inet filter forward ip6 daddr ff00::/8 iifname "dn42_*" oifname "eth0" accept
nft add rule inet filter forward ip6 daddr ff00::/8 iifname "eth0" oifname "dn42_*" accept
nft add rule inet filter forward counter reject with icmpx type admin-prohibited

Persistent machen:

mv /etc/nftables.conf /etc/nftables.conf.bak
echo '#!/usr/sbin/nft -f' > /etc/nftables.conf
echo '' >> /etc/nftables.conf
echo 'flush ruleset' >> /etc/nftables.conf
echo '' >> /etc/nftables.conf
nft -s list ruleset >> /etc/nftables.conf
systemctl enable nftables.service
systemctl start nftables.service

Forwarding aktivieren:

$ echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/10-ip-forward.conf
net.ipv4.ip_forward=1
$ echo "net.ipv6.conf.all.forwarding=1" >> /etc/sysctl.d/10-ip-forward.conf

OPNSense Firewall fw01.nobreakspace.org

  • [x]: announce fd20:bdda:5df0::/64 im radvd, statt fd69:2694:4eb5::
  • [x]: dobby alias
  • [x]: statisches DHCPv4 mapping (optional, eigentlich stat. IPs):
  • [x]: IPv4 port forwarding:
  • [x]: IPv6 incoming erlauben:
    • Firewall→Rules→Wan, hinzufügen:
      • Action: Pass
      • Disabled: false
      • Quick: Apply the action immediately on match
      • Interface: WAN
      • Direction: in
      • TCP/IP version: IPv6
      • Protocol: any
      • Source/invert: false
      • Source: any
      • Destination/invert: false
      • Destination: dobby
      • Destination port range: from: any, to: any
      • Gateway: default
  • [x]: Variante A) statische Routen zu dobby hinzufügen
    • ~~Routing: General:~~
      • ~~Enable: yes~~
    • ~~Routing: STATIC → General:~~
      • ~~Enable: yes~~
    • ~~Routing: STATIC → Routes, Add:~~
      • ~~IPv6:~~
        • ~~Network: fd00::/8~~
        • ~~Gateway: fd20:bdda:5df0::8~~
        • ~~Interface: LAN~~
    • System: Gateways: Configuration, Add:
      • IPv6:
        • Name: dobby_dn42_ipv6
        • Description: dobby dn42 IPv6 Gateway
        • Interface: LAN
        • Address Family: IPv6
        • IP address: fd20:bdda:5df0::8
        • (Upstream Gateway: no!)
      • IPv4:
        • Name: dobby_dn42_ipv4
        • Description: dobby dn42 IPv4 Gateway
        • Interface: LAN
        • Address Family: IPv4
        • IP address: 172.23.208.8
        • (Upstream Gateway: no!)
      • System: Routes: Configuration, Add:
        • IPv6:
          • Network Address: fd00::/8
          • Gateway: dobby_dn42_ipv6
          • Description: dn42 (+Freifunk) IPv6
        • IPv4, dn42:
          • Network Address: 172.20.0.0/14
          • Gateway: dobby_dn42_ipv4
          • Description: dn42 IPv4
        • IPv4, ChaosVPN:
          • Network Address: 172.31.0.0/16
          • Gateway: dobby_dn42_ipv4
          • Description: ChaosVPN (via dn42)
        • IPv4, ChaosVPN, neonetwork, Freifunk:
          • Network Address: 10.0.0.0/8
          • Gateway: dobby_dn42_ipv4
          • Description: ChaosVPN, neonetwork, Freifunk/ICVPN (via dn42)
  • [ ]: Variante B) full BGP import von dobby, export Filter auf dobby (→ Routing: BGP)
  • [x]: DNS hinzufügen: https://dn42.dev/services/DNS
    • Services: Unbound DNS: Advanced:
      • Private Domains: add „dn42“
    • Services: Unbound DNS: Query Forwarding → Custom forwarding, add:
      • Enabled: yes
      • Domain: dn42
      • Address: fd42:d42:d42:54::1
      • Description: dn42 DNS

Bird2

$ apt-get install bird2
$ mv bird.conf bird.conf.bak

/etc/bird/bird.conf:

hauptsächlich von hier kopiert:

################################################
#               Variable header                #
################################################

define OWNAS =  4242421976;
define OWNIP =  172.23.208.8;
define OWNIPv6 = fd20:bdda:5df0::8;
define OWNNET = 172.23.208.0/23;
define OWNNETv6 = fd20:bdda:5df0::/48;
define OWNNETSET = [172.23.208.0/23+];
define OWNNETSETv6 = [fd20:bdda:5df0::/48+];

################################################
#                 Header end                   #
################################################

router id OWNIP;

protocol device {
    scan time 10;
}

/*
 *  Utility functions
 */

function is_self_net() {
  return net ~ OWNNETSET;
}

function is_self_net_v6() {
  return net ~ OWNNETSETv6;
}

function is_valid_network() {
  return net ~ [
    172.20.0.0/14{21,29}, # dn42
    172.20.0.0/24{28,32}, # dn42 Anycast
    172.21.0.0/24{28,32}, # dn42 Anycast
    172.22.0.0/24{28,32}, # dn42 Anycast
    172.23.0.0/24{28,32}, # dn42 Anycast
    172.31.0.0/16+,       # ChaosVPN
    10.100.0.0/14+,       # ChaosVPN
    10.127.0.0/16{16,32}, # neonetwork
    10.0.0.0/8{15,24}     # Freifunk.net
  ];
}

roa4 table dn42_roa;
roa6 table dn42_roa_v6;

ipv6 table mcast6;

protocol static {
    roa4 { table dn42_roa; };
    include "/etc/bird/roa_dn42.conf";
};

protocol static {
    roa6 { table dn42_roa_v6; };
    include "/etc/bird/roa_dn42_v6.conf";
};

function is_valid_network_v6() {
  return net ~ [
    fd00::/8{44,64} # ULA address space as per RFC 4193
  ];
}

protocol kernel {
    scan time 20;

    ipv6 {
        import none;
        export filter {
            if source = RTS_STATIC then reject;
            krt_prefsrc = OWNIPv6;
            accept;
        };
    };
};

protocol kernel {
    scan time 20;
    kernel table 20;

    ipv6 {
        table mcast6;
        
        import none;
        export filter {
            if source = RTS_STATIC then reject;
            krt_prefsrc = OWNIPv6;
            accept;
        };
    };
};

protocol kernel {
    scan time 20;

    ipv4 {
        import none;
        export filter {
            if source = RTS_STATIC then reject;
            krt_prefsrc = OWNIP;
            accept;
        };
    };
}

protocol static {
    route OWNNET reject;

    ipv4 {
        import all;
        export none;
    };
}

protocol static {
    route OWNNETv6 reject;

    ipv6 {
        import all;
        export none;
    };
}

protocol static {
    route OWNNETv6 reject;

    ipv6 {
        table mcast6;
        import all;
        export none;
    };
}

protocol bgp ROUTE_COLLECTOR
{
  local as OWNAS;
  #neighbor fd42:4242:2601:ac12::1 as 4242422602;
  neighbor fd42:d42:d42:179::1 as 4242422602;

  # enable multihop as the collector is not locally connected
  multihop;

  ipv4 {
    # export all available paths to the collector    
    add paths tx;

    # import/export filters
    import none;
    export filter {
      # export all valid routes
      if ( is_valid_network() && source ~ [ RTS_STATIC, RTS_BGP ] )
      then {
        accept;
      }
      reject;
    };
  };

  ipv6 {
    # export all available paths to the collector    
    add paths tx;

    # import/export filters
    import none;
    export filter {
      # export all valid routes
      if ( is_valid_network_v6() && source ~ [ RTS_STATIC, RTS_BGP ] )
      then {
        accept;
      }
      reject;
    };
  };
  
  ipv6 multicast {
    table mcast6;
    # export all available paths to the collector
    add paths tx;

    # import/export filters
    import none;
    export filter {
      # export all valid routes
      if ( is_valid_network_v6() && source ~ [ RTS_STATIC, RTS_BGP ] )
      then {
        accept;
      }
      reject;
    };
  };
}

template bgp dnpeers {
    local as OWNAS;
    path metric 1;

    ipv4 {
        import filter {
          if is_valid_network() && !is_self_net() then {
            if (roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID) then {
              print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
              reject;
            } else accept;
          } else reject;
        };

        export filter { if is_valid_network() && source ~ [RTS_STATIC, RTS_BGP] then accept; else reject; };
        import limit 9000 action block;
    };

    ipv6 {   
        include "/etc/bird/dn42_v6_filters.conf";
        import filter {
          if is_valid_network_v6() && !is_self_net_v6() then {
            if (roa_check(dn42_roa_v6, net, bgp_path.last) != ROA_VALID) then {
              print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
              reject;
            } else accept;
          } else reject;
        };
        export filter { if is_valid_network_v6() && source ~ [RTS_STATIC, RTS_BGP] then accept; else reject; };
        import limit 9000 action block; 
    };
}

template bgp dnpeersmc from dnpeers {
    ipv6 multicast {
        table mcast6;

        import filter { reject; };
        export filter { reject; };

        import limit 9000 action block;
        import table on;
        export table on;
    };
}

include "/etc/bird/peers/*";

/etc/bird/dn42_v6_filters.conf:

import filter {
  if is_valid_network_v6() && !is_self_net_v6() then {
    if (roa_check(dn42_roa_v6, net, bgp_path.last) != ROA_VALID) then {
      print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
      reject;
    } else accept;
  } else reject;
};
export filter { if is_valid_network_v6() && source ~ [RTS_STATIC, RTS_BGP] then accept; else reject; };

ROA updaten

# /etc/systemd/system/dn42-roa.service
[Unit]
Description=Update DN42 ROA

[Service]
Type=oneshot
ExecStart=curl -sfSLR -o /etc/bird/roa_dn42.conf -z /etc/bird/roa_dn42.conf https://dn42.burble.com/roa/dn42_roa_bird2_4.conf
ExecStart=curl -sfSLR -o /etc/bird/roa_dn42_v6.conf -z /etc/bird/roa_dn42_v6.conf https://dn42.burble.com/roa/dn42_roa_bird2_6.conf
ExecStart=birdc configure
# /etc/systemd/system/dn42-roa.timer
[Unit]
Description=Update DN42 ROA periodically

[Timer]
OnBootSec=2m
OnUnitActiveSec=15m
AccuracySec=1m

[Install]
WantedBy=timers.target
$ systemctl daemon-reload
$ systemctl enable dn42-roa.timer
$ systemctl start dn42-roa.timer

Peer hinzufügen

$ apt-get install --no-install-recommends wireguard-tools
$ cd /etc/systemd/network/
$ PEERNAME=replaceexamplepeer
$ PEERASN=replaceexapmlepeerasn
$ PEERIP4=...
$ PEERIP6=...
$ sh -c "umask 066; touch dn42-$PEERNAME-wg.key; chown systemd-network:systemd-network dn42-$PEERNAME-wg.key"
$ wg genkey | tee -a dn42-$PEERNAME-wg.key | wg pubkey > dn42-$PEERNAME-wg.pub
$ cat << EOF > dn42-${PEERNAME}-wg.netdev
[NetDev]
Name=dn42_${PEERNAME}_wg
Kind=wireguard
Description=DN42 ${PEERNAME} WG tunnel
MTUBytes=1392

[WireGuard]
ListenPort=$(for i in `seq 2300 2399`; do grep -q "^ListenPort=$i\$" dn42-*.netdev && continue; echo "$i"; break; done)
PrivateKeyFile=/etc/systemd/network/dn42-${PEERNAME}-wg.key

[WireGuardPeer]
#PublicKey=
#Endpoint=
AllowedIPs=fe80::/64
AllowedIPs=fd00::/8
#Add ff00::/8 if using PIM/multicast, too:
#AllowedIPs=ff00::/8
AllowedIPs=172.16.0.0/12
AllowedIPs=10.0.0.0/8
EOF
$ cat << EOF > dn42-${PEERNAME}-wg.network
[Match]
Name=dn42_${PEERNAME}_wg

[Network]
DHCP=no
IPv6AcceptRA=false
IPForward=yes

# for networkd >= 244 KeepConfiguration stops networkd from
# removing routes on this interface when restarting
KeepConfiguration=yes

[Address]
Address=fe80::1976/64

[Address]
Address=172.20.240.$(for i in `seq 0 255`; do grep -q "^Address=172\.20\.240\.$i/32\$" dn42-*.network && continue; echo "$i"; break; done)/32
#Peer=

#Add below if using PIM/multicast, too:
#[Link]
#Multicast=true
EOF

`PublicKey`, `Endpoint` und `Peer` mit den Werten der Gegenseite updaten. Dann `networkctl reload` aufrufen.

$ cat << EOF > /etc/bird/peers/dn42-${PEERNAME}.conf
protocol bgp dn42_${PEERNAME} from dnpeers {
        neighbor ${PEERIP4} as ${PEERASN};
}

protocol bgp dn42_${PEERNAME}_v6 from dnpeers {
        neighbor ${PEERIP6}%dn42_${PEERNAME}_wg as ${PEERASN};
}
EOF

Oder alternativ/präferiert via multiprotocol „extended next hop“ (IPv4 via v6 next hop):

$ cat << EOF > /etc/bird/peers/dn42-${PEERNAME}.conf
protocol bgp dn42_${PEERNAME}_v6 from dnpeers {
        neighbor ${PEERIP6}%dn42_${PEERNAME}_wg as ${PEERASN};
        
        ipv4 {
                extended next hop on;
        };
}
EOF

Dann hat man lustige Routen wie diese:

$ ip -4 route show prot bird via inet6 fe80::b
10.26.0.0/16 via inet6 fe80::b dev dn42_ffda_wg src 172.23.208.8 metric 32 
10.29.0.0/16 via inet6 fe80::b dev dn42_ffda_wg src 172.23.208.8 metric 32 
10.37.0.0/16 via inet6 fe80::b dev dn42_ffda_wg src 172.23.208.8 metric 32 
10.56.0.0/16 via inet6 fe80::b dev dn42_ffda_wg src 172.23.208.8 metric 32 
10.60.128.0/20 via inet6 fe80::b dev dn42_ffda_wg src 172.23.208.8 metric 32
...

Und man benötigt keine IPv4 Adress Absprachen für den Wireguard Tunnel, für dn42-${PEERNAME}-wg.network.

pim6sd

mkdir ~/dev
cd ~/dev
apt install git autoconf build-essential yacc flex debhelper-compat
git clone "https://github.com/troglobit/pim6sd.git"
cd pim6sd
./configure
make
dpkg-buildpackage -us -uc
dpkg -i ../pim6sd_2.1.0-1_amd64.deb

Add an IPv6 address to the pim-router-id interface which you'd want pim6sd to use for PIM:

$ cat << EOF > /etc/systemd/network/pim-router-id.netdev
[NetDev]
Name=pim-router-id
Kind=dummy
EOF
$ cat << EOF > /etc/systemd/network/pim-router-id.network
[Match]
Name=pim-router-id

[Network]
Address=fd20:bdda:5df0::8/128

[Link]
Multicast=true
EOF

Add VRF interface for an alternative routing table:

$ cat << EOF > /etc/systemd/network/dn42-mc6-vrf.netdev
[NetDev]
Name=dn42_mc6_vrf
Kind=vrf

[VRF]
TableId=20
EOF
$ cat << EOF > /etc/systemd/network/dn42-mc6-vrf.network
[Match]
Name=dn42_mc6_vrf
EOF
$ cat << EOF > /etc/systemd/network/lo.network
[Match]
Name=lo

[Route]
#ip -6 route add table 42 unreachable default metric 4278198272
Table=20
Destination=::/0
Type=unreachable
Metric=4278198272
EOF

Calculate your personal, embedded-RP multicast prefix matching your network prefix via RFC3956

  • Pattern: ff7e:<RIID><plen>:<prefix>::/96
    • Prefix: fd20:bdda:5df0::/64
    • Prefix length: 64 == 0x40
    • RIID: An arbitrary number between 0x1 and 0xf, here 8 to match the address on pim-router-id
    • Result:
      • Multicast prefix: ff7e:840:fd20:bdda:5df0::/96
      • RP address: fd20:bdda:5df0::<RIID> → fd20:bdda:5df0::8
$ cat << EOF > /etc/pim6sd.conf
# /etc/pim6sd.conf
# disable all interfaces by default
default_phyint_status disable;

# enable the pim-router-id interface first to acquire the correct primary address
phyint pim-router-id enable;

# downstream interface uses MLD to find listeners
phyint eth0 mld_version any enable;

# This one is for PIM / routing, not listeners / MLD.
# Add more interfaces as required below
phyint dn42_tx_wg nolistener enable;
phyint dn42_ffhl_wg nolistener enable;

# configure rendezvous point for the personal multicast prefix
cand_rp pim-router-id;
group_prefix ff7e:840:fd20:bdda:5df0::/96;

source_outgoing_interface dn42_mc6_vrf;
EOF
$ cat << EOF > /etc/systemd/system/pim6sd.service
# /etc/systemd/system/pim6sd.service
[Unit]
Description=pim6sd - PIM-SM daemon for IPv6
After=network-online.target

[Service]
Type=exec
ExecStart=pim6sd -n -f /etc/pim6sd.conf
RestartSteps=10
RestartMaxDelaySec=30
Restart=always

[Install]
WantedBy=multi-user.target
EOF

bird BGP/MLD watchdog:

#!/bin/sh
# /usr/local/sbin/bird-bgp-pim-watchdog.sh

# Ignore route collector AS for instance
EXCLUDED_ASNS="4242422602"
FILTERS_CONF="/etc/bird/dn42_v6_filters.conf"
PIM6SD_PIDFILE="/var/run/pim6sd.pid"
BIRD_PEERS_DIR="/etc/bird/peers/"

get_pim6sd_neighbors() {
	local pid

	if [ ! -f "${PIM6SD_PIDFILE}" ]; then
		return 0
	fi

	pid="$(grep '^[0-9]*$' "${PIM6SD_PIDFILE}")"
	if [ -z "$pid" ] || ! ps -p "$pid" > /dev/null; then
		return 0
	fi

	pim6stat -p "${PIM6SD_PIDFILE}" | awk -v RS= '/^PIM Neighbor List/' | tail -n+3 | awk '{ print $3"%"$2 }'
}

has_bgp_mc_channel() {
	local neighinfo="$1"

	echo "$neighinfo" | grep -q '^[ ]*Channel ipv6-mc$'
}

is_excluded_as() {
	local neighinfo="$1"
	local asn=""

	for asn in ${EXCLUDED_ASNS}; do
		echo "$neighinfo" | grep -q "^[ ]*Neighbor AS:[ ]*$asn" && return 0
	done

	return 1
#	birdc show protocol all ROUTE_COLLECTOR | grep -q "^[ ]*Neighbor AS:[ ]*4242422602"
}

get_birdc_bgpmc_neigh_addr() {
	local info="$1"

	echo "$info" | sed -n "s/^[ ]*Neighbor address:[ ]*\(.*\)$/\1/p"
}

get_bird_bgmc_conf_toggle() {
	local conf="$1"
	local file

	# get filename in an include in an "ipv6 multicast" section
	file="$(cat "$conf" | \
			grep -v '^[[:space:]]*#' | \
			tr '\n' ' ' | \
			sed -n 's/.*ipv6 multicast[[:space:]]*{[^}]*include[[:space:]]*"\([^"]*\)".*/\1/p')"

	[ -L "$file" ] && echo "$file"
}

get_bird_bgmc_conf() {
	local neigh="$1"

	grep -Ilr "$neigh" "${BIRD_PEERS_DIR}" | head -n1
}

check_pim_neighbors() {
	local addr="$1"
	local neigh

	echo "$pimneighbors" | grep -q "^$addr\$"
}

update_conftoggle() {
	local conftoggle="$1"
	local source="$2"
	local rconftoggle="$(realpath "$conftoggle")"
	local rsource="$(realpath "$source")"


	echo "Updating $conftoggle to $source"
	if [ "$rconftoggle" = "$rsource" ]; then
		# nothing changed
		return 0
	fi

	if [ -z "$conftoggle" ]; then
		return 1
	fi

	ln -sf "$source" "$conftoggle" && echo "CHANGED"
}

enable_bird_bgpmc_neighbor() {
	local conftoggle="$1"

	update_conftoggle "$conftoggle" "${FILTERS_CONF}"
}

disable_bird_bgpmc_neighbor() {
	local conftoggle="$1"

	update_conftoggle "$conftoggle" "/dev/null"
}

update_bird_bgpmc_neighbor() {
	local neigh="$1"
	local info="$2"
	local addr="$(get_birdc_bgpmc_neigh_addr "$info")"
	local conf="$(get_bird_bgmc_conf "$neigh")"
	local conftoggle="$(get_bird_bgmc_conf_toggle "$conf")"

	if [ -z "$addr" ]; then
		echo "Error: Could not find BGP neighbor address for neighbor \"$neigh\""
		return 1
	fi
	if [ -z "$conf" ]; then
		echo "Error: Could not find config for neighbor \"$neigh\""
		return 1
	fi
	if [ -z "$conftoggle" ]; then
		echo "Error: Could not find config toggle for neighbor \"$neigh\""
		return 1
	fi

	echo "neigh: $neigh, addr: $addr"
	if check_pim_neighbors "$addr"; then
		enable_bird_bgpmc_neighbor "$conftoggle"
	else
		disable_bird_bgpmc_neighbor "$conftoggle"
	fi

	return $?
}

update_bird_bgpmc_neighbors() {
	local neigh

	birdc show protocols | \
		sed -n "s/^\([^ ]*\) BGP .*/\1/p" | \
			while read neigh; do \
				local neighinfo="$(birdc show protocols all "$neigh")"

				is_excluded_as "$neighinfo" && continue
				has_bgp_mc_channel "$neighinfo" || continue

				update_bird_bgpmc_neighbor "$neigh" "$neighinfo"
			done
}

pimneighbors="$(get_pim6sd_neighbors)"

CHANGED="$(update_bird_bgpmc_neighbors)"

if [ -n "$CHANGED" ]; then
	echo "CHANGED, calling birdc configure"
	if ! birdc configure; then
		echo "Error: Could not (re)configure bird" >&2
		exit 1
	fi
else
	echo "nothing changed"
fi
$ cat << EOF > /etc/systemd/system/bird-bgp-pim-watchdog.service
# /etc/systemd/system/bird-bgp-pim-watchdog.service
[Unit]
Description=bird BGP route import/export watchdog for PIM/multicast
After=bird.service

[Service]
Type=oneshot
ExecStart=bird-bgp-pim-watchdog.sh
EOF
$ cat << EOF > /etc/systemd/system/bird-bgp-pim-watchdog.timer
# /etc/systemd/system/bird-bgp-pim-watchdog.timer
[Unit]
Description=Run the bird BGP/PIM watchdog periodically

[Timer]
OnBootSec=2m
OnUnitActiveSec=5m
AccuracySec=1m

[Install]
WantedBy=timers.target
EOF
mkdir /etc/bird/peersmods/

For a new PIM peer:

ln -s /dev/null /etc/bird/peersmods/dn42-tx-mc6-filters.conf
$ cat << EOF > /etc/bird/peers/dn42-${PEERNAME}.conf
protocol bgp dn42_${PEERNAME}_v6 from dnpeersmc {
        neighbor ${PEERIP6}%dn42_${PEERNAME}_wg as ${PEERASN};
        
        ipv4 {
                extended next hop on;
        };
        
        ipv6 multicast {
                include "/etc/bird/peersmods/dn42-${PEERNAME}-mc6-filters.conf";
        };
}
EOF
systemctl daemon-reload
systemctl start pim6sd
systemctl enable pim6sd
systemctl enable bird-bgp-pim-watchdog.timer
systemctl start bird-bgp-pim-watchdog.service
systemctl start bird-bgp-pim-watchdog.timer
infrastruktur/host/dobby-setup.txt · Zuletzt geändert: von Linus Lüssing