====== Dobby Setup ======
[[infrastruktur:host:dobby|Dobby overview]]
===== 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 ins nbsp Netz nur bei established/related 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 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::
* https://fw01.nobreakspace.org/ui/interfaces/vip
* dort `fd69:2694:4eb5::/48` auf `fd20:bdda:5df0::1/64` geändert
* [x]: dobby alias
* https://fw01.nobreakspace.org/ui/firewall/alias
* Firewall->Aliases, add:
* Enabled: true
* Name: dobby
* Type: Host(s)
* Categories: services
* Content: 172.23.208.8, 2a01:170:1112::8
* Description: dn42 BGP router
* [x]: statisches DHCPv4 mapping (optional, eigentlich stat. IPs):
* https://fw01.nobreakspace.org/services_dhcp.php?if=lan
* MAC address: BC:24:11:0F:A6:06
* IP address: 172.23.208.8
* Hostname: dobby
* [x]: IPv4 port forwarding:
* https://fw01.nobreakspace.org/firewall_nat.php
* Description: dobby dn42 tunnels
* Interface: WAN
* Destination: 82.139.255.241
* Redirect target IP: 172.23.208.8
* Protocol: UDP
* Destination port range: 2300-2399
* [x]: IPv6 incoming erlauben:
* https://fw01.nobreakspace.org/firewall_rules.php?if=wan
* 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:
* https://dn42.dev/howto/Bird2#example-configuration
* https://dn42.dev/services/Route-Collector.md#bgp-configuration
################################################
# 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;
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;
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 bgp ROUTE_COLLECTOR
{
local as OWNAS;
neighbor fd42:4242:2601:ac12::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;
};
};
}
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 {
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;
};
}
include "/etc/bird/peers/*";
==== 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
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=
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.