Start using age for secret management
This commit is contained in:
parent
276c8f33c8
commit
da9160559c
39 changed files with 281 additions and 30 deletions
15
README.md
15
README.md
|
@ -1,5 +1,20 @@
|
||||||
# NixOS config
|
# NixOS config
|
||||||
|
|
||||||
|
## Secrets
|
||||||
|
|
||||||
|
There are two types of secrets in this repository. Secret secrets, and
|
||||||
|
secret configuration.
|
||||||
|
|
||||||
|
Secret secrets should never be world-readable, even to users who are
|
||||||
|
logged in to one of the hosts managed by this configuration. These are
|
||||||
|
generally managed by agenix, allowing them to still be put in the nix
|
||||||
|
store.
|
||||||
|
|
||||||
|
Secret configuration is generally more security through obscurity
|
||||||
|
(e.g. some services that I run that I don't want the whole world to
|
||||||
|
know what ports they run on). These are managed with git-crypt and are
|
||||||
|
files that end in `secret.nix`.
|
||||||
|
|
||||||
## Setting up a new dev environment
|
## Setting up a new dev environment
|
||||||
|
|
||||||
* Create a new `*.nix` file in the shells directory that describes the environment (this is the hard part).
|
* Create a new `*.nix` file in the shells directory that describes the environment (this is the hard part).
|
||||||
|
|
|
@ -1,7 +1,25 @@
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
automount_opts = "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s";
|
||||||
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./mounts/secret.nix ];
|
fileSystems = {
|
||||||
|
"/mnt/ugent/files" = {
|
||||||
|
device = "//files.ugent.be/ecvpeteg";
|
||||||
|
fsType = "cifs";
|
||||||
|
options = [ "credentials=/run/secrets/passwords/ugent-mount-credentials,${automount_opts},users,vers=3.0,noperm,domain=UGENT,sec=ntlmv2i" ];
|
||||||
|
noCheck = true;
|
||||||
|
};
|
||||||
|
"/mnt/ugent/webhost" = {
|
||||||
|
device = "//webhost.ugent.be/ecvpeteg";
|
||||||
|
fsType = "cifs";
|
||||||
|
options = [ "credentials=/run/secrets/passwords/ugent-mount-credentials,${automount_opts},users,vers=3.0" ];
|
||||||
|
noCheck = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
age.secrets."passwords/ugent-mount-credentials".file = ../secrets/passwords/ugent-mount-credentials.age;
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.keyutils ];
|
environment.systemPackages = [ pkgs.keyutils ];
|
||||||
# Remove this once https://github.com/NixOS/nixpkgs/issues/34638 is resolved
|
# Remove this once https://github.com/NixOS/nixpkgs/issues/34638 is resolved
|
||||||
|
|
Binary file not shown.
|
@ -16,8 +16,8 @@
|
||||||
enable = true;
|
enable = true;
|
||||||
permitRootLogin = "no";
|
permitRootLogin = "no";
|
||||||
hostKeys = [
|
hostKeys = [
|
||||||
{ bits = 4096; path = "/var/secrets/ssh_host_rsa_key"; type = "rsa"; }
|
{ bits = 4096; path = "/run/secrets/ssh_host_rsa_key"; type = "rsa"; }
|
||||||
{ path = "/var/secrets/ssh_host_ed25519_key"; type = "ed25519"; }
|
{ path = "/run/secrets/ssh_host_ed25519_key"; type = "ed25519"; }
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
hostPath = "/srv/data";
|
hostPath = "/srv/data";
|
||||||
isReadOnly = false;
|
isReadOnly = false;
|
||||||
};
|
};
|
||||||
"/var/secrets" = {
|
"/run/secrets" = {
|
||||||
hostPath = "${config.chvp.dataPrefix}/var/secrets/data-access";
|
hostPath = "/run/secrets/data-access";
|
||||||
isReadOnly = true;
|
isReadOnly = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -26,5 +26,10 @@
|
||||||
localAddress6 = "fc00::2";
|
localAddress6 = "fc00::2";
|
||||||
config = import ./config.nix;
|
config = import ./config.nix;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
age.secrets."data-access/ssh_host_rsa_key".file = ../../secrets/data-access/ssh_host_rsa_key.age;
|
||||||
|
age.secrets."data-access/ssh_host_rsa_key.pub".file = ../../secrets/data-access/ssh_host_rsa_key.pub.age;
|
||||||
|
age.secrets."data-access/ssh_host_ed25519_key".file = ../../secrets/data-access/ssh_host_ed25519_key.age;
|
||||||
|
age.secrets."data-access/ssh_host_ed25519_key.pub".file = ../../secrets/data-access/ssh_host_ed25519_key.pub.age;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
27
flake.lock
generated
27
flake.lock
generated
|
@ -1,12 +1,32 @@
|
||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"agenix": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1620877075,
|
||||||
|
"narHash": "sha256-XvgTqtmQZHegu9UMDSR50gK5cHEM2gbnRH0qecmdN54=",
|
||||||
|
"owner": "ryantm",
|
||||||
|
"repo": "agenix",
|
||||||
|
"rev": "e543aa7d68f222e1e771165da9e9a64b5bf7b3e3",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "ryantm",
|
||||||
|
"repo": "agenix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"emacs-overlay": {
|
"emacs-overlay": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1624097579,
|
"lastModified": 1624127230,
|
||||||
"narHash": "sha256-vy447LhWdLaikwXx3BtNdlY4rmgNM35fwZzZ5SyY/4M=",
|
"narHash": "sha256-0Wg07rR5u4F/02/mJU+CjwyYryBHB/zMOz7ArEnMlt8=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "emacs-overlay",
|
"repo": "emacs-overlay",
|
||||||
"rev": "eb561e58db5ab3b52b1157da189c48a27fb7dca9",
|
"rev": "e9ced9b4f2e49488a97b20dc43fafea7284715a7",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -70,6 +90,7 @@
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
|
"agenix": "agenix",
|
||||||
"emacs-overlay": "emacs-overlay",
|
"emacs-overlay": "emacs-overlay",
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
description = "Nixos configuration flake";
|
description = "Nixos configuration flake";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
|
agenix = {
|
||||||
|
url = "github:ryantm/agenix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
emacs-overlay.url = "github:nix-community/emacs-overlay/master";
|
emacs-overlay.url = "github:nix-community/emacs-overlay/master";
|
||||||
home-manager = {
|
home-manager = {
|
||||||
url = "github:nix-community/home-manager/master";
|
url = "github:nix-community/home-manager/master";
|
||||||
|
@ -11,7 +15,7 @@
|
||||||
utils.url = "github:gytis-ivaskevicius/flake-utils-plus/master";
|
utils.url = "github:gytis-ivaskevicius/flake-utils-plus/master";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = inputs@{ self, nixpkgs, emacs-overlay, home-manager, utils }: utils.lib.systemFlake {
|
outputs = inputs@{ self, nixpkgs, agenix, emacs-overlay, home-manager, utils }: utils.lib.systemFlake {
|
||||||
inherit self inputs;
|
inherit self inputs;
|
||||||
# This config can only be evaluated on x86_64-linux because of IFD
|
# This config can only be evaluated on x86_64-linux because of IFD
|
||||||
supportedSystems = [ "x86_64-linux" ];
|
supportedSystems = [ "x86_64-linux" ];
|
||||||
|
@ -27,6 +31,7 @@
|
||||||
nix.nixPath = [ "/etc/channels" ];
|
nix.nixPath = [ "/etc/channels" ];
|
||||||
})
|
})
|
||||||
utils.nixosModules.saneFlakeDefaults
|
utils.nixosModules.saneFlakeDefaults
|
||||||
|
agenix.nixosModules.age
|
||||||
home-manager.nixosModules.home-manager
|
home-manager.nixosModules.home-manager
|
||||||
./modules
|
./modules
|
||||||
];
|
];
|
||||||
|
@ -44,6 +49,7 @@
|
||||||
buildInputs = [
|
buildInputs = [
|
||||||
pkgs.nixpkgs-fmt
|
pkgs.nixpkgs-fmt
|
||||||
(pkgs.writeShellScriptBin "fetchpatch" "curl -L https://github.com/NixOS/nixpkgs/pull/$1.patch -o patches/$1.patch")
|
(pkgs.writeShellScriptBin "fetchpatch" "curl -L https://github.com/NixOS/nixpkgs/pull/$1.patch -o patches/$1.patch")
|
||||||
|
agenix.defaultPackage.x86_64-linux
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
docker.enable = true;
|
docker.enable = true;
|
||||||
eid.enable = true;
|
eid.enable = true;
|
||||||
git.email = "charlotte.vanpetegem@ugent.be";
|
git.email = "charlotte.vanpetegem@ugent.be";
|
||||||
|
sshd.enable = true;
|
||||||
zfs = {
|
zfs = {
|
||||||
enable = true;
|
enable = true;
|
||||||
encrypted = true;
|
encrypted = true;
|
||||||
|
|
|
@ -22,31 +22,36 @@
|
||||||
fileSystems."/" = {
|
fileSystems."/" = {
|
||||||
device = "rpool/local/root";
|
device = "rpool/local/root";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/nix" = {
|
fileSystems."/nix" = {
|
||||||
device = "rpool/local/nix";
|
device = "rpool/local/nix";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/nix/store" = {
|
fileSystems."/nix/store" = {
|
||||||
device = "rpool/local/nix-store";
|
device = "rpool/local/nix-store";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
};
|
neededForBoot = true;
|
||||||
|
|
||||||
fileSystems."/boot" = {
|
|
||||||
device = "/dev/disk/by-uuid/A5BA-352A";
|
|
||||||
fsType = "vfat";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/cache" = {
|
fileSystems."/cache" = {
|
||||||
device = "rpool/local/cache";
|
device = "rpool/local/cache";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/data" = {
|
fileSystems."/data" = {
|
||||||
device = "rpool/safe/data";
|
device = "rpool/safe/data";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" = {
|
||||||
|
device = "/dev/disk/by-uuid/A5BA-352A";
|
||||||
|
fsType = "vfat";
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices = [
|
swapDevices = [
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
eid.enable = true;
|
eid.enable = true;
|
||||||
git.email = "charlotte@vanpetegem.me";
|
git.email = "charlotte@vanpetegem.me";
|
||||||
minecraft.client = true;
|
minecraft.client = true;
|
||||||
|
sshd.enable = true;
|
||||||
zeroad.enable = true;
|
zeroad.enable = true;
|
||||||
zfs = {
|
zfs = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
|
@ -22,24 +22,27 @@
|
||||||
fileSystems."/" = {
|
fileSystems."/" = {
|
||||||
device = "rpool/local/root";
|
device = "rpool/local/root";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/nix" = {
|
fileSystems."/nix" = {
|
||||||
device = "rpool/local/nix";
|
device = "rpool/local/nix";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/data" = {
|
fileSystems."/data" = {
|
||||||
device = "rpool/safe/data";
|
device = "rpool/safe/data";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/cache" = {
|
fileSystems."/cache" = {
|
||||||
device = "rpool/local/cache";
|
device = "rpool/local/cache";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
fileSystems."/boot" = {
|
fileSystems."/boot" = {
|
||||||
device = "/dev/disk/by-uuid/BEEE-D83A";
|
device = "/dev/disk/by-uuid/BEEE-D83A";
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
|
|
|
@ -25,22 +25,27 @@
|
||||||
"/" = {
|
"/" = {
|
||||||
device = "zroot/local/root";
|
device = "zroot/local/root";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
"/nix" = {
|
"/nix" = {
|
||||||
device = "zroot/local/nix";
|
device = "zroot/local/nix";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
"/nix/store" = {
|
"/nix/store" = {
|
||||||
device = "zroot/local/nix-store";
|
device = "zroot/local/nix-store";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
"/data" = {
|
"/data" = {
|
||||||
device = "zroot/safe/data";
|
device = "zroot/safe/data";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
"/cache" = {
|
"/cache" = {
|
||||||
device = "zroot/safe/cache";
|
device = "zroot/safe/cache";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
"/srv/data" = {
|
"/srv/data" = {
|
||||||
device = "zdata/data";
|
device = "zdata/data";
|
||||||
|
|
|
@ -25,22 +25,27 @@
|
||||||
"/" = {
|
"/" = {
|
||||||
device = "zroot/local/root";
|
device = "zroot/local/root";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
"/nix" = {
|
"/nix" = {
|
||||||
device = "zroot/local/nix";
|
device = "zroot/local/nix";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
"/nix/store" = {
|
"/nix/store" = {
|
||||||
device = "zroot/local/nix-store";
|
device = "zroot/local/nix-store";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
"/data" = {
|
"/data" = {
|
||||||
device = "zroot/safe/data";
|
device = "zroot/safe/data";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
"/cache" = {
|
"/cache" = {
|
||||||
device = "zroot/safe/cache";
|
device = "zroot/safe/cache";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
"/srv/data" = {
|
"/srv/data" = {
|
||||||
device = "zdata/data";
|
device = "zdata/data";
|
||||||
|
|
Binary file not shown.
|
@ -106,7 +106,7 @@ in
|
||||||
environment = env;
|
environment = env;
|
||||||
path = [ pkgs.ffmpeg gems gems.wrappedRuby ];
|
path = [ pkgs.ffmpeg gems gems.wrappedRuby ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
EnvironmentFile = "${config.chvp.dataPrefix}/var/secrets/accentor-api";
|
EnvironmentFile = config.age.secrets."passwords/services/accentor".path;
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
User = "accentor";
|
User = "accentor";
|
||||||
Group = "accentor";
|
Group = "accentor";
|
||||||
|
@ -128,7 +128,7 @@ in
|
||||||
environment = env;
|
environment = env;
|
||||||
path = [ pkgs.ffmpeg gems gems.wrappedRuby ];
|
path = [ pkgs.ffmpeg gems gems.wrappedRuby ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
EnvironmentFile = "${config.chvp.dataPrefix}/var/secrets/accentor-api";
|
EnvironmentFile = config.age.secrets."passwords/services/accentor".path;
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
User = "accentor";
|
User = "accentor";
|
||||||
Group = "accentor";
|
Group = "accentor";
|
||||||
|
@ -140,6 +140,11 @@ in
|
||||||
|
|
||||||
}) 4));
|
}) 4));
|
||||||
|
|
||||||
|
age.secrets."passwords/services/accentor" = {
|
||||||
|
file = ../secrets/passwords/services/accentor.age;
|
||||||
|
owner = "accentor";
|
||||||
|
};
|
||||||
|
|
||||||
users.users.accentor = {
|
users.users.accentor = {
|
||||||
group = "accentor";
|
group = "accentor";
|
||||||
home = "${config.chvp.dataPrefix}/var/lib/accentor";
|
home = "${config.chvp.dataPrefix}/var/lib/accentor";
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./default/secret.nix
|
|
||||||
./accentor.nix
|
./accentor.nix
|
||||||
./bluetooth.nix
|
./bluetooth.nix
|
||||||
./docker.nix
|
./docker.nix
|
||||||
|
@ -132,8 +131,15 @@
|
||||||
home = "/home/charlotte";
|
home = "/home/charlotte";
|
||||||
description = "Charlotte Van Petegem";
|
description = "Charlotte Van Petegem";
|
||||||
extraGroups = [ "systemd-journal" ] ++ lib.optionals config.chvp.graphical [ "input" "video" ];
|
extraGroups = [ "systemd-journal" ] ++ lib.optionals config.chvp.graphical [ "input" "video" ];
|
||||||
|
passwordFile = config.age.secrets."passwords/users/charlotte".path;
|
||||||
};
|
};
|
||||||
|
root.passwordFile = config.age.secrets."passwords/users/root".path;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
age.secrets = {
|
||||||
|
"passwords/users/charlotte".file = ../secrets/passwords/users/charlotte.age;
|
||||||
|
"passwords/users/root".file = ../secrets/passwords/users/root.age;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -6,16 +6,18 @@
|
||||||
example = true;
|
example = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf config.chvp.smartd.enable {
|
config = lib.mkIf config.chvp.globalMailer.enable {
|
||||||
services.ssmtp = {
|
services.ssmtp = {
|
||||||
enable = true;
|
enable = true;
|
||||||
authUser = "webmaster@vanpetegem.me";
|
authUser = "webmaster@vanpetegem.me";
|
||||||
authPassFile = "/data/var/secrets/ssmtp-mail-pass";
|
authPassFile = config.age.secrets."passwords/services/ssmtp-pass".path;
|
||||||
domain = "${config.networking.hostName}.vanpetegem.me";
|
domain = "${config.networking.hostName}.vanpetegem.me";
|
||||||
hostName = "mail.vanpetegem.me:465";
|
hostName = "mail.vanpetegem.me:465";
|
||||||
root = "webmaster@vanpetegem.me";
|
root = "webmaster@vanpetegem.me";
|
||||||
setSendmail = true;
|
setSendmail = true;
|
||||||
useTLS = true;
|
useTLS = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
age.secrets."passwords/services/ssmtp-pass".file = ../secrets/passwords/services/ssmtp-pass.age;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
dbtype = "pgsql";
|
dbtype = "pgsql";
|
||||||
dbhost = "/run/postgresql";
|
dbhost = "/run/postgresql";
|
||||||
adminuser = "admin";
|
adminuser = "admin";
|
||||||
adminpassFile = "${config.chvp.dataPrefix}/var/secrets/nextcloud-admin-password";
|
adminpassFile = config.age.secrets."passwords/services/nextcloud-admin".path;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
nginx.virtualHosts."nextcloud.vanpetegem.me" = {
|
nginx.virtualHosts."nextcloud.vanpetegem.me" = {
|
||||||
|
@ -37,6 +37,10 @@
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
age.secrets."passwords/services/nextcloud-admin" = {
|
||||||
|
file = ../secrets/passwords/services/nextcloud-admin.age;
|
||||||
|
owner = "nextcloud";
|
||||||
|
};
|
||||||
systemd.services."nextcloud-setup" = {
|
systemd.services."nextcloud-setup" = {
|
||||||
requires = [ "postgresql.service" ];
|
requires = [ "postgresql.service" ];
|
||||||
after = [ "postgresql.service" ];
|
after = [ "postgresql.service" ];
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
fqdn = "data.vanpetegem.me";
|
fqdn = "data.vanpetegem.me";
|
||||||
options = {
|
options = {
|
||||||
default = true;
|
default = true;
|
||||||
basicAuthFile = "/data/var/secrets/data.vanpetegem.me.htpasswd";
|
|
||||||
root = "/srv/data";
|
root = "/srv/data";
|
||||||
locations = {
|
locations = {
|
||||||
"/".extraConfig = ''
|
"/".extraConfig = ''
|
||||||
|
@ -47,7 +46,7 @@
|
||||||
security.acme = {
|
security.acme = {
|
||||||
certs."vanpetegem.me" = {
|
certs."vanpetegem.me" = {
|
||||||
dnsProvider = "cloudflare";
|
dnsProvider = "cloudflare";
|
||||||
credentialsFile = "/data/var/secrets/vanpetegem.me-cloudflare";
|
credentialsFile = config.age.secrets."passwords/services/acme".path;
|
||||||
extraDomainNames = [
|
extraDomainNames = [
|
||||||
"*.vanpetegem.me"
|
"*.vanpetegem.me"
|
||||||
"cvpetegem.be"
|
"cvpetegem.be"
|
||||||
|
@ -61,6 +60,10 @@
|
||||||
acceptTerms = true;
|
acceptTerms = true;
|
||||||
preliminarySelfsigned = false;
|
preliminarySelfsigned = false;
|
||||||
};
|
};
|
||||||
|
age.secrets."passwords/services/acme" = {
|
||||||
|
file = ../secrets/passwords/services/acme.age;
|
||||||
|
owner = "acme";
|
||||||
|
};
|
||||||
chvp.zfs.systemLinks = [
|
chvp.zfs.systemLinks = [
|
||||||
{ type = "data"; path = "/var/lib/acme"; }
|
{ type = "data"; path = "/var/lib/acme"; }
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
|
||||||
./sshd/secret.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
options.chvp.sshd.enable = lib.mkOption {
|
options.chvp.sshd.enable = lib.mkOption {
|
||||||
default = false;
|
default = false;
|
||||||
example = true;
|
example = true;
|
||||||
|
@ -19,6 +15,10 @@
|
||||||
{ bits = 4096; path = "${config.chvp.dataPrefix}/etc/ssh/ssh_host_rsa_key"; type = "rsa"; }
|
{ bits = 4096; path = "${config.chvp.dataPrefix}/etc/ssh/ssh_host_rsa_key"; type = "rsa"; }
|
||||||
{ path = "${config.chvp.dataPrefix}/etc/ssh/ssh_host_ed25519_key"; type = "ed25519"; }
|
{ path = "${config.chvp.dataPrefix}/etc/ssh/ssh_host_ed25519_key"; type = "ed25519"; }
|
||||||
];
|
];
|
||||||
|
authorizedKeysFiles = [ "/run/secrets/authorized_keys/%u" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
age.secrets."authorized_keys/charlotte".file = ../secrets/authorized_keys/charlotte.age;
|
||||||
|
age.secrets."authorized_keys/root".file = ../secrets/authorized_keys/root.age;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -9,8 +9,8 @@
|
||||||
config = lib.mkIf config.chvp.syncthing-server.enable {
|
config = lib.mkIf config.chvp.syncthing-server.enable {
|
||||||
services.syncthing = {
|
services.syncthing = {
|
||||||
enable = true;
|
enable = true;
|
||||||
dataDir = "${config.chvp.dataPrefix}/var/lib/synthing";
|
dataDir = "${config.chvp.dataPrefix}/var/lib/syncthing";
|
||||||
configDir = "${config.chvp.dataPrefix}/var/lib/synthing/.config";
|
configDir = "${config.chvp.dataPrefix}/var/lib/syncthing/.config";
|
||||||
openDefaultPorts = true;
|
openDefaultPorts = true;
|
||||||
guiAddress = "127.0.0.1:8384";
|
guiAddress = "127.0.0.1:8384";
|
||||||
};
|
};
|
||||||
|
@ -20,9 +20,13 @@
|
||||||
fqdn = "syncthing.vanpetegem.me";
|
fqdn = "syncthing.vanpetegem.me";
|
||||||
basicProxy = "http://localhost:8384";
|
basicProxy = "http://localhost:8384";
|
||||||
options = {
|
options = {
|
||||||
basicAuthFile = "${config.chvp.dataPrefix}/var/secrets/syncthing.vanpetegem.me.htpasswd";
|
basicAuthFile = config.age.secrets."passwords/services/syncthing-basic-auth".path;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
age.secrets."passwords/services/syncthing-basic-auth" = {
|
||||||
|
file = ../secrets/passwords/services/syncthing-basic-auth.age;
|
||||||
|
owner = "nginx";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
46
secrets.nix
Normal file
46
secrets.nix
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
let
|
||||||
|
kholinar = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOL8MzChayhcVTfZvE3/ExwXpq2+LbihjzUVlKeIGoOL";
|
||||||
|
lasting-integrity = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMKJmeY7j5LxWVv3fKzqG4Bvg/ZhOp8iwk0utpyMWMSk";
|
||||||
|
urithiru = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOrzOpyzDc5BVtAeb5//PnMRcp+9B+DjfU7p2YpaH6a2";
|
||||||
|
hosts = [
|
||||||
|
kholinar
|
||||||
|
lasting-integrity
|
||||||
|
urithiru
|
||||||
|
];
|
||||||
|
servers = [
|
||||||
|
lasting-integrity
|
||||||
|
urithiru
|
||||||
|
];
|
||||||
|
|
||||||
|
charlotte = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICDb17zAg3zwvdYHNZqXSGYKseCz5281Ha6oOYPbwFYD"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJY5nXR/V6wcMRxugD7GTOF8kwfGnAT2CRuJ2Qi60vsm"
|
||||||
|
];
|
||||||
|
users = charlotte;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
"secrets/passwords/users/charlotte.age".publicKeys = hosts ++ users;
|
||||||
|
"secrets/passwords/users/root.age".publicKeys = hosts ++ users;
|
||||||
|
|
||||||
|
"secrets/authorized_keys/charlotte.age".publicKeys = hosts ++ users;
|
||||||
|
"secrets/authorized_keys/root.age".publicKeys = hosts ++ users;
|
||||||
|
|
||||||
|
"secrets/passwords/ugent-mount-credentials.age".publicKeys = [ kholinar ] ++ users;
|
||||||
|
|
||||||
|
"secrets/passwords/services/accentor.age".publicKeys = [ urithiru ] ++ users;
|
||||||
|
|
||||||
|
"secrets/passwords/services/ssmtp-pass.age".publicKeys = servers ++ users;
|
||||||
|
|
||||||
|
"secrets/passwords/services/acme.age".publicKeys = servers ++ users;
|
||||||
|
|
||||||
|
"secrets/passwords/services/nextcloud-admin.age".publicKeys = [ lasting-integrity ] ++ users;
|
||||||
|
|
||||||
|
"secrets/passwords/services/syncthing-basic-auth.age".publicKeys = [ lasting-integrity ] ++ users;
|
||||||
|
|
||||||
|
"secrets/passwords/services/data-basic-auth.age".publicKeys = [ urithiru ] ++ users;
|
||||||
|
|
||||||
|
"secrets/data-access/ssh_host_rsa_key.age".publicKeys = [ urithiru ] ++ users;
|
||||||
|
"secrets/data-access/ssh_host_rsa_key.pub.age".publicKeys = [ urithiru ] ++ users;
|
||||||
|
"secrets/data-access/ssh_host_ed25519_key.age".publicKeys = [ urithiru ] ++ users;
|
||||||
|
"secrets/data-access/ssh_host_ed25519_key.pub.age".publicKeys = [ urithiru ] ++ users;
|
||||||
|
}
|
BIN
secrets/authorized_keys/charlotte.age
Normal file
BIN
secrets/authorized_keys/charlotte.age
Normal file
Binary file not shown.
BIN
secrets/authorized_keys/root.age
Normal file
BIN
secrets/authorized_keys/root.age
Normal file
Binary file not shown.
BIN
secrets/data-access/ssh_host_ed25519_key.age
Normal file
BIN
secrets/data-access/ssh_host_ed25519_key.age
Normal file
Binary file not shown.
BIN
secrets/data-access/ssh_host_ed25519_key.pub.age
Normal file
BIN
secrets/data-access/ssh_host_ed25519_key.pub.age
Normal file
Binary file not shown.
BIN
secrets/data-access/ssh_host_rsa_key.age
Normal file
BIN
secrets/data-access/ssh_host_rsa_key.age
Normal file
Binary file not shown.
BIN
secrets/data-access/ssh_host_rsa_key.pub.age
Normal file
BIN
secrets/data-access/ssh_host_rsa_key.pub.age
Normal file
Binary file not shown.
BIN
secrets/passwords/services/accentor.age
Normal file
BIN
secrets/passwords/services/accentor.age
Normal file
Binary file not shown.
14
secrets/passwords/services/acme.age
Normal file
14
secrets/passwords/services/acme.age
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 hKAFvQ wr/VRSxPJd0I4JDFD9MrHkp5KFOOPxZS7m1HjSegRCw
|
||||||
|
JFCiaYNZEQJmyvW4hLCOwIq7VX3KSlmnAIoh2UhNAJY
|
||||||
|
-> ssh-ed25519 9PfEBQ dZRsqkDI9rfIvO6TpVzGWFYwPBXICkKTe5x8VXIVDGM
|
||||||
|
2uS5NUHLEWUNy9C8x06+RUdX7xQpBBfjr+01rDMbgBU
|
||||||
|
-> ssh-ed25519 s9rb8g 46cu8IBR9fma7MFs4otOWjoMXHqnbuRDM+bj4IxDVGw
|
||||||
|
/UkN3Agfceht7ChZbh+ceoUuB++mYmugd16vuLSPqxE
|
||||||
|
-> ssh-ed25519 yad4VQ Hv13vZsVZvbV2w5uNQdB8PQZCLvok2MpNVC4PPLGKUc
|
||||||
|
6NrLD1I8u0ClEtSsOb4jVVFDVzuJL9n3IW4CnA75ovA
|
||||||
|
-> NO3YbI(z-grease m4 \QIZ]>
|
||||||
|
f69xlR/avrj2Rt86RB0MfdYwgW9xOUKko5dLppsenHk
|
||||||
|
--- Af1B47mEXz4XvANBR/JACMf1lKXsgKcofVAAKPq4A9E
|
||||||
|
Gスナ∵シ~Uォ鉙6ゥ
|
||||||
|
Y7@ェイg9ロス<EFBE9B>zナ<7A>b_チ轢ケXC9mチ[&<26><04>サ<EFBFBD>ケ;.R-トシI|レ ョッ<1A>}し渺tVW8/レマ淸rアユ昻NIヲ4*幌ーL?"<22>y, 2@マモ3ー[D<>PセンrⅨ
|
BIN
secrets/passwords/services/data-basic-auth.age
Normal file
BIN
secrets/passwords/services/data-basic-auth.age
Normal file
Binary file not shown.
12
secrets/passwords/services/nextcloud-admin.age
Normal file
12
secrets/passwords/services/nextcloud-admin.age
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 hKAFvQ x9t/cSncNIVOU166JjWIntDJ08ar6jqEDqm2SHdIJmU
|
||||||
|
Wi1kSAfImT7O3ZHQffngy2+OK9MkcxRdTIsWj0Uvppc
|
||||||
|
-> ssh-ed25519 s9rb8g FBbDb07Wot6y7VbFtZ6p6pmdPXu61fOMXn4zobmYXn0
|
||||||
|
9WV10AVHinYMy6DfsTbDnNuCry1lunNiL8rYlM3VAu0
|
||||||
|
-> ssh-ed25519 yad4VQ qkqTUmEzVzMlL+MzQZ6jbuEuMMr7fmkao02BTEXz0CI
|
||||||
|
NuJBm09rWAPDAAiKCpjOvLn/lTqrjv4O8ZlNdZqaMsU
|
||||||
|
-> OPQKCjr-grease {eEXe/H n
|
||||||
|
LeU7ay4hMrv1r+ot0bHboLAzGJBQ7E02y3lMXZaMfyYd9eBh9W3iQ8Js+UZa9g9G
|
||||||
|
gODPDb4M8+UtZh3VSGHqtfJzTCrvkPjbys3CpGRz/3oZR2v5PP8
|
||||||
|
--- JmNEtjO4ODYoLNKN2K6Di0/XwkCgq8dAEhEkrQSjBwQ
|
||||||
|
Ù-˜Ð3’=ïtk\R|bš<62>é{K‹Î²Á‹^úå²ÓâKtâZ`Žòˆ‹Z>£QS{s™Ô®y•
|
14
secrets/passwords/services/ssmtp-pass.age
Normal file
14
secrets/passwords/services/ssmtp-pass.age
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 hKAFvQ BDIrYjLZNtA13rPVoIxP6W1dWF88I+CLL6pUvJ6vK0g
|
||||||
|
MeEh3+IhgF5InzslImtzfa9lvlpDzWM6u5YYfPXKhd4
|
||||||
|
-> ssh-ed25519 9PfEBQ vaD7NtryG1+F4D520aqqzjy4nlCKed3lA+KZqDl2YGk
|
||||||
|
TNhvAb5h30I1s9t4nOwRdm0MjSSflPmS5sHbundkNTM
|
||||||
|
-> ssh-ed25519 s9rb8g xjBrIBaOJIo6wKzPzXGOtnk07jxTxooVL/0m+MIy/HE
|
||||||
|
HV2SSpBGm/zf90PEkUjkkEDpFdunF2MoYvE1F4CAqjo
|
||||||
|
-> ssh-ed25519 yad4VQ ET642EsdlhOrFWumUNg0lu2fGKCC88VkeEuATqGLuks
|
||||||
|
nPNM56yWuAVt6NWSjIswR/y0S0eSNMooz5Kfm5KRz0M
|
||||||
|
-> Djkn-grease
|
||||||
|
WAU+Og
|
||||||
|
--- v4AxWOuI+CKCiqa/71rOuE2b37ez7tJ7Q4bdsYLZ2fA
|
||||||
|
ÝgÛ‚ñ§ìfù¥8£³=®x´à<C2B4>]¾TûoL:<3A>Ÿ"<®Dò&Å!
|
||||||
|
Ù5q÷¹©|HÒŒÝ
|
12
secrets/passwords/services/syncthing-basic-auth.age
Normal file
12
secrets/passwords/services/syncthing-basic-auth.age
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 hKAFvQ 63BaTeRhefvCFbl7sXA7zathah0syNOsB0PjWTtCd1c
|
||||||
|
cdfHW5eOGchofdjrnY7Ze1wyFI/rBmP/OEdw8xovkTI
|
||||||
|
-> ssh-ed25519 s9rb8g n8oehnxhiyHiu3WY54SBcei+hVdmGAvNL5qpDcJYIwQ
|
||||||
|
0CCTSTWzxS6A0yLdbxkkOlv2Fh+ybIUUrAq+QPv8gII
|
||||||
|
-> ssh-ed25519 yad4VQ lbuGjXnI6dRhGPgC1ffKwkMuncqJFRF3SlLmiAMGjGA
|
||||||
|
zuQv5lIHDNhjnDYAwyZ+FvEQB48e78GsFZniHVJWWNM
|
||||||
|
-> wcaNCh-grease SaMY3 Tu|&}! xRRDg'(
|
||||||
|
hvUFh0BFX9rSu/X0SVH7baf9JZLMhOI6PSimLxLgZpXb+0pjSU3Jb1IzFSFK94PC
|
||||||
|
gK3HgTrqyzvp7qb5E1Xm0P19
|
||||||
|
--- uzs+KId6F4ecLgEE295pBQra5JvdXRTVAZiyrIj5mr8
|
||||||
|
ª&uH7˜ÔZ£è“ßy…iæ*¦0ɸñ¡{ªB?²;ñeéŸ<C3A9>l"åõ¯ÖuºWÜ:<3A>é짱•2`BßËÞNú’gX‘2!Ÿäp$
|
12
secrets/passwords/ugent-mount-credentials.age
Normal file
12
secrets/passwords/ugent-mount-credentials.age
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 aUd9Ng VKPLzPWI+pe5Yd/MSdHdBDuTX8rZC/+p469vEPFoXxk
|
||||||
|
98Yzz1zt1wyQgjG86118I5idbFuSuKAEkvjddC+T4fs
|
||||||
|
-> ssh-ed25519 s9rb8g BEGtkNLFNifqjGFk8qEqjuXEv+2WcDI0DRPxXtm+OCU
|
||||||
|
trMzwuQwyICXkZuA4wuVflqWFVkUb3d7meW/EpxoqfE
|
||||||
|
-> ssh-ed25519 yad4VQ 4j0mcq45zOkde4411/Dm9/A8plCsWWipTpC8oVjsBxE
|
||||||
|
yWVNOfmT0UBkZRVKrd8eK1ZXEbj0DBmUfLm3P75ue3c
|
||||||
|
-> dA-grease KK9j4 +>n>m %
|
||||||
|
ZT+0vtK8K2BUHbW13tlDNHKtMzQW4oZUOazYJ0naCCgKSRu9am9cfsm+Ul3TpafN
|
||||||
|
enO42MOQ5i00H/6KCIo+0qc4hw4kQV0
|
||||||
|
--- hR3HgO0pfUOtWM2K4/l1OT+nIa7ZBBxSt+KWYwHEuXs
|
||||||
|
B½Ù¬ŠèIÃÏ…<>‹ùêšÅNaxœ+u©ù¹ÄŸNOI‚LuæÞ½'󔬼UÛr»‡[5qòü´›¡Í˜ÿr5U.¡Â"À;ˆ04!¥"6<>-<2D>œÉ
|
15
secrets/passwords/users/charlotte.age
Normal file
15
secrets/passwords/users/charlotte.age
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 aUd9Ng WEsRJzdyJ2h91IjEW9qyJgdFL27slwb0bjNu2oWlOXA
|
||||||
|
ZTWFzYPh6nKz7aF4sUpQpqEEtwhv6XBDqsDeIZ5N8y8
|
||||||
|
-> ssh-ed25519 hKAFvQ e4tF880/zOdeGMErRQgG2UrAu9qRKG7c53ZW8HFDbwA
|
||||||
|
P2PTG82mqsyCwwbkNuUEaesj8jt3zh5bQJO3cXjPZUk
|
||||||
|
-> ssh-ed25519 9PfEBQ eSTg5KgEj/Mo5bdm5KIJuhT4obRRNjHuQtINEtRujCc
|
||||||
|
WvL4uXbwESfRlv7LiSXJDcxbUmhVMgVuvfxcwn5kQoU
|
||||||
|
-> ssh-ed25519 s9rb8g hYZ3gd2LKLkVwdWBB7KIR4UeWKwF+h9k03SrkYy2EwE
|
||||||
|
VhSvTYWMcJE4tjgOqZR/qUrZqKQ7r5N+0uHGuxNyYqk
|
||||||
|
-> ssh-ed25519 yad4VQ D6MeV5YwTfPEz/YLQaxnzYr1LFq5RnVTsYln1uQMaUc
|
||||||
|
btZV3uKDahlmR1oSlJtRRuO8pbWYW8KqaHSAxRO0roc
|
||||||
|
-> ]V-grease 7lw %=7"61= R:.zkVJ:
|
||||||
|
|
||||||
|
--- Qjis1vuiXUaYlXuArvVJT7At/jQlGxYMNL+fxAlSGG8
|
||||||
|
ËñËZϼ<>ûŸÃ&<26>Âí@Ïò¹‘t¹bÕÊ„Û£ =RXu@ ¡X1×?ŽîP~M΄³Fü»4{»@¹ßZ<C39F>“0¢Øöã£$Q¸íï&Œ<>kÀ¸›Òf'{ùÕë!Ü#£Sygx„°áH×òßV=Dܦˆ<ü[e÷Ÿ
|
17
secrets/passwords/users/root.age
Normal file
17
secrets/passwords/users/root.age
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 aUd9Ng 8n1tz2i+HxzSliHHBHc+kmgpWbbNgCppLrEN0P+9DFQ
|
||||||
|
hE3bzq0j5gxNdk8VmYQypxjT+da8jRLIkUR3GP+4DnU
|
||||||
|
-> ssh-ed25519 hKAFvQ M9Ju7grYMVOKxLjYVP3GGvV4rYT6F3VfDLI8EhsIEyQ
|
||||||
|
Slkggok27UFcYpKyEO1m4UMiJm/lp7CxVRmx4kQxqlg
|
||||||
|
-> ssh-ed25519 9PfEBQ bf4KuUS1ep4Gk3fDmG78I2FcEh848++jRE71CYIQIRg
|
||||||
|
Wldrb1cqj3/8vOITln7X8KtC+CTljsj0WY7knNySeQg
|
||||||
|
-> ssh-ed25519 s9rb8g Gp2mA+WShFq16ZYU8fImzqAJ96HZSv4MnT0tZ8RmyAM
|
||||||
|
t8tIVz/PYgkAuCnmaoBzdNN7Eedk47pXN62fLnvCkvQ
|
||||||
|
-> ssh-ed25519 yad4VQ 5oHcwG9X9fQ/I1gkCFP0bR9X1dlugq+XLhNChahcD18
|
||||||
|
M2+r0JfRNooc3bOPMtbae7RMJMvmdeFgvwFc9eNaJHs
|
||||||
|
-> E:Oz-grease Ehb$"
|
||||||
|
oL5+EmXX4BIy3ug9u4HrEOoCtO8aNMu70KjMWQqOqwkuk4t81DoG28+/ruew+a5m
|
||||||
|
zcEsAb1gDFJb+usuVPF37nijiR8
|
||||||
|
--- v4M0JQCd5ST1rzXfkpfgHfibXDN7EZ3/3VnYXnT23tY
|
||||||
|
#ÍvtÉz<Va]iUúV"ÄA§vEDŒánÃbf¼}Á
|
||||||
|
šÜ$gÓv„¸âI<C3A2>®ÜèÖÀˆS%3P=Jn²©¤¥ Ø÷°¾]=ÜÄÕ«[I›§’êÉî2}Höšøkd6EzÇüCåsÔ†Í-°µ<06>Ïà<C38F>xÌ9á5ïÞžë2ÑY^þŒ$
|
Loading…
Add table
Add a link
Reference in a new issue