diff --git a/deployment/LICENSE.md b/deployment/LICENSE.md new file mode 100644 index 0000000..215ac7a --- /dev/null +++ b/deployment/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 TiMMi Transport + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/deployment/README.md b/deployment/README.md new file mode 100644 index 0000000..87834a6 --- /dev/null +++ b/deployment/README.md @@ -0,0 +1,71 @@ +This repository contains the completely declarative+reproducible configurations to deploy a server hosting the „beherbergung“ service and basic infrastructure for reliabiliy+maintainability. +Most of the service definitions should re reusable with minimal adaptions for completely different projects. + +* CI/CD +* buildcache +* [monitoring + alerting](./modules/monitoring/README.md) +* backup +* dns +* reverse proxy + acme + +Secrets are encrypted with sops. + +## Deploy + +Once the servers are installed following [the bootstrap instructions](#bootstrap), the roll out of configuration changes on all servers is trivial. +As a developer with an [authorized key](./modules/hetzner.nix), call: + +```shell +nix run +``` + +## Update + +To update all flakes and redeploy, call: + +```shell +nix flake update +nix run +``` + +## Bootstrap + +To setup a new server: +1. boot a nixos image +2. mount the future / to /mnt +3. copy this repo to /mnt/etc/nixos +4. check flake.nix and hosts/$HOSTNAME/\*configuration.nix + - set a correct static ipv6 +5. nixos-install: + +```shell +nix-shell -p nixUnstable --command "nixos-install --no-root-passwd --flake .#${HOSTNAME}" +``` + +6. setup sops: + +6.1. add the new hosts key to sops config + +```shell +nix shell /etc/nixos#ssh-to-pgp --command ssh-to-pgp -i /etc/ssh/ssh_host_rsa_key +edit .sops.yaml sops/keys/hosts/$HOSTNAME.asc +``` + +6.2. add pubkey to the developers keyring +```shell +gpg --import sops/keys/hosts/$HOSTNAME.asc +``` + +6.3. edit secrets + use them + +```shell +nix shell .#sops --command sops sops/secrets/* +edit modules/sops.nix +``` + +## Ensure, outgoing SMTP is permitted by your hoster: + +```shell +openssl s_client -connect smtp.1und1.de:587 -starttls smtp +openssl s_client -connect smtp.1und1.de:465 +``` diff --git a/deployment/hosts/beherbergung-lifeline/configuration.nix b/deployment/hosts/beherbergung-lifeline/configuration.nix new file mode 100644 index 0000000..07de3b6 --- /dev/null +++ b/deployment/hosts/beherbergung-lifeline/configuration.nix @@ -0,0 +1,15 @@ +{ config, pkgs, ... }: +{ + imports = [ + ../../modules/hetzner.nix + ]; + + system.stateVersion = "21.11"; + + networking = { + hostName = "beherbergung-lifeline"; + interfaces.ens3 = { + ipv6.addresses = [ { address = "2a01:4f8:c0c:cf13::1"; prefixLength = 64; } ]; + }; + }; +} diff --git a/deployment/modules/default.nix b/deployment/modules/default.nix new file mode 100644 index 0000000..19efea1 --- /dev/null +++ b/deployment/modules/default.nix @@ -0,0 +1,15 @@ +{ config, pkgs, ... }: +{ + time.timeZone = "Europe/Berlin"; + + environment.systemPackages = with pkgs; [ + vim tmux + wget curl + htop atop iotop iftop + file bc jq + git + bind.dnsutils + ]; + + environment.variables = { EDITOR = "vim"; }; +} diff --git a/deployment/modules/hetzner.nix b/deployment/modules/hetzner.nix new file mode 100644 index 0000000..fbfe2ec --- /dev/null +++ b/deployment/modules/hetzner.nix @@ -0,0 +1,48 @@ +## a common hardware-configuration.nix for our hetzner servers + +{ config, lib, pkgs, modulesPath, ... }: +{ + imports = [ (modulesPath + "/profiles/qemu-guest.nix") ]; + + boot.initrd.availableKernelModules = [ "ata_piix" "virtio_pci" "virtio_scsi" "xhci_pci" "sd_mod" "sr_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = { + device = "/dev/sda1"; + fsType = "ext4"; + }; + + swapDevices = [ ]; + + boot.loader.grub = { + enable = true; + version = 2; + devices = [ "/dev/sda" ]; + }; + + networking = { + useDHCP = false; + interfaces.ens3 = { + useDHCP = true; + #ipv6.addresses ## should be set for each host + }; + defaultGateway6 = { + address = "fe80::1"; + interface = "ens3"; + }; + }; + + users.users.root = { + openssh.authorizedKeys.keys = [ + ## J03 + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDW+YfsFtRz1h/0ubcKU+LyGfxH505yUkbWa5VtRFNWF2fjTAYGj6o5M4dt+fv1h370HXvvOBtt8sIlWQgMsD10+9mvjdXWhTcpnYPx4yWuyEERE1/1BhItrog6XJKAedbCDpQQ+POoewouiHWVAUfFByPj5RXuE8zKUeIEkGev/QKrKTLnTcS8zFs/yrokf1qYYR571B3U8IPDjpV/Y1GieG3MSNaefIMCwAAup1gPkUA0XZ4A1L7NdEiUEHlceKVu9eYiWUM+wDRunBXnLHubeGyP8KmBA7PNKgml3WWRNTZjqNQk4u9Bl+Qea5eCkD8KI257EqgXYXy0QBWNyF8X j03@l302" + ]; + }; + + services.openssh = { + enable = true; + permitRootLogin = "prohibit-password"; + }; +} diff --git a/deployment/modules/nix.nix b/deployment/modules/nix.nix new file mode 100644 index 0000000..6867142 --- /dev/null +++ b/deployment/modules/nix.nix @@ -0,0 +1,16 @@ +{ config, pkgs, nixpkgs, ... }: +{ + boot.cleanTmpDir = true; + + nix.package = pkgs.nixUnstable; + nix.extraOptions = "experimental-features = nix-command flakes"; + + #nix.daemonIONiceLevel = 7; + #nix.daemonNiceLevel = 19; + + nix.autoOptimiseStore = true; + nix.gc = { + automatic = true; + dates = "weekly"; + }; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..9fce575 --- /dev/null +++ b/flake.lock @@ -0,0 +1,107 @@ +{ + "nodes": { + "dns": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1635273082, + "narHash": "sha256-EHiDP2jEa7Ai5ZwIf5uld9RVFcV77+2SUxjQXwJsJa0=", + "owner": "kirelagin", + "repo": "dns.nix", + "rev": "c7b9645da9c0ddce4f9de4ef27ec01bb8108039a", + "type": "github" + }, + "original": { + "owner": "kirelagin", + "repo": "dns.nix", + "type": "github" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1614513358, + "narHash": "sha256-LakhOx3S1dRjnh0b5Dg3mbZyH0ToC9I8Y2wKSkBaTzU=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5466c5bbece17adaab2d82fae80b46e807611bf3", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nix-deploy-git": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1637044180, + "narHash": "sha256-5r3pOGql5wr0PtuOb0rJ0EeorcT3A43tWYRRvnZB0jk=", + "owner": "johannesloetzsch", + "repo": "nix-deploy-git", + "rev": "c1c0b1def56009e8647bfe57c555c6bea0fb2b1a", + "type": "github" + }, + "original": { + "owner": "johannesloetzsch", + "ref": "main", + "repo": "nix-deploy-git", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1646588256, + "narHash": "sha256-ZHljmNlt19nSm0Mz8fx6QEhddKUkU4hhwFmfNmGn+EY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "2ebb6c1e5ae402ba35cca5eec58385e5f1adea04", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-21.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "dns": "dns", + "nix-deploy-git": "nix-deploy-git", + "nixpkgs": "nixpkgs", + "sops-nix": "sops-nix" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1646696263, + "narHash": "sha256-a+6WgDoU2fd4bbSFMqK67i/ZTPzia29otmyeODa1uDU=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "4e21493d34f7485a568e05b9cbefa11fe047ecd3", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..d857ff3 --- /dev/null +++ b/flake.nix @@ -0,0 +1,64 @@ +{ + description = "https://github.com/internet4refugees/beherbergung.git development environment + package + deployment"; + + inputs = { + #nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-21.11"; + sops-nix = { + url = "github:Mic92/sops-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + nix-deploy-git = { + url = "github:johannesloetzsch/nix-deploy-git/main"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + dns = { + url = "github:kirelagin/dns.nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { self, nixpkgs, sops-nix, nix-deploy-git, dns }: + let + system = "x86_64-linux"; + pkgs = import nixpkgs { inherit system; }; + inherit (pkgs) lib; + + commonAttrs = { + system = "x86_64-linux"; + extraArgs = { flake = self; inherit system dns; }; + }; + commonModules = [ + ./deployment/modules/nix.nix + ./deployment/modules/default.nix + #sops-nix.nixosModules.sops + #./deployment/modules/sops.nix + #./deployment/modules/dns.nix + #./deployment/modules/monitoring/client.nix + #./deployment/modules/nginx/timmi.nix + #nix-deploy-git.nixosModule + #./deployment/modules/nix-deploy-git.nix + ]; + in + rec { + legacyPackages.${system} = (lib.mergeAttrs pkgs { + #nixos-deploy = import ./tools/deploy.nix { inherit pkgs; }; + }); + + #defaultPackage.${system} = legacyPackages.${system}.nixos-deploy; + + nixosConfigurations = { + + beherbergung-lifeline = nixpkgs.lib.nixosSystem (lib.mergeAttrs commonAttrs { + modules = commonModules ++ [ + ./deployment/hosts/beherbergung-lifeline/configuration.nix + #./deployment/modules/nginx/timmi-public.nix + #./deployment/modules/binarycache/client.nix + #./deployment/modules/binarycache/server.nix + #./deployment/modules/monitoring/server.nix + ]; + }); + + }; + }; +}