From 5f8203d9015bac95cf78bd6bd3546fe9cd82fc87 Mon Sep 17 00:00:00 2001 From: Astro Date: Wed, 5 May 2021 17:35:44 +0200 Subject: [PATCH] nixos-module/container/bird: add check-upstream services --- nix/nixos-module/container/bird.nix | 74 ++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/nix/nixos-module/container/bird.nix b/nix/nixos-module/container/bird.nix index 61304fb..93d7c04 100644 --- a/nix/nixos-module/container/bird.nix +++ b/nix/nixos-module/container/bird.nix @@ -1,5 +1,5 @@ # Routing daemon configuration -{ hostName, config, options, lib, ... }: +{ hostName, config, options, lib, pkgs, ... }: let hostConf = config.site.hosts.${hostName}; @@ -350,4 +350,76 @@ in ''} ''; }; + + # Script that pings internet hosts every few minutes to determine if + # the upstream actually works. The associated OSPF instance will be + # enabled/disabled on state change. + systemd.services = + let + interval = 5; + targets = { + ipv4 = [ + # inbert.c3d2.de + "217.197.83.184" + # ccc.de + "195.54.164.39" + # Cloud DNS services + "9.9.9.9" + "8.8.8.8" + "1.1.1.1" + ]; + ipv6 = [ + # inbert.c3d2.de + "2001:67c:1400:2240::1" + # ccc.de + "2001:67c:20a0:2:0:164:0:39" + # Cloud DNS services + "2620:fe::9" + "2606:4700:4700::1111" + "2001:4860:4860::8888" + ]; + }; + instance = { + ipv4 = "ZW4_${hostName}"; + ipv6 = "ZW6_${hostName}"; + }; + checkService = addressFamily: { + description = "Check connectivity for ${addressFamily}"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + User = "bird2"; + Group = "bird2"; + }; + path = [ pkgs.bird2 "/run/wrappers" ]; + script = '' + STATE=unknown + + while true; do + NEW_STATE=unknown + false \ + ${lib.concatMapStrings (target: + " || ping -n -s 0 -c 1 -w 1 ${target} 2>/dev/null >/dev/null \\\n" + ) targets.${addressFamily}} \ + && NEW_STATE=up \ + || NEW_STATE=down + + if [ $STATE != $NEW_STATE ]; then + echo "Connectivity change from $STATE to $NEW_STATE" + if [ $NEW_STATE = up ]; then + birdc enable ${instance.${addressFamily}} + else + birdc disable ${instance.${addressFamily}} + fi + fi + + STATE=$NEW_STATE + sleep ${toString interval} + done + ''; + }; + in lib.mkIf isUpstream { + check-upstream-ipv4 = checkService "ipv4"; + check-upstream-ipv6 = checkService "ipv6"; + }; }