aboutsummaryrefslogtreecommitdiff
path: root/tharos
diff options
context:
space:
mode:
Diffstat (limited to 'tharos')
-rw-r--r--tharos/boot.nix51
-rw-r--r--tharos/caddy.nix29
-rw-r--r--tharos/cgit.nix99
-rw-r--r--tharos/default.nix49
-rw-r--r--tharos/nextcloud.nix106
-rw-r--r--tharos/security.nix46
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";
+ };
+ };
+ };
+ };
+}