diff --git a/configs/manager.nix b/configs/manager.nix index ccaab25..0b1cc7d 100644 --- a/configs/manager.nix +++ b/configs/manager.nix @@ -25,7 +25,7 @@ with lib; { }; }; - #imports = [ ./tailnet.nix ]; + imports = [ ./tailnet.nix ]; config = mkIf config.nixManager.enable { sops.defaultSopsFile = config.xin-secrets.manager; diff --git a/configs/tailnet.nix b/configs/tailnet.nix index 44718c7..509646b 100644 --- a/configs/tailnet.nix +++ b/configs/tailnet.nix @@ -10,48 +10,158 @@ let let acls = { hosts = { - europa = "100.92.31.80"; - startpage = "100.120.84.116"; - startdev = "100.92.56.119"; - go = "100.117.47.51"; - nbc = "100.122.61.43"; # nix-binary-cache - console = "100.87.112.70"; - box = "100.120.151.126"; + console = "100.83.166.33"; + nbc = "100.74.8.55"; + startpage = "127.0.0.1"; + gitle = "100.111.162.87"; + faf = "100.80.94.131"; + h = "100.83.77.133"; + box = "100.115.16.150"; + pwntie = "100.84.170.57"; + sputnik = "100.78.154.31"; + europa = "100.64.26.122"; }; tagOwners = { - "tag:untrusted" = [ "qbit@github" ]; - "tag:minservice" = [ "qbit@github" ]; - "tag:sshonly" = [ "qbit@github" ]; - "tag:apper" = [ "qbit@github" ]; - "tag:golink" = [ "qbit@github" ]; - "tag:lab" = [ "qbit@github" ]; + "tag:admin" = [ "autogroup:admin" ]; + "tag:untrusted" = [ "qbit@tapenet.org" ]; + "tag:ro-service" = [ "qbit@tapenet.org" ]; + "tag:mobile" = [ "qbit@tapenet.org" ]; + "tag:laptop" = [ "qbit@tapenet.org" ]; + "tag:internal-server" = [ "qbit@tapenet.org" ]; + "tag:external-server" = [ "qbit@tapenet.org" ]; + "tag:work" = [ "qbit@tapenet.org" ]; + "tag:dns-server" = [ "qbit@tapenet.org" ]; + "tag:openbsd" = [ "qbit@tapenet.org" ]; }; acls = [ { + # Allow laptops and mobile devices to ssh to everything action = "accept"; - src = [ "tag:untrusted" ]; - dst = [ - "europa:22" - "europa:12304" - "startpage:443" - "startdev:443" - "go:80" - "tag:lab:22" - "nbc:443" - ]; - } - { - action = "accept"; - src = [ "tag:minservice" "tag:sshonly" ]; - dst = [ "*:22" "box:3030" "nbc:443" "console:2222" ]; - } - { - action = "accept"; - src = [ "qbit@github" ]; + src = [ "tag:mobile" "tag:laptop" ]; dst = [ "*:*" ]; } + { + "action" = "accept"; + "src" = [ "tag:internal-server" "tag:external-server" "tag:work" "tag:laptop" ]; + "dst" = [ "nbc:443" ]; + } + { + "action" = "accept"; + "src" = [ "tag:untrusted" "tag:internal-server" ]; + "dst" = [ "tag:ro-service:443" ]; + } + { + "action" = "accept"; + "src" = [ "tag:work" ]; + "dst" = [ "console:2222" "startpage:443" ]; + } + { + "action" = "accept"; + "src" = [ "tag:openbsd" ]; + "dst" = [ "box:443" ]; + } + { + # prometheus + "action" = "accept"; + "src" = [ "box" ]; + "dst" = [ "h:9002" "pwntie:9002" ]; + } + { + # DNS + "action" = "accept"; + "src" = [ "*" ]; + "dst" = [ "faf:53" ]; + "proto" = "udp"; + } + { + # ollama + "action" = "accept"; + "src" = [ "europa" ]; + "dst" = [ "pwntie:11434" ]; + "proto" = "tcp"; + } + ]; + + tests = [ + { + # RO service can't access things + "src" = "tag:ro-service"; + "deny" = [ "tag:laptop:443" "tag:mobile:80" "tag:laptop:22" ]; + } + { + "src" = "tag:external-server"; + "deny" = [ "tag:laptop:22" ]; + } + { + "src" = "tag:laptop"; + "allow" = [ "tag:ro-service:443" "tag:ro-service:80" "tag:external-server:22" ]; + } + { + "src" = "tag:laptop"; + "allow" = [ "qbit@tapenet.org:22" ]; + } + { + "src" = "tag:untrusted"; + "deny" = [ "tag:laptop:22" ]; + "allow" = [ "tag:ro-service:443" ]; + } + { + "src" = "tag:laptop"; + "allow" = [ "tag:untrusted:22" "tag:untrusted:2222" "tag:work:22" ]; + } + { + "src" = "tag:work"; + "deny" = [ "tag:laptop:22" ]; + } + + # Gitle shouldn't be able to access things, but things should access it + { + "src" = "gitle"; + "deny" = [ "tag:laptop:22" ]; + } + { + "src" = "tag:laptop"; + "allow" = [ "gitle:22" ]; + } + { + "src" = "tag:laptop"; + "allow" = [ "faf:53" ]; + } + { + "src" = "tag:internal-server"; + "allow" = [ "nbc:443" "tag:ro-service:443" ]; + } + { + "src" = "tag:laptop"; + "allow" = [ "h:8967" ]; + } + { + "src" = "h"; + "proto" = "udp"; + "allow" = [ "faf:53" ]; + } + { + "src" = "tag:openbsd"; + "proto" = "tcp"; + "allow" = [ "box:443" ]; + } + { + "src" = "sputnik"; + "proto" = "tcp"; + "allow" = [ "europa:1714" ]; + } + { + "src" = "sputnik"; + "proto" = "udp"; + "allow" = [ "europa:1714" ]; + } + { + "src" = "europa"; + "proto" = "tcp"; + "allow" = [ "pwntie:11434" ]; + } ]; }; in @@ -59,26 +169,28 @@ let name = "tailnet-acls.json"; text = builtins.toJSON acls; }; - aclUpdateScript = pkgs.writeShellScriptBin "tailnet-acl-updater" '' - set -eu + aclUpdateScript = pkgs.writeShellScriptBin + "tailnet-acl-updater" + '' + set -eu - . ${config.sops.secrets.po_env.path} + . ${config.sops.secrets.po_env.path} - JQ=${pkgs.jq}/bin/jq - PO=${inputs.po.packages.${pkgs.system}.po}/bin/po + JQ=${pkgs.jq}/bin/jq + PO=${inputs.po.packages.${pkgs.system}.po}/bin/po - APIURL="https://api.tailscale.com/api/v2/tailnet/-/acl" - TOKEN="$(cat ${config.sops.secrets.tailnet_acl_manager.path}):" + APIURL="https://api.tailscale.com/api/v2/tailnet/-/acl" + TOKEN="$(cat ${config.sops.secrets.tailnet_acl_manager.path}):" - ERROR="$(${pkgs.curl}/bin/curl "$APIURL/validate" -u "$TOKEN" -d @${tailnetACLs} | $JQ -r .message)" + ERROR="$(${pkgs.curl}/bin/curl "$APIURL/validate" -u "$TOKEN" -d @${tailnetACLs} | $JQ -r .message)" - if [ "$ERROR" = "null" ]; then - RESP="$(${pkgs.curl}/bin/curl "$APIURL" -u "$TOKEN" -d @${tailnetACLs} | $JQ -r .message)" - if [ "$RESP" != "null" ]; then - $PO -title "Failed to update TailNet!" -body "$RESP" + if [ "$ERROR" = "null" ]; then + RESP="$(${pkgs.curl}/bin/curl "$APIURL" -u "$TOKEN" -d @${tailnetACLs} | $JQ -r .message)" + if [ "$RESP" != "null" ]; then + $PO -title "Failed to update TailNet!" -body "$RESP" + fi fi - fi - ''; + ''; jobs = [ { name = "update-talenet-acls";