diff --git a/nixos/boxes/colony/vms/shill/containers/default.nix b/nixos/boxes/colony/vms/shill/containers/default.nix index 7436738..76bc2eb 100644 --- a/nixos/boxes/colony/vms/shill/containers/default.nix +++ b/nixos/boxes/colony/vms/shill/containers/default.nix @@ -6,5 +6,6 @@ ./chatterbox.nix ./jackflix ./object.nix + ./toot.nix ]; } diff --git a/nixos/boxes/colony/vms/shill/containers/middleman/default.nix b/nixos/boxes/colony/vms/shill/containers/middleman/default.nix index 2bda636..4910b63 100644 --- a/nixos/boxes/colony/vms/shill/containers/middleman/default.nix +++ b/nixos/boxes/colony/vms/shill/containers/middleman/default.nix @@ -240,6 +240,9 @@ ${lib.my.nginx.proxyHeaders} + # caching + proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=4g; + vhost_traffic_status_zone; map $upstream_status $nix_cache_control { diff --git a/nixos/boxes/colony/vms/shill/containers/middleman/vhosts.nix b/nixos/boxes/colony/vms/shill/containers/middleman/vhosts.nix index 73c9d53..125c8ad 100644 --- a/nixos/boxes/colony/vms/shill/containers/middleman/vhosts.nix +++ b/nixos/boxes/colony/vms/shill/containers/middleman/vhosts.nix @@ -42,6 +42,7 @@ let autoindex on; ''; }; + "/.well-known/webfinger".return = "301 https://toot.nul.ie$request_uri"; }; in { @@ -299,6 +300,62 @@ in }; useACMEHost = lib.my.pubDomain; }; + + "toot.nul.ie" = + let + mkAssetLoc = name: { + tryFiles = "$uri =404"; + extraConfig = '' + add_header Cache-Control "public, max-age=2419200, must-revalidate"; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; + ''; + }; + in + { + root = "${pkgs.mastodon}/public"; + locations = mkMerge [ + (genAttrs [ + "= /sw.js" + "~ ^/assets/" + "~ ^/avatars/" + "~ ^/emoji/" + "~ ^/headers/" + "~ ^/packs/" + "~ ^/shortcuts/" + "~ ^/sounds/" + ] mkAssetLoc) + { + "/".tryFiles = "$uri @proxy"; + + "^~ /api/v1/streaming" = { + proxyPass = "http://toot-ctr.${config.networking.domain}:55000"; + proxyWebsockets = true; + extraConfig = '' + ${lib.my.nginx.proxyHeaders} + proxy_set_header Proxy ""; + + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; + ''; + }; + "@proxy" = { + proxyPass = "http://toot-ctr.${config.networking.domain}:55001"; + proxyWebsockets = true; + extraConfig = '' + ${lib.my.nginx.proxyHeaders} + proxy_set_header Proxy ""; + proxy_pass_header Server; + + proxy_cache CACHE; + proxy_cache_valid 200 7d; + proxy_cache_valid 410 24h; + proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; + add_header X-Cached $upstream_cache_status; + ''; + }; + } + ]; + useACMEHost = lib.my.pubDomain; + }; }; minio = diff --git a/nixos/boxes/colony/vms/shill/containers/toot.nix b/nixos/boxes/colony/vms/shill/containers/toot.nix new file mode 100644 index 0000000..79e94e0 --- /dev/null +++ b/nixos/boxes/colony/vms/shill/containers/toot.nix @@ -0,0 +1,144 @@ +{ lib, ... }: { + nixos.systems.toot = { + system = "x86_64-linux"; + nixpkgs = "mine"; + + assignments = { + internal = { + name = "toot-ctr"; + domain = lib.my.colony.domain; + ipv4.address = "${lib.my.colony.start.ctrs.v4}8"; + ipv6 = { + iid = "::8"; + address = "${lib.my.colony.start.ctrs.v6}8"; + }; + }; + }; + + configuration = { lib, pkgs, config, assignments, allAssignments, ... }: + let + inherit (lib) mkMerge mkIf genAttrs; + inherit (lib.my) networkdAssignment; + in + { + config = mkMerge [ + { + my = { + deploy.enable = false; + server.enable = true; + + secrets = { + key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILSslLkDe54AKYzxdtKD70zcU72W0EpYsfbdJ6UFq0QK"; + files = genAttrs + (map (f: "toot/${f}") [ + "postgres-password.txt" + "secret-key.txt" + "otp-secret.txt" + "vapid-key.txt" + "smtp-password.txt" + "s3-secret-key.txt" + ]) + (_: with config.services.mastodon; { + owner = user; + inherit group; + }); + }; + + firewall = { + tcp.allowed = [ + 19999 + + config.services.mastodon.webPort + config.services.mastodon.streamingPort + ]; + }; + }; + + systemd = { + network.networks."80-container-host0" = networkdAssignment "host0" assignments.internal; + services = { + # No option to provide an S3 secret access key file :( + mastodon-init-dirs.script = '' + echo "AWS_SECRET_ACCESS_KEY=\""$(< ${config.age.secrets."toot/s3-secret-key.txt".path})"\"" >> /var/lib/mastodon/.secrets_env + ''; + + # Can't use the extraConfig because these services expect a different format for the both family bind address... + mastodon-streaming.environment.BIND = "::"; + mastodon-web.environment.BIND = "[::]"; + }; + }; + + services = { + netdata.enable = true; + mastodon = mkMerge [ + { + enable = true; + localDomain = "nul.ie"; + extraConfig.WEB_DOMAIN = "toot.nul.ie"; + + secretKeyBaseFile = config.age.secrets."toot/secret-key.txt".path; + otpSecretFile = config.age.secrets."toot/otp-secret.txt".path; + vapidPrivateKeyFile = config.age.secrets."toot/vapid-key.txt".path; + vapidPublicKeyFile = toString (pkgs.writeText + "vapid-pubkey.txt" + "BAyRyD2pnLQtMHr3J5AzjNMll_HDC6ra1ilOLAUmKyhkEdbm7_OwKZUgw1UefY4CHEcv4OOX9TnnN2DOYYuPZu8="); + + enableUnixSocket = false; + configureNginx = false; + trustedProxy = allAssignments.middleman.internal.ipv6.address; + + database = { + createLocally = false; + host = "colony-psql"; + user = "mastodon"; + passwordFile = config.age.secrets."toot/postgres-password.txt".path; + name = "mastodon"; + }; + + smtp = { + createLocally = false; + fromAddress = "Mastodon "; + host = "mail.nul.ie"; + port = 587; + authenticate = true; + user = "toot@nul.ie"; + passwordFile = config.age.secrets."toot/smtp-password.txt".path; + }; + extraConfig.SMTP_ENABLE_STARTTLS_AUTO = "true"; + + redis.createLocally = true; + + # TODO: Re-enable when nixpkgs is updated + #mediaAutoRemove = { + # enable = true; + # olderThanDays = 30; + #}; + } + { + extraConfig = { + S3_ENABLED = "true"; + S3_BUCKET = "mastodon"; + AWS_ACCESS_KEY_ID = "mastodon"; + S3_ENDPOINT = "https://s3.nul.ie/"; + S3_REGION = "eu-central-1"; + S3_PROTOCOL = "https"; + S3_HOSTNAME = "mastodon.s3.nul.ie"; + + S3_ALIAS_HOST = "mastodon.s3.nul.ie"; + }; + } + ]; + }; + } + (mkIf config.my.build.isDevVM { + virtualisation = { + forwardPorts = with config.services.mastodon; [ + { from = "host"; guest.port = webPort; } + { from = "host"; guest.port = streamingPort; } + ]; + }; + }) + ]; + }; + }; +} diff --git a/nixos/boxes/colony/vms/shill/default.nix b/nixos/boxes/colony/vms/shill/default.nix index c63b3b9..c394e13 100644 --- a/nixos/boxes/colony/vms/shill/default.nix +++ b/nixos/boxes/colony/vms/shill/default.nix @@ -155,6 +155,7 @@ "/mnt/minio".readOnly = false; }; }; + toot = {}; }; in mkMerge [ diff --git a/nixos/modules/tmproot.nix b/nixos/modules/tmproot.nix index 5c1f6d9..32528d0 100644 --- a/nixos/modules/tmproot.nix +++ b/nixos/modules/tmproot.nix @@ -189,6 +189,12 @@ in (mkIf config.services.resolved.enable { my.tmproot.unsaved.ignore = [ "/etc/resolv.conf" ]; }) + (mkIf config.services.nginx.enable { + my.tmproot.unsaved.ignore = [ "/var/cache/nginx" ]; + }) + (mkIf config.services.mastodon.enable { + my.tmproot.unsaved.ignore = [ "/var/lib/mastodon/.secrets_env" ]; + }) (mkIf config.my.build.isDevVM { my.tmproot.unsaved.ignore = [ "/nix" ]; @@ -366,6 +372,20 @@ in }; }; }) + (mkIf config.services.mastodon.enable { + my.tmproot.persistence.config.directories = with config.services.mastodon; [ + { + directory = "/var/lib/mastodon/public-system"; + inherit user group; + } + { + directory = "/var/lib/redis-mastodon"; + mode = "700"; + user = "redis-mastodon"; + group = "redis-mastodon"; + } + ]; + }) ])) ]); diff --git a/secrets/chatterbox/nul.ie.signing.key.age b/secrets/chatterbox/nul.ie.signing.key.age index 51b24b7..b35556f 100644 Binary files a/secrets/chatterbox/nul.ie.signing.key.age and b/secrets/chatterbox/nul.ie.signing.key.age differ diff --git a/secrets/chatterbox/synapse.yaml.age b/secrets/chatterbox/synapse.yaml.age index d5ce637..0101ed9 100644 Binary files a/secrets/chatterbox/synapse.yaml.age and b/secrets/chatterbox/synapse.yaml.age differ diff --git a/secrets/dhparams.pem.age b/secrets/dhparams.pem.age index db8f587..ab7db92 100644 Binary files a/secrets/dhparams.pem.age and b/secrets/dhparams.pem.age differ diff --git a/secrets/estuary/netdata/powerdns.conf.age b/secrets/estuary/netdata/powerdns.conf.age index 0e87cb2..9133721 100644 --- a/secrets/estuary/netdata/powerdns.conf.age +++ b/secrets/estuary/netdata/powerdns.conf.age @@ -1,10 +1,9 @@ age-encryption.org/v1 --> ssh-ed25519 n8CpUw iETDBtdye4piq/xqWpbInrU2FOPEEKea4k4lVzAwSjo -azZL62Gq2MZP8ix0HiySJvAD6cAHkL3Be20We8OQQM4 --> X25519 NRs9OnWiXplaM8CnZqmOUNsPThBOIEsnr9FDzMrlVDI -ZTXNz2tHYMEbkOKMMmu7IPoAq6Bivn0iyso5dGi/aew --> C%.jkH-grease 47 -ZZhoIPOgltI7bYaGSDHUQLU ---- IOE3R6sGvuDXeUyYtGuf5DDEMIzBjAEI3hD8yHnRibU -uyb\>"!$)miڋD} =*I0^Ft:7<<ޥKl>ƌd.1~a_OnwB.G5meC.$ -[{'/ 2*c递1vߴ \ No newline at end of file +-> ssh-ed25519 n8CpUw 3b8J/xL277WAajHymjDJobariLmoDAhUyQpLdB9cfXo +i3vbIUk+NawecuYN24PYPkeCcPU6tcSv2uyeThUXLxM +-> X25519 e7KpW0DuROUPbJnwH9bmuukI4CssFChIlGiQZ9eJ2m8 +95FinF9t9H14AaWEsZrboHvVjDpawT438N8x0u9aqEM +-> SQ-grease yKgA| >{Zf` %\ }#]TR;rx +ufI0F4kKHxaxb6ulmD2nwef1y9I +--- N9HQTIQ5VVZI/MQnddn+iic0NpcXDVn+y+TsdJmqfYM +gn=j>Od: OJ0N^ˤU~ (Q ^:0BdFB=v[ .MC2ʿE=Y/%K|Cڵ}&!w>}o S??^!Bв \ No newline at end of file diff --git a/secrets/estuary/netdata/powerdns_recursor.conf.age b/secrets/estuary/netdata/powerdns_recursor.conf.age index 80619f1..4fb8a64 100644 --- a/secrets/estuary/netdata/powerdns_recursor.conf.age +++ b/secrets/estuary/netdata/powerdns_recursor.conf.age @@ -1,10 +1,11 @@ age-encryption.org/v1 --> ssh-ed25519 n8CpUw 4Uz8X3DA0qi11jxT9YNhKoeEeDPzwo4NJH9k4eM08Xo -PCHTFDA4A0tzGjgrkYOmIyrtNK0uV+rHNdZW/ntRNAc --> X25519 3sNBOVg/VLvSP+Eezi+qdrKgvUfQCpCjfSRw6F+Vb1U -ixF2OOSSX6YdrJ1dBRZHMJA7cuZMU9l2kAm7Vp28W7g --> j(Bq}H-m-grease ZYUY SPd -wpnnHgPzm87eHBnd64JWPvCXyGejDcFGpQ1ny1DxIeQLJGpz/neBMrkpjMz7i4vF -/Ad3IzRvmWo1ZHbk ---- 06ibUv3aHvqyXOp6dIibVq3TWH4TGwKYDIxOcDI7p9o -)l F1B4C@,WcJpc^ C:eM¡iɖ6T<4<&TyqE̤xV7 ˂Uh]Lm3Wd /hÉ`M>"DNk=]@ \ No newline at end of file +-> ssh-ed25519 n8CpUw 6uHZyoyVt2gGwiKcnXNoYKhKRe4VoruWKEKKhDZGWE4 +Koe5ZXD5VXbxN54uhLAZgjOJDd898gxoAv8eug57n6A +-> X25519 7HmjFGzmHrcLL4OoylHByV9HQEjLoHJI3aL1KQPa40U +kmlyNDJy4wZUlQuIMYXjGGa8goX6p0kqCmctcvjhZg8 +-> Qt-grease +gFRjzic9zrBNWUd/9b8dcMhrf4I8B2dsXFnkXMJJ/QTXH3Vwo0x78VQrcsDCBeFQ +bFoadWMaFb8tiEzOTUmL4D3v8cUoQNik +--- 5K/uMQHfY+rbs+XlqWjPoIkZWiNcaqcd2PJxwbDP4GI +-?KsaeIJޖM1Z3T0"-Q;t~*oTSu %-?ƈ ssh-ed25519 n8CpUw NFyy9tfPWXMqC4fUHFTISB3N3m1P6/5w5CsbHW3uGwA -BsURcFPmnc6pJC73JlC1JullIIr1cEm7LISctfR2HCY --> X25519 6pX8pYBHpt7a8I62IbS5a/JoyME7C4wSNVq9R/B4olA -mQqqFa7aGn0PJGb+3CwaE/0/VxmP0qzFkDTiV1EpDvE --> JusY"4K4-grease 0p9 +_0 -MUgjTTYvQmfSeT12H20EbDSGTWXmukYPCdGfH1WInr5bbZJI ---- siLfYgb7hAdIkqPT9M8SdZrUwLlmiiMEb2EHobEFUDA -5!;z-3|rRկVr53~%9Ixn#ӫkv$z!l;PL&>;9; \ No newline at end of file +-> ssh-ed25519 n8CpUw 1h5DOKUmcFLWvD09R9Hg+kPtKskdJuIS0/Y+TJ4XlRs +tD9fRfDHl/CPjeN17xAWQhd1KWcoqDmf6bstgb6HRsU +-> X25519 vt8XCj+Ju/TeP7JwEZrofUtatTRjxD3ROngwQbTkhzE +iKSnIjHuYy3apf45NZ6kLgIV5dVIhc4fOCflVh7D9Sg +-> @\)-6C-grease vcL@ yq^]X +08U2EyiwGEU9t+P4s8Vu+mTH7UZuaDCUpiv4w9KbTGV+dAe2Fw +--- ux9a8/Et2aI1Lmkmvn+xkemaWcW/wghIb/Jcz/h6rNE +Ŏc_Q1bMNB \DTm`.\*[҂x֙JSH# yDnz}%6' \ No newline at end of file diff --git a/secrets/hercules/aws-credentials.ini.age b/secrets/hercules/aws-credentials.ini.age index 5ec95cb..d885eee 100644 Binary files a/secrets/hercules/aws-credentials.ini.age and b/secrets/hercules/aws-credentials.ini.age differ diff --git a/secrets/hercules/binary-caches.json.age b/secrets/hercules/binary-caches.json.age index 980af15..f31f327 100644 Binary files a/secrets/hercules/binary-caches.json.age and b/secrets/hercules/binary-caches.json.age differ diff --git a/secrets/hercules/cluster-join-token.key.age b/secrets/hercules/cluster-join-token.key.age index 1eef06f..1ac8211 100644 Binary files a/secrets/hercules/cluster-join-token.key.age and b/secrets/hercules/cluster-join-token.key.age differ diff --git a/secrets/jackflix/mullvad-privkey.age b/secrets/jackflix/mullvad-privkey.age index d7e13e4..fbdcda3 100644 Binary files a/secrets/jackflix/mullvad-privkey.age and b/secrets/jackflix/mullvad-privkey.age differ diff --git a/secrets/middleman/cloudflare-credentials.conf.age b/secrets/middleman/cloudflare-credentials.conf.age index 100e18b..20184dd 100644 Binary files a/secrets/middleman/cloudflare-credentials.conf.age and b/secrets/middleman/cloudflare-credentials.conf.age differ diff --git a/secrets/middleman/nginx-sso.yaml.age b/secrets/middleman/nginx-sso.yaml.age index 7a13f3e..8ce5577 100644 Binary files a/secrets/middleman/nginx-sso.yaml.age and b/secrets/middleman/nginx-sso.yaml.age differ diff --git a/secrets/minio.env.age b/secrets/minio.env.age index 5fcf233..5353d50 100644 Binary files a/secrets/minio.env.age and b/secrets/minio.env.age differ diff --git a/secrets/nix-cache-gc.ini.age b/secrets/nix-cache-gc.ini.age index ef3c985..d788734 100644 Binary files a/secrets/nix-cache-gc.ini.age and b/secrets/nix-cache-gc.ini.age differ diff --git a/secrets/pdns-file-records.key.age b/secrets/pdns-file-records.key.age index ff7cdfc..c7ac09e 100644 Binary files a/secrets/pdns-file-records.key.age and b/secrets/pdns-file-records.key.age differ diff --git a/secrets/toot/otp-secret.txt.age b/secrets/toot/otp-secret.txt.age new file mode 100644 index 0000000..4353420 --- /dev/null +++ b/secrets/toot/otp-secret.txt.age @@ -0,0 +1,10 @@ +age-encryption.org/v1 +-> ssh-ed25519 62JccA hYLNjdUSu6k/3UWmZ8KUWGgp8oCKg8mXuWbssRJKNGk +bixOLSjVKS4HCC4BpH3FVioqfrZFKu1gU3CrFR5GLxI +-> X25519 SPjyPzWZhxysp+orn9MRLbMgF0bmGJrCyEhwYuGwfA4 +ar3h3erVZheWkRgd4si/LFKrJGhsxFNvP+hpcX4UAyA +-> ;>8csh04-grease +2MVNSFMb/p8+CPGD6yJypa3hAXylVl9V805WrBXP8mGy1AYrg213xqiUKhHp93BB +VuT7rcCaurSxmusUwAoflUowUZ/bWBn/ +--- QzLGsIO6xVPKIxS0kKn9h6yl4tx4jGHgDqKHR/WtCF4 +e0 AiΉ xy2INCISPf rpN8dśF,ZP8jcHRri}N h+x.6i9h13dž?'­5!ѵ͸Иu \ No newline at end of file diff --git a/secrets/toot/postgres-password.txt.age b/secrets/toot/postgres-password.txt.age new file mode 100644 index 0000000..e56e3a4 --- /dev/null +++ b/secrets/toot/postgres-password.txt.age @@ -0,0 +1,10 @@ +age-encryption.org/v1 +-> ssh-ed25519 62JccA QhhGF5N6sMP+P3IdUpmJzNRz2Hm00ZncbuakeU8iQU4 +YF/OzLaTwVHF6TAiQ0DS62T4YB6mbzwGUBKiC57tttQ +-> X25519 Pm6IdBMnfg2dXyShGK/rab40kgaHntQl2i1+U6mdXDk +juv9BOJ30uI4i86v1FK0mD2m09FO1H6fgBS3Hd4LKc0 +-> ?U`0-grease +tBHyO/6iUm7Dce1vJeez7ojMHxyBtgBCX/GoFkvZR5MbC0L0lwDaKYV/iNtyI/mz +lX65tP5ZM0RRMb8OduMLOtd0fGz0SO2CwlwyVbMcYptJoFvH2Nk +--- 8StTTi8cIRWmha1obVORyGBiSga4pIocUrKMiNHPIEk + M\ 0me AfL>4}2^vkP#XR \ No newline at end of file diff --git a/secrets/toot/s3-secret-key.txt.age b/secrets/toot/s3-secret-key.txt.age new file mode 100644 index 0000000..cbeb244 --- /dev/null +++ b/secrets/toot/s3-secret-key.txt.age @@ -0,0 +1,13 @@ +age-encryption.org/v1 +-> ssh-ed25519 62JccA 5pH4eHN72U1/YuyqlT8f7+K2LflVAcSmdhgcYJaEbA8 +h6Psi0r7rQ3vR4QidV31ooOQDSz/jDU/JONG+v7g/nY +-> X25519 wv8cuge1iRgd/wBUDPsEIxveR2/POc64KKS7l9vGSjc +rqcKowLY3seymydklTmQoLORb3H47Oqmg15hmu3Q+UM +-> ;=-grease \K*OpV +yJ/JvmkgmjspPcq5QckIB9zgSbHVPHhGUnvAWDlp4l8DJPFZfyj+u43eAr5z2q08 +I1NF/kRRj4rdinLFRlAI8fKCQj6ifcZ7vg1fe0CB/QRTx/4t6ekJp05z/wRP7ZLz +vw +--- sUj+V1ze8uxcObXJOPYsk/F8bz72vUWrj7VM9BLC478 +h(ڤK^-㚂QQͯD@`l! +ۀ +* \ No newline at end of file diff --git a/secrets/toot/secret-key.txt.age b/secrets/toot/secret-key.txt.age new file mode 100644 index 0000000..4a43a23 Binary files /dev/null and b/secrets/toot/secret-key.txt.age differ diff --git a/secrets/toot/smtp-password.txt.age b/secrets/toot/smtp-password.txt.age new file mode 100644 index 0000000..121a7ae --- /dev/null +++ b/secrets/toot/smtp-password.txt.age @@ -0,0 +1,10 @@ +age-encryption.org/v1 +-> ssh-ed25519 62JccA CMVPtLHq9uZiwxGStO2uG2EjdIsDtT8EBpg+FqcpwRk +BdpqFObr1lIpFSI8JGbw2ZY7ytCzHJbnlcG1inENwC8 +-> X25519 p0bB1J+ilWsouqw0WfzUShDHdHYE4rDYypT8WIhx12k +FnQGRuclUZQyv6EgXGS5whj0oQ7cXuWBVPb8SNYRFrE +-> yIy>EDE-grease eYO +;!yF] cv#J vMrf +XglB4bN9hrclLT6HDgyggakuIg +--- hZbvazlSkllx3S//GGiCiKiFzIqpczGoyYutfa+ACBo +(Eg.=i +(u` "Qd@׽+[eZ# \ No newline at end of file diff --git a/secrets/toot/vapid-key.txt.age b/secrets/toot/vapid-key.txt.age new file mode 100644 index 0000000..c4c74fc Binary files /dev/null and b/secrets/toot/vapid-key.txt.age differ diff --git a/secrets/user-passwd.txt.age b/secrets/user-passwd.txt.age index b712c6b..a3d54bf 100644 Binary files a/secrets/user-passwd.txt.age and b/secrets/user-passwd.txt.age differ diff --git a/secrets/vaultwarden.env.age b/secrets/vaultwarden.env.age index 7391acd..c79e486 100644 Binary files a/secrets/vaultwarden.env.age and b/secrets/vaultwarden.env.age differ diff --git a/secrets/whale2/valheim.env.age b/secrets/whale2/valheim.env.age index 56eeb2a..c11c710 100644 --- a/secrets/whale2/valheim.env.age +++ b/secrets/whale2/valheim.env.age @@ -1,10 +1,10 @@ age-encryption.org/v1 --> ssh-ed25519 /EJXvg zqgNJtsJoogjGP75yueFFWd3oe0H64W5CQcujNCWZ0M -cVeKmN0jo/y7n5QS2Dp4U0uxK+jGwlQnwXNxR87z020 --> X25519 J2MeXbL+kGLV3MePB1RMphd7XUfAiL7BTfRWut5lkTE -PlaRjS9QfL0R1wTx5XJNhjOn2PCG/6QIT3x8I5QG9wo --> |#-grease t|Z9XXy p:XF -LPPVfms2cH4f51GHS7rSwzBOBQulDAANNYGwl22AkZfSNHotvpHdguuJ0S1D+aEj -d7jlo/xce10TcNJwKYNeTn775g ---- l2P0/sNogMDU0AmwSuK8BPJnXTj3a7jwwQ0P7ho8Etw -52F4bC涹&iK/AYx&ԭ/gQ&zIg$dmd \ No newline at end of file +-> ssh-ed25519 /EJXvg BJZrrIl9HdCRVcGbolryOYl07K/Af4lwdo0kcdfi1nE +Z/zOV6v9llrTCguPg2pFSmJFFlY2Bv7rLYF8ynHT+gA +-> X25519 Mxyf7SL+faoCveud/lCQFcjyKMNxTnKsqwKTbznaPic +oDSnX4u5ked4Rfnt0giv1MQKPNChuvyd9hqnPX1JPTQ +-> 1*T*F|}-grease '`: I"ixoC k~b=\i%m mPT2XC +E3KZgVKf5pW4H6o1lQcxWTFNL7M1BBIYjrGO5g2BAEXJRi4klfzRL9DwRXrs2/Rm +pJHAEuTpdD0j1JegZpB9ObocIy6UuL+/Ng5yDQk +--- ODMxWjzAalxE3jjTHTest+r6B0tnS5xKScTzzAbEJgg +G5s=^ؖsr)qך"4p3KvQĄ6@0} \ No newline at end of file