From 3d188ab76ec77cb3260c3df9b0845a6fe28e864c Mon Sep 17 00:00:00 2001 From: arcnmx Date: Sat, 13 Jan 2024 12:42:41 -0800 Subject: [PATCH] refactor: postgresql --- modules/nixos/home-assistant.nix | 3 ++ modules/nixos/postgres.nix | 47 ++++++++++++++++++++++++++++++++ nixos/home-assistant.nix | 5 ++-- nixos/postgres.nix | 22 ++++++++++++--- systems/tei/nixos.nix | 3 +- systems/tei/secrets.yaml | 5 ++-- systems/tewi/nixos.nix | 1 + systems/tewi/secrets.yaml | 7 +++-- 8 files changed, 80 insertions(+), 13 deletions(-) create mode 100644 modules/nixos/postgres.nix diff --git a/modules/nixos/home-assistant.nix b/modules/nixos/home-assistant.nix index 95bc98ec..b9bf752c 100644 --- a/modules/nixos/home-assistant.nix +++ b/modules/nixos/home-assistant.nix @@ -82,6 +82,9 @@ in { "200::/7" "100.64.0.0/10" "fd7a:115c:a1e0:ab12::/64" + "fd7a:115c:a1e0::/96" + "10.1.1.0/24" + "fd0a::/64" "::1" ]; }; diff --git a/modules/nixos/postgres.nix b/modules/nixos/postgres.nix new file mode 100644 index 00000000..362baf45 --- /dev/null +++ b/modules/nixos/postgres.nix @@ -0,0 +1,47 @@ +{ + config, + lib, + ... +}: let + inherit (lib.modules) mkIf mkMerge mkOptionDefault mkDefault; + inherit (lib.options) mkOption mkEnableOption; + inherit (lib.lists) any; + cfg = config.services.postgresql; + ensureUserModule = { config, ... }: { + options = with lib.types; { + tailscale = { + allow = mkEnableOption "tailscale TCP connections"; + database = mkOption { + type = str; + }; + }; + }; + config = { + tailscale.database = mkIf (config.ensureDBOwnership) ( + mkOptionDefault config.name + ); + }; + }; +in { + options.services.postgresql = with lib.types; { + ensureUsers = mkOption { + type = listOf (submodule ensureUserModule); + }; + }; + config.services.postgresql = { + enableTCPIP = mkIf (any (user: user.tailscale.allow) cfg.ensureUsers) ( + mkDefault true + ); + authentication = let + allowTail = { database, user }: '' + host ${database} ${user} fd7a:115c:a1e0::/96 md5 + host ${database} ${user} fd7a:115c:a1e0:ab12::/64 md5 + host ${database} ${user} 100.64.0.0/10 md5 + ''; + in mkMerge (map + (user: mkIf user.tailscale.allow ( + allowTail { inherit (user.tailscale) database; user = user.name; } + )) cfg.ensureUsers + ); + }; +} diff --git a/nixos/home-assistant.nix b/nixos/home-assistant.nix index 37eb9161..ea3b1287 100644 --- a/nixos/home-assistant.nix +++ b/nixos/home-assistant.nix @@ -1,12 +1,10 @@ { - pkgs, config, lib, ... }: let cfg = config.services.home-assistant; - inherit (lib.modules) mkDefault; - inherit (lib.lists) optional; + inherit (lib.modules) mkIf mkDefault; in { sops.secrets = { ha-integration = { @@ -49,6 +47,7 @@ in { use_webhook = true; }; recorder = { + db_url = mkIf (!config.services.postgresql.enable) "!secret db_url"; auto_purge = true; purge_keep_days = 14; commit_interval = 1; diff --git a/nixos/postgres.nix b/nixos/postgres.nix index a8130276..0329a5d3 100644 --- a/nixos/postgres.nix +++ b/nixos/postgres.nix @@ -1,17 +1,31 @@ { config, - pkgs, + lib, ... -}: { +}: let + inherit (lib.modules) mkIf mkDefault mkAfter; + cfg = config.services.postgresql; +in { services.postgresql = { - enable = true; - package = pkgs.postgresql_14; + enable = mkDefault true; ensureDatabases = ["hass"]; ensureUsers = [ { name = "hass"; ensureDBOwnership = true; + tailscale.allow = !config.services.home-assistant.enable; } ]; }; + + systemd.services.postgresql = mkIf cfg.enable { + postStart = mkAfter '' + $PSQL -tAf ${config.sops.secrets.postgresql-init.path} + ''; + }; + + sops.secrets.postgresql-init = { + owner = "postgres"; + group = "postgres"; + }; } diff --git a/systems/tei/nixos.nix b/systems/tei/nixos.nix index 0a235f0f..beae156f 100644 --- a/systems/tei/nixos.nix +++ b/systems/tei/nixos.nix @@ -7,9 +7,10 @@ nixos.reisen-ct nixos.sops nixos.tailscale + nixos.postgres ]; sops.defaultSopsFile = ./secrets.yaml; - system.stateVersion = "21.05"; + system.stateVersion = "23.11"; } diff --git a/systems/tei/secrets.yaml b/systems/tei/secrets.yaml index 1f317125..31793b5c 100644 --- a/systems/tei/secrets.yaml +++ b/systems/tei/secrets.yaml @@ -1,4 +1,5 @@ tailscale-key: ENC[AES256_GCM,data:0ify9ntv5wgr8S8wUdV72mbjt3h/jjceFnocMEIndeEJ1VYTINKlyoPL8VxVJpsi0QxtH7T7pvw=,iv:iapyEmjAT2gGBj+fTfSRtGX1/cvBmqbyI9h1flPprPM=,tag:UZDyojQcVwkquDPiRtfGKQ==,type:str] +postgresql-init: ENC[AES256_GCM,data:AJY1PhgQ/vPYAugA+oqlm2CUjI+RZ3zVOd2zdMMtFt+uLmcxoAyap/zxvVDzCzzNY/jqAJnUaAr1aYw9Nd2icSMurR4=,iv:S4d4+1ncVlEzy50eU1lyPi3gPC+yvVZe6kGZa+oK2KU=,tag:U98pYwYf3sJRmB7Ac8g9Fw==,type:str] sops: shamir_threshold: 1 kms: [] @@ -15,8 +16,8 @@ sops: bGU0VHd0aFhHRC91WHh0Z0Y4TTE5QzgKpHehWfoJT4F1TtMHJ0tZkoJAPFAihQ7T aunsQeLHJkHv1eWKpraTmo+04GVZofwId/1TtOContveBynfxcuG7Q== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-01-06T21:27:28Z" - mac: ENC[AES256_GCM,data:QVnNJ37mJDOSG0khDHEpez8/sPsh9TqLhXCBXJ9HDZoPiG17LTLp6p0+2NlTuuxF8rHYakDSKnAVamhsuTAdbgKmdG2m1Hm4zRFPLc/GlTr9618fo8/Ob+cIoV9yoTyVFFykQWBS0oNR+dorp9yKpcB8IlyxbtW9WmU1CWEAd2E=,iv:ODW2e+93MKEZ5fsxne2SpLLDyLc6z8X1VCqamoLAPwM=,tag:2uDKu5UEn72z6vL5Y/RT9Q==,type:str] + lastmodified: "2024-01-13T19:40:13Z" + mac: ENC[AES256_GCM,data:dqg0owYRxqm4YPUAJk1fBWJ79jCf/5LFVs85qYDimNp0ghXoCZlCv49SB2IUB37av/ba1/uIIs1TQnzTAt+aIMoY+0qpGT/1STJ1AYhQNl65N02ddvWOSfqyO73/Ebw6QMr5+AzO40B2fP3FVkRNqLfRcnempmOajtDi5gLoxzI=,iv:RVLHFcHwOB9Fdjwi9G/7YVKK19mz6aoGFrnZfp5hTX8=,tag:TTV1WO8TrTA/0LluWwEGdA==,type:str] pgp: - created_at: "2024-01-07T21:18:21Z" enc: |- diff --git a/systems/tewi/nixos.nix b/systems/tewi/nixos.nix index f47f34be..2d9a584e 100644 --- a/systems/tewi/nixos.nix +++ b/systems/tewi/nixos.nix @@ -70,6 +70,7 @@ in { services.cockroachdb.locality = "provider=local,network=gensokyo,host=${config.networking.hostName}"; services.kanidm.serverSettings.db_fs_type = "zfs"; services.tailscale.advertiseExitNode = true; + services.postgresql.package = pkgs.postgresql_14; sops.defaultSopsFile = ./secrets.yaml; diff --git a/systems/tewi/secrets.yaml b/systems/tewi/secrets.yaml index 1fc7f61d..8ad8a954 100644 --- a/systems/tewi/secrets.yaml +++ b/systems/tewi/secrets.yaml @@ -11,7 +11,8 @@ systemd2mqtt-env: ENC[AES256_GCM,data:Zo3+acCcMWgai2ERKbmOlI0hvdkOlNviBqeLb1ALuA z2m-secret: ENC[AES256_GCM,data:SCxz8nbB/QhfPcAzSEDHMpiQnjv+j0xLtg/20qf5ZEe3P5YRaiKXMSqdw6MX7uQtGh8T44raEgS8PFuGKXY423GV/MNPSzMl16DLBwU5P7TL6lYT97uVYRIqWMKqtPy/1f155743wH8HsJvslmg=,iv:Yw9dvH1dBq+vxHvKm0eeHlqVHRdUuzL71mDTbIF7DDg=,tag:bCiDNSwq7P21TwblvVGq6A==,type:str] deluge-auth: ENC[AES256_GCM,data:qJP/CztnN7RV4Z3pP+jbH1B0zzBm8oa3n3X0pecEVe7UI3+NOSwFaQCBD7Q7JDxzh+qTNdQ/wWi7w0XJDG+aRIikgDG28S9RjdPL/w==,iv:GUEwmuk3JWMgsXsDgDrObW657WcN6wcYAsgXhK4Dvx0=,tag:vZMQ67j5kWBWOa6ZqCaQHw==,type:str] syncplay-env: ENC[AES256_GCM,data:MzL/Q4ihwVX+QgdWl20PfpCP8hiPd3uc00FuTJ+gsVN7EJOoDlTyA2pgfw75eklQgWa0r9T+3u3gigo7jxrBqmgD2oYDFrZNKrHyrXlxALQ=,iv:AO7hcXucPqJkCa3u3Y7nrgfIsw9f8fbWBc5g7Kb77cM=,tag:G+URgzoVrwiS6TjEgRy9rg==,type:str] -ha-secrets: ENC[AES256_GCM,data:sw+sxrDyNIOAkHSA2fPLqtHR32iKIaZDdgJ1ZcQTeOqlgdZDhK5XzXiBkpZBTwKswUc2UPDOANsn+YRusX2tUvLYjdxZz4jIBKJuaW3aEtOcxjmG55KYxHmTzSbR4IhpuZ+1wDhvp4UiUqyD273Lt6LTFDmohZAVqwxJc2k4YTZJXiofVf8ywcXPMcS+zIMxb5nBX9EJqgJ80pnBI8vZeCg4pFv/Ux2OoS+PTnkYHnsywf57NA23YcKqnsbJoZwi3e4ooM2erygv0DuoP7QBnBdEf5RKSziECDTDPUFQVNYIOEAgJIYOD/GtZmWMx4SadsmrgTB1RqtAdPnvuuD3jLYW20zci8CxmI4F/h/+8lxUH/TGiG2bUmPYvwTE1eW1cLK91XhxXp6ORyWMGYcR98ryGL00ctD/BaZLdk7FYbQMTF2y2vx5vWAABTnYLsv6H9csmD4O7OeNkd9k+YQB/atENAXRgIiGDvkkbNoRkRU5SzIIHGcjjU7GC6hT+LDportPuhUW+g6KJj0ENOCI0yXNkIfa6LXAJcCmdovJCIbdw1HCGHuu+dc5rSWueiOWo+2rr8loytZTTMwevTaldfrNyu42K+bZI2BkPdXzkPQDeV8y5PmfnXfdXthmmnZbYRyVYUd1OH9L,iv:zxpazCPJTWmuw7/BNj90G89aGyk3fCqBB+RCyKW6QwY=,tag:5zSnrZOxo8G2Wg4LNtEsaQ==,type:str] +postgresql-init: ENC[AES256_GCM,data:40s9cdfJMcKjfNBNQikpAY6FZ0cgVEGC52fnXwH3jC5d9qI56hIv84ZZhZ3/kVyxSwpQL+pY0DxNjAKMqLpXx/Ujsp4=,iv:Cj7RPBM7tzTb4jBONM8DYWuJ/STRj6vO2ZU2MTkBPCM=,tag:rq7ROGRyjVZulDDof8qKDg==,type:str] +ha-secrets: ENC[AES256_GCM,data:ECv4PMo/GFG/G8IKpTmAvScb+7uPA4DK5Y4yI931kjLIynM9m4UcCG/6MNdxm1hPsrv0F/4ye8fN8FVwOBrahF4+xxhEFBe9ACz0Sfohs4tMwS//7drFqjxJ9OPmJ9y149xcHcdDav5TFA078d2WjBEd3eO7StAUxInI9rgJBOhGuAsIYvzekCD7w3gprvzi/luI614Vi8NXLAZGpChPN+NQ0cVfSctG4yAJjQ5r4YpNP3WIHMNR8ZIr4ADFpex74Qg2xPL+AyQSZO+uC+etlUmIPkjDoatNAWY5SG4i0bq1UZQTOO+dsjWE3FAtH0GcBAIF9QMeEvDVQSvv/HXdknDi0YiloQSE/nuA4rtO2I7F54+PDzf3nRoglJHMlb5wrl1VQql76RvOkEADdjImR43RXjHLPF6+oZUODrrOauQre/ZQOVZh9IqSec1FcYxu8tDki04cmQeIeuFh5g+U4Qs+7Uj42yqHmIlk7AT3VQGJDftGiBNt1vU4Y5cBsW9Ygkx/V3LoQFD239r7JW0ys+TGMKtepDMpdd1s5kf1eUPbV4lmVKkuhLPCG/0Dcud7w8WFGkD0itJEzx2vIk6pBnMdCosmDA4FBrPjGqJMc8lUkx/nN5phTH6a+YbXp/YVLvfmr5HAuN6Y+QcVdnUs52NeAq7JpDWGD/HFksvVPT2uA/XPJzM4fMeqWJICpAxOqPvXuL6kGX7B7t4HymH68pdTuJnrLcPO513GRYH/yek4FamPJyICT1m+OhFWYg==,iv:ZkOLrgEMufW5ERndhwATdJqbjDnCxFC5OvIIHQHD42g=,tag:PHhHiKiT7nAiehnkax0ZRA==,type:str] cloudflared-tunnel-apartment: ENC[AES256_GCM,data:ccqV0jqrnbSz/r+C8v5FTWCtWVDHNdMwhiYHmjyrSLRt0xlcfSzqLhlTPMOfcEcded/NgiM9x3KrLm3hjW8GJpnaPGmQhP4GwBFEJ81R7dzXwpzbj0jbkj/sxxE7MEyofxfF+H2g5Kk55Yu148thxOB5Q4w2c6ZT16bHEXD20Cr88+T8chKQycfCWec0tE1WGmJYM3yrnaNvaey4oh4YWl+RApzxuA==,iv:KNjWDOF6PV8SVmXwzgom3wI+mjfnUSAzyuVIkDMgWHI=,tag:q9wOCGsXF5BOKEnt8jEAog==,type:str] cloudflared-tunnel-apartment-deluge: ENC[AES256_GCM,data:BG4ak9wQQjDanJ+RqI33PrAx8g==,iv:s1c/6pWQZim73VjLiJmvR2ly7ktAQf7rJ6Yx34EFddo=,tag:nNu/Re0U5HJSb8JLFu2NMA==,type:str] ha-integration: ENC[AES256_GCM,data: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,iv:tRzbBW/YFMp2vw26M9ediGY49GuxvyV2ijZ1W7mjURQ=,tag:L4ACYnVzdarztrjlsX3cAQ==,type:str] @@ -40,8 +41,8 @@ sops: VndVTG0zQWhsUHcwTkFjK2ZPdzRPUUEKJ3flgZ6/s+TjlFgzsANYaOFiEPQuE4zR 7npNUDFLe26Q32G3j/lLSBzZZfKoOC5SOSp9TB8eWMYSxfNnXEIu0g== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-01-06T20:31:10Z" - mac: ENC[AES256_GCM,data:A9llofFkb5PfjS3KzcINuBuU9TbIFpDswmhBNJ3VpXJSvkrWLVhc3T4TcLotqffXtvidptngjiP0qcK4wM6oXcpfhRs9Td1MDtQQ8B9ICQknmt7ukIDU3FneJuVkxvSpJiNsAIH1x5ZCFzp9Dt550gloYSLklzzl3eozLOwcQ1U=,iv:wV4rjaC9+x+ALxRhlUys2Ao4Fv8E+9QyF7Rf3Kzs15g=,tag:xJzJkgNks3LdkoZEqpJQNg==,type:str] + lastmodified: "2024-01-13T19:43:29Z" + mac: ENC[AES256_GCM,data:7LCZUEhRS7Z8oRLq/9qsZgIGCxLKZIvnMQdWTdsBgcFeRAbEz5LrCrlQVsFX9bFjU4oLUB7RANyYU73sylREYSRvMermZPg9QSWdswGXHz4IG3zF82JE9gZpoJ8Cy4BKQFMbz16gJm2d8glKdctL9cNPnQ8lbotJhc1efGPyac8=,iv:m7AMq30/HMepyNPtYBA6Pvc3o3vnQeSr6nSPAVdOkqo=,tag:DZHt+1qNI0cFbab8X+X/qw==,type:str] pgp: - created_at: "2023-03-10T17:06:53Z" enc: |