diff --git a/hosts/server/hikari/hako/configuration.nix b/hosts/server/hikari/hako/configuration.nix index 4158120..cfa72a9 100644 --- a/hosts/server/hikari/hako/configuration.nix +++ b/hosts/server/hikari/hako/configuration.nix @@ -1,4 +1,34 @@ -{ pkgs, inputs, ... }: +{ lib, pkgs, inputs, ... }: +let + concordSession = pkgs.writeShellScriptBin "concord-session" '' + set -eu + + runtime_dir="''${XDG_RUNTIME_DIR:-/tmp}" + session_dir="$(mktemp -d "$runtime_dir/concord-session.XXXXXX")" + + cleanup() { + rm -rf -- "$session_dir" + } + + trap cleanup EXIT + trap 'exit 129' HUP + trap 'exit 130' INT + trap 'exit 143' TERM + + config_home="$session_dir/config" + state_home="$session_dir/state" + mkdir -p "$config_home" "$state_home" + + cat > "$config_home/config.toml" <<'EOF' +[credentials] +store = "plain" +EOF + + XDG_CONFIG_HOME="$config_home" \ + XDG_STATE_HOME="$state_home" \ + "${inputs.concord.packages.${pkgs.system}.default}/bin/concord" "$@" + ''; +in { imports = [ ./hardware-configuration.nix @@ -29,6 +59,24 @@ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOHP3Z+AYrRh9f8TYyqChKfeyNm3lOe0F75AwRHTTaxD imnyang@kazusa" ]; + users.users.discord = { + isNormalUser = true; + description = "Ephemeral Concord session user"; + shell = pkgs.bashInteractive; + password = ""; + }; + + services.openssh.extraConfig = '' + Match User discord + AuthenticationMethods none + PasswordAuthentication yes + PermitEmptyPasswords yes + ForceCommand ${concordSession}/bin/concord-session + DisableForwarding yes + PermitTTY yes + PermitUserRC no + ''; + environment.systemPackages = with pkgs; [ eza neovim @@ -44,6 +92,19 @@ networking.firewall.enable = false; + # Keep short-lived service memory spikes from turning into a global OOM. + # The host has 8 GiB RAM and currently had no swap configured. + swapDevices = [ + { + # nixpkgs currently requires a label definition for swap submodules, + # but file-backed swap must still use its real path here. + label = "hako-swap"; + device = lib.mkForce "/swapfile"; + } + ]; + + boot.kernel.sysctl."vm.swappiness" = 10; + # /dev/sdd1 (ext4, UUID efdf753d-282c-4b78-9549-a124b353c6a5) fileSystems."/mnt/static" = { device = "/dev/disk/by-uuid/efdf753d-282c-4b78-9549-a124b353c6a5"; diff --git a/hosts/server/hikari/hako/home.nix b/hosts/server/hikari/hako/home.nix index 60c49a2..bcf93b9 100644 --- a/hosts/server/hikari/hako/home.nix +++ b/hosts/server/hikari/hako/home.nix @@ -6,34 +6,6 @@ let nr = import "${inputs.self}/modules/mizukios/features/packages/nr.nix" { inherit pkgs; }; nrr = import "${inputs.self}/modules/mizukios/features/packages/nrr.nix" { inherit pkgs; }; - concord = pkgs.writeShellScriptBin "concord" '' - set -eu - - runtime_dir="''${XDG_RUNTIME_DIR:-/tmp}" - session_dir="$(mktemp -d "$runtime_dir/concord-session.XXXXXX")" - - cleanup() { - rm -rf -- "$session_dir" - } - - trap cleanup EXIT - trap 'exit 129' HUP - trap 'exit 130' INT - trap 'exit 143' TERM - - config_home="$session_dir/config" - state_home="$session_dir/state" - mkdir -p "$config_home" "$state_home" - - cat > "$config_home/config.toml" <<'EOF' -[credentials] -store = "plain" -EOF - - XDG_CONFIG_HOME="$config_home" \ - XDG_STATE_HOME="$state_home" \ - "${inputs.concord.packages.${pkgs.stdenv.hostPlatform.system}.default}/bin/concord" "$@" - ''; in { home.stateVersion = "26.05"; @@ -41,7 +13,6 @@ in home.homeDirectory = "/home/imnyang"; home.packages = [ - concord nr nrr ]; diff --git a/hosts/server/hikari/hako/services/api.nix b/hosts/server/hikari/hako/services/api.nix index 7e0fe85..cf975ef 100644 --- a/hosts/server/hikari/hako/services/api.nix +++ b/hosts/server/hikari/hako/services/api.nix @@ -22,7 +22,7 @@ let ''; outputHashMode = "recursive"; - outputHash = "sha256-ke6cG/cBON6d6giFo1RAQ4gMfIbmagJfCI1FfZl1w/8="; + outputHash = "sha256-RMIfjUQKyC3iTGvBUvneSEMTf1Aws2WiOqRm+GqdPTQ="; }; apiPackage = pkgs.stdenv.mkDerivation { diff --git a/hosts/server/hikari/hako/services/forgejo.nix b/hosts/server/hikari/hako/services/forgejo.nix index 5ec7dfe..fbdbfe7 100644 --- a/hosts/server/hikari/hako/services/forgejo.nix +++ b/hosts/server/hikari/hako/services/forgejo.nix @@ -39,7 +39,7 @@ services.forgejo = { enable = true; - package = pkgs.forgejo; + package = import ../../../../../overlays/forgejo-codefloe.nix { inherit pkgs; }; database = { type = "postgres"; @@ -79,8 +79,8 @@ service = { REGISTER_EMAIL_CONFIRM = true; ENABLE_NOTIFY_MAIL = true; - DISABLE_REGISTRATION = false; - ALLOW_ONLY_EXTERNAL_REGISTRATION = true; + DISABLE_REGISTRATION = true; + ALLOW_ONLY_EXTERNAL_REGISTRATION = false; ENABLE_CAPTCHA = false; REQUIRE_SIGNIN_VIEW = lib.mkForce false; DEFAULT_KEEP_EMAIL_PRIVATE = false; diff --git a/hosts/server/hikari/hako/services/helium-services.nix b/hosts/server/hikari/hako/services/helium-services.nix index e2c9ffb..2afa9a5 100644 --- a/hosts/server/hikari/hako/services/helium-services.nix +++ b/hosts/server/hikari/hako/services/helium-services.nix @@ -18,7 +18,7 @@ let version = "2026-08-26"; src = pkgs.fetchurl { url = "https://chromium.googlesource.com/chromium/deps/hunspell_dictionaries/+archive/cccf64a8acc951afe3f47fee023908e55699bc58.tar.gz"; - hash = "sha256-KMVNa0XsR9BXJzW6d7/D6AzAGErRVRGPU9CjjTIvyv0="; + hash = "sha256-mI929q+yEj0oDWGgt1gA21WTZRN6gm4a35SPCMBYgvU="; }; dontUnpack = true; @@ -201,6 +201,14 @@ in file_server browse } + @ext path /ext + handle @ext { + rewrite * / + reverse_proxy 127.0.0.1:18080 127.0.0.1:18081 { + lb_policy first + } + } + handle_path /ext/* { reverse_proxy 127.0.0.1:18080 127.0.0.1:18081 { lb_policy first diff --git a/modules/home/ssh.nix b/modules/home/ssh.nix index d683c2e..704a08c 100644 --- a/modules/home/ssh.nix +++ b/modules/home/ssh.nix @@ -19,6 +19,14 @@ ControlPath = "~/.ssh/master-%r@%n:%p"; ControlPersist = "no"; }; + + "mizuki.guru" = { + User = "discord"; + PreferredAuthentications = [ "none" ]; + PubkeyAuthentication = false; + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + }; }; }; } diff --git a/overlays/forgejo-codefloe.nix b/overlays/forgejo-codefloe.nix new file mode 100644 index 0000000..c1a199e --- /dev/null +++ b/overlays/forgejo-codefloe.nix @@ -0,0 +1,26 @@ +{ pkgs }: + +let + # CodeFloe's v16.0/forgejo-codefloe deployment branch, pinned for reproducibility. + src = pkgs.fetchzip { + url = "https://codefloe.com/codefloe/forgejo-codefloe/archive/ed1b96c66680ed99d7d11201915eca28587b8171.tar.gz"; + hash = "sha256-hdLR4A2qa2oRUXKmApQngVDy15I214/NB53syNmMacE="; + }; +in +# Revisit the pinned fork and build recipe together when nixpkgs updates Forgejo. +assert pkgs.forgejo.version == "16.0.5"; +(pkgs.forgejo.override { + buildNpmPackage = + args: + pkgs.buildNpmPackage ( + args + // { + inherit src; + npmDepsHash = "sha256-t9v9gVuCd9uqiK47lUDpJdzzwqc6sQwBkPxw/mAST0c="; + } + ); +}).overrideAttrs { + pname = "forgejo-codefloe"; + inherit src; + vendorHash = "sha256-bu1kJqXvPSEehhbG5tkAEQAEbhRl5FlJ+EEM01FiBSY="; +}