Compare commits

..

1 commit

Author SHA1 Message Date
6fe7504460
ci: eval deploy 2024-12-20 18:15:18 +08:00
57 changed files with 623 additions and 921 deletions

View file

@ -1,8 +1,10 @@
name: Eval NixOS Configurations name: Eval NixOS Configurations
on: on:
check_suite: push:
types: [completed] branches:
- deploy
workflow_dispatch:
permissions: permissions:
contents: write contents: write
@ -18,10 +20,6 @@ jobs:
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@v25 uses: cachix/install-nix-action@v25
with:
extra_nix_conf: |
extra-trusted-public-keys = cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g=
extra-substituters = https://cache.garnix.io
- name: Configure Git - name: Configure Git
run: | run: |
@ -35,26 +33,19 @@ jobs:
hosts=$(nix flake show --json | jq -r '.nixosConfigurations | keys[]') hosts=$(nix flake show --json | jq -r '.nixosConfigurations | keys[]')
echo "Found hosts: $hosts" echo "Found hosts: $hosts"
failed_hosts=""
for host in $hosts; do for host in $hosts; do
echo "Eval derivation for $host" echo "Eval derivation for $host"
if ! nix derivation show ".#nixosConfigurations.$host.config.system.build.toplevel" > "eval/$host.json"; then if ! nix show-derivation -L ".#nixosConfigurations.$host.config.system.build.toplevel" > "eval/$host.json"; then
echo "❌ Failed to evaluate $host" echo "❌ Failed to evaluate $host"
failed_hosts+="$host "
rm "eval/$host.json"
else else
echo "✅ Successfully evaluated $host" echo "✅ Successfully evaluated $host"
fi fi
done done
echo "Total hosts: $(echo "$hosts" | wc -w)"
echo "Failed hosts: $failed_hosts" echo "Failed hosts: $failed_hosts"
git add eval/ git add eval/
git commit -m "Update deployment configurations for all hosts" git commit -m "Update deployment configurations for all hosts"
git push -f origin deploy-comin-eval git push origin deploy-comin-eval
# After success, reset deploy-comin to new deploy
git checkout -b deploy-comin
git reset --hard deploy
git push -f origin deploy-comin

128
flake.lock generated
View file

@ -1,17 +1,12 @@
{ {
"nodes": { "nodes": {
"catppuccin": { "catppuccin": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": { "locked": {
"lastModified": 1739283129, "lastModified": 1733001911,
"narHash": "sha256-GXJllf1wY7tOF6uei9S3PnSEghFbnJP1vkxM0kkMOoI=", "narHash": "sha256-uX/9m0TbdhEzuWA0muM5mI/AaWcLiDLjCCyu5Qr9MRk=",
"owner": "catppuccin", "owner": "catppuccin",
"repo": "nix", "repo": "nix",
"rev": "d4e258e29075a86a82dacaf4f5e0985935ae4658", "rev": "a817009ebfd2cca7f70a77884e5098d0a8c83f8e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -31,11 +26,11 @@
"stable": "stable" "stable": "stable"
}, },
"locked": { "locked": {
"lastModified": 1734897875, "lastModified": 1731527002,
"narHash": "sha256-LLpiqfOGBippRax9F33kSJ/Imt8gJXb6o0JwSBiNHCk=", "narHash": "sha256-dI9I6suECoIAmbS4xcrqF8r2pbmed8WWm5LIF1yWPw8=",
"owner": "zhaofengli", "owner": "zhaofengli",
"repo": "colmena", "repo": "colmena",
"rev": "a6b51f5feae9bfb145daa37fd0220595acb7871e", "rev": "e3ad42138015fcdf2524518dd564a13145c72ea1",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -44,26 +39,6 @@
"type": "github" "type": "github"
} }
}, },
"comin": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1734693645,
"narHash": "sha256-Vw3YpuQxwBse5JiTGBH5MSPmqXOXFI4ROs7IF3tRc7k=",
"owner": "xinyangli",
"repo": "comin",
"rev": "c8a66bbd129e88ad916cac59f1ad9f45d39b3190",
"type": "github"
},
"original": {
"owner": "xinyangli",
"repo": "comin",
"type": "github"
}
},
"devshell": { "devshell": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -93,11 +68,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1739517743, "lastModified": 1733168902,
"narHash": "sha256-CPfA2Wdfxz16CTsPFltFj65T0/HikkOa4pQvcts1df4=", "narHash": "sha256-8dupm9GfK+BowGdQd7EHK5V61nneLfr9xR6sc5vtDi0=",
"owner": "nix-community", "owner": "nix-community",
"repo": "disko", "repo": "disko",
"rev": "40da43e8e5620505b9c8aacc4f0d7577ad1aff73", "rev": "785c1e02c7e465375df971949b8dcbde9ec362e5",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -327,11 +302,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1739470101, "lastModified": 1733754861,
"narHash": "sha256-NxNe32VB4XI/xIXrsKmIfrcgtEx5r/5s52pL3CpEcA4=", "narHash": "sha256-3JKzIou54yjiMVmvgdJwopekEvZxX3JDT8DpKZs4oXY=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "5031c6d2978109336637977c165f82aa49fa16a7", "rev": "9ebaa80a227eaca9c87c53ed515ade013bc2bca9",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -401,11 +376,11 @@
"nixvim": "nixvim" "nixvim": "nixvim"
}, },
"locked": { "locked": {
"lastModified": 1741086060, "lastModified": 1732936640,
"narHash": "sha256-35fw6MoEXEutctwNS0z7VQ0AX8thHhU2KT0UxD/s3P4=", "narHash": "sha256-NcluA0L+ZV5MUj3UuQhlkGCj8KoEhX/ObWlMHZ/F/ac=",
"ref": "refs/heads/master", "ref": "refs/heads/master",
"rev": "9240bb4db98fe13b3fdaa0e15a06949959df568a", "rev": "a3709a89797ea094f82d38edeb4a538c07c8c3fa",
"revCount": 26, "revCount": 20,
"type": "git", "type": "git",
"url": "https://git.xiny.li/xin/nixvim" "url": "https://git.xiny.li/xin/nixvim"
}, },
@ -464,11 +439,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1739071773, "lastModified": 1733629314,
"narHash": "sha256-/Ak+Quinhmdxa9m3shjm4lwwwqmzG8zzGhhhhgR1k9I=", "narHash": "sha256-U0vivjQFAwjNDYt49Krevs1murX9hKBFe2Ye0cHpgbU=",
"owner": "Mic92", "owner": "Mic92",
"repo": "nix-index-database", "repo": "nix-index-database",
"rev": "895d81b6228bbd50a6ef22f5a58a504ca99763ea", "rev": "f1e477a7dd11e27e7f98b646349cd66bbabf2fb8",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -488,11 +463,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1739497746, "lastModified": 1733795858,
"narHash": "sha256-Bfok+AZ/iTOmJNndwR7wOZbsuL5/gks3GH2qvWTxpGs=", "narHash": "sha256-K595Q2PrZv2iiumdBkwM2G456T2lKsLD71bn/fbJiQ0=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nix-vscode-extensions", "repo": "nix-vscode-extensions",
"rev": "6113f471097e12ff293e86b36e74aee21c55204e", "rev": "66ced222ef9235f90dbdd754ede3d6476722aaa9",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -503,11 +478,11 @@
}, },
"nixos-hardware": { "nixos-hardware": {
"locked": { "locked": {
"lastModified": 1738816619, "lastModified": 1733481457,
"narHash": "sha256-5yRlg48XmpcX5b5HesdGMOte+YuCy9rzQkJz+imcu6I=", "narHash": "sha256-IS3bxa4N1VMSh3/P6vhEAHQZecQ3oAlKCDvzCQSO5Is=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixos-hardware", "repo": "nixos-hardware",
"rev": "2eccff41bab80839b1d25b303b53d339fbb07087", "rev": "e563803af3526852b6b1d77107a81908c66a9fcf",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -517,27 +492,6 @@
"type": "github" "type": "github"
} }
}, },
"nixos-sbc": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1739031922,
"narHash": "sha256-h1kw65FOtgTbSqhKc/hsvQaqimZ9D0x1FzifuGGbsho=",
"owner": "nakato",
"repo": "nixos-sbc",
"rev": "d0e87bfd6623cce0b730f8919d6f21e02f917264",
"type": "github"
},
"original": {
"owner": "nakato",
"ref": "main",
"repo": "nixos-sbc",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1731139594, "lastModified": 1731139594,
@ -568,11 +522,11 @@
}, },
"nixpkgs-stable": { "nixpkgs-stable": {
"locked": { "locked": {
"lastModified": 1735563628, "lastModified": 1733730953,
"narHash": "sha256-OnSAY7XDSx7CtDoqNh8jwVwh4xNL/2HaJxGjryLWzX8=", "narHash": "sha256-dlK7n82FEyZlHH7BFHQAM5tua+lQO1Iv7aAtglc1O5s=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "b134951a4c9f3c995fd7be05f3243f8ecd65d798", "rev": "7109b680d161993918b0a126f38bc39763e5a709",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -584,11 +538,11 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1739519992, "lastModified": 1733805440,
"narHash": "sha256-9NNxUjwQ4Ty6n8EI1GcMtsEb3Knkho7FZ/QS5crB+Bc=", "narHash": "sha256-AQdCeGt3dMV9/cchlWGMcP0Z8qM47V+B0p7cSRr+HhA=",
"owner": "xinyangli", "owner": "xinyangli",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "90466175893e2e48b5f660eb90daa7e510c2f1c4", "rev": "61b1078fca3a097ce06ada68a6f2766347eed02c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -600,11 +554,11 @@
}, },
"nixpkgs_3": { "nixpkgs_3": {
"locked": { "locked": {
"lastModified": 1739446958, "lastModified": 1733581040,
"narHash": "sha256-+/bYK3DbPxMIvSL4zArkMX0LQvS7rzBKXnDXLfKyRVc=", "narHash": "sha256-Qn3nPMSopRQJgmvHzVqPcE3I03zJyl8cSbgnnltfFDY=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "2ff53fe64443980e139eaa286017f53f88336dd0", "rev": "22c3f2cf41a0e70184334a958e6b124fb0ce3e01",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -647,11 +601,11 @@
"treefmt-nix": "treefmt-nix_2" "treefmt-nix": "treefmt-nix_2"
}, },
"locked": { "locked": {
"lastModified": 1739519565, "lastModified": 1733805328,
"narHash": "sha256-coB/rCQx3FOIyBSa9nLfchlkGDL7ehHZc8U7CJ7YhP4=", "narHash": "sha256-5F49/mOzFb40uUZh71uNr7kBXjDCw5ZfHMbpZjjUVBQ=",
"owner": "nix-community", "owner": "nix-community",
"repo": "NUR", "repo": "NUR",
"rev": "6ced3aa7dffa39ccfb771ac90c39756f9558d489", "rev": "b54fa3d8c020e077d88be036a12a711b84fe2031",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -688,7 +642,6 @@
"inputs": { "inputs": {
"catppuccin": "catppuccin", "catppuccin": "catppuccin",
"colmena": "colmena", "colmena": "colmena",
"comin": "comin",
"disko": "disko", "disko": "disko",
"flake-utils": "flake-utils_2", "flake-utils": "flake-utils_2",
"home-manager": "home-manager", "home-manager": "home-manager",
@ -696,7 +649,6 @@
"nix-index-database": "nix-index-database", "nix-index-database": "nix-index-database",
"nix-vscode-extensions": "nix-vscode-extensions", "nix-vscode-extensions": "nix-vscode-extensions",
"nixos-hardware": "nixos-hardware", "nixos-hardware": "nixos-hardware",
"nixos-sbc": "nixos-sbc",
"nixpkgs": "nixpkgs_2", "nixpkgs": "nixpkgs_2",
"nixpkgs-stable": "nixpkgs-stable", "nixpkgs-stable": "nixpkgs-stable",
"nur": "nur", "nur": "nur",
@ -710,11 +662,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1739262228, "lastModified": 1733785344,
"narHash": "sha256-7JAGezJ0Dn5qIyA2+T4Dt/xQgAbhCglh6lzCekTVMeU=", "narHash": "sha256-pm4cfEcPXripE36PYCl0A2Tu5ruwHEvTee+HzNk+SQE=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "07af005bb7d60c7f118d9d9f5530485da5d1e975", "rev": "a80af8929781b5fe92ddb8ae52e9027fae780d2a",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -49,23 +49,12 @@
catppuccin = { catppuccin = {
url = "github:catppuccin/nix"; url = "github:catppuccin/nix";
inputs.nixpkgs.follows = "nixpkgs";
}; };
disko = { disko = {
url = "github:nix-community/disko"; url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
comin = {
url = "github:xinyangli/comin";
inputs.nixpkgs.follows = "nixpkgs";
};
nixos-sbc = {
url = "github:nakato/nixos-sbc/main";
inputs.nixpkgs.follows = "nixpkgs";
};
}; };
outputs = outputs =
@ -83,8 +72,6 @@
colmena, colmena,
nix-index-database, nix-index-database,
disko, disko,
comin,
nixos-sbc,
... ...
}: }:
let let
@ -120,12 +107,8 @@
sharedNixosModules = [ sharedNixosModules = [
self.nixosModules.default self.nixosModules.default
sops-nix.nixosModules.sops sops-nix.nixosModules.sops
comin.nixosModules.comin
]; ];
nodeNixosModules = { nodeNixosModules = {
weilite = [
./machines/weilite
];
calcite = [ calcite = [
nixos-hardware.nixosModules.asus-zephyrus-ga401 nixos-hardware.nixosModules.asus-zephyrus-ga401
catppuccin.nixosModules.catppuccin catppuccin.nixosModules.catppuccin
@ -155,11 +138,6 @@
disko.nixosModules.disko disko.nixosModules.disko
./machines/biotite ./machines/biotite
]; ];
baryte = [
nixos-sbc.nixosModules.default
nixos-sbc.nixosModules.boards.bananapi.bpir4
./machines/baryte
];
}; };
sharedColmenaModules = [ sharedColmenaModules = [
deploymentModule deploymentModule
@ -215,6 +193,18 @@
}; };
}; };
massicot =
{ ... }:
{
deployment.targetHost = "49.13.13.122";
deployment.buildOnTarget = true;
imports = [
{ nixpkgs.system = "aarch64-linux"; }
machines/massicot
] ++ sharedColmenaModules;
};
la-00 = la-00 =
{ ... }: { ... }:
{ {
@ -272,6 +262,17 @@
] ++ sharedColmenaModules; ] ++ sharedColmenaModules;
}; };
weilite =
{ ... }:
{
imports = [ machines/weilite ] ++ sharedColmenaModules;
deployment = {
targetHost = "weilite.coho-tet.ts.net";
targetPort = 22;
buildOnTarget = false;
};
nixpkgs.system = "x86_64-linux";
};
thorite = thorite =
{ ... }: { ... }:
{ {
@ -301,14 +302,6 @@
calcite = mkNixos { calcite = mkNixos {
hostname = "calcite"; hostname = "calcite";
}; };
weilite = mkNixos {
hostname = "weilite";
};
baryte = mkNixos {
hostname = "baryte";
};
} // self.colmenaHive.nodes; } // self.colmenaHive.nodes;
} }
@ -334,6 +327,7 @@
packages = with pkgs; [ packages = with pkgs; [
nix nix
git git
colmena.packages.${system}.colmena
sops sops
nix-output-monitor nix-output-monitor
nil nil

View file

@ -1,19 +1,10 @@
builds: builds:
- include: include:
- '*.x86_64-linux.*' - '*.x86_64-linux.*'
- defaultPackage.x86_64-linux - defaultPackage.x86_64-linux
- devShell.x86_64-linux - devShell.x86_64-linux
- homeConfigurations.x86_64-linux.* - homeConfigurations.x86_64-linux.*
- homeConfigurations.aarch64-linux.* - homeConfigurations.aarch64-linux.*
- darwinConfigurations.* - darwinConfigurations.*
- nixosConfigurations.* - nixosConfigurations.*
branch: deploy
- include:
- '*.x86_64-linux.*'
- defaultPackage.x86_64-linux
- devShell.x86_64-linux
- homeConfigurations.x86_64-linux.*
- homeConfigurations.aarch64-linux.*
- darwinConfigurations.*
- nixosConfigurations.*
branch: testing-calcite

View file

@ -1,6 +1,5 @@
{ {
xin = { xin = {
calcite = import ./xin/calcite.nix; calcite = import ./xin/calcite.nix;
gold = import ./xin/gold;
}; };
} }

View file

@ -5,9 +5,6 @@ in
{ {
imports = [ imports = [
./common ./common
./common/pentesting.nix
./common/gui/foot.nix
./common/gui/default.nix
]; ];
programs.nix-index-database.comma.enable = true; programs.nix-index-database.comma.enable = true;
@ -61,6 +58,12 @@ in
xdg.enable = true; xdg.enable = true;
custom-hm = { custom-hm = {
alacritty = {
enable = true;
};
cosmic-term = {
enable = true;
};
direnv = { direnv = {
enable = true; enable = true;
}; };
@ -105,12 +108,10 @@ in
xdg.systemDirs.data = [ xdg.systemDirs.data = [
"/usr/share" "/usr/share"
"/var/lib/flatpak/exports/share"
"${homeDirectory}/.local/share/flatpak/exports/share"
]; ];
xdg.configFile."distrobox/distrobox.conf".text = ''
container_additional_volumes="/nix/store:/nix/store:ro /etc/profiles/per-user:/etc/profiles/per-user:ro"
'';
programs.man.generateCaches = false; programs.man.generateCaches = false;
programs.atuin = { programs.atuin = {
@ -118,14 +119,6 @@ in
flags = [ "--disable-up-arrow" ]; flags = [ "--disable-up-arrow" ];
}; };
programs.zathura = {
enable = true;
options = {
recolor = false;
selection-clipboard = "clipboard";
};
};
programs.firefox = { programs.firefox = {
enable = true; enable = true;
policies.DefaultDownloadDirectory = "/media/data/Downloads"; policies.DefaultDownloadDirectory = "/media/data/Downloads";

View file

@ -1,12 +0,0 @@
{ config, pkgs, ... }:
{
home.packages = with pkgs; [
# File Manager
xfce.thunar
xfce.thunar-archive-plugin
xfce.thunar-media-tags-plugin
xfce.thunar-volman
swayimg
];
}

View file

@ -1,15 +0,0 @@
{ pkgs, lib, ... }:
{
programs.foot = {
enable = true;
settings = {
main = {
font = "monospace:size=14";
};
desktop-notifications = {
command = "${lib.getExe pkgs.libnotify} --wait --app-name \${app-id} --icon \${app-id} --category \${category} --urgency \${urgency} --expire-time \${expire-time} --hint STRING:image-path:\${icon} --hint BOOLEAN:suppress-sound:\${muted} --hint STRING:sound-name:\${sound-name} --replace-id \${replace-id} \${action-argument} --print-id -- \${title} \${body}";
inhibit-when-focused = "yes";
};
};
};
}

View file

@ -1,6 +0,0 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
burpsuite
];
}

View file

@ -0,0 +1,25 @@
{ config, pkgs, ... }:
{
imports = [ ../common ];
home.username = "xin";
home.homeDirectory = "/home/xin";
home.stateVersion = "23.05";
# Let Home Manager install and manage itself.
programs.home-manager.enable = true;
accounts.email.accounts.gmail = {
primary = true;
address = "lixinyang411@gmail.com";
flavor = "gmail.com";
};
accounts.email.accounts.whu = {
address = "lixinyang411@whu.edu.cn";
};
accounts.email.accounts.foxmail = {
address = "lixinyang411@foxmail.com";
};
}

View file

@ -1,22 +0,0 @@
{ config, lib, ... }:
{
imports = [
];
config = {
nixpkgs.hostPlatform = "aarch64-linux";
system.stateVersion = "25.05";
users.users.root.hashedPassword = "$y$j9T$NToEZWJBONjSgRnMd9Ur9/$o6n7a9b8eUILQz4d37oiHCCVnDJ8hZTZt.c.37zFfU.";
commonSettings = {
auth.enable = true;
};
services.openssh.enable = true;
services.dae = {
enable = true;
configFile = "/var/lib/dae/config.dae";
};
services.tailscale.enable = true;
time.timeZone = "Asia/Shanghai";
};
}

View file

@ -15,7 +15,6 @@
./services/hedgedoc.nix ./services/hedgedoc.nix
./services/forgejo.nix ./services/forgejo.nix
./services/vaultwarden.nix ./services/vaultwarden.nix
./services/kanidm.nix
]; ];
networking.hostName = "biotite"; networking.hostName = "biotite";
@ -37,7 +36,6 @@
commonSettings = { commonSettings = {
auth.enable = true; auth.enable = true;
comin.enable = true;
}; };
custom.monitoring = { custom.monitoring = {

View file

@ -69,29 +69,28 @@ in
systemd.services.forgejo = { systemd.services.forgejo = {
serviceConfig = { serviceConfig = {
EnvironmentFile = config.sops.templates."forgejo/env".path; EnvironmentFile = config.sops.templates."forgejo/env".path;
preStart =
let
providerName = "kanidm";
args = lib.concatStringsSep " " [
"--name ${providerName}"
"--provider openidConnect"
"--key forgejo"
"--secret $CLIENT_SECRET"
"--icon-url ${idpUrl}/pkg/img/favicon.png"
"--group-claim-name forgejo_role --admin-group Admin"
];
exe = getExe config.services.forgejo.package;
in
''
provider_id=$(${exe} admin auth list | ${pkgs.gnugrep}/bin/grep -w '${providerName}' | cut -f1)
if [[ -z "$provider_id" ]]; then
${exe} admin auth add-oauth ${args}
else
${exe} admin auth update-oauth --id "$provider_id" ${args}
fi
'';
}; };
preStart =
let
providerName = "kanidm";
args = lib.concatStringsSep " " [
"--name ${providerName}"
"--provider openidConnect"
"--key forgejo"
"--secret $CLIENT_SECRET"
"--auto-discover-url https://${idpUrl}/oauth2/openid/forgejo/.well-known/openid-configuration"
"--icon-url https://${idpUrl}/pkg/img/favicon.png"
"--group-claim-name forgejo_role --admin-group Admin"
];
exe = getExe config.services.forgejo.package;
in
''
provider_id=$(${exe} admin auth list | ${pkgs.gnugrep}/bin/grep -w '${providerName}' | cut -f1)
if [[ -z "$provider_id" ]]; then
${exe} admin auth add-oauth ${args}
else
${exe} admin auth update-oauth --id "$provider_id" ${args}
fi
'';
}; };
users.users.git = { users.users.git = {

View file

@ -26,7 +26,7 @@ in
instance-expose-public-timeline = true; instance-expose-public-timeline = true;
oidc-enabled = true; oidc-enabled = true;
oidc-idp-name = "Kanidm"; oidc-idp-name = "Kanidm";
oidc-issuer = "https://${idpUrl}/oauth2/openid/gotosocial"; oidc-issuer = "${idpUrl}/oauth2/openid/gotosocial";
oidc-client-id = "gotosocial"; oidc-client-id = "gotosocial";
oidc-link-existing = true; oidc-link-existing = true;
}; };

View file

@ -20,10 +20,10 @@ in
email = false; email = false;
allowEmailRegister = false; allowEmailRegister = false;
oauth2 = { oauth2 = {
baseURL = "https://${idpUrl}/oauth2/openid/hedgedoc"; baseURL = "${idpUrl}/oauth2/openid/hedgedoc";
authorizationURL = "https://${idpUrl}/ui/oauth2"; authorizationURL = "${idpUrl}/ui/oauth2";
tokenURL = "https://${idpUrl}/oauth2/token"; tokenURL = "${idpUrl}/oauth2/token";
userProfileURL = "https://${idpUrl}/oauth2/openid/hedgedoc/userinfo"; userProfileURL = "${idpUrl}/oauth2/openid/hedgedoc/userinfo";
userProfileEmailAttr = "email"; userProfileEmailAttr = "email";
userProfileUsernameAttr = "name"; userProfileUsernameAttr = "name";
userProfileDisplayNameAttr = "preferred_name"; userProfileDisplayNameAttr = "preferred_name";

View file

@ -1,54 +0,0 @@
{
config,
pkgs,
lib,
...
}:
let
kanidm_listen_port = 5324;
inherit (config.my-lib.settings) idpUrl;
in
{
imports = [
./kanidm-provision.nix
];
security.acme = {
acceptTerms = true;
certs.${idpUrl} = {
email = "lixinyang411@gmail.com";
listenHTTP = "127.0.0.1:1360";
group = "kanidm";
};
};
services.kanidm = {
package = pkgs.kanidm.withSecretProvisioning;
enableServer = true;
serverSettings = {
domain = idpUrl;
origin = "https://${idpUrl}";
bindaddress = "[::]:${toString kanidm_listen_port}";
tls_key = ''${config.security.acme.certs.${idpUrl}.directory}/key.pem'';
tls_chain = ''${config.security.acme.certs.${idpUrl}.directory}/fullchain.pem'';
online_backup.versions = 7;
# db_path = "/var/lib/kanidm/kanidm.db";
};
};
services.caddy = {
enable = true;
virtualHosts."http://${idpUrl}".extraConfig = ''
reverse_proxy ${config.security.acme.certs.${idpUrl}.listenHTTP}
'';
virtualHosts."https://${idpUrl}".extraConfig = ''
reverse_proxy https://127.0.0.1:${toString kanidm_listen_port} {
header_up Host {upstream_hostport}
header_down Access-Control-Allow-Origin "*"
transport http {
tls_server_name ${config.services.kanidm.serverSettings.domain}
}
}
'';
};
}

View file

@ -17,7 +17,7 @@ in
OAUTH2_CLIENT_ID = "miniflux"; OAUTH2_CLIENT_ID = "miniflux";
OAUTH2_CLIENT_SECRET_FILE = "%d/oauth2_secret"; OAUTH2_CLIENT_SECRET_FILE = "%d/oauth2_secret";
OAUTH2_REDIRECT_URL = "${minifluxUrl}/oauth2/oidc/callback"; OAUTH2_REDIRECT_URL = "${minifluxUrl}/oauth2/oidc/callback";
OAUTH2_OIDC_DISCOVERY_ENDPOINT = "https://${idpUrl}/oauth2/openid/miniflux"; OAUTH2_OIDC_DISCOVERY_ENDPOINT = "${idpUrl}/oauth2/openid/miniflux";
OAUTH2_USER_CREATION = 1; OAUTH2_USER_CREATION = 1;
CREATE_ADMIN = 0; CREATE_ADMIN = 0;
}; };

View file

@ -29,13 +29,6 @@ in
''; '';
}; };
# TODO: Waiting for https://github.com/NixOS/nixpkgs/issues/367976
nixpkgs.overlays = [
(final: prev: {
matrix-synapse-unwrapped = prev.matrix-synapse-unwrapped.overridePythonAttrs { doCheck = false; };
})
];
services.matrix-synapse = { services.matrix-synapse = {
enable = true; enable = true;
withJemalloc = true; withJemalloc = true;
@ -85,11 +78,11 @@ in
oidc_providers = [ oidc_providers = [
{ {
idp_id = "Kanidm"; idp_id = "Kanidm";
idp_name = idpUrl; idp_name = lib.removePrefix "https://" idpUrl;
issuer = "${idpUrl}/oauth2/openid/synapse"; issuer = "${idpUrl}/oauth2/openid/synapse";
authorization_endpoint = "https://${idpUrl}/ui/oauth2"; authorization_endpoint = "${idpUrl}/ui/oauth2";
token_endpoint = "https://${idpUrl}/oauth2/token"; token_endpoint = "${idpUrl}/oauth2/token";
userinfo_endpoint = "https://${idpUrl}/oauth2/openid/synapse/userinfo"; userinfo_endpoint = "${idpUrl}/oauth2/openid/synapse/userinfo";
client_id = "synapse"; client_id = "synapse";
client_secret_path = config.sops.secrets."synapse/oidc_client_secret".path; client_secret_path = config.sops.secrets."synapse/oidc_client_secret".path;
scopes = [ scopes = [

View file

@ -6,7 +6,6 @@
}: }:
let let
inherit (lib) mkForce getExe; inherit (lib) mkForce getExe;
inherit (config.my-lib.settings) idpUrl;
in in
{ {
imports = [ imports = [
@ -21,7 +20,6 @@ in
nix = { nix = {
signing.enable = true; signing.enable = true;
}; };
comin.enable = true;
}; };
# Bootloader. # Bootloader.
@ -34,7 +32,6 @@ in
"nvidia_modeset" "nvidia_modeset"
"nvidia_uvm" "nvidia_uvm"
]; ];
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.latest;
boot.supportedFilesystems = [ "ntfs" ]; boot.supportedFilesystems = [ "ntfs" ];
boot.binfmt.emulatedSystems = [ "aarch64-linux" ]; boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
@ -154,15 +151,6 @@ in
services.keyd = { services.keyd = {
enable = true; enable = true;
keyboards = { keyboards = {
default = {
ids = [ "*" ];
settings = {
main = {
capslock = "overload(control, esc)";
control = "overload(control, esc)";
};
};
};
"internal" = { "internal" = {
ids = [ "0b05:1866" ]; ids = [ "0b05:1866" ];
settings = { settings = {
@ -181,6 +169,17 @@ in
}; };
}; };
}; };
"keydous" = {
ids = [
"25a7:fa14"
"3151:4002"
];
settings = {
main = {
capslock = "overload(control, esc)";
};
};
};
}; };
}; };
@ -188,13 +187,9 @@ in
services.printing.enable = true; services.printing.enable = true;
services.printing.drivers = [ services.printing.drivers = [
pkgs.hplip pkgs.hplip
pkgs.gutenprint
pkgs.gutenprintBin pkgs.gutenprintBin
pkgs.canon-cups-ufr2
]; ];
hardware.sane = {
enable = true;
extraBackends = [ pkgs.hplipWithPlugin ];
};
hardware.pulseaudio.enable = false; hardware.pulseaudio.enable = false;
security.rtkit.enable = true; security.rtkit.enable = true;
@ -217,14 +212,13 @@ in
"wheel" "wheel"
"wireshark" "wireshark"
"tss" "tss"
"scanner"
]; ];
}; };
services.kanidm = { services.kanidm = {
enableClient = true; enableClient = true;
clientSettings = { clientSettings = {
uri = "https://${idpUrl}"; uri = "https://auth.xinyang.life";
}; };
}; };
@ -307,7 +301,6 @@ in
zotero zotero
# onlyoffice-bin # onlyoffice-bin
# wemeet
wemeet wemeet
virt-manager virt-manager

View file

@ -12,41 +12,19 @@
networking = { networking = {
networkmanager = { networkmanager = {
enable = true; enable = true;
dns = "default"; dns = "systemd-resolved";
settings = {
main = {
rc-manager = "resolvconf";
};
};
}; };
}; };
networking.resolvconf = { services.resolved = {
enable = true; enable = true;
dnsExtensionMechanism = false;
useLocalResolver = false;
};
services.kresd = {
enable = true;
listenPlain = [ ];
extraConfig = '' extraConfig = ''
log_level("notice") Cache=no
net.listen('127.0.0.1', 53)
modules = { 'hints > iterate', 'stats', 'predict' }
cache.size = 100 * MB
trust_anchors.remove(".")
policy.add(policy.all(policy.TLS_FORWARD( {
{ "8.8.8.8", hostname="dns.google" } })))
''; '';
# policy.add(policy.suffix(policy.FORWARD({ "100.100.100.100" }), policy.todnames({ 'coho-tet.ts.net' })))
}; };
# Enable Tailscale # Enable Tailscale
services.tailscale = { services.tailscale.enable = true;
enable = true;
extraUpFlags = [ "--accept-dns=false" ];
};
# services.tailscale.useRoutingFeatures = "both"; # services.tailscale.useRoutingFeatures = "both";
services.dae.enable = true; services.dae.enable = true;

View file

@ -37,14 +37,12 @@
commonSettings = { commonSettings = {
auth.enable = true; auth.enable = true;
comin.enable = true;
proxyServer = { proxyServer = {
enable = true; enable = true;
users = [ users = [
"wyj" "wyj"
"yhb" "yhb"
"xin" "xin"
"zx"
]; ];
}; };
}; };

View file

@ -9,9 +9,6 @@ sing-box:
xin: xin:
password: ENC[AES256_GCM,data:SRiPFO+Uwy/PT41SIg7eI68wk4AX6so=,iv:aXwP5wa1IrlnvFo/ZL+DYFFHDdWw2Z83de3ApHUTsXo=,tag:sxXoy1FnDxZBQCDeNxphzQ==,type:str] password: ENC[AES256_GCM,data:SRiPFO+Uwy/PT41SIg7eI68wk4AX6so=,iv:aXwP5wa1IrlnvFo/ZL+DYFFHDdWw2Z83de3ApHUTsXo=,tag:sxXoy1FnDxZBQCDeNxphzQ==,type:str]
uuid: ENC[AES256_GCM,data:7xK53SO4x0tOIEIYl6kmmAvnpdsR/tYQoG1t/ytsnO4QqWY3,iv:i694Fnu7g1OA3IGzSaoSGA5/eMPo+I/1TZbYuaQrgNA=,tag:4cUlioJn/IvsvZclgboOSA==,type:str] uuid: ENC[AES256_GCM,data:7xK53SO4x0tOIEIYl6kmmAvnpdsR/tYQoG1t/ytsnO4QqWY3,iv:i694Fnu7g1OA3IGzSaoSGA5/eMPo+I/1TZbYuaQrgNA=,tag:4cUlioJn/IvsvZclgboOSA==,type:str]
zx:
password: ENC[AES256_GCM,data:UkRaj5aadq8Ea3j3wh6YQDzxmew=,iv:vrJ7h97KaWmp7+rkYowdTDI7HIq71ZUIERE3o0BY5Fc=,tag:YEPydn9fLmEBYBDD//6Pfw==,type:str]
uuid: ENC[AES256_GCM,data:W+qXN1Xa5ZMXRQh+7dtZkExFrp6qqEOkoxn8Fj5qQ5U23ytz,iv:559UEoMyY3/RfmwJLFCerkuV0DjTbhaRPbW56toxMEU=,tag:pv706bZgEblyGS7V9mwABA==,type:str]
sops: sops:
kms: [] kms: []
gcp_kms: [] gcp_kms: []
@ -54,8 +51,8 @@ sops:
K1F1SzI2NFNIKzlreVBXSjAxaUxQd28KFaf1uu7OlqIe0TirJFgS3iPjhXPyfNDE K1F1SzI2NFNIKzlreVBXSjAxaUxQd28KFaf1uu7OlqIe0TirJFgS3iPjhXPyfNDE
m2XUjzdXp+chJCzVOFvpYStqz+e08ADEc+jp3YsTLcxyqvXhQdyL/Q== m2XUjzdXp+chJCzVOFvpYStqz+e08ADEc+jp3YsTLcxyqvXhQdyL/Q==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-01-31T07:11:08Z" lastmodified: "2024-12-06T04:35:52Z"
mac: ENC[AES256_GCM,data:CYOPIN29pg5ldsLgkMaqSqKmTKusSBKVVifU2eGPIEILcYEwMmmGkvCH7jG8+QnOicfSTIonA0sPBO/g36X5bLhQIcmzUEnImSXVFLXpvHM2haIxPSHG/xvaLbIPcHMKvHbeyIGIhIdfPp7ssyH1Aa/+PgtfTIMUeOFbIWykgfE=,iv:+u7kyGUgmeEJ2T6rnBS9ACAk4Ka2OPJrz4sCZLVTPP8=,tag:d2eimY7wGwoQZZEh3d0UZA==,type:str] mac: ENC[AES256_GCM,data:DAg4UTwNv+rs6hye2z5UUtA1a4yZbFaAWjLoKAXf87tKgBCZzK8C1q6gLyTQOqp07ptYQd5Q951kfE1a/35SFJsubREzJmu6haxznRgq7pO5HDGqgtjYEHsngsWZh3bUSX/aG2dLISdD81VY68nLzTO0r4h/SL6DNG36RzJgL8E=,iv:V0WhENNt/Szi5VWVD2t5AsWP1tOZUGjFjMNYPDq59XI=,tag:ThRstdzVNtSs6E7qlvKPOw==,type:str]
pgp: [] pgp: []
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.9.2 version: 3.9.1

View file

@ -0,0 +1,74 @@
{
pkgs,
...
}:
{
imports = [
./hardware-configuration.nix
./networking.nix
./services.nix
./services
];
sops = {
defaultSopsFile = ./secrets.yaml;
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
secrets = {
gts_env = {
owner = "gotosocial";
};
};
};
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.efi.efiSysMountPoint = "/boot";
boot.loader.grub = {
enable = true;
efiSupport = true;
configurationLimit = 5;
};
environment.systemPackages = with pkgs; [
cifs-utils
git
];
# Disable docs on servers
documentation.nixos.enable = false;
documentation.man.enable = false;
system.stateVersion = "22.11";
networking = {
hostName = "massicot";
};
services.tailscale.enable = true;
commonSettings = {
auth.enable = true;
nix = {
enable = true;
};
};
security.sudo = {
execWheelOnly = true;
wheelNeedsPassword = false;
};
services.openssh = {
enable = true;
settings = {
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
PermitRootLogin = "no";
GSSAPIAuthentication = "no";
KerberosAuthentication = "no";
};
};
services.fail2ban.enable = true;
programs.mosh.enable = true;
systemd.services.sshd.wantedBy = pkgs.lib.mkForce [ "multi-user.target" ];
}

View file

@ -0,0 +1,32 @@
{ modulesPath, ... }:
{
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
boot.loader.grub = {
efiSupport = true;
device = "nodev";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/AC27-D9D6";
fsType = "vfat";
};
boot.initrd.availableKernelModules = [
"ata_piix"
"uhci_hcd"
"xen_blkfront"
];
boot.initrd.kernelModules = [ "nvme" ];
fileSystems."/" = {
device = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_35068215-part1";
fsType = "ext4";
};
fileSystems."/mnt/storage" = {
device = "/dev/disk/by-id/scsi-0HC_Volume_101302395";
fsType = "btrfs";
options = [
"subvol=storage"
"compress=zstd"
"noatime"
];
};
}

View file

@ -177,11 +177,8 @@ in
"https://immich.xinyang.life:8000/api/oauth/mobile-redirect/" "https://immich.xinyang.life:8000/api/oauth/mobile-redirect/"
"https://immich.xinyang.life:8000/auth/login" "https://immich.xinyang.life:8000/auth/login"
"https://immich.xinyang.life:8000/user-settings" "https://immich.xinyang.life:8000/user-settings"
"https://immich.xiny.li:8443/api/oauth/mobile-redirect/"
"https://immich.xiny.li:8443/auth/login"
"https://immich.xiny.li:8443/user-settings"
]; ];
originLanding = "https://immich.xiny.li:8443/auth/login?autoLaunch=0"; originLanding = "https://immich.xinyang.life:8000/auth/login?autoLaunch=0";
allowInsecureClientDisablePkce = true; allowInsecureClientDisablePkce = true;
scopeMaps = { scopeMaps = {
immich-users = [ immich-users = [

View file

@ -0,0 +1,14 @@
{ pkgs, ... }:
{
networking.useNetworkd = true;
systemd.network.networks."10-wan" = {
matchConfig.MACAddress = "96:00:02:68:7d:2d";
networkConfig = {
DHCP = "ipv4";
Gateway = "fe80::1";
};
address = [
"2a01:4f8:c17:345f::3/64"
];
};
}

View file

@ -0,0 +1,40 @@
storage_box_mount: ENC[AES256_GCM,data:9lOAL3tkfB0pN4/cuM4SX0xoMrW0UUEzTN8spw3MQ3BWrfsRc3Stsce3puXz1sRf,iv:7Q9wzpBgQ3tqcfy0n/c6Ya84Kg60nhR/e2H0pVntWsY=,tag:9a0xvNBGQpCvhxgmV3hrww==,type:str]
gts_env: ENC[AES256_GCM,data:StggMdJPevrDbrVDrBDETdQYnSOaTESkgSqpGKrSHXhS21nyCE5ya7/X4l0GVTXoGCyfWG7vK+PDW22mJxpYcj2CBaVUYDu/,iv:2fqWDaWAWxTXdG7w5HU6jBcappFEByNtYs0Jd6PaYnA=,tag:KGhrMemao6g4FkEAZmmacg==,type:str]
hedgedoc_env: ENC[AES256_GCM,data:+rjEctM6IJUpn7WcAnBS9TkQi2lCq4wKPxbaOApffH0tFyu56SpECrLpmM749I7th3N+UGb0pLM7+Ywr7fbuuMfUuIWom6Y+CKYw4yMlgjzTaaNqBmstvMxLaPnmA01G9ie1rQ==,iv:YBIyQQ6xiUyxSnR5epE5hV9OqETLKC5CFTEaRJdErGU=,tag:77kHYQ2i2APVyadhMhmvWA==,type:str]
grafana_oauth_secret: ENC[AES256_GCM,data:43+EBnN912eK/08MdJokWPxi2Lxn/D4hSHPhNmHOk9awWQ7ut/el0vaAa+Epqnui3le2p4VuotQT6XlIuDLrixIomrc6Qw5HERAEdZmbrGvDlrrNhw==,iv:Pfn8rL0LtG3hym9EdSZRjaPLMlWlut/nt2FEtRWnULo=,tag:moDWqF3aBbnO4aG0Cysfcw==,type:str]
miniflux:
oauth2_secret: ENC[AES256_GCM,data:jcZR9E9jXNKfkAoGgBI19qQeaz26R6qiAWjP4XrftHSCQV974tjJl+fiU8Xgi0bViA==,iv:/aY0bL/oAAHBhohy3FHB/UEDYryw7A7JOKvEbLtDHJg=,tag:Fn/6NurNkRphXySR+y9S9Q==,type:str]
forgejo:
env: ENC[AES256_GCM,data:TMeguXfanISeyvsay9SBqm3SSGKpp5nCkqhHblf0QHNzHWGQKwpORmWfOtVfgOh9qdDqq8wYBpXznmbvixjV,iv:IR/rMoAIvZCw9FURmau4+g8c3pvI9BRs7v1NJ5ia4jI=,tag:kjwf6RN5HN8I2sUhDcr4UQ==,type:str]
restic:
repo_url: ENC[AES256_GCM,data:GMHbrjgwajnYSiqtoYaKiFT/aDWDwlzEkvMLPzYf7C9PvLr7T4zeWyAA9//8huldyxO3+nk6O9lR9ORZKZfb8/MYB7nRB03sZQ==,iv:6uBhsksOGDjoc13U2xWLz7I+0fzGRhnw0nStACqlnug=,tag:uhH28NYq+ly1bmCV/cpxkQ==,type:str]
repo_password: ENC[AES256_GCM,data:jRHNgOk5ChWdqMKsd/V4Xg==,iv:wrgF5pau/RylG1nmJYmvrZ02o67qkkT5PrZAQlXb6Qo=,tag:X0WVpMqi8xeoATss/sSPMA==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1uw059wcwfvd9xuj0hpqzqpeg7qemecspjrsatg37wc7rs2pumfdsgken0c
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1aGRvUUtjcDU2bnhaNDJD
K3c5TnFJeHQzM2VpeHphR2dGeS9NYzcyYjJnCnNrQ3dxL1hqR2MyQXhldUZ1VEJp
N25nVHZ1QjRydW9hTWE5d0x2M2pPNkkKLS0tIFpiRW8rZ1Q1R1RCZGN1ZGs3ek45
UENaRjJPWFJqUlpzd3dHSC9pdnZ6STQKQaaY28FYUk3O9TTkX9LQTzlrqZVojgxY
M+N6LApfdoioQCmXduDbj18i0eUbECTBXR/uEFEIHbn6AJVD/vx7iw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1jle2auermhswqtehww9gqada8car5aczrx43ztzqf9wtcld0sfmqzaecta
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRY0lIeE9tWDA3Q21IWk1E
YnlaQUJybFB2bmFpbG1UZ0UyNG16WkRkZlNVCmUySHVBcXpWekpVN3R5dGs5ODY1
V1ZlUk4zRSs1NkVjY3JSMVVQSXJ1OEkKLS0tIFMzeUNaYVpoNnV3TE1oamEwTEo2
dnFBa0lDWWZtS1BHdzBoVzNTaGNkSEEKi/W1n7RT8NpTp00SBMwxsUJAPDhumJ/i
V2VnaSNwouD3SswTcoBzqQpBP9XrqzjIYGke90ZODFQbMY9WDQ+O0g==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-11-28T03:57:35Z"
mac: ENC[AES256_GCM,data:xjZrlwfWLtZNYfH+KiE2ICt9Jo4nx/LKaEYi/ECN/Od+ZTjety0V6RJ/RfmI6q3K1WMj0sAGc56hCZ0iOn25L8wK6dc14hZVoSwwbIiQ7hTQE5LcK+NbXNmy3r/YC855DHG9kE08eYGHdNcBbckZg3HhkHQ9UYS/Ox/QFFuBa5Q=,iv:N3AW+sr9ET3c/ArXr176haRewYFsfgsNn+hkC0MDJwA=,tag:SCikn+F8btuSBswV+oCdXg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.1

View file

@ -0,0 +1,102 @@
{
config,
pkgs,
lib,
...
}:
let
kanidm_listen_port = 5324;
in
{
imports = [
./kanidm-provision.nix
];
networking.firewall.allowedTCPPorts = [
80
443
2222
8448
];
networking.firewall.allowedUDPPorts = [
80
443
8448
];
custom.monitoring = {
promtail.enable = true;
};
custom.prometheus.exporters = {
enable = true;
blackbox = {
enable = true;
};
node = {
enable = true;
};
};
security.acme = {
acceptTerms = true;
certs."auth.xinyang.life" = {
email = "lixinyang411@gmail.com";
listenHTTP = "127.0.0.1:1360";
group = "kanidm";
};
};
services.kanidm = {
package = pkgs.kanidm.withSecretProvisioning;
enableServer = true;
serverSettings = {
domain = "auth.xinyang.life";
origin = "https://auth.xinyang.life";
bindaddress = "[::]:${toString kanidm_listen_port}";
tls_key = ''${config.security.acme.certs."auth.xinyang.life".directory}/key.pem'';
tls_chain = ''${config.security.acme.certs."auth.xinyang.life".directory}/fullchain.pem'';
online_backup.versions = 7;
# db_path = "/var/lib/kanidm/kanidm.db";
};
};
users.users.conduit = {
isSystemUser = true;
group = "conduit";
};
users.groups.conduit = { };
services.gotosocial = {
enable = true;
settings = {
log-level = "debug";
host = "xinyang.life";
letsencrypt-enabled = false;
bind-address = "localhost";
instance-expose-public-timeline = true;
oidc-enabled = true;
oidc-idp-name = "Kanidm";
oidc-issuer = "https://auth.xinyang.life/oauth2/openid/gts";
oidc-client-id = "gts";
oidc-link-existing = true;
storage-local-base-path = "/mnt/storage/gotosocial/storage";
};
environmentFile = config.sops.secrets.gts_env.path;
};
services.caddy = {
enable = true;
virtualHosts."http://auth.xinyang.life:80".extraConfig = ''
reverse_proxy ${config.security.acme.certs."auth.xinyang.life".listenHTTP}
'';
virtualHosts."https://auth.xinyang.life".extraConfig = ''
reverse_proxy https://127.0.0.1:${toString kanidm_listen_port} {
header_up Host {upstream_hostport}
header_down Access-Control-Allow-Origin "*"
transport http {
tls_server_name ${config.services.kanidm.serverSettings.domain}
}
}
'';
};
}

View file

@ -0,0 +1,5 @@
{
imports = [
./restic.nix
];
}

View file

@ -0,0 +1,42 @@
{
config,
lib,
pkgs,
...
}:
let
sqliteBackup = fromPath: toPath: file: ''
mkdir -p ${toPath}
${lib.getExe pkgs.sqlite} ${fromPath} ".backup '${toPath}/${file}'"
'';
in
{
sops.secrets = {
"restic/repo_url" = {
sopsFile = ../secrets.yaml;
};
"restic/repo_password" = {
sopsFile = ../secrets.yaml;
};
};
custom.restic = {
enable = true;
paths = [
"/backup"
"/mnt/storage"
];
backupPrepareCommand = [
(sqliteBackup "/var/lib/hedgedoc/db.sqlite" "/backup/hedgedoc" "db.sqlite")
(sqliteBackup "/var/lib/bitwarden_rs/db.sqlite3" "/backup/bitwarden_rs" "db.sqlite3")
(sqliteBackup "/var/lib/gotosocial/database.sqlite" "/backup/gotosocial" "database.sqlite")
(sqliteBackup "/var/lib/kanidm/kanidm.db" "/backup/kanidm" "kanidm.db")
];
};
services.restic.backups.${config.networking.hostName} = {
extraBackupArgs = [
"--limit-upload=1024"
];
};
}

View file

@ -69,7 +69,7 @@
neovim neovim
jq jq
iptables iptables
nftables ebtables
tcpdump tcpdump
busybox busybox
ethtool ethtool
@ -88,53 +88,15 @@
systemd.network = { systemd.network = {
enable = true; enable = true;
networks."lan" = {
matchConfig.Name = "enu1";
networkConfig.DHCP = "no";
linkConfig.RequiredForOnline = "no";
};
networks."wan" = { networks."wan" = {
matchConfig.Name = "end0"; matchConfig.Name = "end0";
networkConfig.DHCP = "yes"; networkConfig.DHCP = "yes";
linkConfig.RequiredForOnline = false; linkConfig.RequiredForOnline = "yes";
};
networks."lan" = {
matchConfig.Name = "enu1";
networkConfig = {
DHCP = "no";
DHCPServer = "yes";
Address = "10.1.1.1/24";
};
dhcpServerConfig = {
ServerAddress = "10.1.1.1/24";
UplinkInterface = "end0";
EmitDNS = "yes";
DNS = [ "192.168.1.1" ];
};
linkConfig.RequiredForOnline = false;
};
};
networking.firewall.enable = false;
networking.nftables = {
enable = true;
tables = {
filter = {
family = "inet";
content = ''
chain forward {
iifname { "enu1" } oifname { "end0" } accept comment "Allow trusted LAN to WAN"
iifname { "end0" } oifname { "enu1" } ct state { established, related } accept comment "Allow established back to LANs"
iifname { "enu1" } oifname { "tailscale0" } accept comment "Allow LAN to Tailscale"
}
'';
};
nat = {
family = "ip";
content = ''
chain postrouting {
type nat hook postrouting priority 100; policy accept;
oifname "end0" masquerade
oifname "tailscale0" masquerade
}
'';
};
}; };
}; };
@ -143,11 +105,7 @@
configFile = "/var/lib/dae/config.dae"; configFile = "/var/lib/dae/config.dae";
}; };
services.tailscale = { services.tailscale.enable = true;
enable = true;
extraSetFlags = [
"--advertise-routes=10.1.1.0/24"
];
};
}; };
} }

View file

@ -37,7 +37,6 @@
commonSettings = { commonSettings = {
auth.enable = true; auth.enable = true;
comin.enable = true;
}; };
nixpkgs.system = "x86_64-linux"; nixpkgs.system = "x86_64-linux";

View file

@ -12,8 +12,6 @@ let
hedgedocDomain hedgedocDomain
grafanaUrl grafanaUrl
ntfyUrl ntfyUrl
internalDomain
transmissionExporterUrl
; ;
removeHttps = s: lib.removePrefix "https://" s; removeHttps = s: lib.removePrefix "https://" s;
in in
@ -60,22 +58,7 @@ in
node.enable = true; node.enable = true;
}; };
ruleModules = ruleModules =
[ (mkCaddyRules [ { host = "thorite"; } ])
{
name = "comin_rules";
rules = [
{
alert = "CominBuildFailed";
expr = "comin_build_info != 1";
for = "1m";
labels = {
severity = "critical";
};
}
];
}
]
++ (mkCaddyRules [ { host = "thorite"; } ])
++ (mkNodeRules [ { host = "thorite"; } ]) ++ (mkNodeRules [ { host = "thorite"; } ])
++ (mkBlackboxRules [ { host = "thorite"; } ]); ++ (mkBlackboxRules [ { host = "thorite"; } ]);
}; };
@ -98,24 +81,7 @@ in
]; ];
passwordFile = config.sops.secrets."prometheus/metrics_password".path; passwordFile = config.sops.secrets."prometheus/metrics_password".path;
in in
[ (mkScrapes [
{
job_name = "comin";
scheme = "http";
static_configs = [
{
targets = map (host: "${host}.${internalDomain}:4243") [
"weilite"
"thorite"
"la-00"
"hk-00"
"fra-00"
];
}
];
}
]
++ (mkScrapes [
{ {
name = "immich"; name = "immich";
scheme = "http"; scheme = "http";
@ -152,27 +118,9 @@ in
{ {
name = "loki"; name = "loki";
scheme = "http"; scheme = "http";
address = "thorite.${internalDomain}"; address = "thorite.coho-tet.ts.net";
port = 3100; port = 3100;
} }
{
name = "transmission";
scheme = "http";
address = "weilite.${internalDomain}";
port = 19091;
}
{
name = "sonarr";
scheme = "http";
address = "weilite.${internalDomain}";
port = 21560;
}
{
name = "radarr";
scheme = "http";
address = "weilite.${internalDomain}";
port = 21561;
}
]) ])
++ (mkCaddyScrapes [ ++ (mkCaddyScrapes [
{ address = "thorite.coho-tet.ts.net"; } { address = "thorite.coho-tet.ts.net"; }
@ -181,6 +129,7 @@ in
]) ])
++ (mkNodeScrapes [ ++ (mkNodeScrapes [
{ address = "thorite.coho-tet.ts.net"; } { address = "thorite.coho-tet.ts.net"; }
{ address = "massicot.coho-tet.ts.net"; }
{ address = "weilite.coho-tet.ts.net"; } { address = "weilite.coho-tet.ts.net"; }
{ address = "biotite.coho-tet.ts.net"; } { address = "biotite.coho-tet.ts.net"; }
{ address = "hk-00.coho-tet.ts.net"; } { address = "hk-00.coho-tet.ts.net"; }
@ -190,7 +139,11 @@ in
++ (mkBlackboxScrapes [ ++ (mkBlackboxScrapes [
{ {
hostAddress = "thorite.coho-tet.ts.net"; hostAddress = "thorite.coho-tet.ts.net";
targetAddresses = probeList; targetAddresses = probeList ++ [ "49.13.13.122:443" ];
}
{
hostAddress = "massicot.coho-tet.ts.net";
targetAddresses = probeList ++ [ "45.142.178.32:443" ];
} }
{ {
hostAddress = "weilite.coho-tet.ts.net"; hostAddress = "weilite.coho-tet.ts.net";

View file

@ -12,36 +12,13 @@
./services ./services
]; ];
options = {
node = lib.mkOption {
type = lib.types.attrs;
default = { };
};
};
config = { config = {
networking = { networking.hostName = "weilite";
hostName = "weilite";
useNetworkd = true;
};
systemd.network = {
enable = true;
networks = {
"10-wan" = {
matchConfig.MACAddress = "52:54:00:db:23:d0";
networkConfig.DHCP = "ipv4";
};
};
};
commonSettings = { commonSettings = {
auth.enable = true; auth.enable = true;
nix = { nix = {
enable = true; enable = true;
}; };
comin.enable = true;
};
node = {
mediaDir = "/mnt/nixos/media";
}; };
boot = { boot = {
@ -56,24 +33,25 @@
"usb_storage" "usb_storage"
"sd_mod" "sd_mod"
]; ];
kernelModules = [ kernelModules = [ "kvm-intel" ];
"kvm-intel"
];
kernelPackages = pkgs.linuxPackages_6_12;
}; };
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
environment.systemPackages = [ environment.systemPackages = [ pkgs.virtiofsd ];
pkgs.virtiofsd
pkgs.intel-gpu-tools
pkgs.pciutils
];
sops = { sops = {
defaultSopsFile = ./secrets.yaml; defaultSopsFile = ./secrets.yaml;
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
secrets = { secrets = {
cloudflare_dns_token = {
owner = "caddy";
mode = "400";
};
dnspod_dns_token = {
owner = "caddy";
mode = "400";
};
"restic/localpass" = { "restic/localpass" = {
owner = "restic"; owner = "restic";
}; };
@ -95,6 +73,13 @@
}; };
systemd.mounts = [ systemd.mounts = [
{
what = "immich";
where = "/mnt/XinPhotos/immich";
type = "virtiofs";
options = "rw,nodev,nosuid";
wantedBy = [ "immich-server.service" ];
}
{ {
what = "originals"; what = "originals";
where = "/mnt/XinPhotos/originals"; where = "/mnt/XinPhotos/originals";
@ -103,45 +88,21 @@
wantedBy = [ "immich-server.service" ]; wantedBy = [ "immich-server.service" ];
} }
{ {
what = "nixos"; what = "restic";
where = "/mnt/nixos"; where = "/var/lib/restic";
type = "virtiofs"; type = "virtiofs";
options = "rw,nodev,nosuid"; options = "rw,nodev,nosuid";
}
{
what = "/mnt/nixos/ocis";
where = "/var/lib/ocis";
options = "bind";
after = [ "mnt-nixos.mount" ];
wantedBy = [ "ocis.service" ];
}
{
what = "/mnt/nixos/restic";
where = "/var/lib/restic";
options = "bind";
after = [ "mnt-nixos.mount" ];
wantedBy = [ "restic-rest-server.service" ]; wantedBy = [ "restic-rest-server.service" ];
} }
{ {
what = "/mnt/nixos/immich"; what = "ocis";
where = "/var/lib/immich"; where = "/var/lib/ocis";
options = "bind"; type = "virtiofs";
after = [ "mnt-nixos.mount" ]; options = "rw,nodev,nosuid";
wantedBy = [ "immich-server.service" ]; wantedBy = [ "ocis.service" ];
} }
]; ];
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [
intel-media-driver
intel-vaapi-driver
vaapiVdpau
intel-compute-runtime # OpenCL filter support (hardware tonemapping and subtitle burn-in)
intel-media-sdk # QSV up to 11th gen
];
};
services.openssh.ports = [ services.openssh.ports = [
22 22
2222 2222
@ -167,6 +128,44 @@
# tailscale derper module use nginx for reverse proxy # tailscale derper module use nginx for reverse proxy
services.nginx.enable = lib.mkForce false; services.nginx.enable = lib.mkForce false;
services.caddy = {
enable = true;
package = pkgs.caddy.withPlugins {
caddyModules = [
{
repo = "github.com/caddy-dns/cloudflare";
version = "89f16b99c18ef49c8bb470a82f895bce01cbaece";
}
{
repo = "github.com/caddy-dns/dnspod";
version = "1fd4ce87e919f47db5fa029c31ae74b9737a58af";
}
];
vendorHash = "sha256-OhOeU2+JiJyIW9WdCYq98OKckXQZ9Fn5zULz0aLsXMI=";
};
virtualHosts."derper00.namely.icu:8443".extraConfig = ''
reverse_proxy 127.0.0.1:${toString config.services.tailscale.derper.port}
'';
virtualHosts."weilite.coho-tet.ts.net:8080".extraConfig = ''
reverse_proxy 127.0.0.1:${toString config.services.immich.port}
'';
# API Token must be added in systemd environment file
virtualHosts."immich.xinyang.life:8000".extraConfig = ''
reverse_proxy 127.0.0.1:${toString config.services.immich.port}
'';
globalConfig = ''
acme_dns dnspod {env.DNSPOD_API_TOKEN}
'';
};
networking.firewall.allowedTCPPorts = [ 8000 ];
systemd.services.caddy = {
serviceConfig = {
EnvironmentFile = config.sops.secrets.dnspod_dns_token.path;
};
};
time.timeZone = "Asia/Shanghai"; time.timeZone = "Asia/Shanghai";
fileSystems."/" = { fileSystems."/" = {

View file

@ -1,16 +1,9 @@
caddy: cloudflare_dns_token: ENC[AES256_GCM,data:m4euSkxxJmiMk9UPyeni/hwpl1W9A4MM0ssg71eOBsX4fFyG39NJeKbNTddW7omBx3gKJtnrRuDdOj5wpg==,iv:eRVzsGwz8hWC42jM+VeSUWCS9Gi8VGSY8Fyh+En0jEI=,tag:NNE8VeNQ8kp9KyziVokyuQ==,type:str]
cf_dns_token: ENC[AES256_GCM,data:7PvP3oYMZ3dAeWaJNiuvEweUf3psDhyu90FT6cP0/AIOa0E40sdIRQ==,iv:IIYnZ35xAm9JJa14oHJi+ddI0u7Pgc4MfPLnKT4IlPc=,tag:V1PGZpaVzdN2cLpktbvTnA==,type:str] dnspod_dns_token: ENC[AES256_GCM,data:uZfr3g103amywxh3NMU+AkwuYb61svzyavvQ4rxJijIMIbfPvERrVNcyivoOrFWYXHpPWkhZFdU=,iv:mArVAcebW9i+u26GmQmfmJTsFkR4ZRMIisTqjpMYan8=,tag:Zsmv1Wzfi3+PHigjReToHQ==,type:str]
dnspod_dns_token: ENC[AES256_GCM,data:ATed7RqLu1u06B61Irhd4SCzjK/Z823ygAgzROsNixZ2rExpB/Xo,iv:L121CGA+iZhn9V6mG2qEu3FI91/s7JO3cVTAwmAeqGw=,tag:l/7MXMZNqgFBwgCCMeZR2A==,type:str]
immich: immich:
oauth_client_secret: ENC[AES256_GCM,data:EFs2hPjGMj0idwY3oQVIDTOIWkdwoAoAVjDQE9Z2eAKzUDH3grmYpYE+33V8d/Ux,iv:A9cjwFr/ZqltG62/N8MQ1LhdDbSIVVAqIPVB492zYJw=,tag:VTTtE697BZTVsI32UF53/w==,type:str] oauth_client_secret: ENC[AES256_GCM,data:EFs2hPjGMj0idwY3oQVIDTOIWkdwoAoAVjDQE9Z2eAKzUDH3grmYpYE+33V8d/Ux,iv:A9cjwFr/ZqltG62/N8MQ1LhdDbSIVVAqIPVB492zYJw=,tag:VTTtE697BZTVsI32UF53/w==,type:str]
restic: restic:
localpass: ENC[AES256_GCM,data:GIQAmkpDmGu4+sSG5/b5yQ==,iv:dcu6F8NnVjeQzEG2vM3fOV5owI0PWc86ts20UP3vN18=,tag:vsG8x062FG1pH5YNcAajeg==,type:str] localpass: ENC[AES256_GCM,data:GIQAmkpDmGu4+sSG5/b5yQ==,iv:dcu6F8NnVjeQzEG2vM3fOV5owI0PWc86ts20UP3vN18=,tag:vsG8x062FG1pH5YNcAajeg==,type:str]
transmission:
rpc-password: ENC[AES256_GCM,data:4dumy0hygGOuwU3ANky3xEKRDRBAJWE=,iv:HVV2J+F8HndHZNsMD2YmkWrJOzk5JIapGd0SuQP8VqU=,tag:xqp5pxh5cYYogA4alrmIfg==,type:str]
sonarr:
api-key: ENC[AES256_GCM,data:/CkApTCLQy8TLHGKSM1saacNi9uQDswAjshRSLJk1hg=,iv:PNX4BZLx7krs12lxgORMSarnt0c/ga8yPtoLSzbQ+sY=,tag:V1pp9OCtX5/5fbwLBMGlOQ==,type:str]
radarr:
api-key: ENC[AES256_GCM,data:AeJArngvgmqnxk2g13QjMa6XS893B+3ZdX2K8OqXRQg=,iv:NrQf3yyqRpHMeWQ3bpPH4fUDdo/x2uB6pQCq0ZrFP5c=,tag:Yj2PSy6zRfe8anW0RGuZAQ==,type:str]
sops: sops:
kms: [] kms: []
gcp_kms: [] gcp_kms: []
@ -35,8 +28,8 @@ sops:
V0thRjU4WGpQRGFpcnoxSjZTZHhTTkUKzNMHh9p7GUY3hL5XZ9S4x20CwaItsXFV V0thRjU4WGpQRGFpcnoxSjZTZHhTTkUKzNMHh9p7GUY3hL5XZ9S4x20CwaItsXFV
RKujsFVVBd8Kuq/jyOCBTRCscuHI4LW/wYeZYHFEZFSTK2liAqspgw== RKujsFVVBd8Kuq/jyOCBTRCscuHI4LW/wYeZYHFEZFSTK2liAqspgw==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-02-11T08:45:49Z" lastmodified: "2024-12-03T05:59:51Z"
mac: ENC[AES256_GCM,data:iObzkfSxKET1kE8yQbSxffG1qDO95SWfIRSdwbYcwP4mHOrl5sOtlGEjexVaLl7uKa0SMCK6BghbMr4EdLatiOmngsAzr8bxe/GsPZiCze04nr0VbKBgHxKr74gT8d14dwV+Y+np/5fgRZea7zxzJ4YaVfeUOG9PBsa7L6RWbx0=,iv:LMM096xLa5cOiLVTiFO20jBUaK1Uw4aOqsz7eH9u9vc=,tag:C1fPHN9KFbydcy1lRAhGvQ==,type:str] mac: ENC[AES256_GCM,data:0dLbfkm7fJvH5Mmct0/qHulg2AtDCeeeOgWMXfeGRUaX3GlLDiLga0zW4uNPDuahVecdh6ofvYfBOxFaGUdBCHk9vq5GzrwrzBNhqObWQ3AqVuq5rjqSxEKoFM4Eb5qoqaOefFzT/9qC94NDETTsHhjiEeIgd4fgSr2dazNiFPE=,iv:Ggw0FHzkrhKh5Uzo3seHGwwHsWW/tTAgAl0iIq9PVk4=,tag:rJvUI5/wsLJ01XyKmkRghw==,type:str]
pgp: [] pgp: []
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.9.2 version: 3.9.1

View file

@ -1,63 +0,0 @@
{ config, pkgs, ... }:
{
sops = {
secrets = {
"caddy/cf_dns_token" = {
owner = "caddy";
mode = "400";
};
"caddy/dnspod_dns_token" = {
owner = "caddy";
mode = "400";
};
};
templates."caddy.env".content = ''
CF_API_TOKEN=${config.sops.placeholder."caddy/cf_dns_token"}
DNSPOD_API_TOKEN=${config.sops.placeholder."caddy/dnspod_dns_token"}
'';
};
services.caddy =
let
acmeCF = "tls {
dns cloudflare {env.CF_API_TOKEN}
}";
acmeDnspod = "tls {
dns dnspod {env.DNSPOD_API_TOKEN}
}";
in
{
enable = true;
package = pkgs.caddy.withPlugins {
plugins = [
"github.com/caddy-dns/cloudflare@v0.0.0-20240703190432-89f16b99c18e"
"github.com/caddy-dns/dnspod@v0.0.4"
];
hash = "sha256-9DZ58u/Y17njwQKvCZNys8DrCoRNsHQSBD2hV2cm8uU=";
};
virtualHosts."derper00.namely.icu:8443".extraConfig = ''
${acmeDnspod}
reverse_proxy 127.0.0.1:${toString config.services.tailscale.derper.port}
'';
# API Token must be added in systemd environment file
virtualHosts."immich.xinyang.life:8000".extraConfig = ''
${acmeDnspod}
reverse_proxy 127.0.0.1:${toString config.services.immich.port}
'';
virtualHosts."immich.xiny.li:8443".extraConfig = ''
${acmeCF}
reverse_proxy 127.0.0.1:${toString config.services.immich.port}
'';
};
networking.firewall.allowedTCPPorts = [
8000
8443
];
systemd.services.caddy = {
serviceConfig = {
EnvironmentFile = config.sops.templates."caddy.env".path;
};
};
}

View file

@ -1,11 +1,8 @@
{ {
imports = [ imports = [
./caddy.nix
./ocis.nix ./ocis.nix
./restic.nix ./restic.nix
./media-download.nix ./media-download.nix
./immich.nix ./immich.nix
./jellyfin.nix
./transmission.nix
]; ];
} }

View file

@ -3,14 +3,11 @@
... ...
}: }:
let let
inherit (config.my-lib.settings) idpUrl;
user = config.systemd.services.immich-server.serviceConfig.User; user = config.systemd.services.immich-server.serviceConfig.User;
immichUrl = "immich.xiny.li:8443";
jsonSettings = { jsonSettings = {
oauth = { oauth = {
enabled = true; enabled = true;
issuerUrl = "https://${idpUrl}/oauth2/openid/immich/"; issuerUrl = "https://auth.xinyang.life/oauth2/openid/immich/";
clientId = "immich"; clientId = "immich";
clientSecret = config.sops.placeholder."immich/oauth_client_secret"; clientSecret = config.sops.placeholder."immich/oauth_client_secret";
scope = "openid email profile"; scope = "openid email profile";
@ -19,7 +16,7 @@ let
buttonText = "Login with Kanidm"; buttonText = "Login with Kanidm";
autoLaunch = true; autoLaunch = true;
mobileOverrideEnabled = true; mobileOverrideEnabled = true;
mobileRedirectUri = "https://${immichUrl}/api/oauth/mobile-redirect/"; mobileRedirectUri = "https://immich.xinyang.life:8000/api/oauth/mobile-redirect/";
}; };
passwordLogin = { passwordLogin = {
enabled = false; enabled = false;
@ -49,6 +46,7 @@ in
services.immich = { services.immich = {
enable = true; enable = true;
mediaLocation = "/mnt/XinPhotos/immich";
host = "127.0.0.1"; host = "127.0.0.1";
port = 3001; port = 3001;
openFirewall = true; openFirewall = true;

View file

@ -1,25 +0,0 @@
{ config, pkgs, ... }:
let
cfg = config.services.jellyfin;
in
{
services.jellyfin.enable = true;
systemd.services.jellyfin.serviceConfig = {
BindReadOnlyPaths = [
"/mnt/nixos/media:${cfg.dataDir}/media"
];
};
environment.systemPackages = with pkgs; [
jellyfin
jellyfin-web
jellyfin-ffmpeg
];
services.caddy.virtualHosts."https://weilite.coho-tet.ts.net:8920".extraConfig = ''
reverse_proxy 127.0.0.1:8096
'';
networking.firewall.allowedTCPPorts = [ 8920 ]; # allow on lan
users.users.jellyfin.extraGroups = [ "render" ];
users.groups.media.members = [ cfg.user ];
}

View file

@ -1,16 +1,15 @@
{ config, pkgs, ... }: { pkgs, ... }:
let
inherit (config.my-lib.settings)
internalDomain
;
in
{ {
sops.secrets = {
"sonarr/api-key" = { };
"radarr/api-key" = { };
};
services.jackett = { services.jackett = {
enable = true; enable = true;
package = pkgs.jackett.overrideAttrs {
src = pkgs.fetchFromGitHub {
owner = "jackett";
repo = "jackett";
rev = "v0.22.998";
hash = "sha256-CZvgDWxxIAOTkodgmFNuT3VDW6Ln4Mz+Ki7m91f0BgE=";
};
};
openFirewall = false; openFirewall = false;
}; };
@ -28,25 +27,4 @@ in
services.radarr = { services.radarr = {
enable = true; enable = true;
}; };
services.prometheus.exporters.exportarr-sonarr = {
enable = true;
url = "http://127.0.0.1:8989";
apiKeyFile = config.sops.secrets."sonarr/api-key".path;
listenAddress = "weilite.${internalDomain}";
port = 21560;
};
services.prometheus.exporters.exportarr-radarr = {
enable = true;
url = "http://127.0.0.1:7878";
apiKeyFile = config.sops.secrets."radarr/api-key".path;
listenAddress = "weilite.${internalDomain}";
port = 21561;
};
users.groups.media.members = [
config.services.sonarr.user
config.services.radarr.user
];
} }

View file

@ -34,6 +34,7 @@ in
services.restic.backups = builtins.listToAttrs [ services.restic.backups = builtins.listToAttrs [
(mkPrune "xin" "calcite") (mkPrune "xin" "calcite")
(mkPrune "xin" "massicot")
(mkPrune "xin" "biotite") (mkPrune "xin" "biotite")
(mkPrune "xin" "thorite") (mkPrune "xin" "thorite")
]; ];
@ -41,9 +42,6 @@ in
networking.firewall.allowedTCPPorts = [ 8443 ]; networking.firewall.allowedTCPPorts = [ 8443 ];
services.caddy.virtualHosts."https://backup.xinyang.life:8443".extraConfig = '' services.caddy.virtualHosts."https://backup.xinyang.life:8443".extraConfig = ''
tls {
dns dnspod {env.DNSPOD_API_TOKEN}
}
reverse_proxy ${config.services.restic.server.listenAddress} reverse_proxy ${config.services.restic.server.listenAddress}
''; '';
} }

View file

@ -1,98 +0,0 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.services.transmission;
inherit (config.my-lib.settings) transmissionExporterUrl;
in
{
sops.secrets = {
"transmission/rpc-password" = { };
};
sops.templates."transmission-cred.json" = {
content = builtins.toJSON {
rpc-password = config.sops.placeholder."transmission/rpc-password";
};
};
sops.templates."transmission-cred.env" = {
content = ''
TRANSMISSION_PASSWORD=${config.sops.placeholder."transmission/rpc-password"}
'';
};
services.transmission = {
enable = true;
package = pkgs.transmission_4;
openPeerPorts = true;
credentialsFile = config.sops.templates."transmission-cred.json".path;
settings = {
download-dir = "/mnt/nixos/media";
incomplete-dir = "/mnt/nixos/transmission/incomplete";
alt-speed-down = 40960;
alt-speed-enabled = true;
alt-speed-time-begin = 60;
alt-speed-time-day = 127;
alt-speed-time-enabled = true;
alt-speed-time-end = 420;
alt-speed-up = 4096;
bind-address-ipv4 = "0.0.0.0";
bind-address-ipv6 = "::";
download-queue-enabled = true;
download-queue-size = 10;
incomplete-dir-enabled = true;
lpd-enabled = false;
message-level = 4;
peer-congestion-algorithm = "";
peer-id-ttl-hours = 6;
peer-limit-global = 200;
peer-limit-per-torrent = 50;
peer-port = 51413;
peer-socket-tos = "cs1";
pex-enabled = true;
preallocation = 1;
prefetch-enabled = true;
queue-stalled-enabled = true;
queue-stalled-minutes = 30;
rename-partial-files = true;
rpc-bind-address = "127.0.0.1";
rpc-enabled = true;
rpc-authentication-required = true;
rpc-port = 9092;
rpc-username = "xin";
rpc-whitelist = "127.0.0.1";
speed-limit-down = 20480;
speed-limit-down-enabled = true;
speed-limit-up = 3072;
speed-limit-up-enabled = true;
start-added-torrents = true;
watch-dir-enabled = false;
};
};
services.caddy.virtualHosts."https://weilite.coho-tet.ts.net:9091".extraConfig = ''
reverse_proxy 127.0.0.1:${toString cfg.settings.rpc-port}
'';
systemd.services.prometheus-transmission-exporter = {
enable = true;
wantedBy = [ "transmission.service" ];
environment = {
WEB_ADDR = transmissionExporterUrl;
TRANSMISSION_ADDR = "http://127.0.0.1:${toString cfg.settings.rpc-port}";
TRANSMISSION_USERNAME = "xin";
};
after = [ "tailscaled.service" ];
wants = [ "tailscaled.service" ];
serviceConfig = {
ExecStart = "${lib.getExe pkgs.transmission-exporter}";
EnvironmentFile = config.sops.templates."transmission-cred.env".path;
};
};
networking.firewall.allowedTCPPorts = [ 9091 ]; # allow on lan
users.groups.media.members = [ cfg.user ];
}

View file

@ -34,6 +34,10 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = with pkgs; [
cosmic-files
];
systemd.user.services.xwayland-satellite = { systemd.user.services.xwayland-satellite = {
Install = { Install = {
WantedBy = [ "graphical-session.target" ]; WantedBy = [ "graphical-session.target" ];

View file

@ -13,10 +13,6 @@
name = "Catppuccin-GTK-Dark"; name = "Catppuccin-GTK-Dark";
package = pkgs.magnetic-catppuccin-gtk; package = pkgs.magnetic-catppuccin-gtk;
}; };
iconTheme = {
name = "Qogir";
package = pkgs.qogir-icon-theme;
};
gtk2.configLocation = "${config.xdg.configHome}/gtk-2.0/gtkrc"; gtk2.configLocation = "${config.xdg.configHome}/gtk-2.0/gtkrc";
}; };
}; };

View file

@ -44,6 +44,8 @@ in
modules-right = [ modules-right = [
"network#speed" "network#speed"
"custom/separator" "custom/separator"
"network#if"
"custom/separator"
"pulseaudio" "pulseaudio"
"custom/separator" "custom/separator"
"memory" "memory"
@ -119,6 +121,22 @@ in
format = " {percentage}%"; format = " {percentage}%";
}; };
"network#if" = {
format = "{ifname}";
format-disconnected = "󰌙";
format-ethernet = "󰌘";
format-linked = "{ifname} (No IP) 󰈁";
format-wifi = "{icon}";
format-icons = [
"󰤯"
"󰤟"
"󰤢"
"󰤥"
"󰤨"
];
interval = 10;
};
"network#speed" = { "network#speed" = {
format = "{ifname}"; format = "{ifname}";
format-disconnected = "󰌙"; format-disconnected = "󰌙";

View file

@ -11,8 +11,6 @@ let
mkEnableOption mkEnableOption
; ;
inherit (config.my-lib.settings) idpUrl;
cfg = config.commonSettings.auth; cfg = config.commonSettings.auth;
in in
{ {
@ -24,7 +22,7 @@ in
services.kanidm = { services.kanidm = {
enableClient = true; enableClient = true;
clientSettings = { clientSettings = {
uri = "https://${idpUrl}"; uri = "https://auth.xinyang.life";
}; };
enablePam = true; enablePam = true;
unixSettings = { unixSettings = {
@ -47,11 +45,11 @@ in
environment.etc."ssh/auth" = { environment.etc."ssh/auth" = {
mode = "0555"; mode = "0555";
text = '' text = ''
#!/bin/sh #!${pkgs.stdenv.shell}
${pkgs.kanidm}/bin/kanidm_ssh_authorizedkeys $1 ${pkgs.kanidm}/bin/kanidm_ssh_authorizedkeys $1
''; '';
}; };
users.groups.wheel.members = [ "xin@${idpUrl}" ]; users.groups.wheel.members = [ "xin@auth.xinyang.life" ];
users.groups.kanidm-ssh-runner = { }; users.groups.kanidm-ssh-runner = { };
users.users.kanidm-ssh-runner = { users.users.kanidm-ssh-runner = {
isSystemUser = true; isSystemUser = true;

View file

@ -1,32 +0,0 @@
{
config,
lib,
...
}:
let
inherit (lib)
mkEnableOption
mkIf
;
cfg = config.commonSettings.comin;
in
{
options.commonSettings.comin = {
enable = mkEnableOption "auto updater with comin";
};
config = {
services.comin = mkIf cfg.enable {
enable = true;
remotes = [
{
name = "origin";
url = "https://github.com/xinyangli/nixos-config.git";
branches.main.name = "deploy-comin";
}
];
hostname = config.networking.hostName;
};
};
}

View file

@ -41,8 +41,6 @@ in
nix.optimise.automatic = true; nix.optimise.automatic = true;
nix.channel.enable = false;
nix.settings = { nix.settings = {
experimental-features = [ experimental-features = [
"nix-command" "nix-command"

View file

@ -2,7 +2,6 @@
imports = [ imports = [
./common-settings/auth.nix ./common-settings/auth.nix
./common-settings/autoupgrade.nix ./common-settings/autoupgrade.nix
./common-settings/comin.nix
./common-settings/nix-conf.nix ./common-settings/nix-conf.nix
./common-settings/proxy-server.nix ./common-settings/proxy-server.nix
./common-settings/mainland.nix ./common-settings/mainland.nix

View file

@ -120,11 +120,11 @@ in
webhook_configs = [ webhook_configs = [
{ {
url = "${ntfyUrl}/prometheus-alerts?tpl=yes&m=${lib.escapeURL '' url = "${ntfyUrl}/prometheus-alerts?tpl=yes&m=${lib.escapeURL ''
{{range .alerts}}{{ if eq .status "resolved" }}{{ else }}{{ if eq .status "firing" }}🔥{{end}}{{end}}{{.labels.alertname}} {{range .alerts}}[{{ if eq .status "resolved" }} RESOLVED{{ else }}{{ if eq .status "firing" }}🔥 FIRING{{end}}{{end}}]{{range $k,$v := .labels}}
{{.annotations.summary}} {{$k}}={{$v}}{{end}}
{{end}}''}"; {{end}}''}";
send_resolved = true; send_resolved = true;
max_alerts = 5;
} }
]; ];
} }
@ -158,7 +158,7 @@ in
severity = "critical"; severity = "critical";
}; };
annotations = { annotations = {
summary = "Instance {{ $labels.instance }} of {{ $labels.job }} is down."; summary = "Job {{ $labels.job }} down for 1m.";
}; };
} }
]; ];

View file

@ -5,41 +5,17 @@
... ...
}: }:
let let
inherit (lib) mkIf getExe; inherit (lib) mkIf concatStringsSep;
inherit (config.my-lib.settings) prometheusCollectors; inherit (config.my-lib.settings) prometheusCollectors;
cfg = config.custom.prometheus.exporters; cfg = config.custom.prometheus.exporters;
in in
{ {
config = { config = {
systemd.services.tailscaled.before = systemd.services.tailscaled.after =
(lib.optional cfg.node.enable "prometheus-node-exporters.service") (lib.optional cfg.node.enable "prometheus-node-exporters.service")
++ (lib.optional cfg.blackbox.enable "prometheus-blackbox-exporters.service") ++ (lib.optional cfg.blackbox.enable "prometheus-blackbox-exporters.service")
++ (lib.optional config.services.caddy.enable "caddy.service"); ++ (lib.optional config.services.caddy.enable "caddy.service");
systemd.services.tailscaled.serviceConfig.ExecStartPost =
pkgs.writers.writePython3 "tailscale-wait-online"
{
flakeIgnore = [
"E401" # import on one line
"E501" # line length limit
];
}
''
import subprocess, json, time
for _ in range(30):
status = json.loads(
subprocess.run(
["${getExe config.services.tailscale.package}", "status", "--peers=false", "--json"], capture_output=True
).stdout
)["Self"]["Online"]
if status:
exit(0)
time.sleep(1)
exit(1)
'';
services.prometheus.exporters.node = mkIf cfg.node.enable { services.prometheus.exporters.node = mkIf cfg.node.enable {
enable = true; enable = true;
enabledCollectors = [ enabledCollectors = [

View file

@ -22,9 +22,9 @@ in
name = "Kanidm"; name = "Kanidm";
client_id = "grafana"; client_id = "grafana";
scopes = "openid,profile,email,groups"; scopes = "openid,profile,email,groups";
auth_url = "https://${idpUrl}/ui/oauth2"; auth_url = "${idpUrl}/ui/oauth2";
token_url = "https://${idpUrl}/oauth2/token"; token_url = "${idpUrl}/oauth2/token";
api_url = "https://${idpUrl}/oauth2/openid/grafana/userinfo"; api_url = "${idpUrl}/oauth2/openid/grafana/userinfo";
use_pkce = true; use_pkce = true;
use_refresh_token = true; use_refresh_token = true;
allow_sign_up = true; allow_sign_up = true;

View file

@ -15,7 +15,6 @@ let
; ;
inherit (config.my-lib.settings) inherit (config.my-lib.settings)
alertmanagerPort alertmanagerPort
internalDomain
; ;
cfg = config.custom.monitoring; cfg = config.custom.monitoring;
lokiPort = 3100; lokiPort = 3100;
@ -95,17 +94,16 @@ in
rulerFile = pkgs.writeText "ruler.yml" (builtins.toJSON rulerConfig); rulerFile = pkgs.writeText "ruler.yml" (builtins.toJSON rulerConfig);
in in
mkIf cfg.loki.enable { mkIf cfg.loki.enable {
systemd.services.loki.serviceConfig.After = "tailscaled.service";
services.loki = { services.loki = {
enable = true; enable = true;
configuration = { configuration = {
auth_enabled = false; auth_enabled = false;
server.http_listen_address = "${config.networking.hostName}.${internalDomain}"; server.http_listen_address = "${config.networking.hostName}.coho-tet.ts.net";
server.http_listen_port = lokiPort; server.http_listen_port = lokiPort;
common = { common = {
ring = { ring = {
instance_addr = "${config.networking.hostName}.${internalDomain}"; instance_addr = "${config.networking.hostName}.coho-tet.ts.net";
kvstore.store = "inmemory"; kvstore.store = "inmemory";
}; };
replication_factor = 1; replication_factor = 1;
@ -162,7 +160,7 @@ in
configuration = { configuration = {
server = { server = {
http_listen_address = "${config.networking.hostName}.${internalDomain}"; http_listen_address = "${config.networking.hostName}.coho-tet.ts.net";
http_listen_port = 28183; http_listen_port = 28183;
grpc_listen_port = 0; grpc_listen_port = 0;
}; };
@ -171,7 +169,7 @@ in
clients = [ clients = [
{ {
url = "http://thorite.${internalDomain}:${toString lokiPort}/loki/api/v1/push"; url = "http://thorite.coho-tet.ts.net:${toString lokiPort}/loki/api/v1/push";
} }
]; ];

View file

@ -9,6 +9,4 @@
"idbloader.img" "idbloader.img"
]; ];
}; };
transmission-exporter = prev.callPackage ./pkgs/transmission-exporter.nix { };
}) })

View file

@ -1,9 +1,6 @@
let let
mkFunction = f: (targets: (map f targets)); mkFunction = f: (targets: (map f targets));
mkPort = port: if isNull port then "" else ":${toString port}"; mkPort = port: if isNull port then "" else ":${toString port}";
# get text before "." in the url
subdomain = url: builtins.elemAt (builtins.elemAt (builtins.split "([a-zA-Z0-9]+)\..*" url) 1) 0;
in in
{ {
mkScrapes = mkFunction ( mkScrapes = mkFunction (
@ -132,7 +129,8 @@ in
severity = "critical"; severity = "critical";
}; };
annotations = { annotations = {
summary = "{{ $labels.job }} failed on {{ $labels.instance }}."; summary = "Systemd has failed units on {{ $labels.instance }}";
description = "There are {{ $value }} failed units on {{ $labels.instance }}. Immediate attention required!";
}; };
} }
{ {
@ -143,7 +141,7 @@ in
severity = "warning"; severity = "warning";
}; };
annotations = { annotations = {
summary = "High load average on {{ $labels.instance }}."; summary = "High load average detected on {{ $labels.instance }}";
description = "The 1-minute load average ({{ $value }}) exceeds 80% the number of CPUs."; description = "The 1-minute load average ({{ $value }}) exceeds 80% the number of CPUs.";
}; };
} }
@ -166,7 +164,7 @@ in
severity = "warning"; severity = "warning";
}; };
annotations = { annotations = {
summary = "Disk usage exceeeds 85% on {{ $labels.instance }}"; summary = "High disk usage on {{ $labels.instance }}";
}; };
} }
{ {
@ -179,6 +177,7 @@ in
}; };
annotations = { annotations = {
summary = "Disk usage will exceed 95% in 12 hours on {{ $labels.instance }}"; summary = "Disk usage will exceed 95% in 12 hours on {{ $labels.instance }}";
description = "Disk {{ $labels.mountpoint }} is predicted to exceed 92% usage within 12 hours at current growth rate";
}; };
} }
{ {
@ -189,7 +188,8 @@ in
severity = "warning"; severity = "warning";
}; };
annotations = { annotations = {
summary = "Swap usage above 80% on {{ $labels.instance }}"; summary = "High swap usage on {{ $labels.instance }}";
description = "Swap usage is above 80% for 5 minutes\n Current value: {{ $value }}%";
}; };
} }
{ {
@ -228,7 +228,7 @@ in
... ...
}: }:
{ {
job_name = "blackbox(${subdomain hostAddress})"; job_name = "blackbox(${hostAddress})";
scrape_interval = "1m"; scrape_interval = "1m";
metrics_path = "/probe"; metrics_path = "/probe";
params = { params = {
@ -268,14 +268,14 @@ in
inherit name; inherit name;
rules = [ rules = [
{ {
alert = "ProbeToError"; alert = "ProbeError";
expr = "sum by(instance) (probe_success != 1) > 0"; expr = "probe_success != 1";
for = "3m"; for = "3m";
labels = { labels = {
severity = "critical"; severity = "critical";
}; };
annotations = { annotations = {
summary = "Probing {{ $labels.instance }} failed"; summary = "Probing {{ $labels.instance }} from {{ $labels.from }} failed";
}; };
} }
{ {

View file

@ -1,7 +1,7 @@
{ {
settings = { settings = {
alertmanagerPort = 9093; alertmanagerPort = 9093;
idpUrl = "auth.xiny.li"; idpUrl = "https://auth.xinyang.life";
gotosocialUrl = "https://gts.xiny.li"; gotosocialUrl = "https://gts.xiny.li";
minifluxUrl = "https://rss.xiny.li"; minifluxUrl = "https://rss.xiny.li";
hedgedocDomain = "docs.xiny.li"; hedgedocDomain = "docs.xiny.li";
@ -13,12 +13,8 @@
synapseUrl = "https://xiny.li"; synapseUrl = "https://xiny.li";
synapseDelegateUrl = "https://synapse.xiny.li"; synapseDelegateUrl = "https://synapse.xiny.li";
transmissionExporterUrl = "weilite.coho-tet.ts.net:19091";
prometheusCollectors = [ prometheusCollectors = [
"thorite.coho-tet.ts.net" "thorite.coho-tet.ts.net"
]; ];
internalDomain = "coho-tet.ts.net";
}; };
} }

View file

@ -1,32 +0,0 @@
{
lib,
fetchFromGitHub,
buildGoModule,
}:
buildGoModule rec {
pname = "transmission-exporter";
version = "0-unstable-2024-10-09";
rev = "v${version}";
src = fetchFromGitHub {
rev = "a7872aa2975c7a95af680c51198f4a363e226c8f";
owner = "metalmatze";
repo = "transmission-exporter";
sha256 = "sha256-Ky7eCvC1AqHheqGGOGBNKbtVgg4Y8hDG67gCVlpUwZo=";
};
vendorHash = "sha256-YhmfrM5iAK0zWcUM7LmbgFnH+k2M/tE+f/QQIQmQlZs=";
ldflags = [
"-X github.com/prometheus/common/version.Version=${version}"
"-X github.com/prometheus/common/version.Revision=${rev}"
];
meta = {
description = "Prometheus exporter for Transmission torrent client.";
homepage = "https://github.com/pborzenkov/transmission-exporter";
mainProgram = "transmission-exporter";
license = [ lib.licenses.mit ];
maintainers = [ lib.maintainers.xinyangli ];
};
}