From c76ade9c299beea9f366a562513a07db4c8485ee Mon Sep 17 00:00:00 2001 From: Paul-Henri Froidmont Date: Thu, 15 Jul 2021 13:38:22 +0200 Subject: [PATCH] Move Synapse on hcloud and deploy it with Terraform + NixOs --- .envrc | 2 + .gitignore | 1 + backend1.nix | 115 +++++++++++++++++++++ config.tf | 33 +++--- db1.nix | 34 ++++++ dns.tf | 26 ++--- flake.lock | 27 +++++ flake.nix | 27 +++++ instances.tf | 114 ++++++++++++++++++++ outputs.tf | 7 ++ playbook.yml | 4 +- roles/daily-backup/templates/fullBackup.sh | 8 +- secrets.enc.yml | 34 ++++++ ssh_keys/phfroidmont-desktop.pub | 1 + 14 files changed, 396 insertions(+), 37 deletions(-) create mode 100644 .envrc create mode 100644 backend1.nix create mode 100644 db1.nix create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 instances.tf create mode 100644 outputs.tf create mode 100644 secrets.enc.yml create mode 100644 ssh_keys/phfroidmont-desktop.pub diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3b2cfd9 --- /dev/null +++ b/.envrc @@ -0,0 +1,2 @@ +use flake +export SOPS_PGP_FP="3AC6F170F01133CE393BCD94BE948AFD7E7873BE" diff --git a/.gitignore b/.gitignore index 4c106a6..30ac0aa 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ terraform.tfstate.backup .environment .tmp terraform.tfvars +.direnv \ No newline at end of file diff --git a/backend1.nix b/backend1.nix new file mode 100644 index 0000000..f05d069 --- /dev/null +++ b/backend1.nix @@ -0,0 +1,115 @@ +{ modulesPath, pkgs, lib, config, ... }: +let + fqdn = + let + join = hostName: domain: hostName + lib.optionalString (domain != null) ".${domain}"; + in join "matrix" config.networking.domain; +in { + imports = [ (modulesPath + "/profiles/qemu-guest.nix") ]; + + boot.loader.grub.device = "/dev/sda"; + fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; }; + + # Set NIX_PATH to be the same as the Terraform module + # nix.nixPath = [ "nixpkgs=${pkgs}" ]; + + boot.cleanTmpDir = true; + + networking.hostName = "backend1"; + networking.domain = "banditlair.com"; + networking.firewall.allowPing = true; + networking.firewall.allowedTCPPorts = [ 80 443 ]; + + services.openssh.enable = true; + users.users.root.openssh.authorizedKeys.keyFiles = [ + ./ssh_keys/phfroidmont-desktop.pub + ]; + + security.acme.email = "letsencrypt.account@banditlair.com"; + security.acme.acceptTerms = true; + + services.nginx = { + enable = true; + # only recommendedProxySettings and recommendedGzipSettings are strictly required, + # but the rest make sense as well + recommendedTlsSettings = true; + recommendedOptimisation = true; + recommendedGzipSettings = true; + recommendedProxySettings = true; + + virtualHosts = { + # This host section can be placed on a different host than the rest, + # i.e. to delegate from the host being accessible as ${config.networking.domain} + # to another host actually running the Matrix homeserver. + "${config.networking.domain}" = { + enableACME = true; + forceSSL = true; + + locations."= /.well-known/matrix/server".extraConfig = + let + # use 443 instead of the default 8448 port to unite + # the client-server and server-server port for simplicity + server = { "m.server" = "${fqdn}:443"; }; + in '' + add_header Content-Type application/json; + return 200 '${builtins.toJSON server}'; + ''; + locations."= /.well-known/matrix/client".extraConfig = + let + client = { + "m.homeserver" = { "base_url" = "https://${fqdn}"; }; + "m.identity_server" = { "base_url" = "https://vector.im"; }; + }; + # ACAO required to allow element-web on any URL to request this json file + in '' + add_header Content-Type application/json; + add_header Access-Control-Allow-Origin *; + return 200 '${builtins.toJSON client}'; + ''; + }; + + # Reverse proxy for Matrix client-server and server-server communication + ${fqdn} = { + enableACME = true; + forceSSL = true; + + # Or do a redirect instead of the 404, or whatever is appropriate for you. + # But do not put a Matrix Web client here! See the Element web section below. + locations."/".extraConfig = '' + return 404; + ''; + + # forward all Matrix API calls to the synapse Matrix homeserver + locations."/_matrix" = { + proxyPass = "http://[::1]:8008"; # without a trailing / + }; + }; + }; + }; + + services.matrix-synapse = { + enable = true; + server_name = config.networking.domain; + listeners = [ + { + port = 8008; + bind_address = "::1"; + type = "http"; + tls = false; + x_forwarded = true; + resources = [ + { + names = [ "client" "federation" ]; + compress = false; + } + ]; + } + ]; + database_type = "psycopg2"; + database_args = { + host = "fake"; # This section is overriden in deploy_nixos keys + }; + extraConfigFiles = [ "/var/keys/synapse-extra-config.yaml" ]; + }; + users.users.matrix-synapse.extraGroups = [ "keys" ]; +} diff --git a/config.tf b/config.tf index 19397dc..1d86d5f 100644 --- a/config.tf +++ b/config.tf @@ -2,28 +2,33 @@ terraform { backend "http" { } required_providers { -// hcloud = { -// source = "hetznercloud/hcloud" -// version = "1.24.1" -// } + hcloud = { + source = "hetznercloud/hcloud" + version = "1.24.1" + } hetznerdns = { source = "timohirt/hetznerdns" version = ">= 1.1.1" } + + sops = { + source = "carlpett/sops" + version = "~> 0.5" + } } } -//variable "hcloud_token" {} -// -//provider "hcloud" { -// token = var.hcloud_token -//} -// -//resource "hcloud_ssh_key" "phfroidmont-desktop" { -// name = "phfroidmont-desktop" -// public_key = file("ssh_keys/phfroidmont-desktop.pub") -//} +variable "hcloud_token" {} + +provider "hcloud" { + token = var.hcloud_token +} + +resource "hcloud_ssh_key" "phfroidmont-desktop" { + name = "phfroidmont-desktop" + public_key = file("ssh_keys/phfroidmont-desktop.pub") +} variable "hetznerdns_token" {} diff --git a/db1.nix b/db1.nix new file mode 100644 index 0000000..7129a02 --- /dev/null +++ b/db1.nix @@ -0,0 +1,34 @@ +{ modulesPath, pkgs, ... }: +{ + imports = [ (modulesPath + "/profiles/qemu-guest.nix") ]; + + boot.loader.grub.device = "/dev/sda"; + fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; }; + + # Set NIX_PATH to be the same as the Terraform module + # nix.nixPath = [ "nixpkgs=${pkgs}" ]; + + environment.systemPackages = with pkgs; [ + htop + ]; + boot.cleanTmpDir = true; + networking.hostName = "db1"; + networking.domain = "banditlair.com"; + networking.firewall.allowPing = true; + networking.firewall.interfaces."enp7s0".allowedTCPPorts = [ 5432 ]; + services.openssh.enable = true; + users.users.root.openssh.authorizedKeys.keyFiles = [ + ./ssh_keys/phfroidmont-desktop.pub + ]; + + services.postgresql = { + enable = true; + package = pkgs.postgresql_12; + initialScript = "/var/keys/postgres-init.sql"; + enableTCPIP = true; + authentication = '' + host all all 10.0.1.0/24 md5 + ''; + }; + users.users.postgres.extraGroups = [ "keys" ]; +} diff --git a/dns.tf b/dns.tf index a58ef45..d96f87c 100644 --- a/dns.tf +++ b/dns.tf @@ -7,35 +7,27 @@ data "hetznerdns_zone" "banditlair_zone" { name = "banditlair.com" } -resource "hetznerdns_record" "banditlair_a" { +resource "hetznerdns_record" "banditlair_hcloud_a" { zone_id = data.hetznerdns_zone.banditlair_zone.id name = "@" - value = "144.76.18.197" + value = data.hcloud_floating_ip.main_ip.ip_address type = "A" ttl = 600 } -resource "hetznerdns_record" "banditlair_cname" { +resource "hetznerdns_record" "banditlair_dedicated_a" { zone_id = data.hetznerdns_zone.banditlair_zone.id name = "*" - value = "${data.hetznerdns_zone.banditlair_zone.name}." - type = "CNAME" + value = "144.76.18.197" + type = "A" ttl = 600 } -resource "hetznerdns_record" "ddns_ns" { - zone_id = data.hetznerdns_zone.banditlair_zone.id - name = "ddns.banditlair.com." - value = "ns.banditlair.com." - type = "NS" - ttl = 3600 -} - # Matrix resource "hetznerdns_record" "matrix_a" { zone_id = data.hetznerdns_zone.banditlair_zone.id name = "matrix" - value = hetznerdns_record.banditlair_a.value + value = data.hcloud_floating_ip.main_ip.ip_address type = "A" ttl = 600 } @@ -112,7 +104,7 @@ data "hetznerdns_zone" "falbo_zone" { resource "hetznerdns_record" "falbo_a" { zone_id = data.hetznerdns_zone.falbo_zone.id name = "@" - value = hetznerdns_record.banditlair_a.value + value = hetznerdns_record.banditlair_dedicated_a.value type = "A" ttl = 600 } @@ -172,7 +164,7 @@ data "hetznerdns_zone" "froidmont_zone" { resource "hetznerdns_record" "froidmont_a" { zone_id = data.hetznerdns_zone.froidmont_zone.id name = "@" - value = hetznerdns_record.banditlair_a.value + value = hetznerdns_record.banditlair_dedicated_a.value type = "A" ttl = 600 } @@ -232,7 +224,7 @@ data "hetznerdns_zone" "stb_zone" { resource "hetznerdns_record" "stb_a" { zone_id = data.hetznerdns_zone.stb_zone.id name = "@" - value = hetznerdns_record.banditlair_a.value + value = hetznerdns_record.banditlair_dedicated_a.value type = "A" ttl = 600 } diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..32c7656 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1626117186, + "narHash": "sha256-KSVWpb03y2QootRxAG4RwTI14RUn1vmz/yRgVlDJRpk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a7512bb64b1dd693c97b1219c24032d28f20f9e8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-21.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..25a7cbb --- /dev/null +++ b/flake.nix @@ -0,0 +1,27 @@ +{ + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-21.05"; + + outputs = { self, nixpkgs }: + let + pkgs = nixpkgs.legacyPackages.x86_64-linux; + + inputs = with pkgs; [ + terraform_0_14 + sops + ]; + in { + devShell.x86_64-linux = pkgs.mkShell { + buildInputs = inputs; + }; + + nixosConfigurations.db1 = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ { imports = [ ./db1.nix ]; } ]; + }; + + nixosConfigurations.backend1 = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ { imports = [ ./backend1.nix ]; } ]; + }; + }; +} diff --git a/instances.tf b/instances.tf new file mode 100644 index 0000000..3e4cf11 --- /dev/null +++ b/instances.tf @@ -0,0 +1,114 @@ +data "hcloud_image" "nixos_stable" { + with_selector = "nixos=21.05" +} + +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" +} + +resource "hcloud_network_subnet" "db_network_subnet" { + type = "cloud" + network_id = hcloud_network.private_network.id + network_zone = "eu-central" + ip_range = "10.0.1.0/24" +} + +resource "hcloud_server" "db1" { + name = "db1" + image = data.hcloud_image.nixos_stable.id + server_type = "cpx11" + ssh_keys = [ + hcloud_ssh_key.phfroidmont-desktop.id + ] + keep_disk = true + location = "hel1" + + network { + network_id = hcloud_network.private_network.id + ip = "10.0.1.11" + } + + labels = { + type = "db" + } + + depends_on = [ + hcloud_network_subnet.db_network_subnet + ] +} + +module "deploy_nixos_db1" { + source = "github.com/phfroidmont/terraform-nixos//deploy_nixos?ref=a8d5d31e59f4ce2677272e4849b122b4afc5a8e4" + nixos_config = "db1" + flake = true + target_host = hcloud_server.db1.ipv4_address + ssh_agent = true + keys = { + "postgres-init.sql" = < /backup echo 'Dumping S.T.B. wordpress database' docker exec stb_db_1 sh -c "mysqldump -u stb -p{{stb_mysql_password}} stb > /backups/database.dmp" -echo 'Dumping matrix database' -docker exec matrix_db_1 sh -c "pg_dump -U synapse synapse > /backups/database.dmp" +#echo 'Dumping matrix database' +#docker exec matrix_db_1 sh -c "pg_dump -U synapse synapse > /backups/database.dmp" -echo 'Dumping invidious database' -docker exec invidious_postgres_1 sh -c "pg_dump -U kemal invidious > /backups/database.dmp" +#echo 'Dumping invidious database' +#docker exec invidious_postgres_1 sh -c "pg_dump -U kemal invidious > /backups/database.dmp" echo 'Copying murmur database' docker stop murmur_murmur_1 diff --git a/secrets.enc.yml b/secrets.enc.yml new file mode 100644 index 0000000..97b89d3 --- /dev/null +++ b/secrets.enc.yml @@ -0,0 +1,34 @@ +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] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: [] + lastmodified: "2021-07-14T18:42:34Z" + mac: ENC[AES256_GCM,data:Zjwgb3DudxssTIT0BdQbm/FEJmPsNz6412djBGBKC+KpHU/65Cw6WhjX/cR48zO/4OK3nkfJ/MKq9Vv47QLUlcyJwGgRmdBsowjpcqvrG1UMGKd+sg+rQRtDi8AVicSMJ+cnhMtIAsvGzktl+5Xep3tuFZ7stKwdvkIR9LJr2PI=,iv:1mWlZU++GgkeiCI9JUnbUvMxGR+jmWU1Lle6w2ZVJe8=,tag:AE8l0W7x68BM7OpPJmmV0Q==,type:str] + pgp: + - created_at: "2021-07-14T18:02:07Z" + 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 + -----END PGP MESSAGE----- + fp: 3AC6F170F01133CE393BCD94BE948AFD7E7873BE + unencrypted_suffix: _unencrypted + version: 3.7.1 diff --git a/ssh_keys/phfroidmont-desktop.pub b/ssh_keys/phfroidmont-desktop.pub new file mode 100644 index 0000000..98d7377 --- /dev/null +++ b/ssh_keys/phfroidmont-desktop.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMPhCld0dsDzpdkMvPRdiwd6IX8HF8Mb2V6uQzBl8/syeny8FbZxlZR8gk39RGxNYcLaZ+nA50DS6mOIplXCGdtozfw0Vm+FdITN3apMufWIdobG7Igs1vxKBBbkAb5lwxkEFUCUMzPdCLFHd5zabVH0WE42Be8+hYPLd5W/ikPCOgxRaGwryHHroxRMdkD3PcNE8upSEMdGl51pzgXhO6Fcig8UokOYHxV92SiQ0KEsCbc+oe8e9Gkr7g78tz+6YcTYLY2p2ygR7Vrh/WyTaUVnrNNqL8NIqp+Lc2kVtnqGXHFBJ0Wggaly+AeKWygy+dnOMEGSirhQ6/dUcB/Phz phfroidmont@archdesktop-2017-07-31