at 24.11-pre 9.4 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.bird-lg; 7 8 stringOrConcat = sep: v: if builtins.isString v then v else concatStringsSep sep v; 9 10 frontend_args = let 11 fe = cfg.frontend; 12 in { 13 "--servers" = concatStringsSep "," fe.servers; 14 "--domain" = fe.domain; 15 "--listen" = fe.listenAddress; 16 "--proxy-port" = fe.proxyPort; 17 "--whois" = fe.whois; 18 "--dns-interface" = fe.dnsInterface; 19 "--bgpmap-info" = concatStringsSep "," cfg.frontend.bgpMapInfo; 20 "--title-brand" = fe.titleBrand; 21 "--navbar-brand" = fe.navbar.brand; 22 "--navbar-brand-url" = fe.navbar.brandURL; 23 "--navbar-all-servers" = fe.navbar.allServers; 24 "--navbar-all-url" = fe.navbar.allServersURL; 25 "--net-specific-mode" = fe.netSpecificMode; 26 "--protocol-filter" = concatStringsSep "," cfg.frontend.protocolFilter; 27 }; 28 29 proxy_args = let 30 px = cfg.proxy; 31 in { 32 "--allowed" = concatStringsSep "," px.allowedIPs; 33 "--bird" = px.birdSocket; 34 "--listen" = px.listenAddress; 35 "--traceroute_bin" = px.traceroute.binary; 36 "--traceroute_flags" = concatStringsSep " " px.traceroute.flags; 37 "--traceroute_raw" = px.traceroute.rawOutput; 38 }; 39 40 mkArgValue = value: 41 if isString value 42 then escapeShellArg value 43 else if isBool value 44 then boolToString value 45 else toString value; 46 47 filterNull = filterAttrs (_: v: v != "" && v != null && v != []); 48 49 argsAttrToList = args: mapAttrsToList (name: value: "${name} " + mkArgValue value ) (filterNull args); 50in 51{ 52 options = { 53 services.bird-lg = { 54 package = mkPackageOption pkgs "bird-lg" { }; 55 56 user = mkOption { 57 type = types.str; 58 default = "bird-lg"; 59 description = "User to run the service."; 60 }; 61 62 group = mkOption { 63 type = types.str; 64 default = "bird-lg"; 65 description = "Group to run the service."; 66 }; 67 68 frontend = { 69 enable = mkEnableOption "Bird Looking Glass Frontend Webserver"; 70 71 listenAddress = mkOption { 72 type = types.str; 73 default = "127.0.0.1:5000"; 74 description = "Address to listen on."; 75 }; 76 77 proxyPort = mkOption { 78 type = types.port; 79 default = 8000; 80 description = "Port bird-lg-proxy is running on."; 81 }; 82 83 domain = mkOption { 84 type = types.str; 85 example = "dn42.lantian.pub"; 86 description = "Server name domain suffixes."; 87 }; 88 89 servers = mkOption { 90 type = types.listOf types.str; 91 example = [ "gigsgigscloud" "hostdare" ]; 92 description = "Server name prefixes."; 93 }; 94 95 whois = mkOption { 96 type = types.str; 97 default = "whois.verisign-grs.com"; 98 description = "Whois server for queries."; 99 }; 100 101 dnsInterface = mkOption { 102 type = types.str; 103 default = "asn.cymru.com"; 104 description = "DNS zone to query ASN information."; 105 }; 106 107 bgpMapInfo = mkOption { 108 type = types.listOf types.str; 109 default = [ "asn" "as-name" "ASName" "descr" ]; 110 description = "Information displayed in bgpmap."; 111 }; 112 113 titleBrand = mkOption { 114 type = types.str; 115 default = "Bird-lg Go"; 116 description = "Prefix of page titles in browser tabs."; 117 }; 118 119 netSpecificMode = mkOption { 120 type = types.str; 121 default = ""; 122 example = "dn42"; 123 description = "Apply network-specific changes for some networks."; 124 }; 125 126 protocolFilter = mkOption { 127 type = types.listOf types.str; 128 default = [ ]; 129 example = [ "ospf" ]; 130 description = "Information displayed in bgpmap."; 131 }; 132 133 nameFilter = mkOption { 134 type = types.str; 135 default = ""; 136 example = "^ospf"; 137 description = "Protocol names to hide in summary tables (RE2 syntax),"; 138 }; 139 140 timeout = mkOption { 141 type = types.int; 142 default = 120; 143 description = "Time before request timed out, in seconds."; 144 }; 145 146 navbar = { 147 brand = mkOption { 148 type = types.str; 149 default = "Bird-lg Go"; 150 description = "Brand to show in the navigation bar ."; 151 }; 152 153 brandURL = mkOption { 154 type = types.str; 155 default = "/"; 156 description = "URL of the brand to show in the navigation bar."; 157 }; 158 159 allServers = mkOption { 160 type = types.str; 161 default = "ALL Servers"; 162 description = "Text of 'All server' button in the navigation bar."; 163 }; 164 165 allServersURL = mkOption { 166 type = types.str; 167 default = "all"; 168 description = "URL of 'All servers' button."; 169 }; 170 }; 171 172 extraArgs = mkOption { 173 type = with types; either lines (listOf str); 174 default = [ ]; 175 description = '' 176 Extra parameters documented [here](https://github.com/xddxdd/bird-lg-go#frontend). 177 178 :::{.note} 179 Passing lines (plain strings) is deprecated in favour of passing lists of strings. 180 ::: 181 ''; 182 }; 183 }; 184 185 proxy = { 186 enable = mkEnableOption "Bird Looking Glass Proxy"; 187 188 listenAddress = mkOption { 189 type = types.str; 190 default = "127.0.0.1:8000"; 191 description = "Address to listen on."; 192 }; 193 194 allowedIPs = mkOption { 195 type = types.listOf types.str; 196 default = [ ]; 197 example = [ "192.168.25.52" "192.168.25.53" "192.168.0.0/24" ]; 198 description = "List of IPs or networks to allow (default all allowed)."; 199 }; 200 201 birdSocket = mkOption { 202 type = types.str; 203 default = "/var/run/bird/bird.ctl"; 204 description = "Bird control socket path."; 205 }; 206 207 traceroute = { 208 binary = mkOption { 209 type = types.str; 210 default = "${pkgs.traceroute}/bin/traceroute"; 211 defaultText = literalExpression ''"''${pkgs.traceroute}/bin/traceroute"''; 212 description = "Traceroute's binary path."; 213 }; 214 215 flags = mkOption { 216 type = with types; listOf str; 217 default = [ ]; 218 description = "Flags for traceroute process"; 219 }; 220 221 rawOutput = mkOption { 222 type = types.bool; 223 default = false; 224 description = "Display traceroute output in raw format."; 225 }; 226 }; 227 228 extraArgs = mkOption { 229 type = with types; either lines (listOf str); 230 default = [ ]; 231 description = '' 232 Extra parameters documented [here](https://github.com/xddxdd/bird-lg-go#proxy). 233 234 :::{.note} 235 Passing lines (plain strings) is deprecated in favour of passing lists of strings. 236 ::: 237 ''; 238 }; 239 }; 240 }; 241 }; 242 243 ###### implementation 244 245 config = { 246 247 warnings = 248 lib.optional (cfg.frontend.enable && builtins.isString cfg.frontend.extraArgs) '' 249 Passing strings to `services.bird-lg.frontend.extraOptions' is deprecated. Please pass a list of strings instead. 250 '' 251 ++ lib.optional (cfg.proxy.enable && builtins.isString cfg.proxy.extraArgs) '' 252 Passing strings to `services.bird-lg.proxy.extraOptions' is deprecated. Please pass a list of strings instead. 253 '' 254 ; 255 256 systemd.services = { 257 bird-lg-frontend = mkIf cfg.frontend.enable { 258 enable = true; 259 after = [ "network.target" ]; 260 wantedBy = [ "multi-user.target" ]; 261 description = "Bird Looking Glass Frontend Webserver"; 262 serviceConfig = { 263 Type = "simple"; 264 Restart = "on-failure"; 265 ProtectSystem = "full"; 266 ProtectHome = "yes"; 267 MemoryDenyWriteExecute = "yes"; 268 User = cfg.user; 269 Group = cfg.group; 270 }; 271 script = '' 272 ${cfg.package}/bin/frontend \ 273 ${concatStringsSep " \\\n " (argsAttrToList frontend_args)} \ 274 ${stringOrConcat " " cfg.frontend.extraArgs} 275 ''; 276 }; 277 278 bird-lg-proxy = mkIf cfg.proxy.enable { 279 enable = true; 280 after = [ "network.target" ]; 281 wantedBy = [ "multi-user.target" ]; 282 description = "Bird Looking Glass Proxy"; 283 serviceConfig = { 284 Type = "simple"; 285 Restart = "on-failure"; 286 ProtectSystem = "full"; 287 ProtectHome = "yes"; 288 MemoryDenyWriteExecute = "yes"; 289 User = cfg.user; 290 Group = cfg.group; 291 }; 292 script = '' 293 ${cfg.package}/bin/proxy \ 294 ${concatStringsSep " \\\n " (argsAttrToList proxy_args)} \ 295 ${stringOrConcat " " cfg.proxy.extraArgs} 296 ''; 297 }; 298 }; 299 users = mkIf (cfg.frontend.enable || cfg.proxy.enable) { 300 groups."bird-lg" = mkIf (cfg.group == "bird-lg") { }; 301 users."bird-lg" = mkIf (cfg.user == "bird-lg") { 302 description = "Bird Looking Glass user"; 303 extraGroups = lib.optionals (config.services.bird2.enable) [ "bird2" ]; 304 group = cfg.group; 305 isSystemUser = true; 306 }; 307 }; 308 }; 309 310 meta.maintainers = with lib.maintainers; [ 311 e1mo 312 tchekda 313 ]; 314}