diff --git a/flake.nix b/flake.nix index 389eca4..f8c151e 100755 --- a/flake.nix +++ b/flake.nix @@ -1,5 +1,5 @@ { - description = "NixOS Configurations"; + description = "Nettika's NixOS Configs"; inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05"; diff --git a/hosts/apogee/default.nix b/hosts/apogee/default.nix deleted file mode 100644 index f74e348..0000000 --- a/hosts/apogee/default.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ ... }: { - imports = [ ./gandicloud.nix ]; - - networking.hostName = "apogee"; - - promptSymbol = "🔭"; -} diff --git a/hosts/apogee/gandicloud.nix b/hosts/apogee/gandicloud.nix deleted file mode 100644 index 8df6e08..0000000 --- a/hosts/apogee/gandicloud.nix +++ /dev/null @@ -1,46 +0,0 @@ -# This is the configuration required to run NixOS on GandiCloud. -{ lib, modulesPath, ... }: { - imports = [ (modulesPath + "/virtualisation/openstack-config.nix") ]; - config = { - boot.initrd.kernelModules = [ - "xen-blkfront" - "xen-tpmfront" - "xen-kbdfront" - "xen-fbfront" - "xen-netfront" - "xen-pcifront" - "xen-scsifront" - ]; - - # Show debug kernel message on boot then reduce loglevel once booted - boot.consoleLogLevel = 7; - boot.kernel.sysctl."kernel.printk" = "4 4 1 7"; - - # For "openstack console log show" - boot.kernelParams = [ "console=ttyS0" ]; - systemd.services."serial-getty@ttyS0" = { - enable = true; - wantedBy = [ "multi-user.target" ]; - serviceConfig.Restart = "always"; - }; - - # The device exposed by Xen - boot.loader.grub.device = lib.mkForce "/dev/xvda"; - - # This is to get a prompt via the "openstack console url show" command - systemd.services."getty@tty1" = { - enable = lib.mkForce true; - wantedBy = [ "multi-user.target" ]; - serviceConfig.Restart = "always"; - }; - - # This is required to get an IPv6 address on our infrastructure - networking.tempAddresses = "disabled"; - - nix.extraOptions = '' - experimental-features = nix-command flakes - ''; - - system.stateVersion = "24.11"; - }; -} diff --git a/hosts/astral/default.nix b/hosts/astral/default.nix index 9bd5a71..c600557 100644 --- a/hosts/astral/default.nix +++ b/hosts/astral/default.nix @@ -1,8 +1,14 @@ -{ nixosModules, modulesPath, lib, pkgs, ... }: { +{ modulesPath, nixosModules, agenix, lib, pkgs, ... }: { imports = [ "${modulesPath}/virtualisation/amazon-image.nix" + nixosModules.nano nixosModules.nettika nixosModules.promptmoji + agenix.nixosModules.default + ./forgejo.nix + ./links.nix + ./radicale.nix + ./vaultwarden.nix ]; boot.loader.grub.device = lib.mkForce "/dev/nvme0n1"; @@ -13,23 +19,28 @@ dates = "weekly"; options = "--delete-older-than 30d"; }; - settings.trusted-users = [ "@wheel" ]; + settings = { + trusted-users = [ "@wheel" ]; + experimental-features = [ "nix-command" "flakes" ]; + }; }; networking = { hostName = "astral"; firewall.allowedTCPPorts = [ 80 443 ]; - networkmanager.enable = true; }; users.defaultUserShell = pkgs.fish; security.sudo.wheelNeedsPassword = false; - environment.variables.EDITOR = "nano"; - services.caddy = { enable = true; + package = pkgs.caddy.withPlugins { + plugins = + [ "github.com/abiosoft/caddy-exec@v0.0.0-20240914124740-521d8736cb4d" ]; + hash = "sha256-ef6/x7wjKk0axjX6MfAzTTwPM2FTOTSSyI9zLLrczV0="; + }; virtualHosts = { "astral.leaf.ninja".extraConfig = '' respond "astral is online" @@ -38,32 +49,13 @@ }; }; + services.postgresql.enable = true; + programs.fish.enable = true; - programs.git = { - enable = true; - lfs.enable = true; - config = { - init.defaultBranch = "master"; - user = { - email = "git@nettika.cat"; - name = "Nettika"; - }; - credential.helper = "store"; - }; - }; - - programs.nano = { - enable = true; - nanorc = '' - set autoindent - set linenumbers - ''; - }; - documentation.man.generateCaches = false; - promptSymbol = "✴️"; + promptSymbol = "👻"; time.timeZone = "America/Los_Angeles"; diff --git a/hosts/astral/forgejo.nix b/hosts/astral/forgejo.nix new file mode 100644 index 0000000..366bf7b --- /dev/null +++ b/hosts/astral/forgejo.nix @@ -0,0 +1,38 @@ +{ config, pkgs, ... }: +let domain = "git.leaf.ninja"; +in { + services.forgejo = { + enable = true; + database.type = "postgres"; + lfs.enable = true; + settings = { + server = { + DOMAIN = domain; + ROOT_URL = "https://${domain}/"; + HTTP_PORT = 3000; + }; + service.DISABLE_REGISTRATION = true; + mailer = { + ENABLED = true; + SMTP_ADDR = "smtp.migadu.com"; + FROM = "forgejo@leaf.ninja"; + USER = "forgejo@$leaf.ninja"; + }; + webhook.ALLOWED_HOST_LIST = + pkgs.lib.concatStringsSep "," [ "localhost" "::1" ]; + }; + secrets = { + mailer.PASSWD = config.age.secrets.forgejo-mailer-password.path; + }; + }; + + services.caddy.virtualHosts.${domain}.extraConfig = '' + reverse_proxy localhost:3000 + ''; + + age.secrets.forgejo-mailer-password = { + file = ./secrets/forgejo-mailer-password.age; + mode = "400"; + owner = "forgejo"; + }; +} diff --git a/hosts/astral/links.nix b/hosts/astral/links.nix new file mode 100644 index 0000000..fe836be --- /dev/null +++ b/hosts/astral/links.nix @@ -0,0 +1,21 @@ +{ pkgs, lib, ... }: +let + domain = "nettika.leaf.ninja"; + root = "/srv/links"; +in { + services.caddy.virtualHosts = { + ${domain}.extraConfig = '' + root * ${root} + file_server + ''; + "http://localhost:8081".extraConfig = let git = lib.getExe pkgs.git; + in '' + route { + exec { + command ${git} pull --rebase + directory ${root} + } + } + ''; + }; +} diff --git a/hosts/astral/radicale.nix b/hosts/astral/radicale.nix new file mode 100644 index 0000000..68d3c08 --- /dev/null +++ b/hosts/astral/radicale.nix @@ -0,0 +1,25 @@ +{ config, ... }: +let domain = "radicale.leaf.ninja"; +in { + age.secrets.radicale-htpasswd = { + file = ./secrets/radicale-htpasswd; + mode = "400"; + owner = "radicale"; + }; + + services.radicale = { + enable = true; + settings = { + server.hosts = [ "localhost:5232" ]; + auth = { + type = "htpasswd"; + htpasswd_filename = config.age.secrets.radicale-htpasswd.path; + htpasswd_encryption = "plain"; + }; + }; + }; + + services.caddy.virtualHosts.${domain}.extraConfig = '' + reverse_proxy localhost:5232 + ''; +} diff --git a/hosts/astral/secrets/forgejo-mailer-password.age b/hosts/astral/secrets/forgejo-mailer-password.age new file mode 100644 index 0000000..411e34a --- /dev/null +++ b/hosts/astral/secrets/forgejo-mailer-password.age @@ -0,0 +1,7 @@ +age-encryption.org/v1 +-> ssh-ed25519 f+PJrQ 6h8dfxbHOBbyTK6iwzbqVpUUYJtJhg6XMAoRWDhbdT8 +kZSsccA4qkiTS8wNdZphZ9cioiFbXjR4xkVZBi1j0aM +-> ssh-ed25519 nz/vnw Q+BuraNFun6RwcLPFcKcjBptgpZdddI+hQP2UVKFJmA +WJNvdIDTDBXbaXYw7gom7YQTTNrxlsP1EvTDNN5G9+0 +--- a6gvFS7YixX30i1Jm04vrwzq3Xh9iXufdnZMnPPI+Mw +ԇ]h6+2xD UZeAzDkL;I /'4nLT<4}i _݋ \ No newline at end of file diff --git a/hosts/astral/secrets/radicale-htpasswd b/hosts/astral/secrets/radicale-htpasswd new file mode 100644 index 0000000..36c140f --- /dev/null +++ b/hosts/astral/secrets/radicale-htpasswd @@ -0,0 +1,9 @@ +age-encryption.org/v1 +-> ssh-ed25519 f+PJrQ pKqLrqz0R7kAzNQZ3ChRsoWa63JEN2H2KHtGguF5nSc +6Mk1qDWKx26jPdEzaVMh0vgUeVWjAGcmIPpvSU8BFNE +-> ssh-ed25519 nz/vnw 0PuVNQ97Qa6iCk4pPf34lgS1aPb4CeDB4Qclk5F24T4 +OwJOYMTlTY9+Pj/BwG09z4q2/QViii710Kh3xPU5FRA +--- mSdutlC3gFq8lDjeOGqi361i+DUI1Yg6Bpl7hCfznJA +tQ/rNeKeѥ~ן{_o +y_ܭ}ûP*W5F.ECZ#; +liԧ*]yT \ No newline at end of file diff --git a/hosts/astral/secrets/vaultwarden-env.age b/hosts/astral/secrets/vaultwarden-env.age new file mode 100644 index 0000000..83accd1 Binary files /dev/null and b/hosts/astral/secrets/vaultwarden-env.age differ diff --git a/hosts/astral/vaultwarden.nix b/hosts/astral/vaultwarden.nix new file mode 100644 index 0000000..1041d65 --- /dev/null +++ b/hosts/astral/vaultwarden.nix @@ -0,0 +1,25 @@ +{ config, ... }: +let domain = "vault.leaf.ninja"; +in { + services.vaultwarden = { + enable = true; + config = { + domain = "https://${domain}"; + signupsAllowed = false; + rocketAddress = "0.0.0.0"; + rocketPort = 8222; + smtpHost = "smtp.migadu.com"; + smtpFrom = "vaultwarden@leaf.ninja"; + smtpPort = 587; + smtpSecurity = "starttls"; + smtpUsername = "vaultwarden@leaf.ninja"; + }; + environmentFile = config.age.secrets.vaultwarden-env.path; + }; + + services.caddy.virtualHosts.${domain}.extraConfig = '' + reverse_proxy localhost:8222 + ''; + + age.secrets.vaultwarden-env.file = ./secrets/vaultwarden-env.age; +} diff --git a/hosts/default.nix b/hosts/default.nix index 3795651..1b52d15 100644 --- a/hosts/default.nix +++ b/hosts/default.nix @@ -1,17 +1,24 @@ -{ self, nixpkgs, phps, agenix, ... }: -let inherit (nixpkgs.lib) nixosSystem; +{ self, nixpkgs, phps, agenix }: +let + baseSpecialArgs = { + inherit (self) nixosModules; + inherit agenix; + }; + nixosSystem = args: + nixpkgs.lib.nixosSystem + (nixpkgs.lib.recursiveUpdate args { specialArgs = baseSpecialArgs; }); in { marauder = nixosSystem { system = "x86_64-linux"; modules = [ ./marauder ]; - specialArgs = { - inherit (self) nixosModules; - inherit phps agenix; - }; + specialArgs = { inherit phps; }; }; astral = nixosSystem { system = "x86_64-linux"; modules = [ ./astral ]; - specialArgs = { inherit (self) nixosModules; }; + }; + quasar = nixosSystem { + system = "x86_64-linux"; + modules = [ ./quasar ]; }; } diff --git a/hosts/marauder/default.nix b/hosts/marauder/default.nix index 712e12d..ab09178 100755 --- a/hosts/marauder/default.nix +++ b/hosts/marauder/default.nix @@ -11,6 +11,7 @@ let in { imports = [ ./backup.nix + nixosModules.nano nixosModules.nettika nixosModules.promptmoji agenix.nixosModules.default @@ -30,8 +31,6 @@ in { nixpkgs.config.allowUnfree = true; - environment.variables.EDITOR = "nano"; - documentation.man.generateCaches = false; environment.variables = { @@ -77,6 +76,7 @@ in { }; kernelModules = [ "kvm-amd" ]; kernelParams = [ "amd_pstate=active" ]; + binfmt.emulatedSystems = [ "aarch64-linux" ]; }; hardware = { @@ -103,69 +103,74 @@ in { environment.systemPackages = with pkgs; [ # Chat clients discord - slack - element-desktop - telegram-desktop + cinny-desktop signal-desktop + slack + telegram-desktop # Browsers - firefox filezilla + firefox # Creative - inkscape + bambu-studio + blender gimp + inkscape krita openscad-unstable - bambu-studio orca-slicer + plasticity # Multimedia - vlc - ffmpeg ffcheck - aonsoku + ffmpeg + vlc - # Code Editors + # Editors + abiword + obsidian vscode - arduino-ide # Dev Tools + fossil + just + kondo nixd nixfmt-classic nixpkgs-fmt pyenv rustup - electron - uv - ruff - fossil - just - dioxus-cli # Languages - gcc kotlin nodejs php # Command line + agenix.packages.x86_64-linux.default + backblaze-b2 + dig htop jq - backblaze-b2 + unzip + zip - # Misc - obsidian - intiface-central - prismlauncher - blender + # Network mullvad-vpn qbittorrent + + # Utility Apps + baobab + gparted system-config-printer + + # Misc + gcc + intiface-central openssl pkg-config - agenix.packages.x86_64-linux.default - abiword + prismlauncher ]; programs.git = { @@ -173,22 +178,15 @@ in { lfs.enable = true; config = { init.defaultBranch = "master"; + push.autoSetupRemote = true; user = { - email = "git@nettika.cat"; name = "Nettika"; + email = "git@nettika.cat"; }; credential.helper = "store"; }; }; - programs.nano = { - enable = true; - nanorc = '' - set autoindent - set linenumbers - ''; - }; - programs.steam = { enable = true; remotePlay.openFirewall = true; @@ -199,7 +197,7 @@ in { programs.ssh.extraConfig = '' Host quasar - HostName consortium.chat + HostName quasar.leaf.ninja IdentityFile ~/.ssh/LightsailDefaultKey-us-west-2.pem Host monolith @@ -208,9 +206,6 @@ in { Host astral HostName astral.leaf.ninja IdentityFile ~/.ssh/LightsailDefaultKey-us-west-2.pem - - Host apogee - HostName 46.226.107.209 ''; services.mysql = { diff --git a/hosts/marauder/secrets/restic-env.age b/hosts/marauder/secrets/restic-env.age index 1d93a5d..55e4f77 100644 --- a/hosts/marauder/secrets/restic-env.age +++ b/hosts/marauder/secrets/restic-env.age @@ -1,5 +1,6 @@ age-encryption.org/v1 --> ssh-ed25519 f+PJrQ qccE2xAzfBZ3DCRQtQDgwS1UzjlZx44oUrYjcDfMfDk -I2l6xRJsdQLYB2cMo0Kfi6mVyhZsuSPFG574P8pl12Y ---- WoBlo7fqYRkiBYPoLpa3wHB8ZPCVy32a4aL5UswCHJc -LΚ[N<#] B}f%PxKۨkI ssh-ed25519 f+PJrQ VJshLBSbF93anR9fOJ3Kwhxh1AOdvsS0hoJ86Bw9oBQ +It8hELrRN+EYt9nv75lVHha+ZDUhCDNQVczDZVlDCBs +--- xzJ/50+WOA+IWRXiAvBbJLUlsgsSztQrzbimng2QdlU +Ϭjҍ8K7$wbԲǰ~]NB]QM+cw +Jo͔Sؚ!NDuOnZnNѵV:kc)|JopSHfu19 \ No newline at end of file diff --git a/hosts/marauder/secrets/restic-password.age b/hosts/marauder/secrets/restic-password.age index 58bbd5c..6722ce5 100644 Binary files a/hosts/marauder/secrets/restic-password.age and b/hosts/marauder/secrets/restic-password.age differ diff --git a/hosts/quasar/default.nix b/hosts/quasar/default.nix new file mode 100644 index 0000000..e997ebf --- /dev/null +++ b/hosts/quasar/default.nix @@ -0,0 +1,49 @@ +{ modulesPath, nixosModules, agenix, pkgs, config, ... }: { + imports = [ + "${modulesPath}/virtualisation/amazon-image.nix" + nixosModules.nano + nixosModules.nettika + nixosModules.promptmoji + agenix.nixosModules.default + ./matrix.nix + ]; + + nixpkgs.config.allowUnfree = true; + + nix.settings = { + experimental-features = [ "nix-command" "flakes" ]; + trusted-users = [ "@wheel" ]; + }; + + security.sudo.wheelNeedsPassword = false; + + users.defaultUserShell = pkgs.fish; + + networking = { + hostName = "quasar"; + networkmanager.enable = true; + firewall.allowedTCPPorts = [ 80 443 ]; + }; + + environment.systemPackages = [ pkgs.htop ]; + + services.postgresql.enable = true; + + services.caddy = { + enable = true; + virtualHosts."quasar.leaf.ninja".extraConfig = '' + respond "quasar is online" + header Strict-Transport-Security: "max-age=63072000; includeSubDomains" + ''; + }; + + programs.fish.enable = true; + + promptSymbol = "🌟"; + + documentation.man.generateCaches = false; + + time.timeZone = "America/Los_Angeles"; + + system.stateVersion = "24.05"; +} diff --git a/hosts/quasar/matrix.nix b/hosts/quasar/matrix.nix new file mode 100644 index 0000000..9bb6fa5 --- /dev/null +++ b/hosts/quasar/matrix.nix @@ -0,0 +1,46 @@ +{ pkgs, config, ... }: +let + canonicalDomain = "consortium.chat"; + delegatedDomain = "matrix.consortium.chat"; + adminAppDomain = "admin.consortium.chat"; +in { + age.secrets.matrix-synapse-secrets = { + file = ./secrets/matrix-synapse-secrets.yaml; + owner = "matrix-synapse"; + mode = "400"; + }; + + services.matrix-synapse = { + enable = true; + settings = { + server_name = "consortium.chat"; + database_type = "psycopg2"; + database_args.database = "matrix-synapse"; + }; + extraConfigFiles = [ config.age.secrets.matrix-synapse-secrets.path ]; + }; + + services.caddy.virtualHosts = { + ${canonicalDomain}.extraConfig = let + wellknown = { + server = builtins.toJSON { "m.server" = "${delegatedDomain}:443"; }; + client = builtins.toJSON { + "m.homeserver".base_url = "https://${delegatedDomain}"; + }; + }; + in '' + respond /.well-known/matrix/server `${wellknown.server}` 200 + respond /.well-known/matrix/client `${wellknown.client}` 200 + reverse_proxy localhost:8008 + header Strict-Transport-Security "max-age=63072000; includeSubDomains" + ''; + ${delegatedDomain}.extraConfig = '' + reverse_proxy /_matrix/* localhost:8008 + reverse_proxy /_synapse/client/* localhost:8008 + ''; + ${adminAppDomain}.extraConfig = '' + root * ${pkgs.synapse-admin} + file_server + ''; + }; +} diff --git a/hosts/quasar/secrets/matrix-synapse-secrets.yaml b/hosts/quasar/secrets/matrix-synapse-secrets.yaml new file mode 100644 index 0000000..22adf92 Binary files /dev/null and b/hosts/quasar/secrets/matrix-synapse-secrets.yaml differ diff --git a/hosts/readme.md b/hosts/readme.md new file mode 100644 index 0000000..8b01a00 --- /dev/null +++ b/hosts/readme.md @@ -0,0 +1,6 @@ +# Hosts + +- [astral](astral) - VPS running miscellaneous servers +- [marauder](marauder) - My laptop +- [quasar](quasar) - VPS running the [consortium.chat](https://consortium.chat) + matrix-synapse instance \ No newline at end of file diff --git a/modules/default.nix b/modules/default.nix index f900622..dd877a2 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -1,4 +1,5 @@ { + nano = ./nano.nix; nettika = ./nettika.nix; promptmoji = ./promptmoji.nix; } diff --git a/modules/nano.nix b/modules/nano.nix new file mode 100644 index 0000000..a700807 --- /dev/null +++ b/modules/nano.nix @@ -0,0 +1,11 @@ +{ ... }: { + environment.variables.EDITOR = "nano"; + + programs.nano = { + enable = true; + nanorc = '' + set autoindent + set linenumbers + ''; + }; +} diff --git a/modules/readme.md b/modules/readme.md new file mode 100644 index 0000000..a54b0c6 --- /dev/null +++ b/modules/readme.md @@ -0,0 +1,7 @@ +# Modules + +- `nano`: Base config for [nano](https://www.nano-editor.org) +- `nettika`: Base config for user "nettika" +- `promptmoji`: Fish prompt starting with an emoji to indicate which host I'm + logged into. The emoji is configured with `promptSymbol`. Ignored if + `programs.fish.enabled` is false. \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..b96399f --- /dev/null +++ b/readme.md @@ -0,0 +1,4 @@ +# Nettika's NixOS Configs + +- [hosts](hosts) - my `nixosConfigurations` +- [modules](modules) - my `nixosModules` \ No newline at end of file diff --git a/secrets.nix b/secrets.nix index 493de1b..33a040c 100644 --- a/secrets.nix +++ b/secrets.nix @@ -1,8 +1,17 @@ let - marauder.nettika = + marauder = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHopty1QG8P+OfGxQ9CV0BI1IRB/q6yITzMZaZ6Zspid"; + astral = + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILRJf6qsNoITXPBdiFsmZuLR0dyP/D6WYNP/RQynl3kf"; + quasar = + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOoVsKoMEiA2G0WIC/6gFsNE09yhumWf4xnDuoRcD2Px"; in { - "hosts/marauder/secrets/restic-env.age".publicKeys = [ marauder.nettika ]; - "hosts/marauder/secrets/restic-password.age".publicKeys = - [ marauder.nettika ]; + "hosts/marauder/secrets/restic-env.age".publicKeys = [ marauder ]; + "hosts/marauder/secrets/restic-password.age".publicKeys = [ marauder ]; + "hosts/quasar/secrets/matrix-synapse-secrets.yaml".publicKeys = + [ marauder quasar ]; + "hosts/astral/secrets/vaultwarden-env.age".publicKeys = [ marauder astral ]; + "hosts/astral/secrets/forgejo-mailer-password.age".publicKeys = + [ marauder astral ]; + "hosts/astral/secrets/radicale-htpasswd".publicKeys = [ marauder astral ]; }