Used agenix to manage secrets, 4 services up, ssh

This commit is contained in:
2025-08-08 17:00:47 -04:00
parent ac6c3688ef
commit 911f3589a2
20 changed files with 369 additions and 56 deletions

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "assets/compose"]
path = assets/compose
url = ssh://git@code.lazyworkhorse.net:2222/gortium/compose.git

1
assets/compose Submodule

Submodule assets/compose added at bcaad554a6

84
flake.lock generated
View File

@@ -1,5 +1,49 @@
{
"nodes": {
"agenix": {
"inputs": {
"darwin": [],
"home-manager": "home-manager",
"nixpkgs": [
"nixpkgs"
],
"systems": "systems"
},
"locked": {
"lastModified": 1754337839,
"narHash": "sha256-fEc2/4YsJwtnLU7HCFMRckb0u9UNnDZmwGhXT5U5NTw=",
"owner": "ryantm",
"repo": "agenix",
"rev": "856df6f6922845abd4fd958ce21febc07ca2fa45",
"type": "github"
},
"original": {
"owner": "ryantm",
"repo": "agenix",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1745494811,
"narHash": "sha256-YZCh2o9Ua1n9uCvrvi5pRxtuVNml8X2a03qIFfRKpFs=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "abfad3d2958c9e6300a883bd443512c55dfeb1be",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1753939845,
@@ -16,43 +60,25 @@
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1744868846,
"narHash": "sha256-5RJTdUHDmj12Qsv7XOhuospjAjATNiTMElplWnJE9Hs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "ebe4301cbd8f81c4f8d3244b3632338bbeb6d49c",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"sops-nix": "sops-nix"
"agenix": "agenix",
"nixpkgs": "nixpkgs"
}
},
"sops-nix": {
"inputs": {
"nixpkgs": "nixpkgs_2"
},
"systems": {
"locked": {
"lastModified": 1754328224,
"narHash": "sha256-glPK8DF329/dXtosV7YSzRlF4n35WDjaVwdOMEoEXHA=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "49021900e69812ba7ddb9e40f9170218a7eca9f4",
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"id": "sops-nix",
"type": "indirect"
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},

View File

@@ -1,28 +1,47 @@
{
description = "A very basic flake";
description = "Gortium infra flake";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
agenix = {
url = "github:ryantm/agenix";
inputs.darwin.follows = "";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, sops-nix, ... }@inputs:
outputs = { self, nixpkgs, agenix, ... }@inputs:
let
system = "x86_64-linux";
keys = import ./lib/keys.nix;
paths = {
flake = "/home/gortium/infra";
identities = [ "/home/gortium/.ssh/gortium_ssh_key" "/etc/ssh/ssh_host_ed25519_key" ];
};
overlays = [ agenix.overlays.default ];
pkgs = import nixpkgs {
inherit system;
config = {
allowUnfree = true;
};
inherit system overlays;
config.allowUnfree = true;
};
devShell = import ./shells/nix_dev.nix {
inherit pkgs system agenix;
};
in
{
nixosConfigurations = {
lazyworkhorse = nixpkgs.lib.nixosSystem {
specialArgs = { inherit system; };
specialArgs = { inherit system self keys paths; };
modules = [
{ nixpkgs.overlays = overlays; }
agenix.nixosModules.default
./hosts/lazyworkhorse/configuration.nix
./hosts/lazyworkhorse/hardware-configuration.nix
./modules/default.nix
./users/gortium.nix
];
};
};
devShells.${system}.default = devShell;
};
}

View File

@@ -2,30 +2,27 @@
# your system. Help is available in the configuration.nix(5) man page, on
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
{ config, lib, pkgs, ... }:
{ config, lib, pkgs, self, paths, keys, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
./../../modules/default.nix
./../../users/gortium.nix
];
# NAS Mounting
hoardingcow-mount.enable = true;
# Flakesss
nix.settings.experimental-features = [ "nix-command" "flakes" ];
nix.settings.trusted-users = [ "root" "gortium" ];
# Garbage collection
nix.gc = {
automatic = true;
dates = "weekly"; # You can also use "daily" or a cron-like spec
dates = "daily"; # You can also use "daily" or a cron-like spec
options = "--delete-older-than 7d"; # Keep only 7 days of unreferenced data
};
nix.settings = {
auto-optimise-store = true; # Deduplicate identical files
keep-derivations = false;
keep-outputs = false;
keep-derivations = true;
keep-outputs = true;
auto-optimise-store = true;
};
# Use the systemd-boot EFI boot loader.
@@ -41,7 +38,11 @@
# Set your time zone.
time.timeZone = "America/Montreal";
# Locales
i18n.defaultLocale = "en_CA.UTF-8";
i18n.supportedLocales = [
"en_CA.UTF-8/UTF-8"
];
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_CA.UTF-8";
LC_IDENTIFICATION = "en_CA.UTF-8";
@@ -52,8 +53,34 @@
LC_PAPER = "en_CA.UTF-8";
LC_TELEPHONE = "en_CA.UTF-8";
LC_TIME = "en_CA.UTF-8";
LC_CTYPE = "en_CA.UTF-8";
};
# Private host ssh key
age = {
identityPaths = paths.identities;
secrets = {
lazyworkhorse_host_ssh_key = {
file = "${self}/secrets/lazyworkhorse_host_ssh_key.age";
owner = "root";
group = "root";
mode = "0600";
path = "/etc/ssh/ssh_host_ed25519_key";
};
};
};
# Public host ssh key
environment.etc."ssh/ssh_host_ed25519_key.pub".text = keys.hosts.lazyworkhorse.main;
# Prevent sshd from generating new keys and use this one
services.openssh.hostKeys = [
{
path = "/etc/ssh/ssh_host_ed25519_key";
type = "ed25519";
}
];
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
@@ -81,21 +108,28 @@
pulse.enable = true;
};
environment.sessionVariables = {
NH_FLAKE = paths.flake;
};
# Enable touchpad support (enabled default in most desktopManager).
# services.libinput.enable = true;
# nvim please
environment.variables.EDITOR = "neovim";
environment.variables.EDITOR = "nvim";
# programs.firefox.enable = true;
# List packages installed in system profile.
# You can use https://search.nixos.org/ to find more packages (and options).
# You can use https://Search.nixos.org/ to find more packages (and options).
environment.systemPackages = with pkgs; [
agenix
neovim
docker-compose
wget
age
git
nh
];
# Some programs need SUID wrappers, can be configured further or are
@@ -114,7 +148,7 @@
settings.PermitRootLogin = "no";
};
# Open ports in the firewall.
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.

17
lib/keys.nix Normal file
View File

@@ -0,0 +1,17 @@
{
users = {
gortium = {
main = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILYwvoGdSGbGDVU/Fi7re9NmPJuA29GNH82vT0LqMEKo";
github = "";
gitea = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN9tKezYidZglWBRI9/2I/cBGUUHj2dHY8rHXppYmf7F";
};
};
hosts = {
lazyworkhorse = {
main = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBmPv4JssvhHGIx85UwFxDSrL5anR4eXB/cd9V2i9wdW";
github = "";
gitea = "";
};
};
}

View File

@@ -4,12 +4,9 @@
options = {
grapfical-desktop.enable = lib.mkEnableOption "enable graphical desktop";
};
config = lib.mkIf config.grapfical-desktop.enable {
# Enable the X11 windowing system.
services.xserver.enable = true;
# Hyprland
programs.hyprland = {
enable = true;

View File

@@ -3,6 +3,7 @@
[
./bundles
# ./programs
# ./services
./services
./filesystem
];
}

View File

@@ -0,0 +1,6 @@
{ pkgs, lib, config, ... }: {
imports =
[
./hoardingcow-mount.nix
];
}

View File

@@ -0,0 +1,13 @@
{ pkgs, lib, config, ... }: {
options = {
hoardingcow-mount.enable = lib.mkEnableOption "enable hoardingcow acces";
};
config = lib.mkIf config.hoardingcow-mount.enable {
fileSystems."/mnt/HoardingCow_docker_data" = {
device = "192.168.1.2:/WorkHorse_docker_data";
fsType = "nfs";
options = [ "defaults" "nofail" "_netdev" ];
};
};
}

View File

@@ -0,0 +1,6 @@
{ pkgs, lib, config, ... }: {
imports =
[
./systemd
];
}

View File

@@ -0,0 +1,28 @@
{ pkgs, lib, config, self, keys, paths, ... }: {
imports =
[
./network.nix
./passwordmanager.nix
./versioncontrol.nix
];
virtualisation.docker = {
enable = true;
daemon.settings = {
"dns" = [ "1.1.1.1" "8.8.8.8" ];
};
};
age = {
identityPaths = paths.identities;
secrets = {
containers_env = {
file = self + "/secrets/containers.env.age";
path = "/run/secrets/containers.env";
owner = "root";
group = "root";
mode = "0400";
};
};
};
}

View File

@@ -0,0 +1,40 @@
{ config, pkgs, self, ... }:
let
network_compose_dir = pkgs.stdenv.mkDerivation {
name = "network_compose_dir";
src = self + "/assets/compose/network";
dontUnpack = true;
installPhase = ''
mkdir -p $out
cp -r $src/* $out/
'';
};
in
{
networking.firewall.allowedTCPPorts = [ 80 443 ];
systemd.services.network_stack = {
description = "Traefik + DDNS updater via Docker Compose";
after = [ "network.target" "docker.service" ];
requires = [ "network.target" "docker.service" ];
serviceConfig = {
WorkingDirectory = "${network_compose_dir}";
EnvironmentFile = config.age.secrets.containers_env.path;
# Stop left over container by the same name
ExecStartPre = "${pkgs.bash}/bin/bash -c '${pkgs.docker-compose}/bin/docker-compose down || true'";
# Start the services using Docker Compose
ExecStart = "${pkgs.docker-compose}/bin/docker-compose up -d";
# Stop and remove containers on shutdown
ExecStop = "${pkgs.docker-compose}/bin/docker-compose down";
RemainAfterExit = true;
TimeoutStartSec = 0;
};
wantedBy = [ "multi-user.target" ];
};
}

View File

@@ -0,0 +1,36 @@
{ config, pkgs, self, ... }:
let
passwordmanager_compose_dir = pkgs.stdenv.mkDerivation {
name = "passwordmanager_compose_dir";
src = self + "/assets/compose/passwordmanager";
dontUnpack = true;
installPhase = ''
mkdir -p $out
cp -r $src/* $out/
'';
};
in
{
systemd.services.passwordmanager_stack = {
description = "Bitwarden via Docker Compose";
after = [ "network-online.target" "docker.service" ];
wants = [ "network-online.target" "docker.service" ];
serviceConfig = {
WorkingDirectory = "${passwordmanager_compose_dir}";
# Stop left over container by the same name
ExecStartPre = "${pkgs.bash}/bin/bash -c '${pkgs.docker-compose}/bin/docker-compose down || true'";
# Démarrer les conteneurs avec Docker Compose
ExecStart = "${pkgs.docker-compose}/bin/docker-compose up -d";
# Arrêter et supprimer les conteneurs à larrêt
ExecStop = "${pkgs.docker-compose}/bin/docker-compose down";
RemainAfterExit = true;
TimeoutStartSec = 0;
};
wantedBy = [ "multi-user.target" ];
};
}

View File

@@ -0,0 +1,38 @@
{ config, pkgs, self, ... }:
let
versioncontrol_compose_dir = pkgs.stdenv.mkDerivation {
name = "versioncontrol_compose_dir";
src = self + "/assets/compose/versioncontrol";
dontUnpack = true;
installPhase = ''
mkdir -p $out
cp -r $src/* $out/
'';
};
in
{
networking.firewall.allowedTCPPorts = [ 2222 ];
systemd.services.versioncontrol_stack = {
description = "Gitea via Docker Compose";
after = [ "network-online.target" "docker.service" ];
wants = [ "network-online.target" "docker.service" ];
serviceConfig = {
WorkingDirectory = "${versioncontrol_compose_dir}";
# Stop left over container by the same name
ExecStartPre = "${pkgs.bash}/bin/bash -c '${pkgs.docker-compose}/bin/docker-compose down || true'";
# Démarrer les conteneurs avec Docker Compose
ExecStart = "${pkgs.docker-compose}/bin/docker-compose up -d";
# Arrêter et supprimer les conteneurs à larrêt
ExecStop = "${pkgs.docker-compose}/bin/docker-compose down";
RemainAfterExit = true;
TimeoutStartSec = 0;
};
wantedBy = [ "multi-user.target" ];
};
}

View File

@@ -0,0 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 GhMD8A 9Tjo08Hbj3S+nCdLUylZoUK6meXtuHq9F/qwSJZBYho
iu2MmQ2VHm+QEvqGjkEy02V0cNRanAyhrA8Xu7UWRFk
-> ssh-ed25519 eB5ENw 8UTi2pmZML1Zyh9zCfEx4JqJhQ1vM/jZCEhrkuc1Hh4
et6FoN8E4tgo2DXlt/KTGLRsByJFyDu2oHA/Js/pIB8
--- dmEv5Fz1iUJ3W93lFtkHgtknfQGQNkMqglJZ+3e1qM8
<EFBFBD>U<EFBFBD><EFBFBD><EFBFBD>.<2E><>#C\<11><><EFBFBD> <09>V<EFBFBD><56>-<2D><><EFBFBD><EFBFBD><1F>tp<74>w؁nީ<><02><>n<EFBFBD><<3C>E<EFBFBD><45><EFBFBD>~<7E><>bX<62><02><><EFBFBD>_<EFBFBD><5F><07><><EFBFBD><EFBFBD>u<EFBFBD>l?<3F>),s<>Ec7<63><37><EFBFBD><EFBFBD>v<EFBFBD>;<3B>A<EFBFBD>U<EFBFBD>-<2D>I<EFBFBD>7Y<37>-<2D>3g[<5B>jh~<7E>/<2F>

Binary file not shown.

8
secrets/secrets.nix Normal file
View File

@@ -0,0 +1,8 @@
let
keys = import ../lib/keys.nix;
authorizedKeys = [ keys.users.gortium.main keys.hosts.lazyworkhorse.main ];
in
{
"containers.env.age".publicKeys = authorizedKeys;
"lazyworkhorse_host_ssh_key.age".publicKeys = authorizedKeys;
}

17
shells/nix_dev.nix Normal file
View File

@@ -0,0 +1,17 @@
{ pkgs, system, agenix }:
pkgs.mkShell {
packages = [
pkgs.nixos-rebuild
pkgs.git
pkgs.openssh
pkgs.age
pkgs.nh
agenix.packages.${system}.default
];
shellHook = ''
echo "Welcome to Gortium Infra DevShell"
echo "Use: nixos-rebuild switch --flake .#lazyworkhorse --target-host root@lazyworkhorse"
'';
}

View File

@@ -1,10 +1,26 @@
{ pkgs, inputs, config, ... }: {
# Define a user account. Don't forget to set a password with passwd.
{ pkgs, inputs, config, keys, ... }: {
users.users.gortium = {
isNormalUser = true;
extraGroups = [ "wheel" "docker" ]; # Enable sudo for the user.
packages = with pkgs; [
tree
btop
];
shell = pkgs.zsh;
openssh.authorizedKeys.keys = [
keys.users.gortium.main
];
};
programs.zsh.enable = true;
security.sudo.extraRules = [
{
users = [ "gortium" ];
commands = [
{
command = "ALL";
options = [ "NOPASSWD" ];
}
];
}
];
}