Start migration to NixOS for storage1

This commit is contained in:
Paul-Henri Froidmont 2021-11-29 02:04:29 +01:00
parent 09d2ac3f05
commit 86124dcd4a
Signed by: phfroidmont
GPG key ID: BE948AFD7E7873BE
19 changed files with 589 additions and 173 deletions

11
.sops.yaml Normal file
View file

@ -0,0 +1,11 @@
keys:
- &admin 3AC6F170F01133CE393BCD94BE948AFD7E7873BE
- &server ebdabf42731801d79db14c893639d8f0c7ff61ed
- &storage1 7675e1c632a9a0644c6ab828dbcc48a5300773a8
creation_rules:
- path_regex: secrets.enc.yml$
key_groups:
- pgp:
- *admin
- *server
- *storage1

8
dns.tf
View file

@ -22,6 +22,14 @@ resource "hetznerdns_record" "backend1_a" {
ttl = 600
}
resource "hetznerdns_record" "mail2_a" {
zone_id = data.hetznerdns_zone.banditlair_zone.id
name = "mail2"
value = "78.46.96.243"
type = "A"
ttl = 600
}
resource "hetznerdns_record" "db1_a" {
zone_id = data.hetznerdns_zone.banditlair_zone.id
name = "db1"

View file

@ -4,5 +4,6 @@
htop
nload
tmux
vim
];
}

99
flake.lock generated
View file

@ -52,13 +52,13 @@
"type": "github"
}
},
"nixpkgs_2": {
"nixpkgs-unstable": {
"locked": {
"lastModified": 1637595801,
"narHash": "sha256-LkIMwVFKCuEqidaUdg8uxwpESAXjsPo4oCz3eJ7RaRw=",
"lastModified": 1637841632,
"narHash": "sha256-QYqiKHdda0EOnLGQCHE+GluD/Lq2EJj4hVTooPM55Ic=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "263ef4cc4146c9fab808085487438c625d4426a9",
"rev": "73369f8d0864854d1acfa7f1e6217f7d6b6e3fa1",
"type": "github"
},
"original": {
@ -68,10 +68,84 @@
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1637875414,
"narHash": "sha256-Ica++SXFuLyxX9Q7YxhfZulUif6/gwM8AEQYlUxqSgE=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "3bea86e918d8b54aa49780505d2d4cd9261413be",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-21.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1626852498,
"narHash": "sha256-lOXUJvi0FJUXHTVSiC5qsMRtEUgqM4mGZpMESLuGhmo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "16105403bdd843540cbef9c63fc0f16c1c6eaa70",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-unstable",
"type": "indirect"
}
},
"root": {
"inputs": {
"deploy-rs": "deploy-rs",
"nixpkgs": "nixpkgs_2"
"nixpkgs": "nixpkgs_2",
"nixpkgs-unstable": "nixpkgs-unstable",
"simple-nixos-mailserver": "simple-nixos-mailserver",
"sops-nix": "sops-nix"
}
},
"simple-nixos-mailserver": {
"inputs": {
"nixpkgs": "nixpkgs_3",
"utils": "utils_2"
},
"locked": {
"lastModified": 1622967674,
"narHash": "sha256-8RLe6Rqy2rKR/PGDMg/EVsWihsO+DQe/RYmlXdRZkLs=",
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"rev": "5675b122a947b40e551438df6a623efad19fd2e7",
"type": "gitlab"
},
"original": {
"owner": "simple-nixos-mailserver",
"ref": "nixos-21.05",
"repo": "nixos-mailserver",
"type": "gitlab"
}
},
"sops-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1637735079,
"narHash": "sha256-VC6FEfYHkNMrCd9+0nATtUQAtkWOrkH4gzwGHNG4TTQ=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "871408582627f43d0ecc5e4595dcf20cfe2ee227",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "sops-nix",
"type": "github"
}
},
"utils": {
@ -88,6 +162,21 @@
"repo": "flake-utils",
"type": "github"
}
},
"utils_2": {
"locked": {
"lastModified": 1605370193,
"narHash": "sha256-YyMTf3URDL/otKdKgtoMChu4vfVL3vCMkRqpGifhUn0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5021eac20303a61fafe17224c087f5519baed54d",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
}
},
"root": "root",

View file

@ -1,14 +1,30 @@
{
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
inputs.deploy-rs.url = "github:serokell/deploy-rs";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-21.05";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
sops-nix.url = "github:Mic92/sops-nix";
sops-nix.inputs.nixpkgs.follows = "nixpkgs";
deploy-rs.url = "github:serokell/deploy-rs";
simple-nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver/nixos-21.05";
};
outputs = { self, nixpkgs, deploy-rs }:
outputs = { self, nixpkgs, nixpkgs-unstable, deploy-rs, sops-nix, simple-nixos-mailserver }:
let
pkgs = nixpkgs.legacyPackages.x86_64-linux;
pkgs-unstable = nixpkgs-unstable.legacyPackages.x86_64-linux;
in
{
devShell.x86_64-linux = pkgs.mkShell {
buildInputs = with pkgs; [
sopsPGPKeyDirs = [
"./keys/hosts"
"./keys/users"
];
nativeBuildInputs = [
(pkgs.callPackage sops-nix { }).sops-import-keys-hook
];
buildInputs = with pkgs-unstable; [
nixpkgs-fmt
terraform
terraform-ls
@ -21,11 +37,14 @@
db1 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
sops-nix.nixosModules.sops
./profiles/db.nix
(
{
sops.defaultSopsFile = ./secrets.enc.yml;
networking.hostName = "db1";
networking.domain = "banditlair.com";
nix.registry.nixpkgs.flake = nixpkgs;
system.stateVersion = "21.05";
}
@ -35,11 +54,14 @@
backend1 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
sops-nix.nixosModules.sops
./profiles/backend.nix
(
{
sops.defaultSopsFile = ./secrets.enc.yml;
networking.hostName = "backend1";
networking.domain = "banditlair.com";
nix.registry.nixpkgs.flake = nixpkgs;
system.stateVersion = "21.05";
}
@ -49,11 +71,15 @@
storage1 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
sops-nix.nixosModules.sops
simple-nixos-mailserver.nixosModule
./profiles/storage.nix
(
{
sops.defaultSopsFile = ./secrets.enc.yml;
networking.hostName = "storage1";
networking.domain = "banditlair.com";
nix.registry.nixpkgs.flake = nixpkgs;
system.stateVersion = "21.05";
}
@ -62,30 +88,26 @@
};
};
deploy.nodes = {
db1 = {
hostname = "db1.banditlair.com";
profiles.system = {
deploy.nodes =
let
createSystemProfile = configuration: {
user = "root";
sshUser = "root";
path = deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.db1;
path = deploy-rs.lib.x86_64-linux.activate.nixos configuration;
};
in
{
db1 = {
hostname = "db1.banditlair.com";
profiles.system = createSystemProfile self.nixosConfigurations.db1;
};
backend1 = {
hostname = "backend1.banditlair.com";
profiles.system = {
user = "root";
sshUser = "root";
path = deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.backend1;
};
profiles.system = createSystemProfile self.nixosConfigurations.backend1;
};
storage1 = {
hostname = "78.46.96.243";
profiles.system = {
user = "root";
sshUser = "root";
path = deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.storage1;
};
profiles.system = createSystemProfile self.nixosConfigurations.storage1;
};
};

View file

@ -6,10 +6,6 @@ data "hcloud_floating_ip" "main_ip" {
with_selector = "external=main"
}
data "sops_file" "secrets" {
source_file = "secrets.enc.yml"
}
resource "hcloud_network" "private_network" {
name = "private"
ip_range = "10.0.0.0/16"
@ -54,27 +50,6 @@ resource "hcloud_server" "db1" {
]
}
module "deploy_nixos_db1" {
source = "github.com/phfroidmont/terraform-nixos//deploy_nixos?ref=5f6b38f7e1485d216c14c3cbd6692581e5eaa392"
nixos_config = "db1"
flake = true
target_host = hcloud_server.db1.ipv4_address
ssh_agent = true
keys = {
"postgres-init.sql" = <<-EOT
CREATE ROLE "synapse" WITH LOGIN PASSWORD '${data.sops_file.secrets.data["synapse.db_password"]}';
CREATE DATABASE "synapse" WITH OWNER "synapse"
TEMPLATE template0
LC_COLLATE = "C"
LC_CTYPE = "C";
CREATE ROLE "nextcloud" WITH LOGIN PASSWORD '${data.sops_file.secrets.data["nextcloud.db_password"]}';
CREATE DATABASE "nextcloud" WITH OWNER "nextcloud";
EOT
borgbackup-passphrase = data.sops_file.secrets.data["borg.passphrase"]
borgbackup-ssh-key = data.sops_file.secrets.data["borg.client_keys.db1.private"]
}
}
resource "hcloud_server" "backend1" {
name = "backend1"
image = data.hcloud_image.nixos_stable.id
@ -104,31 +79,3 @@ resource "hcloud_floating_ip_assignment" "main" {
server_id = hcloud_server.backend1.id
}
module "deploy_nixos_backend1" {
source = "github.com/phfroidmont/terraform-nixos//deploy_nixos?ref=5f6b38f7e1485d216c14c3cbd6692581e5eaa392"
nixos_config = "backend1"
flake = true
target_host = hcloud_server.backend1.ipv4_address
ssh_agent = true
keys = {
"synapse-extra-config.yaml" = <<-EOT
database:
name: psycopg2
args:
database: synapse
host: "10.0.1.11"
user: "synapse"
password: "${data.sops_file.secrets.data["synapse.db_password"]}"
macaroon_secret_key: "${data.sops_file.secrets.data["synapse.macaroon_secret_key"]}"
EOT
nextcloud-db-pass = data.sops_file.secrets.data["nextcloud.db_password"]
nextcloud-admin-pass = data.sops_file.secrets.data["nextcloud.admin_password"]
"murmur.env" = <<-EOT
MURMURD_PASSWORD=${data.sops_file.secrets.data["murmur.password"]}
EOT
borgbackup-passphrase = data.sops_file.secrets.data["borg.passphrase"]
borgbackup-ssh-key = data.sops_file.secrets.data["borg.client_keys.backend1.private"]
sshfs-ssh-key = data.sops_file.secrets.data["sshfs_keys.private"]
}
}

28
keys/hosts/server.asc Normal file
View file

@ -0,0 +1,28 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBAAAAAABEADADktn4dr3tJuDBGF/DFn8bFWhSTdRjtguMV9zhgSug3OVyZpD
Vpz+Isud+fACIDRlOPlgw31hwbZX+qiwrO82636oiToawC1W8RNO1XWXsRv77MUT
aszON9t0LYQoGbp8Vg/5Lv3opuLigWVWf7V9GreBX68Q5QakDe2luliFxl53rQVm
vEXGXHl6JFPPRmEPeq2Axcz5kjcyz5wa7yYlmc9V2gNQ4UvUxhVWe7q9OnmogEbh
DAVdouWDiwJDBuGFcaenmP5p8f9gS/K9nzVBSxY7Ng8X0/VINuvAhn6Nw54rXYsa
J6w5XAoAvdCtt8k+smiDtaUId86ClARI3VzWgLgvSeHDheZwwOCzafAyfqymagXU
o/yIDDvpVImk5BScALFj2cBf4DIT6mftjBNCAxzE50Ze0oFHtjeKXrEu2Wq8MiCo
M6FHSuFKJs1N0oED7pPp3qosXykAU3fk1P1cGt1QVsG0vuvyClJczDOBG2OBE5+b
R0uGy2XQehdaAjG+dP2UprRlICVS0nQ3jBk6KcpIhBGYAidiSPdZrn4K0CJmmgde
iAWjvbarD2QTY9wTMWG4SDqVvy/59C57u+QOh9iEPsD8jOojnxPYJBKYHfC55xZk
lnaSmyfH0vVWPKk2sXCVDyh568g03tGqJ0hwyTDM8dFwSaweTNh0s7MnKQARAQAB
zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT
AQgAFgUCAAAAAAkQNjnY8Mf/Ye0CGw8CGQEAAMZiEAC0x6gNgLVxUBQ4yXrO7fFi
EpIGWSX6AJhee53mZ0xLw+3RVBImCSwOKVPKWl0rTKQ9BpNsr2KEa5JHUGFSkr24
9isttUwunhVpTvRuPVsjOHD0LFUA53lVU8n3pqNuFPi3bt1wH89bn1Yjj6jhLahv
3/k6PhLpiIMp6lyE3KOik2eY9+KYbpZPqpKQ054Hrq+PAUug/A8KYY+/WU3i0ncl
1DWkRsuHNnV3JEXqMubxt9zPpyqhG+OtVwgf82+v18/DvcaU7SLEowBLXgf6hmF5
7zVMujr7NSqqR8v/5HuhNW7QNiQKKHSee3oCe2kdm9abPFGmIl613WH0lUncFOjN
iNYlGw0dNLJYb70zfOf0LSd0RAIkmzIF+UfFhpqv7PHYlJmld+P3AbpjdXGrB2rQ
a0tdchiP9qgyo9f4rXFybCykt9Bu/qnh3lHepm+6/lm7uA9RPiWN3U0qSaCAu0eR
JFfBviz7Kqvz3cxiamP7j6li/dyd9ONrfp7dJsf/yxypv7stKUQWhpMTytU+230j
+zR+7Gv0f/0sDPK46x/NF8BLW8dkTaGfrApOQahjGt1sy1fTwpCFqvIce716yjo8
K72JF5q6WeJWtdC35ZAbJ43GuM94CITOXYt3QJFIsnPf8jSJcJ0axxm9zoMCDra0
jDbjKwt16i8sc2nsdL/T+A==
=wX/N
-----END PGP PUBLIC KEY BLOCK-----

28
keys/hosts/storage1.asc Normal file
View file

@ -0,0 +1,28 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBAAAAAABEACUt404dF2T1wYrbIyeCBAudXx/2TBCjaO/PO1fZJbX+Dcb2fqi
kU+w1j1DcMtF2Q/4k3oeEFGbJr/foxfgsC74dJ7QKVNSXR4uFH5Br1RpmhMvqwbB
bQOFjrWQHF3f5s2y3Dkc4cPtv3+BBUGdqIEZK+7PXBieJnzHIagz7uRb5hX1zje8
Q+tbyqrpDYitWLyLLlWGQ38Ur9yxGrspyHPFhPZkIigqWJjfmxYYl4sOGjoOm18m
ohu8CijRP6R7qsjf2oOOvCl1RZCDmnPlx5ukIyaVPQswacGKWAMYFv9GHler/1sI
V2Kkbbm0tVpdaeKmKgZQGsbX4WDkrEtyZD193RkpaqAOT8ebL5ZMn+rlXoPFfG/B
3qciVj6gVd4S5EbjvMUviilbuD3rZPzP7hA+QVyMI01eJYGwaYUCGSRRyC9cHR7R
8RQW9q6SE+JQCoWR1/YnwDeD3TmBVZUWsGtca8LfiKgGWn1/8I7OrRW/xLvW2c/X
b9g2h41zv0WmQEd1qI4OYti7Iq0pNYNXFUz4a4ePggQtlgLnv+AJ7poXDoyPMRGn
npRsnTiKSuxlzwHiPkqeDvTyho3c91AE3Id0RyiQDdwjUlsMNxYKaWBc3wN+ZIJa
SmpucCped1+UuqSWA0kLOwM46UKkiIkN7+C7fdudZXhIPIXOWSS7L0ef6wARAQAB
zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT
AQgAFgUCAAAAAAkQ28xIpTAHc6gCGw8CGQEAAO0TEAA/SUCWVWIlm2DNfu1yJcFT
950dY916f+GDl0+em3JiPx0Fd0Rv5bC3GMJGx9FiJ5Q6mxDADrcTpUikFPHvpMCn
KXj3W1Ou49EPF5OzrxsRjY1ODP/tlStEDa/e8myg8RBEhbLbR7k1h5xlg4S9wGaX
0xT1GrJWX7cXIVqFHMp+EkF/Oyz8PKF1hi5l+x6d2iTS9xOza/QYgpUpo48FzizH
W4y+75XK3MsJ++qhSDiMIc6UFngotK87vbBb1SacMxa/lwu2nf060d1AZ4nSg+NN
Mt0/mO78k7tZVWMlNPvojvwdKnJXdXjfFvJe/yhLF2AXc1D6N4TIMCnUWlSoFL3j
yZPptxkCdy7nEvGkiLq0Ek9TNzD5cSmovxpB85SYdUBo+HqRX0sC6CR6iI455p+e
QRyWPs5PE8aBQY6PQQLg5Fp311rya8Zy6Zp8uYouvaH6cka16zBpRurhJ61oKUdB
VBG9eA43rPJ49o+QQFYvVC63wU4rQ2gSjhxkgDCq2porJ1Hl5R/9BfjEv3MYaxjO
HIhhVhQz4ZQ5oawF1SfyLpkAPFzhn09IRNy5xeW7TAl9W6UNcEY5CVjdGXnkrqjW
ZHLBBBrKpmAO0eCRHvAn9u6L4d/0mspw0v0CEMTultgXmOABCv5aaeLeNS/HDAL9
hilGDJyHAQjo/6xEVVzCKQ==
=Vlbm
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -0,0 +1,52 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
n3lT5t216+2F+fnu25nC2EyR
=bmoC
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -10,12 +10,12 @@ in
default = [ ];
};
additionalReadWritePaths = mkOption {
readWritePaths = mkOption {
type = with types; listOf path;
default = [ ];
};
additionalPreHook = mkOption {
preHook = mkOption {
type = types.lines;
default = "";
};
@ -24,25 +24,31 @@ in
type = with types; either str (listOf str);
default = "03:30";
};
sshKey = mkOption {
type = with types; path;
};
};
config = {
sops.secrets = {
borgPassphrase = {
owner = config.services.borgbackup.jobs.data.user;
key = "borg/passphrase";
};
};
services.borgbackup.jobs.data = {
paths = [ "/nix/var/data" ] ++ cfg.additionalPaths;
paths = [ "/nix/var/data" cfg.sshKey ] ++ cfg.additionalPaths;
doInit = false;
repo = "backup@212.129.12.205:./";
encryption = {
mode = "repokey-blake2";
passCommand = "cat /var/keys/borgbackup-passphrase";
passCommand = "cat ${config.sops.secrets.borgPassphrase.path}";
};
readWritePaths = [
"/var/keys/borgbackup-ssh-key"
] ++ cfg.additionalReadWritePaths;
preHook = ''
#There is no way to specify the permissions on keys so we fix them here
chmod 0600 /var/keys/borgbackup-ssh-key
'' + cfg.additionalPreHook;
environment = { BORG_RSH = "ssh -i /var/keys/borgbackup-ssh-key"; };
readWritePaths = cfg.readWritePaths;
preHook = cfg.preHook;
environment = { BORG_RSH = "ssh -i ${cfg.sshKey}"; };
compression = "lz4";
startAt = cfg.startAt;
prune.keep = {

39
modules/mailserver.nix Normal file
View file

@ -0,0 +1,39 @@
{ config, lib, pkgs, ... }:
{
sops.secrets = {
paultrialPassword = {
key = "email/accounts_passwords/paultrial";
};
};
mailserver = {
enable = true;
fqdn = "mail2.banditlair.com";
domains = [ "banditlair.com" "froidmont.org" "falbo.fr" ];
# mailDirectory = "/nix/var/data/vmail";
loginAccounts = {
"paultrial@banditlair.com" = {
# nix run nixpkgs.apacheHttpd -c htpasswd -nbB "" "super secret password" | cut -d: -f2 > /hashed/password/file/location
hashedPasswordFile = config.sops.secrets.paultrialPassword.path;
};
};
extraVirtualAliases = {
"info@banditlair.com" = "paultrial@banditlair.com";
"postmaster@banditlair.com" = "paultrial@banditlair.com";
"abuse@banditlair.com" = "paultrial@banditlair.com";
"info@froidmont.org" = "paultrial@banditlair.com";
"postmaster@froidmont.org" = "paultrial@banditlair.com";
"abuse@froidmont.org" = "paultrial@banditlair.com";
"info@falbo.fr" = "paultrial@banditlair.com";
"postmaster@falbo.fr" = "paultrial@banditlair.com";
"abuse@falbo.fr" = "paultrial@banditlair.com";
};
# certificateScheme = 3;
};
}

View file

@ -1,11 +1,15 @@
{ config, lib, pkgs, ... }:
{
sops.secrets.murmurEnvFile = {
owner = config.systemd.services.murmur.serviceConfig.User;
key = "murmur.env";
restartUnits = [ "murmur.service" ];
};
services.murmur = {
enable = true;
bandwidth = 128000;
password = "$MURMURD_PASSWORD";
environmentFile = "/var/keys/murmur.env";
environmentFile = config.sops.secrets.murmurEnvFile.path;
};
users.users.murmur.extraGroups = [ "keys" ];
}

View file

@ -6,9 +6,39 @@ let
gidFile = pkgs.writeText "gidfile" ''
nextcloud:33
'';
sshfsOptions = [
"nofail"
"identityfile=/var/keys/sshfs-ssh-key"
in
{
sops.secrets = {
sshfsKey = {
key = "sshfs_keys/private";
restartUnits = [ "var-lib-nextcloud-data.mount" ];
};
nextcloudDbPassword = {
owner = config.users.users.nextcloud.name;
key = "nextcloud/db_password";
restartUnits = [ "nextcloud-setup.service" ];
};
nextcloudAdminPassword = {
owner = config.users.users.nextcloud.name;
key = "nextcloud/admin_password";
restartUnits = [ "nextcloud-setup.service" ];
};
};
environment.systemPackages = with pkgs; [
sshfs
];
systemd.services.nextcloud-data-sshfs = {
wantedBy = [ "multi-user.target" ];
before = [ "phpfpm-nextcloud.service" ];
restartIfChanged = false;
serviceConfig = {
ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p /var/lib/nextcloud/data";
ExecStart =
let
options = builtins.concatStringsSep "," [
"identityfile=${config.sops.secrets.sshfsKey.path}"
"ServerAliveInterval=15"
"idmap=file"
"uidfile=${uidFile}"
@ -17,17 +47,12 @@ let
"default_permissions"
"nomap=ignore"
];
in
{
environment.systemPackages = with pkgs; [
sshfs
];
fileSystems."/var/lib/nextcloud/data" =
{
device = " www-data@10.0.2.2:/var/lib/nextcloud/data";
fsType = "fuse.sshfs";
options = sshfsOptions;
in
"${pkgs.sshfs}/bin/mount.fuse.sshfs www-data@10.0.2.2:/var/lib/nextcloud/data "
+ "/var/lib/nextcloud/data -o ${options}";
ExecStopPost = "-${pkgs.fuse}/bin/fusermount -u /var/lib/nextcloud/data";
KillMode = "process";
};
};
services.nginx = {
@ -48,12 +73,11 @@ in
dbuser = "nextcloud";
dbhost = "10.0.1.11";
dbname = "nextcloud";
dbpassFile = "/var/keys/nextcloud-db-pass";
adminpassFile = "/var/keys/nextcloud-admin-pass";
dbpassFile = "${config.sops.secrets.nextcloudDbPassword.path}";
adminpassFile = "${config.sops.secrets.nextcloudAdminPassword.path}";
adminuser = "root";
overwriteProtocol = "https";
defaultPhoneRegion = "BE";
};
};
users.users.nextcloud.extraGroups = [ "keys" ];
}

View file

@ -1,9 +1,13 @@
{ config, lib, pkgs, ... }:
{
services.postgresql = {
enable = true;
package = pkgs.postgresql_12;
initialScript = "/var/keys/postgres-init.sql";
initialScript = pkgs.writeText "postgres-init.sql" ''
CREATE ROLE "synapse";
CREATE ROLE "nextcloud";
'';
enableTCPIP = true;
identMap = ''
root_as_others root postgres
@ -16,5 +20,47 @@
host all all 10.0.1.0/24 md5
'';
};
users.users.postgres.extraGroups = [ "keys" ];
sops.secrets = {
synapseDbPassword = {
owner = config.services.postgresql.superUser;
key = "synapse/db_password";
restartUnits = [ "postgresql-setup.service" ];
};
nextcloudDbPassword = {
owner = config.services.postgresql.superUser;
key = "nextcloud/db_password";
restartUnits = [ "postgresql-setup.service" ];
};
};
systemd.services.postgresql-setup = let pgsql = config.services.postgresql; in
{
after = [ "postgresql.service" ];
bindsTo = [ "postgresql.service" ];
wantedBy = [ "postgresql.service" ];
path = [
pgsql.package
pkgs.util-linux
];
script = ''
set -eu
PSQL() {
psql --port=${toString pgsql.port} "$@"
}
PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = 'synapse'" | grep -q 1 || PSQL -tAc 'CREATE DATABASE "synapse" OWNER "synapse" TEMPLATE template0 LC_COLLATE = "C" LC_CTYPE = "C"'
PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = 'nextcloud'" | grep -q 1 || PSQL -tAc 'CREATE DATABASE "nextcloud" OWNER "nextcloud"'
synapse_password="$(<'${config.sops.secrets.synapseDbPassword.path}')"
PSQL -tAc "ALTER ROLE synapse WITH PASSWORD '$synapse_password'"
nextcloud_password="$(<'${config.sops.secrets.nextcloudDbPassword.path}')"
PSQL -tAc "ALTER ROLE nextcloud WITH PASSWORD '$nextcloud_password'"
'';
serviceConfig = {
User = pgsql.superUser;
Type = "oneshot";
RemainAfterExit = true;
};
};
}

View file

@ -5,6 +5,16 @@ let
join = hostName: domain: hostName + lib.optionalString (domain != null) ".${domain}";
in
join "matrix" config.networking.domain;
synapseDbConfig = pkgs.writeText "synapse-db-config.yaml" ''
database:
name: psycopg2
args:
database: synapse
host: "10.0.1.11"
user: "synapse"
password: "SYNAPSE_DB_PASSWORD"
macaroon_secret_key: "MACAROON_SECRET_KEY"
'';
in
{
security.acme.email = "letsencrypt.account@banditlair.com";
@ -64,6 +74,43 @@ in
};
};
sops.secrets = {
synapseDbPassword = {
owner = config.systemd.services.matrix-synapse.serviceConfig.User;
key = "synapse/db_password";
restartUnits = [ "matrix-synapse-setup" ];
};
macaroonSecretKey = {
owner = config.systemd.services.matrix-synapse.serviceConfig.User;
key = "synapse/macaroon_secret_key";
restartUnits = [ "matrix-synapse-setup" ];
};
};
systemd.services.matrix-synapse-setup = {
before = [ "matrix-synapse.service" ];
script = ''
set -euo pipefail
install -m 600 ${synapseDbConfig} /run/synapse/synapse-db-config.yaml
${pkgs.replace-secret}/bin/replace-secret 'SYNAPSE_DB_PASSWORD' '${config.sops.secrets.synapseDbPassword.path}' /run/synapse/synapse-db-config.yaml
${pkgs.replace-secret}/bin/replace-secret 'MACAROON_SECRET_KEY' '${config.sops.secrets.macaroonSecretKey.path}' /run/synapse/synapse-db-config.yaml
'';
serviceConfig = {
User = config.systemd.services.matrix-synapse.serviceConfig.User;
Group = config.systemd.services.matrix-synapse.serviceConfig.Group;
Type = "oneshot";
RemainAfterExit = true;
RuntimeDirectory = "synapse";
};
};
systemd.services.matrix-synapse = {
after = [ "matrix-synapse-setup.service" "network.target" ];
bindsTo = [ "matrix-synapse-setup.service" ];
};
services.matrix-synapse = {
enable = true;
server_name = config.networking.domain;
@ -87,7 +134,6 @@ in
host = "fake"; # This section is overriden in deploy_nixos keys
};
dataDir = "/nix/var/data/matrix-synapse";
extraConfigFiles = [ "/var/keys/synapse-extra-config.yaml" ];
extraConfigFiles = [ "/run/synapse/synapse-db-config.yaml" ];
};
users.users.matrix-synapse.extraGroups = [ "keys" ];
}

View file

@ -11,11 +11,19 @@
../modules/custom-backup-job.nix
];
sops.secrets = {
borgSshKey = {
owner = config.services.borgbackup.jobs.data.user;
key = "borg/client_keys/backend1/private";
};
};
services.custom-backup-job = {
additionalPaths = [ "/var/lib/nextcloud/config" ];
additionalReadWritePaths = [ "/nix/var/data/murmur" ];
additionalPreHook = "cp /var/lib/murmur/murmur.sqlite /nix/var/data/murmur/murmur.sqlite";
readWritePaths = [ "/nix/var/data/murmur" ];
preHook = "cp /var/lib/murmur/murmur.sqlite /nix/var/data/murmur/murmur.sqlite";
startAt = "03:30";
sshKey = config.sops.secrets.borgPassphrase.path;
};
networking.localCommands = "ip addr add 95.216.177.3/32 dev enp1s0";
@ -34,7 +42,7 @@
allow localhost
check file nextcloud-data-mounted with path /var/lib/nextcloud/data/index.html
start = "${pkgs.systemd}/bin/systemctl start var-lib-nextcloud-data.mount"
start = "${pkgs.systemd}/bin/systemctl start nextcloud-data-sshfs.service"
'';
};

View file

@ -10,13 +10,21 @@
networking.firewall.interfaces."enp7s0".allowedTCPPorts = [ 5432 ];
sops.secrets = {
borgSshKey = {
owner = config.services.borgbackup.jobs.data.user;
key = "borg/client_keys/db1/private";
};
};
services.custom-backup-job = {
additionalReadWritePaths = [ "/nix/var/data/postgresql" ];
additionalPreHook = ''
readWritePaths = [ "/nix/var/data/postgresql" ];
preHook = ''
${pkgs.postgresql_12}/bin/pg_dump -U synapse synapse > /nix/var/data/postgresql/synapse.dmp
${pkgs.postgresql_12}/bin/pg_dump -U nextcloud nextcloud > /nix/var/data/postgresql/nextcloud.dmp
'';
startAt = "03:00";
sshKey = config.sops.secrets.borgSshKey.path;
};
networking.firewall.interfaces."ens10".allowedTCPPorts = [ 80 ];

View file

@ -4,5 +4,11 @@
../environment.nix
../hardware/hetzner-dedicated-storage1.nix
../modules/openssh.nix
../modules/mailserver.nix
];
security.acme.email = "letsencrypt.account@banditlair.com";
security.acme.acceptTerms = true;
networking.firewall.allowedTCPPorts = [ 80 ];
}

View file

@ -2,9 +2,12 @@ synapse:
db_password: ENC[AES256_GCM,data:hy2BgTsRaZDQZULTW/csmnRy5ZjDEuPqxyuINv0ov5pFzDkozJVL1wut3HgBXjYZ8bqNjS5pCPQtkznw,iv:i41zKGwvPGIEZP0ZjhRaY4UMeOXBovQmLr1e1ewZhV4=,tag:3kKKYouH+lOrNxPJE5ul/Q==,type:str]
macaroon_secret_key: ENC[AES256_GCM,data:6n1gCit2MC8l4VR9DSUR87BB+hY5Oza33423sbV8sNIXmZsPzhyvxaBalK/0TVjLH6Q=,iv:OgHxNG96ZW4+LPZhLAtOD01Wibad6vSX6s4BrPE67YE=,tag:OGIz/ufUwt8/pUMLvoaXtg==,type:str]
nextcloud:
db_password: ENC[AES256_GCM,data:48+DQ2TcAtq809r7DU3SZEKxy8iXrNLtAgOTH5GbZvEigu9ROtLTCG5hN1NguYkjln7ix63k1RqiwQnO,iv:0ZHDn0LWHzdep7DmmnfwhNUGJQ8mgy6S0aGhDVtWixE=,tag:JP7NyIaDHogzm8VYu+lDqw==,type:str]
db_password: ENC[AES256_GCM,data:guuBM5ag+Q014Y+rt0+E9hJcYfLcXV8HfJdbWRuI7BC+Gsjr82OkowFYquFLvcnMAgYWXroy73jW4I4v,iv:KDm/er5h/rK6jqRQdS36LPAw3oOk/yZya0OMPoJlyBg=,tag:4AXG7/BRHOoYJwvVwJxhPw==,type:str]
admin_password: ENC[AES256_GCM,data:zTOHKYJmBbA6Tca2l+vO748dGzP2XkAvZHmJtrbftDI5Q/1mS3ZLw16g1DT+pKXF7VIUm2plR7ZRtxwq,iv:87lrQzhdyz1YiIO25fXwn0TvEASm/H8N5cZUckIm780=,tag:VXyNu8CnoY/ShK7dHnPTWA==,type:str]
murmur.password: ENC[AES256_GCM,data:5Yu67/hMwdaIiDlU,iv:dAX6NCQTJtw3DZSzl3+zGTRAxCa93NxB0sAq0HegQbw=,tag:ibgGwH/fFMRuedv2zjsgnA==,type:str]
murmur.env: ENC[AES256_GCM,data:bErJrzpPRrBhUeW113qt9xbJWsrxiI8YIibZ3l0=,iv:2dIlmdLKB+nktQ4/O1W3xtfcCRowW9MkxncDiDpZyck=,tag:3UkSGVKV00385iZ66rHOpw==,type:str]
email:
accounts_passwords:
paultrial: ENC[AES256_GCM,data:fDGYNdu9DQcfheOkc5aixUGmHPrVh4/6JGAECwhl64zpxXqPQ/jqYoaOMz3o3wozF1g+ZOKdBd2daBm0,iv:nyz37z1gmKbdpBDRvEe/4l36+evh89kpgowNxd+KdE0=,tag:j6JWAXglSPtKqN0v7akrSg==,type:str]
borg:
passphrase: ENC[AES256_GCM,data:RNUTb29sOdsg4KnB/0nIFGJFV/2nlMH4pxGFlgXdtTgDe2opT/moUg==,iv:6kdBeq+qFWnPB+N+zpKNdFkmkskOVMabdj8Uxk9QeQI=,tag:MxNqn5p9P0JpsjkNm9iYEQ==,type:str]
client_keys:
@ -23,28 +26,68 @@ sops:
azure_kv: []
hc_vault: []
age: []
lastmodified: "2021-07-16T12:36:44Z"
mac: ENC[AES256_GCM,data:TfKYVlibtFY0YfpnmQO28v0YAQX6HQRJrf+qIj/3gKY4XEMUGzl0dGxTD5yKNmFORkPrbjrq2SjxUqjCGklvGohDroZxF/qMbdbaLqO8hQCtohs2T71+JX/yTYUwXuHAdOh+q3D0emlx6CY+jvNh1PGtUXcbpU4/oOYC6JEsmmU=,iv:+wIvq7vkbICrJocs+I8pzJzTqIzVWgtisg534An+ma8=,tag:kzk5+uxtIJbitKp/IW1Ozg==,type:str]
lastmodified: "2021-11-28T21:13:22Z"
mac: ENC[AES256_GCM,data:+FuqGDiCmui2F230m0ec/LFhmD5dvpbkn/Ov8fpuWo5WfZLkrn6Kb05F7CwiML2GFhQbw9G5Q07mlOkzoIOnTz+pxZhPE/JGRUREjyipPtu2T0UXbYb1E9LoO40lrrwYJ/5QLXKys1ozfXMhZ6cAP9P5evLmIb8j1P/KQ7y4lsI=,iv:iXw4QwK9N/gJQSU8sub69EZUdqaIflWbRohX8S1Xz2w=,tag:aUAIUSfVpzrymciKdJjUCQ==,type:str]
pgp:
- created_at: "2021-07-14T18:02:07Z"
- created_at: "2021-11-29T00:57:34Z"
enc: |
-----BEGIN PGP MESSAGE-----
hQIMAy9TuQ4zAbDHAQ/6AjQzGb2sOzHZblU/VEQce+gUebo4otQvMY5sQVl6xmBU
y+JiSRyUy3euGcAdNvkB9fxgNrKB5amaeP2Hte1cjJsy+iBHnmTlPKmBKet6mgJY
0Q1BDZf8oJUsioiHZeDfo3XLEVuIiJ/ek3v6NYPI1lfmkgV6J7oAzTYT30Z57v6C
zah7EcZa1Cr33hC1Ibb6o14Rzf2xgk17/fyXmFNyNnTu6XJxU85g1JDdcMKwRDpQ
y7VE6/nMSN0p2CGUFTuLPg7zfa9e6zDZ7UblXTV5EXPndf1MQ8Ni/AmPdQ8A9rjt
5kP9+Cv2CFfdXW1dgqORkQ9UC8hXdt0N3BR1X0BZWPmQyhODDUdkXndVqNDYUg8q
tXEN1WS66BUUB1nGbSnSa6SLLbMwB5Jle9qf5axJnCmlHLifCq9tGHhGH8h/NGNA
9o59iUV2pJxIaOoye9PQ4jo43J/O19YaRefETO6D5Y8SIXC0zX0IXGY/sEusaZlT
Iz7wEr+dc4Xy38PWzXM8p9u5ixzwYB7q7zt2OBuiiD51zD6TTjn2PUmuyY+uaqhX
KcmbrjGsu/HzcRlmvkVgYgpUqf7AqmaKIwGsSd1On8hpNxQI3/kiJnEjpRW+iqyb
EB7d8KQbpRlxCs5MMU6LznD7zvCeXyy3a0U+CFB+5tp74Wj6kxKpMZl0BYPfMrvS
XgGiTJ0By1L2lJphYxdKFQtoMqOZrr+y7/x/peEclPzKvdvIPHLE3P6HmOfWSJTh
Z6rXZDUtcBvyTEQInP5WJ1l37WiZ3B9LFRPq4Ej/0zrfsJfqmRYPQFJaMucjlNQ=
=eKml
hQIMAy9TuQ4zAbDHARAApLHzffnk0EttyN3lSGqZAzMN/0dszvw3ekwGzoo0O3lW
PsBLodK3xDSJSVl9mAuW4yxU46PVpQA/Oh4TKLpyyjZM9fZru1M+KHToAE52m4dk
4OT8BQ9bAYu9mMuyv4u/D87jFDwpRfT963gqAtvRmZntzN4kf0uXwTVlW0HOCcqt
VzgWoh8izkI4itkVbQTcQNI/1nFLdN6waNUGBN9js9MR/fbHnsnzhxWTH2/2y9Iq
kCoww1uovRQrPRU3CNeyR+frO9wVQH5JwEyNJvWaoQ3fvAWR8TN4Jx/oSOWBpcwt
2WtGLPUxzayKN6JDjrdyi8FhVStcl8d6BN6WbRtnmLGuuCf007he+nIfuGt+IZ29
k2j9iniUUIIvRGGlr62Qg75D+I7t/EohrtFZ9q/jlvn1vEwm5PfioBfkdsm+Jijd
gXspGZjLhCz4cJ+5dCmm43aP0iL072GzwgVSMAsuk0PPUljeoh0l+B2XZ9EcC76J
r/WSL7/9fWYLnSaD52Nq4NyWzriPZxmL/aFFH1TdZ9b9axYsWoy8kfFHSDKExZyX
YkHzfbAVARRn33LtWUY0zEuIitquUSVC3i/9ZFMkgYVE1FDZ0DENBqrSo+myGniU
2b/Qet/yL3oz/wluZ6hYN5hix5VOkWEiBVtZPUyuPdOHIDofvx0MMSflnaGFkUrS
XgGPftShIWOFjr8C6b5S2s6D92FcHWRQFL9MnEGCx4fUPyRZh1Ls845C6UhYsBdX
/vp5p81ag3OFbbDkxhn0WlGx0E9pkgtmXD7kmDiwSwE/za3FEIh7mBWGcjEXb+o=
=AivY
-----END PGP MESSAGE-----
fp: 3AC6F170F01133CE393BCD94BE948AFD7E7873BE
- created_at: "2021-11-29T00:57:34Z"
enc: |
-----BEGIN PGP MESSAGE-----
hQIMAzY52PDH/2HtAQ/+O4IE9qPx0KmHFtlZJhKY7UftVVC22c1jVkaaap8fvh8W
500ZqnT9CPlIi6n7Hf6uKUj9kt93epiHSw5PtsNjQYBA7iqWdsQQ3hj19E7cSUkA
+HrczLrH5qrnL11Q5JMehR0G1kwZtyVNpXZAD7HIK2s/LiOGJe5DxvcPykNQtmAx
ZFE4H9OhBF5eHPL6gp5Sk1EA8nEzfBDp/aKn1L6aXL5ALDc8AXIBf2haIvjob5DE
0E23NyWqt0apShMzBDpJ3+82xBLjVjWYPVzq4J86jddKp1KjsWOGCynkHs7uYL3X
ce+wMufv8RfUqZNSkURkesXJTJT3VMvNdtlcPEnRebXbPce7Ico9Ht/hVMuViqjV
zB6AeS+MQDg9AyNLZHncRKY0+xZRqLURHurdTXD0F2dR1hv3z3Ew8qBykLTT8Sbu
z6ugJ4y9bs25/ffu/j2I5a65rpral4q/0SmkroWQG3M35zETWyutxGfNWXZlI5eK
NYMsKmcfx8WdzjHRY14eNpnLkhkKnJnBq9FWT66eHf1eD1y1E0DYfvYy22S7S9tO
uYbKgOhgp6caTYMKX4JcGwKuvZIN5BIAYOFNWKBc4ZhvSkwiE5smeg+x5bdxjcEM
bsw8hSJKzoScljgQLMMknP2Rh0iTfxWadV7BFSbQTUU0ivg6tuVUrdYzQIRZ5RrS
UAFXA8MwOtAu7E4nrlJspkWFF37tVpQsWRmFvOTmYktM1ZgNM+v8WkuQCKRAp2QV
HMvzDyvob+mCnyorXext7MXR6KVJJVeilgUfySMzodc5
=4/BS
-----END PGP MESSAGE-----
fp: ebdabf42731801d79db14c893639d8f0c7ff61ed
- created_at: "2021-11-29T00:57:34Z"
enc: |
-----BEGIN PGP MESSAGE-----
hQIMA9vMSKUwB3OoAQ/+OJdLIsaRekFe/M33Om5OVngw/AUHBj5SRILTHjROZBxW
RKvIRJy197PQj3lF1VaxWgnv2nIcVSSVQetLpWzXu9jq3zLMNwMtKD0s+zbzhTme
sdJb54CXu2WpDUpQirGg6VqOyAYy5mlVCRi5GkCFtm4nagg+Z5simlL8pfk+yXFD
hVqiQd+dy82QSKzl4RVltev/yhSL5RIVWP94VfJIuWAXQetr/tPOTl8ZNMqWQCvM
a0QU/okRP5x+HAHMHU9AnWHkiAe6WWbkZpBNsc116Pv6dXFgpeC/RDA1lExOaXDV
fYc+szCPhB9ki+JeZ4+C4I7h8rS+/aIkTdTFRHkuah+xkWRwOOy/cos9p+EjQze4
dlQGP5roMhZYpbwSzCRDIYO4+t6fi+TMcQ7F4GWWMcSmUXedA0VBo1eVHTKunvFG
gXW+l9MrUnzJ4zNOuf5rl2ce6yxDfCD5x+v3Pqq+Sf0EG6p8w6UWuFystcZNbEoE
RTCKztMv5GdJ6AiRBZKqDV1qtsPhXl1iW/aVY0xnvbhAJ0ycVHwNGn2GprkNJKLi
ht9XGBSPBokP7wIvfhve/LLKptFhkaPFoqbGHCejIvz2AuHeKoE53UaVzi0E3TM6
k8sYMgu6qX/V7pySm8OIMhm92xGokpvvsY3K/h0oCOt4jd53vlxmXJ7N8J+hXbrS
UAHcXm47rTr1y8yeWFr3U89qilETGqaRe83AFjdUp0tJBBt6c4jycM3g0ZNI3mhR
JKX4XKknqjTndfskCRf6UE0qF0Ta878mt2e7D0PA0DsP
=Qy/A
-----END PGP MESSAGE-----
fp: 7675e1c632a9a0644c6ab828dbcc48a5300773a8
unencrypted_suffix: _unencrypted
version: 3.7.1