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