diff options
Diffstat (limited to 'tharos')
| -rw-r--r-- | tharos/boot.nix | 51 | ||||
| -rw-r--r-- | tharos/caddy.nix | 29 | ||||
| -rw-r--r-- | tharos/cgit.nix | 99 | ||||
| -rw-r--r-- | tharos/default.nix | 49 | ||||
| -rw-r--r-- | tharos/nextcloud.nix | 106 | ||||
| -rw-r--r-- | tharos/security.nix | 46 |
6 files changed, 380 insertions, 0 deletions
diff --git a/tharos/boot.nix b/tharos/boot.nix new file mode 100644 index 0000000..1843e63 --- /dev/null +++ b/tharos/boot.nix @@ -0,0 +1,51 @@ +{ inputs, ... }: +{ + flake.machines.tharos = { + nixos = + { + modulesPath, + ... + }: + { + imports = [ + inputs.disko.nixosModules.default + "${modulesPath}/profiles/qemu-guest.nix" + ]; + disko.devices.disk.main = { + device = "/dev/vda"; + type = "disk"; + content = { + type = "gpt"; + partitions = { + # Die KVM läuft auf SeaBIOS, daher muss es hier eine MBR-Partition sein + boot = { + size = "1M"; + type = "EF02"; + }; + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + + /* + ANMERKUNG: Erhalten durch: + + nix run .#machines.infect-tharos -- --no-reboot --generate-hardware-config nixos-hardware-config <datei> + */ + boot.initrd.availableKernelModules = [ + "ata_piix" + "uhci_hcd" + "virtio_pci" + "virtio_blk" + ]; + boot.kernelModules = [ "kvm-amd" ]; + }; + }; +} diff --git a/tharos/caddy.nix b/tharos/caddy.nix new file mode 100644 index 0000000..fc152c7 --- /dev/null +++ b/tharos/caddy.nix @@ -0,0 +1,29 @@ +{ self, ... }: +{ + flake.domain = "heimfeld.hamburg"; + flake.machines.tharos = { + nixos = + { ... }: + { + networking.firewall.allowedTCPPorts = [ + 80 + 443 + ]; + + services.caddy = { + enable = true; + email = "redaktion@${self.domain}"; + }; + }; + + vm = + { pkgs, ... }: + { + services.caddy.globalConfig = '' + local_certs + ''; + + systemd.services.caddy.path = [ pkgs.nssTools ]; # Irrelevante Warnung unterdrücken + }; + }; +} diff --git a/tharos/cgit.nix b/tharos/cgit.nix new file mode 100644 index 0000000..b4a75c3 --- /dev/null +++ b/tharos/cgit.nix @@ -0,0 +1,99 @@ +{ self, ... }: +{ + + flake.machines.tharos = + let + path = "/git/infra"; + in + { + nixos = + { + config, + pkgs, + lib, + ... + }: + let + cgit = config.services.cgit.infra.nginx.virtualHost; + nginx = lib.head config.services.nginx.virtualHosts.${cgit}.listen; + in + { + users.groups.git = { }; + users.users = lib.mapAttrs (_: _': { extraGroups = [ "git" ]; }) self.keys; + environment.systemPackages = with pkgs; [ git ]; + + systemd.services.init-git-repos = { + wantedBy = [ "multi-user.target" ]; + before = [ "cgit.service" ]; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + + script = '' + if [ ! -f ${path} ]; then + ${lib.getExe pkgs.git} init --shared=group --bare ${path} + fi + ''; + }; + + systemd.tmpfiles.rules = [ + "d ${path} 2775 root git -" + ]; + + services.cgit.infra = rec { + enable = true; + nginx.virtualHost = "git.${self.domain}"; + repos.infra = { + desc = "Quellcode für die technische Infrastruktur des Stadtteilbeirats Heimfeld"; + inherit path; + clone-url = "https://${nginx.virtualHost}/$CGIT_REPO_URL ssh://${self.domain}${path}"; + }; + settings = { + about-filter = "${pkgs.cgit}/lib/cgit/filters/about-formatting.sh"; + readme = ":README.md"; + enable-commit-graph = true; + }; + }; + services.nginx.virtualHosts.${cgit}.listen = [ + { + addr = "127.0.0.1"; + port = 8083; + } + ]; + services.caddy.virtualHosts.${cgit}.extraConfig = '' + reverse_proxy localhost:${toString nginx.port} + ''; + }; + vm = + { + config, + lib, + ... + }: + let + httpPort = 700; + cgit = config.services.cgit.infra.nginx.virtualHost; + in + { + services.cgit.infra = { + nginx.virtualHost = lib.mkForce "git.localhost"; + + repos.infra.clone-url = lib.mkForce "http://${cgit}:${ + with config.virtualisation; toString (portOffset + exposedPorts.http.port) + }/$CGIT_REPO_URL ssh://localhost:${ + toString (config.virtualisation.portOffset + lib.head config.services.openssh.ports) + }${path}"; + }; + + services.caddy.virtualHosts = { + "http://${cgit}:${toString config.virtualisation.exposedPorts.http.port}".extraConfig = + config.services.caddy.virtualHosts.${cgit}.extraConfig; + }; + services.getty.helpLine = lib.mkBefore '' + cgit: http://${cgit}:${with config.virtualisation; toString (portOffset + exposedPorts.http.port)} + ''; + }; + }; +} diff --git a/tharos/default.nix b/tharos/default.nix new file mode 100644 index 0000000..65f2024 --- /dev/null +++ b/tharos/default.nix @@ -0,0 +1,49 @@ +{ + self, + ... +}: +{ + flake.machines.tharos = { + bootstrap-target = "root@${self.machines.tharos.deploy-target}"; + # Administratoren verbinden sich mit ihrem selbst festgelegten Nutzernamen + deploy-target = "81.169.239.254"; + nixos = + { ... }: + { + nixpkgs.hostPlatform = "x86_64-linux"; + system.stateVersion = "25.05"; + + services.cloud-init = { + enable = true; + network.enable = true; + }; + # `cloud-init` übernimmt Netzwerkeinstellungen + networking.useDHCP = false; + + nix = { + settings.trusted-users = [ + "root" + "@wheel" + ]; + settings.experimental-features = [ + "nix-command" + "flakes" + ]; + }; + }; + + vm = + { lib, ... }: + { + virtualisation = { + memorySize = 4096; + diskSize = 4096; + cores = 2; + graphics = false; + }; + + services.cloud-init.enable = lib.mkForce false; + networking.useDHCP = lib.mkForce true; + }; + }; +} diff --git a/tharos/nextcloud.nix b/tharos/nextcloud.nix new file mode 100644 index 0000000..eedb507 --- /dev/null +++ b/tharos/nextcloud.nix @@ -0,0 +1,106 @@ +{ self, ... }: +{ + flake.machines.tharos = { + nixos = + { config, lib, ... }: + let + apps = config.services.nextcloud.package.packages.apps; + nextcloud = config.services.nextcloud.hostName; + nginx = lib.head config.services.nginx.virtualHosts.${nextcloud}.listen; + in + { + services.nextcloud = { + enable = true; + hostName = "nextcloud.${self.domain}"; + database.createLocally = true; + config.dbtype = "pgsql"; + extraAppsEnable = true; + extraApps = { + inherit (apps) + contacts + calendar + tables + spreed # Videokonferenzen + # cospend # Rudimentäre Buchhaltung + # deck # Issue-Tracker + ; + }; + settings = { + trusted_proxies = [ nginx.addr ]; + mail_smtpmode = "smtp"; + mail_smtphost = "smtp.tharos-net.de"; + mail_smtpport = 587; + mail_smtpauth = true; + mail_smtptimeout = 30; + mail_smtpname = "nextcloud@${self.domain}"; + mail_from_address = "nextcloud"; + mail_domain = self.domain; + mail_smtpstreamoptions = { + /* + ACHTUNG: Hier ist Angriffsfläche! + Dringend den Mailserver ordentlich einrichten! + */ + ssl = { + allow_self_signed = true; + verify_peer = false; + verify_peer_name = false; + }; + }; + }; + /* + Vor erstmaligem Anwenden der Konfiguration: + + echo $PASSWORT | ssh tharos 'sudo install -m 600 /dev/stdin /var/lib/nextcloud/initialrootpassword' + cat $SECRETS | ssh tharos 'sudo install -m 600 -o nextcloud -g nextcloud /dev/stdin /var/lib/nextcloud/secrets.json' + + Die Dateien bleiben auf dem System! + Das einmalige Root-Passwort wird nicht wieder verwendet. + + Besser wäre natürlich zentralisiertes Management von geheimen Daten. + */ + secretFile = "/var/lib/nextcloud/secrets.json"; + config.adminpassFile = "/var/lib/nextcloud/initialrootpassword"; + }; + services.nginx.virtualHosts.${nextcloud} = { + listen = [ + { + addr = "127.0.0.1"; + port = 8080; + } + ]; + }; + services.caddy = { + virtualHosts.${nextcloud}.extraConfig = '' + reverse_proxy http://${nginx.addr}:${toString nginx.port} + ''; + }; + }; + vm = + { config, lib, ... }: + + let + nextcloud = config.services.nextcloud.hostName; + in + { + services.nextcloud = { + https = lib.mkForce false; + hostName = lib.mkForce "nextcloud.localhost"; + }; + + systemd.tmpfiles.rules = [ + "f /var/lib/nextcloud/secrets.json 0600 nextcloud nextcloud - {}" + "f /var/lib/nextcloud/initialrootpassword 0600 nextcloud nextcloud - root" + ]; + + services.caddy.virtualHosts = { + "http://${nextcloud}:${toString config.virtualisation.exposedPorts.http.port}".extraConfig = + config.services.caddy.virtualHosts.${nextcloud}.extraConfig; + }; + services.getty.helpLine = lib.mkBefore '' + Nextcloud: http://${nextcloud}:${ + with config.virtualisation; toString (portOffset + exposedPorts.http.port) + } + ''; + }; + }; +} diff --git a/tharos/security.nix b/tharos/security.nix new file mode 100644 index 0000000..03b59dc --- /dev/null +++ b/tharos/security.nix @@ -0,0 +1,46 @@ +{ + self, + inputs, + ... +}: +{ + flake.machines.tharos = { + nixos = + { + lib, + modulesPath, + ... + }: + { + # Kein Login für Nutzer die nicht explizit deklariert sind + users.mutableUsers = false; + users.users = lib.mapAttrs (username: keyFiles: { + isNormalUser = true; + openssh.authorizedKeys.keyFiles = keyFiles; + # ANMERKUNG: Der Einfachheit halber sind bis auf Weiteres alle Nutzer mit SSH-Zugang auch Administratoren + extraGroups = [ "wheel" ]; + }) self.keys; + + /* + `sudo` über SSH ohne Passworteingabe + ANMERKUNG: Nutzer sollten in ihrem ` ~/.ssh/config` für die Maschine einstellen: + + ForwardAgent: yes + */ + security.pam.sshAgentAuth.enable = true; + security.pam.services.sudo.sshAgentAuth = true; + + # Nur Administratoren können den angemeldeten Benutzer wechseln + security.pam.services.su.requireWheel = true; + + networking.firewall.allowPing = true; + services.openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + PermitRootLogin = "prohibit-password"; + }; + }; + }; + }; +} |
