2022-05-19 09:37:12 +00:00
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
cfg = config.services.bird-lg;
|
2023-04-14 13:32:00 +00:00
|
|
|
|
|
|
|
stringOrConcat = sep: v: if builtins.isString v then v else concatStringsSep sep v;
|
|
|
|
|
|
|
|
frontend_args = let
|
|
|
|
fe = cfg.frontend;
|
|
|
|
in {
|
|
|
|
"--servers" = concatStringsSep "," fe.servers;
|
|
|
|
"--domain" = fe.domain;
|
|
|
|
"--listen" = fe.listenAddress;
|
|
|
|
"--proxy-port" = fe.proxyPort;
|
|
|
|
"--whois" = fe.whois;
|
|
|
|
"--dns-interface" = fe.dnsInterface;
|
|
|
|
"--bgpmap-info" = concatStringsSep "," cfg.frontend.bgpMapInfo;
|
|
|
|
"--title-brand" = fe.titleBrand;
|
|
|
|
"--navbar-brand" = fe.navbar.brand;
|
|
|
|
"--navbar-brand-url" = fe.navbar.brandURL;
|
|
|
|
"--navbar-all-servers" = fe.navbar.allServers;
|
|
|
|
"--navbar-all-url" = fe.navbar.allServersURL;
|
|
|
|
"--net-specific-mode" = fe.netSpecificMode;
|
|
|
|
"--protocol-filter" = concatStringsSep "," cfg.frontend.protocolFilter;
|
|
|
|
};
|
|
|
|
|
|
|
|
proxy_args = let
|
|
|
|
px = cfg.proxy;
|
|
|
|
in {
|
|
|
|
"--allowed" = concatStringsSep "," px.allowedIPs;
|
|
|
|
"--bird" = px.birdSocket;
|
|
|
|
"--listen" = px.listenAddress;
|
|
|
|
"--traceroute_bin" = px.traceroute.binary;
|
2023-04-14 12:36:06 +00:00
|
|
|
"--traceroute_flags" = concatStringsSep " " px.traceroute.flags;
|
2023-04-14 13:32:00 +00:00
|
|
|
"--traceroute_raw" = px.traceroute.rawOutput;
|
|
|
|
};
|
|
|
|
|
|
|
|
mkArgValue = value:
|
|
|
|
if isString value
|
|
|
|
then escapeShellArg value
|
|
|
|
else if isBool value
|
|
|
|
then boolToString value
|
|
|
|
else toString value;
|
|
|
|
|
|
|
|
filterNull = filterAttrs (_: v: v != "" && v != null && v != []);
|
|
|
|
|
|
|
|
argsAttrToList = args: mapAttrsToList (name: value: "${name} " + mkArgValue value ) (filterNull args);
|
2022-05-19 09:37:12 +00:00
|
|
|
in
|
|
|
|
{
|
|
|
|
options = {
|
|
|
|
services.bird-lg = {
|
|
|
|
package = mkOption {
|
|
|
|
type = types.package;
|
|
|
|
default = pkgs.bird-lg;
|
|
|
|
defaultText = literalExpression "pkgs.bird-lg";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "The Bird Looking Glass package to use.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
user = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "bird-lg";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "User to run the service.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
group = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "bird-lg";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Group to run the service.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
frontend = {
|
2022-08-28 19:18:44 +00:00
|
|
|
enable = mkEnableOption (lib.mdDoc "Bird Looking Glass Frontend Webserver");
|
2022-05-19 09:37:12 +00:00
|
|
|
|
|
|
|
listenAddress = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "127.0.0.1:5000";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Address to listen on.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
proxyPort = mkOption {
|
|
|
|
type = types.port;
|
|
|
|
default = 8000;
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Port bird-lg-proxy is running on.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
domain = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
example = "dn42.lantian.pub";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Server name domain suffixes.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
servers = mkOption {
|
|
|
|
type = types.listOf types.str;
|
|
|
|
example = [ "gigsgigscloud" "hostdare" ];
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Server name prefixes.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
whois = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "whois.verisign-grs.com";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Whois server for queries.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
dnsInterface = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "asn.cymru.com";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "DNS zone to query ASN information.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
bgpMapInfo = mkOption {
|
|
|
|
type = types.listOf types.str;
|
|
|
|
default = [ "asn" "as-name" "ASName" "descr" ];
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Information displayed in bgpmap.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
titleBrand = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "Bird-lg Go";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Prefix of page titles in browser tabs.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
netSpecificMode = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "";
|
|
|
|
example = "dn42";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Apply network-specific changes for some networks.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
protocolFilter = mkOption {
|
|
|
|
type = types.listOf types.str;
|
|
|
|
default = [ ];
|
|
|
|
example = [ "ospf" ];
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Information displayed in bgpmap.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
nameFilter = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "";
|
|
|
|
example = "^ospf";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Protocol names to hide in summary tables (RE2 syntax),";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
timeout = mkOption {
|
|
|
|
type = types.int;
|
|
|
|
default = 120;
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Time before request timed out, in seconds.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
navbar = {
|
|
|
|
brand = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "Bird-lg Go";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Brand to show in the navigation bar .";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
brandURL = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "/";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "URL of the brand to show in the navigation bar.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
allServers = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "ALL Servers";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Text of 'All server' button in the navigation bar.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
allServersURL = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "all";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "URL of 'All servers' button.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
extraArgs = mkOption {
|
2023-04-14 13:32:00 +00:00
|
|
|
type = with types; either lines (listOf str);
|
|
|
|
default = [ ];
|
2022-08-03 20:46:41 +00:00
|
|
|
description = lib.mdDoc ''
|
|
|
|
Extra parameters documented [here](https://github.com/xddxdd/bird-lg-go#frontend).
|
2023-04-14 13:32:00 +00:00
|
|
|
|
|
|
|
:::{.note}
|
|
|
|
Passing lines (plain strings) is deprecated in favour of passing lists of strings.
|
|
|
|
:::
|
2022-08-03 01:05:47 +00:00
|
|
|
'';
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
proxy = {
|
2022-08-28 19:18:44 +00:00
|
|
|
enable = mkEnableOption (lib.mdDoc "Bird Looking Glass Proxy");
|
2022-05-19 09:37:12 +00:00
|
|
|
|
|
|
|
listenAddress = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "127.0.0.1:8000";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Address to listen on.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
allowedIPs = mkOption {
|
|
|
|
type = types.listOf types.str;
|
|
|
|
default = [ ];
|
|
|
|
example = [ "192.168.25.52" "192.168.25.53" ];
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "List of IPs to allow (default all allowed).";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
birdSocket = mkOption {
|
|
|
|
type = types.str;
|
2023-04-14 13:32:00 +00:00
|
|
|
default = "/var/run/bird/bird.ctl";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Bird control socket path.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
traceroute = {
|
|
|
|
binary = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "${pkgs.traceroute}/bin/traceroute";
|
|
|
|
defaultText = literalExpression ''"''${pkgs.traceroute}/bin/traceroute"'';
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Traceroute's binary path.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
|
2023-04-14 12:36:06 +00:00
|
|
|
flags = mkOption {
|
|
|
|
type = with types; listOf str;
|
|
|
|
default = [ ];
|
|
|
|
description = lib.mdDoc "Flags for traceroute process";
|
|
|
|
};
|
|
|
|
|
2022-05-19 09:37:12 +00:00
|
|
|
rawOutput = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "Display traceroute output in raw format.";
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
extraArgs = mkOption {
|
2023-04-14 13:32:00 +00:00
|
|
|
type = with types; either lines (listOf str);
|
|
|
|
default = [ ];
|
2022-08-03 20:46:41 +00:00
|
|
|
description = lib.mdDoc ''
|
|
|
|
Extra parameters documented [here](https://github.com/xddxdd/bird-lg-go#proxy).
|
2023-04-14 13:32:00 +00:00
|
|
|
|
|
|
|
:::{.note}
|
|
|
|
Passing lines (plain strings) is deprecated in favour of passing lists of strings.
|
|
|
|
:::
|
2022-08-03 01:05:47 +00:00
|
|
|
'';
|
2022-05-19 09:37:12 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
###### implementation
|
|
|
|
|
|
|
|
config = {
|
2023-04-14 13:32:00 +00:00
|
|
|
|
|
|
|
warnings =
|
|
|
|
lib.optional (cfg.frontend.enable && builtins.isString cfg.frontend.extraArgs) ''
|
|
|
|
Passing strings to `services.bird-lg.frontend.extraOptions' is deprecated. Please pass a list of strings instead.
|
|
|
|
''
|
|
|
|
++ lib.optional (cfg.proxy.enable && builtins.isString cfg.proxy.extraArgs) ''
|
|
|
|
Passing strings to `services.bird-lg.proxy.extraOptions' is deprecated. Please pass a list of strings instead.
|
|
|
|
''
|
|
|
|
;
|
|
|
|
|
2022-05-19 09:37:12 +00:00
|
|
|
systemd.services = {
|
|
|
|
bird-lg-frontend = mkIf cfg.frontend.enable {
|
|
|
|
enable = true;
|
|
|
|
after = [ "network.target" ];
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
description = "Bird Looking Glass Frontend Webserver";
|
|
|
|
serviceConfig = {
|
|
|
|
Type = "simple";
|
|
|
|
Restart = "on-failure";
|
|
|
|
ProtectSystem = "full";
|
|
|
|
ProtectHome = "yes";
|
|
|
|
MemoryDenyWriteExecute = "yes";
|
|
|
|
User = cfg.user;
|
|
|
|
Group = cfg.group;
|
|
|
|
};
|
|
|
|
script = ''
|
|
|
|
${cfg.package}/bin/frontend \
|
2023-04-14 13:32:00 +00:00
|
|
|
${concatStringsSep " \\\n " (argsAttrToList frontend_args)} \
|
|
|
|
${stringOrConcat " " cfg.frontend.extraArgs}
|
2022-05-19 09:37:12 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
bird-lg-proxy = mkIf cfg.proxy.enable {
|
|
|
|
enable = true;
|
|
|
|
after = [ "network.target" ];
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
description = "Bird Looking Glass Proxy";
|
|
|
|
serviceConfig = {
|
|
|
|
Type = "simple";
|
|
|
|
Restart = "on-failure";
|
|
|
|
ProtectSystem = "full";
|
|
|
|
ProtectHome = "yes";
|
|
|
|
MemoryDenyWriteExecute = "yes";
|
|
|
|
User = cfg.user;
|
|
|
|
Group = cfg.group;
|
|
|
|
};
|
|
|
|
script = ''
|
|
|
|
${cfg.package}/bin/proxy \
|
2023-04-14 13:32:00 +00:00
|
|
|
${concatStringsSep " \\\n " (argsAttrToList proxy_args)} \
|
|
|
|
${stringOrConcat " " cfg.proxy.extraArgs}
|
2022-05-19 09:37:12 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
users = mkIf (cfg.frontend.enable || cfg.proxy.enable) {
|
|
|
|
groups."bird-lg" = mkIf (cfg.group == "bird-lg") { };
|
|
|
|
users."bird-lg" = mkIf (cfg.user == "bird-lg") {
|
|
|
|
description = "Bird Looking Glass user";
|
|
|
|
extraGroups = lib.optionals (config.services.bird2.enable) [ "bird2" ];
|
|
|
|
group = cfg.group;
|
|
|
|
isSystemUser = true;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
2023-04-14 15:51:28 +00:00
|
|
|
|
|
|
|
meta.maintainers = with lib.maintainers; [
|
|
|
|
e1mo
|
|
|
|
tchekda
|
|
|
|
];
|
2022-05-19 09:37:12 +00:00
|
|
|
}
|