diff --git a/flake.lock b/flake.lock index 4392619c..b8b38901 100644 --- a/flake.lock +++ b/flake.lock @@ -40,6 +40,22 @@ "type": "github" } }, + "blobs": { + "flake": false, + "locked": { + "lastModified": 1604995301, + "narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=", + "owner": "simple-nixos-mailserver", + "repo": "blobs", + "rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265", + "type": "gitlab" + }, + "original": { + "owner": "simple-nixos-mailserver", + "repo": "blobs", + "type": "gitlab" + } + }, "emacs-overlay": { "locked": { "lastModified": 1646499853, @@ -90,6 +106,28 @@ "type": "github" } }, + "nixos-mailserver": { + "inputs": { + "blobs": "blobs", + "nixpkgs": [ + "nixpkgs" + ], + "utils": "utils" + }, + "locked": { + "lastModified": 1645895212, + "narHash": "sha256-SbR7HtHg7/UopLYLmMwwFZGF0BTmg0tLwIU/rQtRLfk=", + "owner": "simple-nixos-mailserver", + "repo": "nixos-mailserver", + "rev": "7de138037f62679e2fefa0549af543412dab0d1a", + "type": "gitlab" + }, + "original": { + "owner": "simple-nixos-mailserver", + "repo": "nixos-mailserver", + "type": "gitlab" + } + }, "nixpkgs": { "locked": { "lastModified": 1646254136, @@ -127,10 +165,11 @@ "agenix": "agenix", "emacs-overlay": "emacs-overlay", "home-manager": "home-manager", + "nixos-mailserver": "nixos-mailserver", "nixpkgs": "nixpkgs", "nur": "nur", "tetris": "tetris", - "utils": "utils" + "utils": "utils_2" } }, "tetris": { @@ -154,6 +193,21 @@ } }, "utils": { + "locked": { + "lastModified": 1605370193, + "narHash": "sha256-YyMTf3URDL/otKdKgtoMChu4vfVL3vCMkRqpGifhUn0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5021eac20303a61fafe17224c087f5519baed54d", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "utils_2": { "inputs": { "flake-utils": "flake-utils" }, diff --git a/flake.nix b/flake.nix index 463ff173..8ec4b1e5 100644 --- a/flake.nix +++ b/flake.nix @@ -15,6 +15,10 @@ url = "github:nix-community/home-manager"; inputs.nixpkgs.follows = "nixpkgs"; }; + nixos-mailserver = { + url = "gitlab:simple-nixos-mailserver/nixos-mailserver"; + inputs.nixpkgs.follows = "nixpkgs"; + }; nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nur.url = "github:nix-community/NUR"; tetris = { @@ -24,7 +28,7 @@ utils.url = "github:gytis-ivaskevicius/flake-utils-plus"; }; - outputs = inputs@{ self, nixpkgs, accentor, agenix, emacs-overlay, home-manager, nur, tetris, utils }: + outputs = inputs@{ self, nixpkgs, accentor, agenix, emacs-overlay, home-manager, nixos-mailserver, nur, tetris, utils }: let customPackages = callPackage: { jdtls = callPackage ./packages/jdtls { }; @@ -61,7 +65,8 @@ }) accentor.nixosModule agenix.nixosModules.age - home-manager.nixosModules.home-manager + home-manager.nixosModule + nixos-mailserver.nixosModule ./modules ]; }; diff --git a/machines/lasting-integrity/default.nix b/machines/lasting-integrity/default.nix index 3aa63f6f..375591c3 100644 --- a/machines/lasting-integrity/default.nix +++ b/machines/lasting-integrity/default.nix @@ -5,10 +5,7 @@ time.timeZone = "Europe/Berlin"; - networking = { - hostId = "b352adfe"; - firewall.allowedTCPPorts = [ 25 143 465 587 993 4190 ]; - }; + networking.hostId = "b352adfe"; # Machine-specific module settings chvp = { @@ -35,6 +32,12 @@ fast = true; location = "192.168.0.1"; } + { + path = "zdata/big-apps/mail"; + remotePath = "zdata/recv/lasting-integrity/big-apps/mail"; + fast = true; + location = "192.168.0.1"; + } { path = "zdata/big-apps/nextcloud"; remotePath = "zdata/recv/lasting-integrity/big-apps/nextcloud"; @@ -45,69 +48,47 @@ rootDataset = "zroot/local/root"; }; }; - development = { - docker.enable = true; - git.enable = true; - }; games = { particles.server = true; tetris.server = true; }; services = { + mail.enable = true; matrix.enable = true; - nginx = { - extraPostACMEScripts = [ - '' - cp fullchain.pem /data/root/mailcow/data/assets/ssl/cert.pem - cp key.pem /data/root/mailcow/data/assets/ssl/key.pem - pushd /data/root/mailcow - ${pkgs.bash}/bin/bash -c "source mailcow.conf && ${pkgs.docker-compose}/bin/docker-compose restart" - popd - '' - ]; - hosts = [ - { - fqdn = "vanpetegem.me"; - options = { - locations = let matrixRedirect = { - proxyPass = "http://127.0.0.1:8448"; - extraConfig = '' - proxy_read_timeout 600; - client_max_body_size 10M; - proxy_set_header X-Forwarded-Ssl on; - ''; - }; in - { - "/_matrix" = matrixRedirect; - "/.well-known/matrix" = matrixRedirect; - "/".return = "307 https://www.vanpetegem.me$request_uri"; - }; - }; - } - { fqdn = "www.vanpetegem.me"; } - { - fqdn = "cvpetegem.be"; - options = { - locations."/".return = "307 https://www.cvpetegem.be$request_uri"; - }; - } - { fqdn = "www.cvpetegem.be"; } - { - fqdn = "chvp.be"; - options = { - locations."/".return = "307 https://www.chvp.be$request_uri"; - }; - } - { fqdn = "www.chvp.be"; } - { - fqdn = "mail.vanpetegem.me"; - basicProxy = "http://127.0.0.1:8080"; - } - ]; - }; + nginx.hosts = [ + { + fqdn = "vanpetegem.me"; + options = { + locations = let matrixRedirect = { + proxyPass = "http://127.0.0.1:8448"; + extraConfig = '' + proxy_read_timeout 600; + client_max_body_size 10M; + proxy_set_header X-Forwarded-Ssl on; + ''; + }; in + { + "/_matrix" = matrixRedirect; + "/.well-known/matrix" = matrixRedirect; + "/".return = "307 https://www.vanpetegem.me$request_uri"; + }; + }; + } + { fqdn = "www.vanpetegem.me"; } + { + fqdn = "cvpetegem.be"; + options.locations."/".return = "307 https://www.cvpetegem.be$request_uri"; + } + { fqdn = "www.cvpetegem.be"; } + { + fqdn = "chvp.be"; + options.locations."/".return = "307 https://www.chvp.be$request_uri"; + } + { fqdn = "www.chvp.be"; } + ]; nextcloud.enable = true; syncthing.enable = true; - tunnel.enable = true; }; }; + services.ssmtp.enable = false; } diff --git a/machines/lasting-integrity/hardware.nix b/machines/lasting-integrity/hardware.nix index 6846f931..342b3cbc 100644 --- a/machines/lasting-integrity/hardware.nix +++ b/machines/lasting-integrity/hardware.nix @@ -42,6 +42,10 @@ fsType = "zfs"; neededForBoot = true; }; + "/data/var/vmail" = { + device = "zdata/big-apps/mail"; + fsType = "zfs"; + }; "/data/var/lib/nextcloud" = { device = "zdata/big-apps/nextcloud"; fsType = "zfs"; diff --git a/modules/base/mail/default.nix b/modules/base/mail/default.nix index edcf3f52..65b8ce79 100644 --- a/modules/base/mail/default.nix +++ b/modules/base/mail/default.nix @@ -2,7 +2,7 @@ { services.ssmtp = { - enable = true; + enable = lib.mkDefault true; authUser = "webmaster@vanpetegem.me"; authPassFile = config.age.secrets."passwords/services/ssmtp-pass".path; domain = "${config.networking.hostName}.vanpetegem.me"; diff --git a/modules/base/sshd/default.nix b/modules/base/sshd/default.nix index 72faf6d5..4745eb54 100644 --- a/modules/base/sshd/default.nix +++ b/modules/base/sshd/default.nix @@ -12,7 +12,7 @@ ]; }; - age.secrets."authorized_keys/root"= { + age.secrets."authorized_keys/root" = { file = ../../../secrets/authorized_keys/root.age; path = "/root/.ssh/authorized_keys"; symlink = false; diff --git a/modules/services/default.nix b/modules/services/default.nix index 9b03d605..61cac99f 100644 --- a/modules/services/default.nix +++ b/modules/services/default.nix @@ -6,10 +6,10 @@ ./containers ./data-access ./deluge + ./mail ./matrix ./nextcloud ./nginx ./syncthing - ./tunnel ]; } diff --git a/modules/services/mail/default.nix b/modules/services/mail/default.nix new file mode 100644 index 00000000..f0484528 --- /dev/null +++ b/modules/services/mail/default.nix @@ -0,0 +1,88 @@ +{ config, lib, pkgs, ... }: + +let + keyFile = "${config.security.acme.certs."vanpetegem.me".directory}/key.pem"; + certFile = "${config.security.acme.certs."vanpetegem.me".directory}/fullchain.pem"; +in +{ + options.chvp.services.mail.enable = lib.mkEnableOption "mail"; + + config = lib.mkIf config.chvp.services.mail.enable { + mailserver = { + enable = true; + fqdn = "mail.vanpetegem.me"; + domains = [ "vanpetegem.me" "cvpetegem.be" "chvp.be" "accentor.tech" "toekomstlabo.be" ]; + loginAccounts = { + "charlotte@vanpetegem.me" = { + hashedPasswordFile = config.age.secrets."passwords/services/mail/charlotte@vanpetegem.me".path; + aliases = [ "@chvp.be" "@cvpetegem.be" ]; + }; + "expenses-noreply@vanpetegem.me" = { + hashedPasswordFile = config.age.secrets."passwords/services/mail/expenses-noreply@vanpetegem.me".path; + sendOnly = true; + }; + "huis@vanpetegem.me".hashedPasswordFile = config.age.secrets."passwords/services/mail/huis@vanpetegem.me".path; + "peter@vanpetegem.me".hashedPasswordFile = config.age.secrets."passwords/services/mail/peter@vanpetegem.me".path; + "postbot@vanpetegem.me" = { + hashedPasswordFile = config.age.secrets."passwords/services/mail/postbot@vanpetegem.me".path; + aliases = [ "@vanpetegem.me" ]; + }; + "robbe@vanpetegem.me".hashedPasswordFile = config.age.secrets."passwords/services/mail/robbe@vanpetegem.me".path; + "ugent@cvpetegem.be" = { + hashedPasswordFile = config.age.secrets."passwords/services/mail/ugent@cvpetegem.be".path; + aliases = [ "charlotte.vanpetegem@ugent.be" ]; + }; + "webmaster@vanpetegem.me".hashedPasswordFile = config.age.secrets."passwords/services/mail/webmaster@vanpetegem.me".path; + }; + indexDir = "${config.chvp.cachePrefix}/var/lib/dovecot/indices"; + fullTextSearch = { + enable = true; + memoryLimit = 4000; + }; + lmtpSaveToDetailMailbox = "no"; + extraVirtualAliases = { + "team@accentor.tech" = [ "charlotte@vanpetegem.me" "robbe@vanpetegem.me" ]; + }; + forwards = { + "info@toekomstlabo.be" = "robbe+toekomstlabo@robbevanpetegem.be"; + }; + mailDirectory = "${config.chvp.dataPrefix}/var/vmail"; + useFsLayout = false; + certificateScheme = 1; + certificateFile = certFile; + keyFile = keyFile; + dkimKeyDirectory = "${config.chvp.dataPrefix}/var/dkim"; + }; + + services.postfix = { + config.sender_dependent_default_transport_maps = [ "hash:/etc/postfix/sender_map" ]; + mapFiles.sender_map = pkgs.writeText "postfix-sender-map" '' + charlotte.vanpetegem@ugent.be smtp:[127.0.0.1]:9797 + ''; + }; + + systemd.services.tunnel = { + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + script = "${pkgs.openssh}/bin/ssh -i ${config.age.secrets."files/services/tunnel/key".path} -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -o ControlPath=none -NT -p $SSH_PORT -L 0.0.0.0:9797:$CONN_HOST:$CONN_PORT $USER@$SSH_HOST"; + serviceConfig = { + RestartSec = "5s"; + Restart = "on-failure"; + EnvironmentFile = config.age.secrets."files/services/tunnel/env".path; + }; + }; + + age.secrets = { + "files/services/tunnel/key".file = ../../../secrets/files/services/tunnel/key.age; + "files/services/tunnel/env".file = ../../../secrets/files/services/tunnel/env.age; + "passwords/services/mail/charlotte@vanpetegem.me".file = ../../../secrets/passwords/services/mail/charlotte_at_vanpetegem.me.age; + "passwords/services/mail/expenses-noreply@vanpetegem.me".file = ../../../secrets/passwords/services/mail/expenses-noreply_at_vanpetegem.me.age; + "passwords/services/mail/huis@vanpetegem.me".file = ../../../secrets/passwords/services/mail/huis_at_vanpetegem.me.age; + "passwords/services/mail/peter@vanpetegem.me".file = ../../../secrets/passwords/services/mail/peter_at_vanpetegem.me.age; + "passwords/services/mail/postbot@vanpetegem.me".file = ../../../secrets/passwords/services/mail/postbot_at_vanpetegem.me.age; + "passwords/services/mail/robbe@vanpetegem.me".file = ../../../secrets/passwords/services/mail/robbe_at_vanpetegem.me.age; + "passwords/services/mail/ugent@cvpetegem.be".file = ../../../secrets/passwords/services/mail/ugent_at_cvpetegem.be.age; + "passwords/services/mail/webmaster@vanpetegem.me".file = ../../../secrets/passwords/services/mail/webmaster_at_vanpetegem.me.age; + }; + }; +} diff --git a/modules/services/nginx/default.nix b/modules/services/nginx/default.nix index f3730d25..aff9270c 100644 --- a/modules/services/nginx/default.nix +++ b/modules/services/nginx/default.nix @@ -27,18 +27,6 @@ } ]; }; - extraPostACMEScripts = lib.mkOption { - default = [ ]; - example = [ - '' - cp fullchain.pem /data/home/charlotte/synapse/slack/cert.crt - cp privkey.pem /data/home/charlotte/synapse/slack/key.pem - pushd /data/home/charlotte/synapse - ''${pkgs.docker-compose}/bin/docker-compose restart slack - popd - '' - ]; - }; }; config = lib.mkIf config.chvp.services.nginx.enable { @@ -54,7 +42,6 @@ "chvp.be" "*.chvp.be" ]; - postRun = lib.concatStrings config.chvp.services.nginx.extraPostACMEScripts; }; defaults.email = "webmaster@vanpetegem.me"; acceptTerms = true; diff --git a/modules/services/tunnel/default.nix b/modules/services/tunnel/default.nix deleted file mode 100644 index 6e9b6a7f..00000000 --- a/modules/services/tunnel/default.nix +++ /dev/null @@ -1,25 +0,0 @@ -{ config, pkgs, lib, ... }: - -{ - options.chvp.services.tunnel.enable = lib.mkOption { - default = false; - example = true; - }; - - config = lib.mkIf config.chvp.services.tunnel.enable { - networking.firewall.trustedInterfaces = [ "br-mailcow" ]; - systemd.services.tunnel = { - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - script = "${pkgs.openssh}/bin/ssh -i ${config.age.secrets."files/services/tunnel/key".path} -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -o ControlPath=none -NT -p $SSH_PORT -L 0.0.0.0:9797:$CONN_HOST:$CONN_PORT $USER@$SSH_HOST"; - serviceConfig = { - RestartSec = "5s"; - Restart = "on-failure"; - EnvironmentFile = config.age.secrets."files/services/tunnel/env".path; - }; - }; - - age.secrets."files/services/tunnel/key".file = ../../../secrets/files/services/tunnel/key.age; - age.secrets."files/services/tunnel/env".file = ../../../secrets/files/services/tunnel/env.age; - }; -} diff --git a/secrets.nix b/secrets.nix index 9f9e960e..81c0f7e1 100644 --- a/secrets.nix +++ b/secrets.nix @@ -40,6 +40,14 @@ in "secrets/passwords/services/accentor.age".publicKeys = [ urithiru ] ++ users; + "secrets/passwords/services/mail/charlotte_at_vanpetegem.me.age".publicKeys = [ lasting-integrity ] ++ users; + "secrets/passwords/services/mail/expenses-noreply_at_vanpetegem.me.age".publicKeys = [ lasting-integrity ] ++ users; + "secrets/passwords/services/mail/huis_at_vanpetegem.me.age".publicKeys = [ lasting-integrity ] ++ users; + "secrets/passwords/services/mail/peter_at_vanpetegem.me.age".publicKeys = [ lasting-integrity ] ++ users; + "secrets/passwords/services/mail/postbot_at_vanpetegem.me.age".publicKeys = [ lasting-integrity ] ++ users; + "secrets/passwords/services/mail/robbe_at_vanpetegem.me.age".publicKeys = [ lasting-integrity ] ++ users; + "secrets/passwords/services/mail/ugent_at_cvpetegem.be.age".publicKeys = [ lasting-integrity ] ++ users; + "secrets/passwords/services/mail/webmaster_at_vanpetegem.me.age".publicKeys = [ lasting-integrity ] ++ users; "secrets/passwords/services/ssmtp-pass.age".publicKeys = hosts ++ users; "secrets/passwords/services/acme.age".publicKeys = servers ++ users; diff --git a/secrets/passwords/services/mail/charlotte_at_vanpetegem.me.age b/secrets/passwords/services/mail/charlotte_at_vanpetegem.me.age new file mode 100644 index 00000000..fd8b9b7a --- /dev/null +++ b/secrets/passwords/services/mail/charlotte_at_vanpetegem.me.age @@ -0,0 +1,11 @@ +age-encryption.org/v1 +-> ssh-ed25519 hKAFvQ ahBZiWAQJ8gDr9iXra/ss3Z0Av9D1ie9JSKLF4c/Okw +yFgKlZZTQpJEgk3fcSGNYH5pSzp/Hk0UgE9IqyTHa4s +-> ssh-ed25519 s9rb8g c18VGG0c1TUodSAJ9yse6NnTxU55vD3/GxFT6AKDMxE +D/eY7Yy8aEQI+G7NnLv7wYuj4wKgss5LtC+hziJ82GE +-> ssh-ed25519 yad4VQ uFPIuBUVcB4uNWT2n0zG47B0lS3xJNc9eYC2UYjOXik +HASW6oo49CCCqDhVxBQWV8ospBSFZQj2US1NFbenItE +-> xB*-grease Y/qK/}Qi \1]9X~ +eFWnjgXubs1JoPMhz13W6fU +--- HMRxW/o6WnGKX1VBIhVoibAA3LgI8IFY71I7sbmj08I +;N Nf`. ?H8pfPL1=d昚<5_N+h*kOՋKW:C*Gˢ""<|mPIFَB \ No newline at end of file diff --git a/secrets/passwords/services/mail/expenses-noreply_at_vanpetegem.me.age b/secrets/passwords/services/mail/expenses-noreply_at_vanpetegem.me.age new file mode 100644 index 00000000..1078cbdc --- /dev/null +++ b/secrets/passwords/services/mail/expenses-noreply_at_vanpetegem.me.age @@ -0,0 +1,13 @@ +age-encryption.org/v1 +-> ssh-ed25519 hKAFvQ K0/OGHgNGGOXqUcbDgCIrzW4t73SPSeUd+gG5jnm00c +KGhXDqs6PEG4aMVujmHC6m5srF3f8AA7Qwoero2HEYA +-> ssh-ed25519 s9rb8g JTk9eebQUBH+iblr1D4l1/GEuw44dSL+6+z3bCvewQA +kQX7BhNb06o+MvTaZJAjeXzxzMgG97yBSi7i8wQilXI +-> ssh-ed25519 yad4VQ aVsBmsu8EUJGSdZSkMMRoqCMSSnerZ1ZQSSQdL74pHA +TBoBMYpaaSW4JxnSNjFmMQZWuG980eO3eUx+sBJ6Sx4 +-> D0j-grease /Vnw;b}W !Qi wxsjo,Ns 3SP +gICLXBnxzhuWZYcEAjHqTUXthxk3OXXOKcqaqZ4TPgJNlP+w2tQPI9mKkKvBsyxC +kPRmsQrMeaKkbSBd7E9ukHmjFFrUr976dbYEYBVr +--- ct4WJvTs7bBnsMIYGgKpqDqQP6lD6HKy0M9YZr6nMtE +M@b(%J}$`Q' +;)UGQm3%jF7ֈpIAɜud bsiWn55l*wtBըZ4>1ټvC/] \ No newline at end of file diff --git a/secrets/passwords/services/mail/huis_at_vanpetegem.me.age b/secrets/passwords/services/mail/huis_at_vanpetegem.me.age new file mode 100644 index 00000000..60ba3b2a --- /dev/null +++ b/secrets/passwords/services/mail/huis_at_vanpetegem.me.age @@ -0,0 +1,13 @@ +age-encryption.org/v1 +-> ssh-ed25519 hKAFvQ ipuOfR53i4N9K7WU3n42Z8T4Yx4stuFR+ZbwZ//qOhA +u+B/ghnsEtRkdhfMhzq0mXqITnIN/fBZWL1Qr4AJqMQ +-> ssh-ed25519 s9rb8g Z8bMCuAsDgYPFqkHbrjmApusx/eGzht/hlRMf+SMVxc +Ll7OIxlh3MhlDNZuP+AOY7uumdoRkhdFzX0Wnk3u36E +-> ssh-ed25519 yad4VQ x8zMlh1ik/u/H6w1Pz/EqHbkjf9YfGSAyGJNu1sJyU0 +hw4aZDrMN7TSR9pdstgb/mtcGekFlFP32IfcWHQHhqk +-> =-grease +akxvkvEU2dQoOjC23uvAhwVdbbEu6UgholfEeMJmXPPxg52ajnGvQl8TCHsMZB+v +DoiJ6IPsByE +--- Qu6IXI4VY6a66SOQDxH7iwcbu2+HfKb8yoQ8MU9Jf1Y +h_<3Vop +5x_!UՁQb>1U! 库3dHŌB]* p`*L$J0LpmܵCbP{ \ No newline at end of file diff --git a/secrets/passwords/services/mail/peter_at_vanpetegem.me.age b/secrets/passwords/services/mail/peter_at_vanpetegem.me.age new file mode 100644 index 00000000..07599a44 Binary files /dev/null and b/secrets/passwords/services/mail/peter_at_vanpetegem.me.age differ diff --git a/secrets/passwords/services/mail/postbot_at_vanpetegem.me.age b/secrets/passwords/services/mail/postbot_at_vanpetegem.me.age new file mode 100644 index 00000000..ebfa9af5 Binary files /dev/null and b/secrets/passwords/services/mail/postbot_at_vanpetegem.me.age differ diff --git a/secrets/passwords/services/mail/robbe_at_vanpetegem.me.age b/secrets/passwords/services/mail/robbe_at_vanpetegem.me.age new file mode 100644 index 00000000..589684cb Binary files /dev/null and b/secrets/passwords/services/mail/robbe_at_vanpetegem.me.age differ diff --git a/secrets/passwords/services/mail/ugent_at_cvpetegem.be.age b/secrets/passwords/services/mail/ugent_at_cvpetegem.be.age new file mode 100644 index 00000000..bfcfafcd Binary files /dev/null and b/secrets/passwords/services/mail/ugent_at_cvpetegem.be.age differ diff --git a/secrets/passwords/services/mail/webmaster_at_vanpetegem.me.age b/secrets/passwords/services/mail/webmaster_at_vanpetegem.me.age new file mode 100644 index 00000000..5afe051f --- /dev/null +++ b/secrets/passwords/services/mail/webmaster_at_vanpetegem.me.age @@ -0,0 +1,12 @@ +age-encryption.org/v1 +-> ssh-ed25519 hKAFvQ JHjuI9rQDBEZvK8NN3KmDOL4tZsGZMec1EFXrMSY1nw +n0uoSU5wTkQYf9xBOEiWWfMjjATk7T0orntiSjTKdtE +-> ssh-ed25519 s9rb8g E1lkFCR7hM5LXWBZ51y5hZvUN4+pHIudkXmpU8wkLCY +eEvc/SXb2d8vqRTroayijnVB99ZO4RPgK03fCR37O94 +-> ssh-ed25519 yad4VQ x6B/1ZQOMgbjbs32U7j4Rr4/MmBLyCg+cIPDynFJuXA +6loeFyyP9g2R3/p//6iUCn3YfMl2otRcIvl2srWBpd0 +-> PH~?+-grease +GX64yaOgkxrMz9cfX6BfbXuefE8PPeYyIke4bGCxbsRSibDHaHfcd8OiIKxAHkP7 +IwNDaBN+FSoIvKc +--- 8Vd7zRm8JAo0kYXwuP5+AlAIyEWzahj7NKv2VZOsdWo +%RMi JRMF~qNCPlͣͫbF4j3Wb܂, ךޔAgI`y⡌`@eHkamLOX \ No newline at end of file