Compare commits
351 commits
34
README.md
34
README.md
|
@ -1,3 +1,33 @@
|
|||
# nixos-config
|
||||
# nixfiles
|
||||
|
||||
My NixOS configuration files
|
||||
My NixOS configuration files.
|
||||
|
||||
The canonical location for this repository is https://git.unspecified.systems/qenya/nixfiles. If you're viewing it elsewhere, it is a mirror and may not be up-to-date.
|
||||
|
||||
## Machines
|
||||
|
||||
### Managed
|
||||
* `kilgharrah`: Custom-built personal desktop; also currently running Jellyfin, Navidrome and Audiobookshelf servers (and an FTP server, for shits and giggles)
|
||||
* `tohru`: Dell Latitude 5300, personal laptop
|
||||
* `elucredassa`: Acer Aspire A315-53, old laptop with a broken keyboard that now sits in a corner being a backup server
|
||||
* `yevaud`: Oracle Cloud free AMD VM, hosts a Forgejo instance and WireGuard server for the other machines in the network
|
||||
* `orm`: Oracle Cloud free AMD VM, hosts an instance of Actual Budget and a PostgreSQL server for other services that need one
|
||||
* `kalessin`: Oracle Cloud free ARM VM, currently idling
|
||||
|
||||
### Referenced only
|
||||
* `shaw`: [My girlfriend's NAS](https://github.com/randomnetcat/nix-configs/tree/main/hosts/shaw)
|
||||
* `latias`: My Steam Deck
|
||||
|
||||
## Usage
|
||||
|
||||
### Building
|
||||
|
||||
To build locally, run `nixos-rebuild switch --flake .#[hostname]` as root.
|
||||
|
||||
To build the remote machines, run `colmena apply`. See the [colmena documentation](https://colmena.cli.rs/) for command-line options. Notable options include:
|
||||
* `--on [hostname]`: build a specific machine only
|
||||
* `--reboot`: reboot after building (but note [this bug](https://github.com/zhaofengli/colmena/issues/166) means it may hang even when the reboot completes successfully)
|
||||
|
||||
### Updating
|
||||
|
||||
`nix flake update --commit-lock-file`
|
||||
|
|
29
common/base-graphical/default.nix
Normal file
29
common/base-graphical/default.nix
Normal file
|
@ -0,0 +1,29 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.qenya.base-graphical;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./desktop.nix
|
||||
./sound.nix
|
||||
];
|
||||
|
||||
options.qenya.base-graphical.enable = mkEnableOption "Base configuration for graphical environments";
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.xserver.enable = true;
|
||||
services.libinput.enable = true;
|
||||
services.printing.enable = true;
|
||||
services.avahi = {
|
||||
enable = true;
|
||||
nssmdns4 = true;
|
||||
openFirewall = true;
|
||||
};
|
||||
|
||||
fonts.packages = with pkgs; [
|
||||
corefonts
|
||||
];
|
||||
};
|
||||
}
|
35
common/base-graphical/desktop.nix
Normal file
35
common/base-graphical/desktop.nix
Normal file
|
@ -0,0 +1,35 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkIf mkMerge mkOption types;
|
||||
cfg = config.qenya.base-graphical;
|
||||
in
|
||||
{
|
||||
options.qenya.base-graphical.desktop = mkOption {
|
||||
type = types.enum [ "gnome" "plasma6" ];
|
||||
default = "gnome";
|
||||
example = "plasma6";
|
||||
description = "Which display manager and desktop manager to use.";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
(mkIf (cfg.desktop == "gnome") {
|
||||
services.xserver.displayManager.gdm.enable = true;
|
||||
services.xserver.desktopManager.gnome.enable = true;
|
||||
# TODO: agree on this with randomcat as it affects her too, since for some reason this is system-wide
|
||||
# environment.gnome.excludePackages = with pkgs.gnome; [
|
||||
# pkgs.gnome-tour
|
||||
# epiphany # GNOME Web
|
||||
# geary
|
||||
# gnome-calendar
|
||||
# gnome-contacts
|
||||
# gnome-music
|
||||
# ];
|
||||
})
|
||||
(mkIf (cfg.desktop == "plasma6") {
|
||||
services.displayManager.sddm.enable = true;
|
||||
services.displayManager.sddm.wayland.enable = true;
|
||||
services.desktopManager.plasma6.enable = true;
|
||||
})
|
||||
]);
|
||||
}
|
20
common/base-graphical/sound.nix
Normal file
20
common/base-graphical/sound.nix
Normal file
|
@ -0,0 +1,20 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.qenya.base-graphical;
|
||||
in
|
||||
{
|
||||
config = mkIf cfg.enable {
|
||||
security.rtkit.enable = true;
|
||||
services.pipewire = {
|
||||
enable = true;
|
||||
alsa.enable = true;
|
||||
alsa.support32Bit = true;
|
||||
pulse.enable = true;
|
||||
jack.enable = true;
|
||||
};
|
||||
hardware.pulseaudio.enable = false; # this theoretically defaults to false but something else seems to be flipping it
|
||||
environment.systemPackages = with pkgs; [ helvum ]; # patchbay
|
||||
};
|
||||
}
|
17
common/base-server/default.nix
Normal file
17
common/base-server/default.nix
Normal file
|
@ -0,0 +1,17 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.qenya.base-server;
|
||||
in
|
||||
{
|
||||
options.qenya.base-server.enable = mkEnableOption "Base configuration for headless servers";
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
time.timeZone = "Etc/UTC";
|
||||
|
||||
# Allow remote deployment with colmena
|
||||
deployment.targetUser = null;
|
||||
security.sudo.wheelNeedsPassword = false;
|
||||
};
|
||||
}
|
13
common/boot.nix
Normal file
13
common/boot.nix
Normal file
|
@ -0,0 +1,13 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkIf;
|
||||
in
|
||||
{
|
||||
boot.loader = {
|
||||
systemd-boot.enable = true;
|
||||
systemd-boot.editor = false;
|
||||
systemd-boot.memtest86.enable = mkIf config.nixpkgs.hostPlatform.isx86 true;
|
||||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
}
|
18
common/default.nix
Normal file
18
common/default.nix
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
imports = [
|
||||
./base-graphical
|
||||
./base-server
|
||||
./users
|
||||
./boot.nix
|
||||
./gpg.nix
|
||||
./home-manager.nix
|
||||
./misc.nix
|
||||
./nginx.nix
|
||||
./nix.nix
|
||||
./openssh.nix
|
||||
./packages.nix
|
||||
./sanoid.nix
|
||||
./security.nix
|
||||
./steam.nix
|
||||
];
|
||||
}
|
8
common/gpg.nix
Normal file
8
common/gpg.nix
Normal file
|
@ -0,0 +1,8 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
programs.gnupg.agent = {
|
||||
enable = true;
|
||||
enableSSHSupport = true;
|
||||
};
|
||||
}
|
12
common/home-manager.nix
Normal file
12
common/home-manager.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
{ config, lib, pkgs, inputs, ... }:
|
||||
|
||||
{
|
||||
home-manager = {
|
||||
useUserPackages = true;
|
||||
useGlobalPkgs = true;
|
||||
backupFileExtension = "backup";
|
||||
extraSpecialArgs = {
|
||||
inherit inputs;
|
||||
};
|
||||
};
|
||||
}
|
12
common/misc.nix
Normal file
12
common/misc.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
nix.gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
randomizedDelaySec = "45min";
|
||||
options = "--delete-older-than 30d";
|
||||
};
|
||||
nix.optimise.automatic = true;
|
||||
services.fstrim.enable = true;
|
||||
}
|
25
common/nginx.nix
Normal file
25
common/nginx.nix
Normal file
|
@ -0,0 +1,25 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
services.nginx = {
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
|
||||
appendHttpConfig = ''
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload" always;
|
||||
add_header Content-Security-Policy "default-src https: data: blob: ws: 'unsafe-inline' 'wasm-unsafe-eval'; object-src 'none'; base-uri 'self';" always;
|
||||
add_header Referrer-Policy strict-origin-when-cross-origin;
|
||||
add_header X-Frame-Options SAMEORIGIN;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-Clacks-Overhead "GNU Terry Pratchett" always;
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
'';
|
||||
};
|
||||
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = "auto@qenya.tel";
|
||||
};
|
||||
}
|
21
common/nix.nix
Normal file
21
common/nix.nix
Normal file
|
@ -0,0 +1,21 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
nix.settings.experimental-features = "nix-command flakes";
|
||||
nixpkgs.flake = {
|
||||
source = lib.cleanSource pkgs.path;
|
||||
setNixPath = true;
|
||||
setFlakeRegistry = true;
|
||||
};
|
||||
nix.nixPath = [ "nixpkgs=flake:nixpkgs" ];
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
nix.settings.trusted-users = [ "@wheel" ];
|
||||
|
||||
# this is a dependency of feishin (used in qenya's home-manager). it does not actually have a known vulnerability,
|
||||
# it's just unsuspported because Electron's support cycle is a ludicrously short 6 months.
|
||||
# feishin's dev is going to be rewriting it without Electron (as "audioling").
|
||||
# modern software development was a mistake.
|
||||
nixpkgs.config.permittedInsecurePackages = [
|
||||
"electron-31.7.7"
|
||||
];
|
||||
}
|
11
common/openssh.nix
Normal file
11
common/openssh.nix
Normal file
|
@ -0,0 +1,11 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings = {
|
||||
PasswordAuthentication = false;
|
||||
PermitRootLogin = "no";
|
||||
};
|
||||
};
|
||||
}
|
23
common/packages.nix
Normal file
23
common/packages.nix
Normal file
|
@ -0,0 +1,23 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
btop
|
||||
git
|
||||
wget
|
||||
|
||||
# hardware troubleshooting
|
||||
lshw
|
||||
parted
|
||||
smartmontools
|
||||
|
||||
# network troubleshooting
|
||||
inetutils
|
||||
lsof
|
||||
tcpdump
|
||||
netcat # <3
|
||||
wireguard-tools
|
||||
];
|
||||
|
||||
environment.wordlist.enable = true;
|
||||
}
|
35
common/sanoid.nix
Normal file
35
common/sanoid.nix
Normal file
|
@ -0,0 +1,35 @@
|
|||
{ config, pkgs, inputs, ... }:
|
||||
|
||||
{
|
||||
config = {
|
||||
services.sanoid = {
|
||||
enable = true;
|
||||
extraArgs = [ "--verbose" ];
|
||||
|
||||
# Local snapshots for important datasets
|
||||
templates."production" = {
|
||||
yearly = 0;
|
||||
monthly = 3;
|
||||
daily = 30;
|
||||
hourly = 36;
|
||||
autosnap = true;
|
||||
autoprune = true;
|
||||
};
|
||||
|
||||
# Reduced-retention version for datasets that are backed up to the NAS
|
||||
templates."safe" = {
|
||||
yearly = 0;
|
||||
monthly = 0;
|
||||
daily = 7;
|
||||
hourly = 24;
|
||||
autosnap = true;
|
||||
autoprune = true;
|
||||
};
|
||||
|
||||
# datasets."rpool_sggau1/reese/system" = {
|
||||
# useTemplate = [ "safe" ];
|
||||
# recursive = "zfs";
|
||||
# };
|
||||
};
|
||||
};
|
||||
}
|
5
common/security.nix
Normal file
5
common/security.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
{ config, lib, pkgs,... }:
|
||||
|
||||
{
|
||||
security.sudo.execWheelOnly = true;
|
||||
}
|
12
common/steam.nix
Normal file
12
common/steam.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
config = lib.mkIf config.programs.steam.enable {
|
||||
programs.steam = {
|
||||
remotePlay.openFirewall = true;
|
||||
dedicatedServer.openFirewall = true;
|
||||
};
|
||||
|
||||
services.joycond.enable = true;
|
||||
};
|
||||
}
|
33
common/users/default.nix
Normal file
33
common/users/default.nix
Normal file
|
@ -0,0 +1,33 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkIf mkOption types genAttrs;
|
||||
cfg = config.fountain;
|
||||
in
|
||||
{
|
||||
# TODO: consider DRY-ing these
|
||||
imports = [
|
||||
./gaelan.nix
|
||||
./qenya.nix
|
||||
./randomcat.nix
|
||||
./trungle.nix
|
||||
];
|
||||
|
||||
options.fountain = {
|
||||
admins = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = "List of users who should have root on this system";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
users.mutableUsers = false;
|
||||
|
||||
users.users = genAttrs cfg.admins
|
||||
(name: {
|
||||
extraGroups = [ "wheel" ];
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
23
common/users/gaelan.nix
Normal file
23
common/users/gaelan.nix
Normal file
|
@ -0,0 +1,23 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkIf mkEnableOption;
|
||||
keys = import ../../keys.nix;
|
||||
cfg = config.fountain.users.gaelan;
|
||||
in
|
||||
{
|
||||
options.fountain.users.gaelan = {
|
||||
enable = mkEnableOption "user gaelan";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.users.gaelan = {
|
||||
uid = 1003;
|
||||
isNormalUser = true;
|
||||
group = "gaelan";
|
||||
openssh.authorizedKeys.keys = keys.users.gaelan;
|
||||
};
|
||||
|
||||
users.groups.gaelan.gid = config.users.users.gaelan.uid;
|
||||
};
|
||||
}
|
28
common/users/qenya.nix
Normal file
28
common/users/qenya.nix
Normal file
|
@ -0,0 +1,28 @@
|
|||
{ config, lib, pkgs, self, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkIf mkEnableOption;
|
||||
keys = import ../../keys.nix;
|
||||
cfg = config.fountain.users.qenya;
|
||||
in
|
||||
{
|
||||
options.fountain.users.qenya = {
|
||||
enable = mkEnableOption "user qenya";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.users.qenya = {
|
||||
uid = 1001;
|
||||
isNormalUser = true;
|
||||
group = "qenya";
|
||||
shell = pkgs.zsh;
|
||||
openssh.authorizedKeys.keys = keys.users.qenya;
|
||||
};
|
||||
|
||||
users.groups.qenya.gid = config.users.users.qenya.uid;
|
||||
|
||||
programs.zsh.enable = true;
|
||||
|
||||
home-manager.users."qenya" = self.homeManagerModules."qenya";
|
||||
};
|
||||
}
|
23
common/users/randomcat.nix
Normal file
23
common/users/randomcat.nix
Normal file
|
@ -0,0 +1,23 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkIf mkEnableOption;
|
||||
keys = import ../../keys.nix;
|
||||
cfg = config.fountain.users.randomcat;
|
||||
in
|
||||
{
|
||||
options.fountain.users.randomcat = {
|
||||
enable = mkEnableOption "user randomcat";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.users.randomcat = {
|
||||
uid = 1000;
|
||||
isNormalUser = true;
|
||||
group = "randomcat";
|
||||
openssh.authorizedKeys.keys = keys.users.randomcat;
|
||||
};
|
||||
|
||||
users.groups.randomcat.gid = config.users.users.randomcat.uid;
|
||||
};
|
||||
}
|
23
common/users/trungle.nix
Normal file
23
common/users/trungle.nix
Normal file
|
@ -0,0 +1,23 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkIf mkEnableOption;
|
||||
keys = import ../../keys.nix;
|
||||
cfg = config.fountain.users.trungle;
|
||||
in
|
||||
{
|
||||
options.fountain.users.trungle = {
|
||||
enable = mkEnableOption "user trungle";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.users.trungle = {
|
||||
uid = 1002;
|
||||
isNormalUser = true;
|
||||
group = "trungle";
|
||||
openssh.authorizedKeys.keys = keys.users.trungle;
|
||||
};
|
||||
|
||||
users.groups.trungle.gid = config.users.users.trungle.uid;
|
||||
};
|
||||
}
|
427
flake.lock
427
flake.lock
|
@ -1,24 +1,441 @@
|
|||
{
|
||||
"nodes": {
|
||||
"actual": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs-unstable"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1738814288,
|
||||
"narHash": "sha256-4WqR/ligsEvxcFOjui1dwquR8U327uGoBjdI5p0ey4A=",
|
||||
"ref": "main",
|
||||
"rev": "f64adb78f15981d60af97e7aa691d2ebdf48ceaa",
|
||||
"revCount": 21,
|
||||
"type": "git",
|
||||
"url": "https://git.xeno.science/xenofem/actual-nix"
|
||||
},
|
||||
"original": {
|
||||
"ref": "main",
|
||||
"type": "git",
|
||||
"url": "https://git.xeno.science/xenofem/actual-nix"
|
||||
}
|
||||
},
|
||||
"agenix": {
|
||||
"inputs": {
|
||||
"darwin": [],
|
||||
"home-manager": [],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1736955230,
|
||||
"narHash": "sha256-uenf8fv2eG5bKM8C/UvFaiJMZ4IpUFaQxk9OH5t/1gA=",
|
||||
"owner": "ryantm",
|
||||
"repo": "agenix",
|
||||
"rev": "e600439ec4c273cf11e06fe4d9d906fb98fa097c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "ryantm",
|
||||
"repo": "agenix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"birdsong": {
|
||||
"locked": {
|
||||
"lastModified": 1738782723,
|
||||
"narHash": "sha256-tQ8DZrB9pucCl0qOEzvqRBrrYS0f72Sxhf+jYJQV1eE=",
|
||||
"ref": "main",
|
||||
"rev": "a40220a4b977bc04cbe9e13ff5c667ed6f252677",
|
||||
"revCount": 22,
|
||||
"type": "git",
|
||||
"url": "https://git.qenya.tel/qenya/birdsong"
|
||||
},
|
||||
"original": {
|
||||
"ref": "main",
|
||||
"type": "git",
|
||||
"url": "https://git.qenya.tel/qenya/birdsong"
|
||||
}
|
||||
},
|
||||
"colmena": {
|
||||
"inputs": {
|
||||
"flake-compat": [],
|
||||
"flake-utils": "flake-utils",
|
||||
"nix-github-actions": [],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"stable": []
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1739900653,
|
||||
"narHash": "sha256-hPSLvw6AZQYrZyGI6Uq4XgST7benF/0zcCpugn/P0yM=",
|
||||
"owner": "zhaofengli",
|
||||
"repo": "colmena",
|
||||
"rev": "2370d4336eda2a9ef29fce10fa7076ae011983ab",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "zhaofengli",
|
||||
"repo": "colmena",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"firefox-addons": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs-unstable"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"dir": "pkgs/firefox-addons",
|
||||
"lastModified": 1744010161,
|
||||
"narHash": "sha256-6PNBLb/YXVlx2YaDqtljQYpk2MlE0VRjGXcEg1RN/qw=",
|
||||
"owner": "rycee",
|
||||
"repo": "nur-expressions",
|
||||
"rev": "60f50437003e17137a871686dfa3fc4291edd5e5",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
"dir": "pkgs/firefox-addons",
|
||||
"owner": "rycee",
|
||||
"ref": "master",
|
||||
"repo": "nur-expressions",
|
||||
"type": "gitlab"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1743550720,
|
||||
"narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "c621e8422220273271f52058f618c94e405bb0f5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"locked": {
|
||||
"lastModified": 1659877975,
|
||||
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_2": {
|
||||
"inputs": {
|
||||
"systems": "systems_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flakey-profile": {
|
||||
"locked": {
|
||||
"lastModified": 1712898590,
|
||||
"narHash": "sha256-FhGIEU93VHAChKEXx905TSiPZKga69bWl1VB37FK//I=",
|
||||
"owner": "lf-",
|
||||
"repo": "flakey-profile",
|
||||
"rev": "243c903fd8eadc0f63d205665a92d4df91d42d9d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "lf-",
|
||||
"repo": "flakey-profile",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"home-manager": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1743808813,
|
||||
"narHash": "sha256-2lDQBOmlz9ggPxcS7/GvcVdzXMIiT+PpMao6FbLJSr0=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "a9f8b3db211b4609ddd83683f9db89796c7f6ac6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"ref": "release-24.11",
|
||||
"repo": "home-manager",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"home-manager-unstable": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs-unstable"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1744008831,
|
||||
"narHash": "sha256-g3mHJLB8ShKuMaBBZxiGuoftJ22f7Boegiw5xBUnS8E=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "f463902a3f03e15af658e48bcc60b39188ddf734",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"lix": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1737234286,
|
||||
"narHash": "sha256-pgDJZjj4jpzkFxsqBTI/9Yb0n3gW+DvDtuv9SwQZZcs=",
|
||||
"rev": "079528098f5998ba13c88821a2eca1005c1695de",
|
||||
"type": "tarball",
|
||||
"url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/079528098f5998ba13c88821a2eca1005c1695de.tar.gz?rev=079528098f5998ba13c88821a2eca1005c1695de"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://git.lix.systems/lix-project/lix/archive/release-2.92.tar.gz"
|
||||
}
|
||||
},
|
||||
"lix-module": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_2",
|
||||
"flakey-profile": "flakey-profile",
|
||||
"lix": "lix",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1742943028,
|
||||
"narHash": "sha256-fprwZKE1uMzO9tiWWOrmLWBW3GPkMayQfb0xOvVFIno=",
|
||||
"rev": "868d97695bab9d21f6070b03957bcace249fbe3c",
|
||||
"type": "tarball",
|
||||
"url": "https://git.lix.systems/api/v1/repos/lix-project/nixos-module/archive/868d97695bab9d21f6070b03957bcace249fbe3c.tar.gz?rev=868d97695bab9d21f6070b03957bcace249fbe3c"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://git.lix.systems/lix-project/nixos-module/archive/2.92.0-3.tar.gz"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1716361217,
|
||||
"narHash": "sha256-mzZDr00WUiUXVm1ujBVv6A0qRd8okaITyUp4ezYRgc4=",
|
||||
"lastModified": 1743813633,
|
||||
"narHash": "sha256-BgkBz4NpV6Kg8XF7cmHDHRVGZYnKbvG0Y4p+jElwxaM=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "46397778ef1f73414b03ed553a3368f0e7e33c2f",
|
||||
"rev": "7819a0d29d1dd2bc331bec4b327f0776359b1fa6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-23.11",
|
||||
"ref": "nixos-24.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1743296961,
|
||||
"narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-small": {
|
||||
"locked": {
|
||||
"lastModified": 1743891346,
|
||||
"narHash": "sha256-QNxnxIi6PJEnwJp7ZXUpxX4/z/cmRJGeIOkIYfYh/8E=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f27c6099cec4fe9b67c7fbc51d8324dcb4b52694",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.11-small",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1743827369,
|
||||
"narHash": "sha256-rpqepOZ8Eo1zg+KJeWoq1HAOgoMCDloqv5r2EAa9TSA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "42a1c966be226125b48c384171c44c651c236c22",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-unstable-small": {
|
||||
"locked": {
|
||||
"lastModified": 1743948488,
|
||||
"narHash": "sha256-uKcMmNPvGPb58MhAFru/CMDYl69nZRK3A3SLch9ejgA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "da98c5d529f118c82e80a3f9b4fb01fdeba3cf7a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable-small",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"plasma-manager": {
|
||||
"inputs": {
|
||||
"home-manager": [
|
||||
"home-manager-unstable"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs-unstable"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1742765550,
|
||||
"narHash": "sha256-2vVIh2JrL6GAGfgCeY9e6iNKrBjs0Hw3bGQEAbwVs68=",
|
||||
"owner": "nix-community",
|
||||
"repo": "plasma-manager",
|
||||
"rev": "b70be387276e632fe51232887f9e04e2b6ef8c16",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "plasma-manager",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"randomcat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1744004743,
|
||||
"narHash": "sha256-MIWwT/A4IfXmmSMCU3lVVnFJNmkXpYxcK+Fishja6XY=",
|
||||
"owner": "randomnetcat",
|
||||
"repo": "nix-configs",
|
||||
"rev": "335ef83e439cfcb4781d5a8f54f606afb63e9f48",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "randomnetcat",
|
||||
"repo": "nix-configs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
"actual": "actual",
|
||||
"agenix": "agenix",
|
||||
"birdsong": "birdsong",
|
||||
"colmena": "colmena",
|
||||
"firefox-addons": "firefox-addons",
|
||||
"flake-parts": "flake-parts",
|
||||
"home-manager": "home-manager",
|
||||
"home-manager-unstable": "home-manager-unstable",
|
||||
"lix-module": "lix-module",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-small": "nixpkgs-small",
|
||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||
"nixpkgs-unstable-small": "nixpkgs-unstable-small",
|
||||
"plasma-manager": "plasma-manager",
|
||||
"randomcat": "randomcat",
|
||||
"scoutshonour": "scoutshonour"
|
||||
}
|
||||
},
|
||||
"scoutshonour": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs-unstable"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1735301893,
|
||||
"narHash": "sha256-d95MCTUYMCcOQv4LpmWxPuVnx7McezXYs2Idw8u8ngI=",
|
||||
"ref": "main",
|
||||
"rev": "f447cd380ea1fb81a0ff8f292b6bbdf0be9c9520",
|
||||
"revCount": 23,
|
||||
"type": "git",
|
||||
"url": "https://git.qenya.tel/qenya/nix-scoutshonour"
|
||||
},
|
||||
"original": {
|
||||
"ref": "main",
|
||||
"type": "git",
|
||||
"url": "https://git.qenya.tel/qenya/nix-scoutshonour"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_2": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
180
flake.nix
180
flake.nix
|
@ -1,14 +1,178 @@
|
|||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
|
||||
};
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
|
||||
nixpkgs-small.url = "github:NixOS/nixpkgs/nixos-24.11-small";
|
||||
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
nixpkgs-unstable-small.url = "github:NixOS/nixpkgs/nixos-unstable-small";
|
||||
|
||||
outputs = { self, nixpkgs, ... }@inputs: {
|
||||
nixosConfigurations.tohru = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [
|
||||
./hosts/tohru/configuration.nix
|
||||
];
|
||||
lix-module = {
|
||||
# lix haven't figured out automatic updates yet: https://git.lix.systems/lix-project/nixos-module/issues/39
|
||||
url = "https://git.lix.systems/lix-project/nixos-module/archive/2.92.0-3.tar.gz";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager/release-24.11";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
home-manager-unstable = {
|
||||
url = "github:nix-community/home-manager";
|
||||
inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||
};
|
||||
|
||||
plasma-manager = {
|
||||
url = "github:nix-community/plasma-manager";
|
||||
inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||
inputs.home-manager.follows = "home-manager-unstable";
|
||||
};
|
||||
|
||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
|
||||
agenix = {
|
||||
url = "github:ryantm/agenix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.darwin.follows = "";
|
||||
inputs.home-manager.follows = "";
|
||||
};
|
||||
|
||||
colmena = {
|
||||
url = "github:zhaofengli/colmena";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.stable.follows = "";
|
||||
inputs.nix-github-actions.follows = "";
|
||||
inputs.flake-compat.follows = "";
|
||||
};
|
||||
|
||||
randomcat = {
|
||||
url = "github:randomnetcat/nix-configs";
|
||||
flake = false;
|
||||
};
|
||||
|
||||
firefox-addons = {
|
||||
url = "gitlab:rycee/nur-expressions?ref=master&dir=pkgs/firefox-addons";
|
||||
inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||
};
|
||||
|
||||
# Third-party flake providing package and NixOS module for Actual Budget as
|
||||
# nixpkgs are having trouble: https://github.com/NixOS/nixpkgs/issues/269069
|
||||
actual = {
|
||||
url = "git+https://git.xeno.science/xenofem/actual-nix?ref=main";
|
||||
inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||
};
|
||||
|
||||
birdsong.url = "git+https://git.qenya.tel/qenya/birdsong?ref=main";
|
||||
|
||||
scoutshonour = {
|
||||
url = "git+https://git.qenya.tel/qenya/nix-scoutshonour?ref=main";
|
||||
inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = inputs@{ self, nixpkgs, nixpkgs-small, nixpkgs-unstable, flake-parts, colmena, ... }:
|
||||
flake-parts.lib.mkFlake { inherit inputs; } {
|
||||
imports = [ ./flake ];
|
||||
|
||||
systems = [ "x86_64-linux" "aarch64-linux" ];
|
||||
|
||||
perSystem = { pkgs, system, ... }: {
|
||||
devShells.default = pkgs.mkShell {
|
||||
packages = [
|
||||
inputs.colmena.packages.${system}.colmena
|
||||
inputs.agenix.packages.${system}.default
|
||||
inputs.plasma-manager.packages.${system}.rc2nix
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
flake.nixosConfigurations = self.outputs.colmenaHive.nodes;
|
||||
flake.colmenaHive = colmena.lib.makeHive self.outputs.colmena;
|
||||
|
||||
# The name of this output type is not standardised. I have picked
|
||||
# "homeManagerModules" as the discussion here suggests it's the most common:
|
||||
# https://github.com/nix-community/home-manager/issues/1783
|
||||
#
|
||||
# However, note CppNix >= 2.22.3, >= 2.24 has blessed "homeModules":
|
||||
# https://github.com/NixOS/nix/pull/10858
|
||||
flake.homeManagerModules = {
|
||||
"qenya".imports = [
|
||||
inputs.plasma-manager.homeManagerModules.plasma-manager
|
||||
./home/qenya
|
||||
];
|
||||
|
||||
"qenya@shaw".imports = [ ./hosts/shaw/home.nix ];
|
||||
};
|
||||
|
||||
fountain.backup = {
|
||||
keys = {
|
||||
elucredassa = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOFa3hjej6KGmS2aQ4s46Y7U8pN4yyR2FuMofpHRwXNk syncoid@elucredassa" ];
|
||||
};
|
||||
sync = {
|
||||
"orm-state" = {
|
||||
dataset = "state";
|
||||
sourceHost = "orm";
|
||||
targetHost = "elucredassa";
|
||||
source = "rpool_orm";
|
||||
target = "rpool_elucredassa/backup/orm";
|
||||
};
|
||||
"kalessin-state" = {
|
||||
dataset = "state";
|
||||
sourceHost = "kalessin";
|
||||
targetHost = "elucredassa";
|
||||
source = "rpool_kalessin";
|
||||
target = "rpool_elucredassa/backup/kalessin";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
flake.colmena = {
|
||||
meta = {
|
||||
nixpkgs = import nixpkgs-unstable {
|
||||
system = "x86_64-linux";
|
||||
overlays = [
|
||||
inputs.lix-module.overlays.default
|
||||
];
|
||||
};
|
||||
nodeNixpkgs = {
|
||||
kilgharrah = import nixpkgs { system = "x86_64-linux"; };
|
||||
tohru = import nixpkgs { system = "x86_64-linux"; };
|
||||
elucredassa = import nixpkgs-small { system = "x86_64-linux"; };
|
||||
yevaud = import nixpkgs-small { system = "x86_64-linux"; };
|
||||
orm = import nixpkgs-small { system = "x86_64-linux"; };
|
||||
kalessin = import nixpkgs-small { system = "aarch64-linux"; };
|
||||
};
|
||||
specialArgs = {
|
||||
inherit self;
|
||||
inherit inputs;
|
||||
};
|
||||
};
|
||||
|
||||
defaults = { config, lib, pkgs, ... }: {
|
||||
deployment.targetHost = lib.mkDefault config.networking.fqdn;
|
||||
deployment.buildOnTarget = lib.mkDefault true;
|
||||
|
||||
imports = [
|
||||
inputs.lix-module.nixosModules.default
|
||||
inputs.home-manager.nixosModules.home-manager
|
||||
inputs.agenix.nixosModules.default
|
||||
inputs.birdsong.nixosModules.default
|
||||
inputs.actual.nixosModules.default
|
||||
./common
|
||||
./services
|
||||
(builtins.toPath "${inputs.randomcat}/services/default.nix")
|
||||
];
|
||||
};
|
||||
|
||||
kilgharrah.deployment.targetHost = null; # disable remote deployment
|
||||
tohru.deployment.targetHost = null; # disable remote deployment
|
||||
elucredassa.deployment.targetHost = "10.127.3.2"; # no fqdn yet
|
||||
|
||||
kilgharrah.imports = [ ./hosts/kilgharrah ];
|
||||
tohru.imports = [ ./hosts/tohru ];
|
||||
elucredassa.imports = [ ./hosts/elucredassa ];
|
||||
yevaud.imports = [ ./hosts/yevaud ];
|
||||
orm.imports = [ ./hosts/orm ];
|
||||
kalessin.imports = [ ./hosts/kalessin ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
138
flake/backup.nix
Normal file
138
flake/backup.nix
Normal file
|
@ -0,0 +1,138 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.fountain.backup;
|
||||
keys = import ../keys.nix;
|
||||
|
||||
syncOptions = {
|
||||
dataset = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The name of the dataset to be synced (not including its parent
|
||||
datasets, if any). This will be the same on the source and target.
|
||||
It must already exist on the source, defined with the
|
||||
{option}`randomcat.services.zfs` module, and not exist on the target.
|
||||
'';
|
||||
};
|
||||
sourceHost = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The host from which the dataset should be synced. Must be an entry in
|
||||
{option}`flake.colmena`.
|
||||
'';
|
||||
};
|
||||
targetHost = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The host to which the dataset should be synced. Must be an entry in
|
||||
{option}`flake.colmena`.
|
||||
'';
|
||||
};
|
||||
source = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The path to the synced dataset in the ZFS namespace on the source host,
|
||||
excluding the component that is the name of the dataset itself.
|
||||
'';
|
||||
};
|
||||
target = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The path to the synced dataset in the ZFS namespace on the target host,
|
||||
excluding the component that is the name of the dataset itself. It must
|
||||
already exist, defined with the {option}`randomcat.services.zfs`
|
||||
module.
|
||||
'';
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
options.fountain.backup = {
|
||||
keys = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.listOf lib.types.singleLineStr);
|
||||
default = { };
|
||||
description = ''
|
||||
Lists of verbatim OpenSSH public keys that may be used to identify the
|
||||
syncoid user on each target host. The key to each list must be the
|
||||
host's hostname, as listed in {option}`flake.colmena`.
|
||||
'';
|
||||
example = {
|
||||
host = [ "ssh-rsa AAAAB3NzaC1yc2etc/etc/etcjwrsh8e596z6J0l7 example@host" ];
|
||||
bar = [ "ssh-ed25519 AAAAC3NzaCetcetera/etceteraJZMfk3QPfQ foo@bar" ];
|
||||
};
|
||||
};
|
||||
|
||||
sync = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule { options = syncOptions; });
|
||||
default = { };
|
||||
description = ''
|
||||
Details of ZFS datasets whose snapshots should be synced from machine
|
||||
to machine using syncoid. Syncoid will run hourly at 15 past the hour
|
||||
and copy all ZFS snapshots from the source dataset to the target
|
||||
dataset (recursing into child datasets).
|
||||
|
||||
See descriptions for the individual options for more details. The name
|
||||
of each attribute in this set is arbitrary and used to generate systemd
|
||||
unit names.
|
||||
|
||||
This module does not actually cause snapshots to be taken; sanoid must
|
||||
be configured separately to do this.
|
||||
'';
|
||||
example = {
|
||||
"orm-state" = {
|
||||
dataset = "state";
|
||||
sourceHost = "orm";
|
||||
targetHost = "elucredassa";
|
||||
source = "rpool_orm";
|
||||
target = "rpool_elucredassa/backup/orm";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# TODO: add some assertions to verify the options
|
||||
|
||||
config.flake.colmena = lib.mkMerge (lib.mapAttrsToList
|
||||
(name: sync:
|
||||
let
|
||||
inherit (sync) dataset sourceHost targetHost source target;
|
||||
# TODO: don't want to have to dig into the node config for the fqdn
|
||||
sourceFqdn = config.flake.nixosConfigurations.${sourceHost}.config.networking.fqdn;
|
||||
in
|
||||
{
|
||||
${sourceHost} = { pkgs, ... }: {
|
||||
randomcat.services.zfs.datasets."${source}/${dataset}".zfsPermissions.users.backup = [ "hold" "send" ];
|
||||
|
||||
users.users.backup = {
|
||||
group = "backup";
|
||||
isSystemUser = true;
|
||||
useDefaultShell = true;
|
||||
openssh.authorizedKeys.keys = cfg.keys.${targetHost};
|
||||
packages = with pkgs; [ mbuffer lzop ]; # syncoid uses these if available but doesn't pull them in automatically
|
||||
};
|
||||
users.groups.backup = { };
|
||||
};
|
||||
|
||||
${targetHost} = {
|
||||
randomcat.services.zfs.datasets.${target}.zfsPermissions.users.syncoid = [ "mount" "create" "receive" "recordsize" ];
|
||||
|
||||
services.syncoid = {
|
||||
enable = true;
|
||||
interval = "*-*-* *:15:00";
|
||||
commonArgs = [ "--no-sync-snap" ];
|
||||
commands = {
|
||||
${name} = {
|
||||
source = "backup@${sourceFqdn}:${source}/${dataset}";
|
||||
target = "${target}/${dataset}";
|
||||
recursive = true;
|
||||
recvOptions = "ux recordsize o compression=lz4";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# TODO: this should be handled by a networking module
|
||||
programs.ssh.knownHosts.${sourceFqdn}.publicKey = keys.machines.${sourceHost};
|
||||
};
|
||||
})
|
||||
cfg.sync
|
||||
);
|
||||
}
|
19
flake/colmena.nix
Normal file
19
flake/colmena.nix
Normal file
|
@ -0,0 +1,19 @@
|
|||
# https://git.lix.systems/the-distro/infra/src/commit/fbb23bf517206175764f154ddfd304b9ec501f87/colmena.nix
|
||||
{ lib, ... }: {
|
||||
options.flake.colmena = lib.mkOption {
|
||||
type = lib.types.submodule {
|
||||
freeformType = lib.types.attrsOf (lib.mkOptionType {
|
||||
name = "NixOS module";
|
||||
description = "module containing NixOS options and/or config";
|
||||
descriptionClass = "noun";
|
||||
check = value: builtins.isAttrs value || builtins.isFunction value || builtins.isPath value;
|
||||
merge = loc: defs: {
|
||||
imports = map (def: def.value) defs;
|
||||
};
|
||||
});
|
||||
options.meta = lib.mkOption {
|
||||
type = lib.types.attrs;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
6
flake/default.nix
Normal file
6
flake/default.nix
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
imports = [
|
||||
./backup.nix
|
||||
./colmena.nix
|
||||
];
|
||||
}
|
BIN
home/qenya/dconf/background-image.jpg
Executable file
BIN
home/qenya/dconf/background-image.jpg
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.3 MiB |
24
home/qenya/dconf/default.nix
Normal file
24
home/qenya/dconf/default.nix
Normal file
|
@ -0,0 +1,24 @@
|
|||
{ config, lib, pkgs, osConfig, ... }:
|
||||
|
||||
# dconf is the configuration manager for GNOME.
|
||||
|
||||
let
|
||||
isGnome = osConfig.services.xserver.desktopManager.gnome.enable;
|
||||
in
|
||||
{
|
||||
dconf.enable = isGnome;
|
||||
|
||||
dconf.settings = {
|
||||
"org/gnome/settings-daemon/plugins/color".night-light-enabled = true;
|
||||
"org/gnome/desktop/sound".event-sounds = false;
|
||||
"org/gnome/desktop/sound".allow-volume-above-100-percent = true;
|
||||
};
|
||||
|
||||
imports = [
|
||||
./desktop.nix
|
||||
./keyboard.nix
|
||||
./mouse-touchpad.nix
|
||||
./multitasking.nix
|
||||
./shell.nix
|
||||
];
|
||||
}
|
23
home/qenya/dconf/desktop.nix
Normal file
23
home/qenya/dconf/desktop.nix
Normal file
|
@ -0,0 +1,23 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let inherit (lib) mkIf;
|
||||
in {
|
||||
dconf.settings = {
|
||||
"org/gnome/desktop/background" = {
|
||||
picture-options = "zoom";
|
||||
picture-uri = "${config.home.homeDirectory}/.background-image";
|
||||
picture-uri-dark = "${config.home.homeDirectory}/.background-image";
|
||||
};
|
||||
"org/gnome/desktop/screensaver" = {
|
||||
picture-options = "zoom";
|
||||
picture-uri = "${config.home.homeDirectory}/.background-image";
|
||||
};
|
||||
"org/gnome/desktop/interface" = {
|
||||
color-scheme = "prefer-dark";
|
||||
enable-hot-corners = false;
|
||||
};
|
||||
};
|
||||
home.file.".background-image" = mkIf config.dconf.enable {
|
||||
source = ./background-image.jpg;
|
||||
};
|
||||
}
|
12
home/qenya/dconf/keyboard.nix
Normal file
12
home/qenya/dconf/keyboard.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
# { config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
dconf.settings = {
|
||||
"org/gnome/desktop/wm/keybindings" = {
|
||||
# These are largely useless on most normal systems
|
||||
# and conflict with VS Code's default keybinds for "Copy Line Up/Down"
|
||||
move-to-workspace-up = [ ];
|
||||
move-to-workspace-down = [ ];
|
||||
};
|
||||
};
|
||||
}
|
16
home/qenya/dconf/mouse-touchpad.nix
Normal file
16
home/qenya/dconf/mouse-touchpad.nix
Normal file
|
@ -0,0 +1,16 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
dconf.settings = {
|
||||
"org/gnome/desktop/peripherals/mouse" = {
|
||||
natural-scroll = false;
|
||||
};
|
||||
"org/gnome/desktop/peripherals/touchpad" = {
|
||||
click-method = "fingers";
|
||||
disable-while-typing = false;
|
||||
natural-scroll = true; # the correct option, whatever Janet says
|
||||
tap-to-click = true;
|
||||
two-finger-scrolling-enabled = true;
|
||||
};
|
||||
};
|
||||
}
|
11
home/qenya/dconf/multitasking.nix
Normal file
11
home/qenya/dconf/multitasking.nix
Normal file
|
@ -0,0 +1,11 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
dconf.settings = {
|
||||
"org/gnome/mutter" = {
|
||||
edge-tiling = true;
|
||||
dynamic-workspaces = true;
|
||||
workspaces-only-on-primary = true;
|
||||
};
|
||||
};
|
||||
}
|
26
home/qenya/dconf/shell.nix
Normal file
26
home/qenya/dconf/shell.nix
Normal file
|
@ -0,0 +1,26 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
dconf.settings = {
|
||||
"org/gnome/shell" = {
|
||||
disable-user-extensions = true;
|
||||
|
||||
# TODO: this is fine for now on tohru (the only GNOME system I use) but shouldn't depend on certain apps being installed
|
||||
favorite-apps = [
|
||||
"discord.desktop"
|
||||
"org.gnome.Evolution.desktop"
|
||||
"firefox.desktop"
|
||||
"torbrowser.desktop"
|
||||
"steam.desktop"
|
||||
"codium.desktop"
|
||||
"org.gnome.Console.desktop"
|
||||
"org.gnome.Nautilus.desktop"
|
||||
"org.gnome.SystemMonitor.desktop"
|
||||
];
|
||||
|
||||
# TODO: fill this out (needs preinstalled stuff removing first)
|
||||
# app-picker-layout = [
|
||||
# ...
|
||||
# ];
|
||||
};
|
||||
};
|
||||
}
|
15
home/qenya/default.nix
Normal file
15
home/qenya/default.nix
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
imports = [
|
||||
./dconf
|
||||
./plasma
|
||||
./firefox.nix
|
||||
./git.nix
|
||||
./packages.nix
|
||||
./tmux.nix
|
||||
./vscode.nix
|
||||
./xdg-mime-apps.nix
|
||||
./zsh.nix
|
||||
];
|
||||
|
||||
home.stateVersion = "23.11";
|
||||
}
|
59
home/qenya/firefox.nix
Normal file
59
home/qenya/firefox.nix
Normal file
|
@ -0,0 +1,59 @@
|
|||
{ config, lib, pkgs, osConfig, inputs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkIf;
|
||||
isGraphical = osConfig.services.xserver.enable;
|
||||
in
|
||||
{
|
||||
programs.firefox = lib.mkIf isGraphical {
|
||||
enable = true;
|
||||
languagePacks = [ "en-GB" ];
|
||||
|
||||
profiles.default = {
|
||||
extensions = with inputs.firefox-addons.packages.${pkgs.hostPlatform.system}; [
|
||||
bitwarden
|
||||
ublock-origin
|
||||
];
|
||||
|
||||
settings = {
|
||||
"browser.startup.page" = 3; # resume previous session
|
||||
"browser.newtabpage.activity-stream.showSponsored" = false;
|
||||
"browser.newtabpage.activity-stream.showSponsoredTopSites" = false;
|
||||
|
||||
# disable telemetry
|
||||
"datareporting.healthreport.uploadEnabled" = false;
|
||||
"app.shield.optoutstudies.enabled" = false;
|
||||
"browser.crashReports.unsubmittedCheck.autoSubmit2" = false;
|
||||
|
||||
# disable prefetch?
|
||||
|
||||
# DNS over HTTPS
|
||||
"network.trr.custom_uri" = "https://base.dns.mullvad.net/dns-query";
|
||||
"network.trr.excluded-domains" = "detectportal.firefox.com";
|
||||
"network.trr.mode" = 3;
|
||||
"network.trr.uri" = "https://base.dns.mullvad.net/dns-query";
|
||||
|
||||
"browser.search.suggest.enabled" = false;
|
||||
"browser.urlbar.suggest.searches" = false;
|
||||
|
||||
"dom.security.https_only_mode" = true;
|
||||
"browser.contentblocking.category" = "strict"; # Enhanced Tracking Protection
|
||||
# I think these are implied by the above
|
||||
# "privacy.donottrackheader.enabled" = true;
|
||||
# "privacy.trackingprotection.enabled" = true;
|
||||
# "privacy.trackingprotection.emailtracking.enabled" = true;
|
||||
# "privacy.trackingprotection.socialtracking.enabled" = true;
|
||||
|
||||
"privacy.sanitize.sanitizeOnShutdown" = true;
|
||||
"privacy.clearOnShutdown_v2.historyFormDataAndDownloads" = false;
|
||||
|
||||
"dom.private-attribution.submission.enabled" = false; # disable "Privacy-Preserving Attribution for Advertising"
|
||||
"extensions.autoDisableScopes" = 0; # automatically enable extensions installed through nix
|
||||
|
||||
# external password manager
|
||||
"signon.rememberSignons" = false;
|
||||
"extensions.formautofill.creditCards.enabled" = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
14
home/qenya/git.nix
Normal file
14
home/qenya/git.nix
Normal file
|
@ -0,0 +1,14 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
programs.git = {
|
||||
enable = true;
|
||||
userName = "Katherina Walshe-Grey";
|
||||
userEmail = "git@qenya.tel";
|
||||
extraConfig = {
|
||||
init.defaultBranch = "main";
|
||||
pull.rebase = true;
|
||||
push.autoSetupRemote = true;
|
||||
};
|
||||
};
|
||||
}
|
34
home/qenya/packages.nix
Normal file
34
home/qenya/packages.nix
Normal file
|
@ -0,0 +1,34 @@
|
|||
{ config, lib, pkgs, osConfig, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) optionals;
|
||||
isGraphical = osConfig.services.xserver.enable;
|
||||
in
|
||||
{
|
||||
home.packages = with pkgs; [
|
||||
eza # like `ls` but fancier
|
||||
hexyl # like `xxd` but cooler
|
||||
tree # like `ls -R` but nicer
|
||||
units
|
||||
zip
|
||||
unzip
|
||||
|
||||
# Extremely important
|
||||
fortune
|
||||
cowsay
|
||||
lolcat
|
||||
] ++ optionals isGraphical [
|
||||
bitwarden
|
||||
discord
|
||||
feishin
|
||||
gimp-with-plugins
|
||||
jellyfin-media-player
|
||||
tor-browser-bundle-bin
|
||||
zoom-us
|
||||
|
||||
# libreoffice
|
||||
libreoffice
|
||||
hunspell
|
||||
hunspellDicts.en_GB-ise
|
||||
];
|
||||
}
|
11
home/qenya/plasma/default.nix
Normal file
11
home/qenya/plasma/default.nix
Normal file
|
@ -0,0 +1,11 @@
|
|||
{ config, lib, pkgs, osConfig, ... }:
|
||||
|
||||
let
|
||||
isPlasma = osConfig.services.desktopManager.plasma6.enable || osConfig.services.xserver.desktopManager.plasma5.enable;
|
||||
in
|
||||
{
|
||||
programs.plasma.enable = isPlasma;
|
||||
programs.plasma.overrideConfig = true;
|
||||
|
||||
imports = [ ];
|
||||
}
|
33
home/qenya/tmux.nix
Normal file
33
home/qenya/tmux.nix
Normal file
|
@ -0,0 +1,33 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
# Derived from https://github.com/srid/nixos-config/blob/master/home/tmux.nix
|
||||
|
||||
programs.tmux = {
|
||||
enable = true;
|
||||
clock24 = true;
|
||||
shortcut = "a"; # `screen` muscle memory compatibility
|
||||
baseIndex = 1; # this is a UI, 0-indexing is not appropriate, fight me
|
||||
newSession = true; # skip the manual step
|
||||
escapeTime = 0; # otherwise I keep reflexively hammering Esc
|
||||
secureSocket = false; # make sessions survive user logout
|
||||
|
||||
plugins = with pkgs; [
|
||||
tmuxPlugins.better-mouse-mode
|
||||
];
|
||||
mouse = true;
|
||||
|
||||
extraConfig = ''
|
||||
# https://old.reddit.com/r/tmux/comments/mesrci/tmux_2_doesnt_seem_to_use_256_colors/
|
||||
set -g default-terminal "xterm-256color"
|
||||
set -ga terminal-overrides ",*256col*:Tc"
|
||||
set -ga terminal-overrides '*:Ss=\E[%p1%d q:Se=\E[ q'
|
||||
set-environment -g COLORTERM "truecolor"
|
||||
|
||||
# easy-to-remember split pane commands
|
||||
bind | split-window -h -c "#{pane_current_path}"
|
||||
bind - split-window -v -c "#{pane_current_path}"
|
||||
bind c new-window -c "#{pane_current_path}"
|
||||
'';
|
||||
};
|
||||
}
|
83
home/qenya/vscode.nix
Normal file
83
home/qenya/vscode.nix
Normal file
|
@ -0,0 +1,83 @@
|
|||
{ config, lib, pkgs, osConfig, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkIf mkDefault;
|
||||
isGraphical = osConfig.services.xserver.enable;
|
||||
in
|
||||
{
|
||||
programs.vscode = mkIf isGraphical {
|
||||
enable = true;
|
||||
enableExtensionUpdateCheck = false;
|
||||
enableUpdateCheck = false;
|
||||
package = pkgs.vscodium;
|
||||
extensions = with pkgs.vscode-extensions; [
|
||||
charliermarsh.ruff
|
||||
dbaeumer.vscode-eslint
|
||||
eamodio.gitlens
|
||||
golang.go
|
||||
jdinhlife.gruvbox
|
||||
jnoortheen.nix-ide
|
||||
matangover.mypy
|
||||
mkhl.direnv
|
||||
ms-python.black-formatter
|
||||
ms-python.python
|
||||
rust-lang.rust-analyzer
|
||||
vadimcn.vscode-lldb
|
||||
];
|
||||
mutableExtensionsDir = false;
|
||||
userSettings = {
|
||||
"css.format.spaceAroundSelectorSeparator" = true;
|
||||
"css.format.newlineBetweenSelectors" = false;
|
||||
"debug.allowBreakpointsEverywhere" = true;
|
||||
"extensions.autoUpdate" = false;
|
||||
"files.insertFinalNewline" = true;
|
||||
"git.autofetch" = true;
|
||||
"git.confirmSync" = false;
|
||||
"git.enableSmartCommit" = true;
|
||||
"git.inputValidation" = true;
|
||||
"git.inputValidationSubjectLength" = null;
|
||||
"javascript.updateImportsOnFileMove.enabled" = "always";
|
||||
"nix.enableLanguageServer" = true;
|
||||
"nix.serverPath" = "${pkgs.nil}/bin/nil";
|
||||
"nix.serverSettings".nil = {
|
||||
diagnostics.ignored = [ "unused_binding" "unused_with" ];
|
||||
formatting.command = [ "${pkgs.nixpkgs-fmt}/bin/nixpkgs-fmt" ];
|
||||
nix.flake.autoArchive = true;
|
||||
};
|
||||
"rust-analyzer.check.command" = "clippy";
|
||||
"terminal.integrated.allowChords" = false;
|
||||
"terminal.integrated.defaultProfile.linux" = "zsh";
|
||||
"workbench.colorTheme" = "Gruvbox Dark Medium";
|
||||
|
||||
"[go]" = {
|
||||
"editor.defaultFormatter" = "golang.go";
|
||||
"editor.formatOnSave" = false;
|
||||
};
|
||||
"go.alternateTools" = {
|
||||
"go" = "${pkgs.go}/bin/go";
|
||||
"golangci-lint" = "${pkgs.golangci-lint}/bin/golangci-lint";
|
||||
"gopls" = "${pkgs.gopls}/bin/gopls";
|
||||
"dlv" = "${pkgs.delve}/bin/dlv";
|
||||
"staticcheck" = "${pkgs.go-tools}/bin/staticcheck";
|
||||
};
|
||||
"go.lintTool" = "golangci-lint";
|
||||
"go.toolsManagement.checkForUpdates" = "off";
|
||||
"gopls" = {
|
||||
"formatting.gofumpt" = true;
|
||||
"ui.semanticTokens" = true;
|
||||
};
|
||||
|
||||
"[python]" = {
|
||||
"editor.defaultFormatter" = "ms-python.black-formatter";
|
||||
"editor.formatOnSave" = true;
|
||||
"editor.codeActionsOnSave" = {
|
||||
"source.fixAll" = "explicit";
|
||||
"source.organizeImports" = "explicit";
|
||||
};
|
||||
};
|
||||
"ruff.nativeServer" = "on";
|
||||
"ruff.path" = "${pkgs.ruff}/bin/ruff";
|
||||
"mypy.dmypyExecutable" = "${pkgs.mypy}/bin/dmypy";
|
||||
};
|
||||
};
|
||||
}
|
21
home/qenya/xdg-mime-apps.nix
Normal file
21
home/qenya/xdg-mime-apps.nix
Normal file
|
@ -0,0 +1,21 @@
|
|||
{ config, lib, pkgs, osConfig, ... }:
|
||||
|
||||
let
|
||||
isGraphical = osConfig.services.xserver.enable;
|
||||
in
|
||||
{
|
||||
xdg.mimeApps = {
|
||||
enable = isGraphical;
|
||||
defaultApplications = {
|
||||
"application/pdf" = [ "org.gnome.Evince.desktop" "org.kde.okular.desktop" ];
|
||||
"application/zip" = [ "org.gnome.FileRoller.desktop" "org.kde.ark.desktop" ];
|
||||
"image/gif" = [ "org.gnome.Loupe.desktop" "org.kde.gwenview.desktop" ];
|
||||
"image/jpeg" = [ "org.gnome.Loupe.desktop" "org.kde.gwenview.desktop" ];
|
||||
"image/png" = [ "org.gnome.Loupe.desktop" "org.kde.gwenview.desktop" ];
|
||||
"text/plain" = [ "org.gnome.TextEditor.desktop" "org.kde.kate.desktop" ];
|
||||
"x-scheme-handler/http" = "firefox.desktop";
|
||||
"x-scheme-handler/https" = "firefox.desktop";
|
||||
"x-scheme-handler/mailto" = "org.gnome.Evolution.desktop"; # TODO: email on KDE - is Kontact any good?
|
||||
};
|
||||
};
|
||||
}
|
38
home/qenya/zsh.nix
Normal file
38
home/qenya/zsh.nix
Normal file
|
@ -0,0 +1,38 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
home.packages = with pkgs; [ direnv ];
|
||||
programs.zsh = {
|
||||
enable = true;
|
||||
enableCompletion = true;
|
||||
autosuggestion.enable = true;
|
||||
syntaxHighlighting.enable = true;
|
||||
dotDir = ".config/zsh";
|
||||
|
||||
shellAliases = {
|
||||
ll = "ls -l";
|
||||
|
||||
# don't clobber
|
||||
mv = "mv -i";
|
||||
rename = "rename -i";
|
||||
|
||||
nix-shell = ''nix-shell --command "zsh"''; # TODO: tweak theme to display something when inside nix-shell
|
||||
};
|
||||
|
||||
history = {
|
||||
size = 10000;
|
||||
path = "${config.xdg.dataHome}/zsh/history";
|
||||
ignorePatterns = [ "rm *" "pkill *" ];
|
||||
};
|
||||
|
||||
oh-my-zsh = {
|
||||
enable = true;
|
||||
plugins = [ "git" "sudo" "direnv" ];
|
||||
theme = "agnoster";
|
||||
};
|
||||
|
||||
envExtra = ''
|
||||
DEFAULT_USER=qenya
|
||||
'';
|
||||
};
|
||||
}
|
43
hosts/elucredassa/default.nix
Normal file
43
hosts/elucredassa/default.nix
Normal file
|
@ -0,0 +1,43 @@
|
|||
{ config, lib, pkgs, inputs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkForce;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./filesystems.nix
|
||||
./hardware.nix
|
||||
./networking.nix
|
||||
];
|
||||
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
networking.hostName = "elucredassa";
|
||||
networking.hostId = "a8ec6755";
|
||||
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" "rtsx_pci_sdmmc" ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
|
||||
qenya.base-server.enable = true;
|
||||
|
||||
i18n.defaultLocale = "en_GB.UTF-8";
|
||||
console.keyMap = "uk";
|
||||
services.xserver.xkb.layout = "gb";
|
||||
|
||||
# These are populated by fountain.backup
|
||||
randomcat.services.zfs.datasets = {
|
||||
"rpool_elucredassa/backup" = { mountpoint = "none"; };
|
||||
"rpool_elucredassa/backup/kalessin" = { mountpoint = "none"; };
|
||||
"rpool_elucredassa/backup/orm" = { mountpoint = "none"; };
|
||||
};
|
||||
|
||||
qenya.services.distributed-builds = {
|
||||
enable = true;
|
||||
keyFile = "/etc/ssh/ssh_host_ed25519_key";
|
||||
builders = [ "kilgharrah" ];
|
||||
};
|
||||
|
||||
fountain.users.qenya.enable = true;
|
||||
fountain.admins = [ "qenya" ];
|
||||
|
||||
system.stateVersion = "24.11";
|
||||
}
|
23
hosts/elucredassa/filesystems.nix
Normal file
23
hosts/elucredassa/filesystems.nix
Normal file
|
@ -0,0 +1,23 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
boot.initrd.luks.devices = {
|
||||
"luks-rpool-elucredassa".device = "/dev/disk/by-uuid/5ece5b58-c57a-41ae-b086-03707c39c9a7";
|
||||
};
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "rpool_elucredassa/root";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/2519-E2D6";
|
||||
fsType = "vfat";
|
||||
options = [ "fmask=0077" "dmask=0077" ];
|
||||
};
|
||||
};
|
||||
|
||||
swapDevices = [{ device = "/dev/disk/by-uuid/c7c48325-e90d-414d-b579-84cb45616ee9"; }];
|
||||
|
||||
boot.supportedFilesystems = [ "ntfs" ]; # for USB drives
|
||||
}
|
11
hosts/elucredassa/hardware.nix
Normal file
11
hosts/elucredassa/hardware.nix
Normal file
|
@ -0,0 +1,11 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
hardware.enableAllFirmware = true;
|
||||
hardware.cpu.intel.updateMicrocode = true;
|
||||
services.fwupd.enable = true;
|
||||
|
||||
# this is an old laptop
|
||||
services.logind.lidSwitch = "ignore";
|
||||
}
|
||||
|
48
hosts/elucredassa/networking.nix
Normal file
48
hosts/elucredassa/networking.nix
Normal file
|
@ -0,0 +1,48 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
systemd.network.enable = true;
|
||||
networking.useDHCP = false;
|
||||
|
||||
systemd.network.networks."10-wan" = {
|
||||
matchConfig.Name = "enp1s0f1";
|
||||
networkConfig = {
|
||||
DHCP = "ipv4";
|
||||
IPv6AcceptRA = true;
|
||||
Tunnel = "sit-he-ipv6";
|
||||
};
|
||||
linkConfig.RequiredForOnline = "routable";
|
||||
};
|
||||
|
||||
systemd.network.netdevs."25-he-ipv6" = {
|
||||
netdevConfig = {
|
||||
Name = "sit-he-ipv6";
|
||||
Kind = "sit";
|
||||
Description = "Hurricane Electric IPv6 Tunnel";
|
||||
MTUBytes = 1480;
|
||||
};
|
||||
|
||||
tunnelConfig = {
|
||||
Remote = "216.66.88.98";
|
||||
TTL = 255;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.network.networks."25-he-ipv6" = {
|
||||
matchConfig.Name = "sit-he-ipv6";
|
||||
networkConfig.Address = [ "2001:470:1f1c:3e::2/64" ];
|
||||
routes = [{ Destination = [ "::/0" ]; }];
|
||||
};
|
||||
|
||||
birdsong.peering = {
|
||||
enable = true;
|
||||
privateKeyFile = "/etc/wireguard/privatekey";
|
||||
persistentKeepalive = 29;
|
||||
};
|
||||
|
||||
# restricted to fit within the 6in4 tunnel
|
||||
systemd.network.netdevs."30-birdsong".netdevConfig.MTUBytes = 1280;
|
||||
# these two lines work around this bug: https://github.com/NixOS/nixpkgs/issues/375960
|
||||
systemd.network.netdevs."30-birdsong".netdevConfig.Kind = "wireguard";
|
||||
systemd.network.netdevs."30-birdsong".netdevConfig.Name = "wg-birdsong";
|
||||
}
|
40
hosts/kalessin/default.nix
Normal file
40
hosts/kalessin/default.nix
Normal file
|
@ -0,0 +1,40 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
keys = import ../../keys.nix;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
./networking.nix
|
||||
];
|
||||
|
||||
nixpkgs.hostPlatform = "aarch64-linux";
|
||||
networking.hostName = "kalessin";
|
||||
networking.hostId = "534b538e";
|
||||
networking.domain = "birdsong.network";
|
||||
|
||||
fountain.users.qenya.enable = true;
|
||||
fountain.admins = [ "qenya" ];
|
||||
fountain.users.randomcat.enable = true;
|
||||
fountain.users.trungle.enable = true;
|
||||
|
||||
qenya.base-server.enable = true;
|
||||
|
||||
qenya.services.remote-builder = {
|
||||
enable = true;
|
||||
authorizedKeys.keys = [ ];
|
||||
};
|
||||
|
||||
randomcat.services.zfs.datasets = {
|
||||
"rpool_kalessin/state" = { mountpoint = "none"; };
|
||||
};
|
||||
|
||||
services.sanoid.datasets."rpool_kalessin/state" = {
|
||||
useTemplate = [ "production" ];
|
||||
recursive = "zfs";
|
||||
process_children_only = true;
|
||||
};
|
||||
|
||||
system.stateVersion = "23.11";
|
||||
}
|
38
hosts/kalessin/hardware-configuration.nix
Normal file
38
hosts/kalessin/hardware-configuration.nix
Normal file
|
@ -0,0 +1,38 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "virtio_scsi" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "rpool_kalessin/root";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/nix" =
|
||||
{ device = "rpool_kalessin/nix";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/var" =
|
||||
{ device = "rpool_kalessin/var";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/2ADE-A033";
|
||||
fsType = "vfat";
|
||||
options = [ "fmask=0077" "dmask=0077" ];
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
}
|
18
hosts/kalessin/networking.nix
Normal file
18
hosts/kalessin/networking.nix
Normal file
|
@ -0,0 +1,18 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
networking.useNetworkd = true;
|
||||
networking.interfaces.enp0s6.useDHCP = true;
|
||||
|
||||
age.secrets.wireguard-peer-kalessin = {
|
||||
file = ../../secrets/wireguard-peer-kalessin.age;
|
||||
owner = "root";
|
||||
group = "systemd-network";
|
||||
mode = "640";
|
||||
};
|
||||
|
||||
birdsong.peering = {
|
||||
enable = true;
|
||||
privateKeyFile = config.age.secrets.wireguard-peer-kalessin.path;
|
||||
};
|
||||
}
|
8
hosts/kilgharrah/backup.nix
Normal file
8
hosts/kilgharrah/backup.nix
Normal file
|
@ -0,0 +1,8 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
services.sanoid.datasets."rpool_albion/state" = {
|
||||
useTemplate = [ "production" ];
|
||||
recursive = "zfs";
|
||||
};
|
||||
}
|
67
hosts/kilgharrah/default.nix
Normal file
67
hosts/kilgharrah/default.nix
Normal file
|
@ -0,0 +1,67 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
keys = import ../../keys.nix;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./backup.nix
|
||||
./filesystems.nix
|
||||
./hardware.nix
|
||||
./networking.nix
|
||||
./ftp.nix
|
||||
];
|
||||
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
networking.hostName = "kilgharrah";
|
||||
networking.hostId = "72885bb5";
|
||||
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod" ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
|
||||
qenya.base-graphical.enable = true;
|
||||
qenya.base-graphical.desktop = "plasma6";
|
||||
|
||||
time.timeZone = "Europe/London";
|
||||
i18n.defaultLocale = "en_GB.UTF-8";
|
||||
console.keyMap = "uk";
|
||||
services.xserver.xkb.layout = "gb";
|
||||
|
||||
fountain.users.qenya.enable = true;
|
||||
age.secrets.user-password-kilgharrah-qenya.file = ../../secrets/user-password-kilgharrah-qenya.age;
|
||||
users.users.qenya.hashedPasswordFile = config.age.secrets.user-password-kilgharrah-qenya.path;
|
||||
fountain.admins = [ "qenya" ];
|
||||
home-manager.users.qenya = { pkgs, ... }: {
|
||||
home.packages = with pkgs; [ obs-studio ];
|
||||
# For the moment, this hosts some network-accessible services, so we want it on 24/7
|
||||
programs.plasma.powerdevil.AC.autoSuspend.action = "nothing";
|
||||
};
|
||||
|
||||
qenya.services.remote-builder = {
|
||||
enable = true;
|
||||
authorizedKeys.keys = [
|
||||
keys.machines.yevaud
|
||||
keys.machines.orm
|
||||
keys.machines.tohru
|
||||
keys.machines.elucredassa
|
||||
];
|
||||
};
|
||||
|
||||
programs.steam.enable = true;
|
||||
qenya.services.audiobookshelf = {
|
||||
enable = true;
|
||||
domain = "audiobookshelf.qenya.tel";
|
||||
};
|
||||
qenya.services.jellyfin = {
|
||||
enable = true;
|
||||
domain = "jellyfin.qenya.tel";
|
||||
};
|
||||
qenya.services.navidrome = {
|
||||
enable = true;
|
||||
domain = "music.qenya.tel";
|
||||
dataDir = "/srv/music";
|
||||
};
|
||||
|
||||
system.stateVersion = "24.05";
|
||||
|
||||
}
|
93
hosts/kilgharrah/filesystems.nix
Normal file
93
hosts/kilgharrah/filesystems.nix
Normal file
|
@ -0,0 +1,93 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
# SSD on board
|
||||
|
||||
boot.initrd.luks.devices = {
|
||||
"cryptroot".device = "/dev/disk/by-uuid/b414aaba-0a36-4135-a7e1-dc9489286acd";
|
||||
};
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=@" "compress=zstd" ];
|
||||
};
|
||||
"/home" = {
|
||||
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=@home" "compress=zstd" ];
|
||||
};
|
||||
"/nix" = {
|
||||
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=@nix" "compress=zstd" "noatime" ];
|
||||
};
|
||||
"/swap" = {
|
||||
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=@swap" "noatime" ];
|
||||
};
|
||||
"/root" = {
|
||||
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=@root" "compress=zstd" ];
|
||||
};
|
||||
"/srv" = {
|
||||
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=@srv" "compress=zstd" ];
|
||||
};
|
||||
"/var/cache" = {
|
||||
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=@cache" "compress=zstd" "noatime" ];
|
||||
};
|
||||
"/var/tmp" = {
|
||||
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=@tmp" "compress=zstd" "noatime" ];
|
||||
};
|
||||
"/var/log" = {
|
||||
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=@log" "compress=zstd" "noatime" ];
|
||||
};
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/9582-E78D";
|
||||
fsType = "vfat";
|
||||
options = [ "fmask=0022" "dmask=0022" ];
|
||||
};
|
||||
};
|
||||
|
||||
swapDevices = [{
|
||||
device = "/swap/swapfile";
|
||||
size = 32 * 1024;
|
||||
}];
|
||||
|
||||
|
||||
# HDD in bay
|
||||
|
||||
environment.etc.crypttab.text = ''
|
||||
albion UUID=8a924f24-9b65-4f05-aeda-5b4080cc7aa1 /root/luks-albion.key
|
||||
'';
|
||||
|
||||
randomcat.services.zfs.datasets = {
|
||||
"rpool_albion/data" = { mountpoint = "none"; };
|
||||
"rpool_albion/data/steam" = { mountpoint = "/home/qenya/.local/share/Steam"; };
|
||||
"rpool_albion/state" = { mountpoint = "none"; };
|
||||
"rpool_albion/state/audiobookshelf" = { mountpoint = "/var/lib/audiobookshelf"; };
|
||||
"rpool_albion/state/jellyfin" = { mountpoint = "/var/lib/jellyfin"; };
|
||||
"rpool_albion/state/navidrome" = { mountpoint = "/var/lib/navidrome"; };
|
||||
"rpool_albion/srv" = { mountpoint = "none"; };
|
||||
"rpool_albion/srv/audiobookshelf" = { mountpoint = "/srv/audiobookshelf"; };
|
||||
"rpool_albion/srv/ftp" = { mountpoint = "/srv/ftp"; };
|
||||
"rpool_albion/srv/jellyfin" = { mountpoint = "/srv/jellyfin"; };
|
||||
"rpool_albion/srv/music" = { mountpoint = "/srv/music"; };
|
||||
};
|
||||
|
||||
|
||||
# Other
|
||||
|
||||
boot.supportedFilesystems = [ "ntfs" "zfs" ];
|
||||
}
|
70
hosts/kilgharrah/ftp.nix
Normal file
70
hosts/kilgharrah/ftp.nix
Normal file
|
@ -0,0 +1,70 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
age.secrets.ftp-userDb-qenya = {
|
||||
# To update this, see the nixos docs for services.vsftpd.userDbPath. Note
|
||||
# that the command it gives to create a userDb, if applied to an *existing*
|
||||
# userDb, will *add* the entries from the source file, overwriting any
|
||||
# entries with the same username but leaving other existing entries intact.
|
||||
# Also note the database format does not salt hashes.
|
||||
file = ../../secrets/ftp-userDb-qenya.age;
|
||||
|
||||
# we have to specify this manually because pam_userdb strips the extension
|
||||
path = "/etc/vsftpd/userDb.db";
|
||||
};
|
||||
|
||||
services.vsftpd = {
|
||||
enable = true;
|
||||
localUsers = true;
|
||||
forceLocalLoginsSSL = true;
|
||||
forceLocalDataSSL = true;
|
||||
rsaCertFile = "${config.security.acme.certs."ftp.qenya.tel".directory}/fullchain.pem";
|
||||
rsaKeyFile = "${config.security.acme.certs."ftp.qenya.tel".directory}/key.pem";
|
||||
|
||||
enableVirtualUsers = true;
|
||||
userlistDeny = false; # turn userlist from a denylist into an allowlist
|
||||
userlist = [ "qenya" ]; # this is just a list of the users in the userDb
|
||||
userDbPath = "/etc/vsftpd/userDb";
|
||||
|
||||
localRoot = "/srv/ftp";
|
||||
|
||||
extraConfig = ''
|
||||
# nothing in the default cipher suite is enabled in modern ssl clients!
|
||||
ssl_ciphers=HIGH
|
||||
|
||||
# set this to something firewallable
|
||||
pasv_min_port=51000
|
||||
pasv_max_port=51099
|
||||
|
||||
# don't bother with upgrading to TLS, just listen on FTPS only
|
||||
implicit_ssl=YES
|
||||
listen_port=990
|
||||
'';
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
"ftp.qenya.tel" = {
|
||||
forceSSL = true;
|
||||
useACMEHost = "ftp.qenya.tel";
|
||||
locations."/".return = "503";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
security.acme.certs = {
|
||||
"ftp.qenya.tel" = {
|
||||
webroot = "/var/lib/acme/acme-challenge";
|
||||
group = "acme_ftp.qenya.tel";
|
||||
};
|
||||
};
|
||||
|
||||
users.groups."acme_ftp.qenya.tel".members = [
|
||||
"vsftpd" # not configurable in the vsftpd nixos module
|
||||
config.services.nginx.group
|
||||
];
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 990 80 443 ];
|
||||
networking.firewall.allowedTCPPortRanges = [{ from = 51000; to = 51099; }];
|
||||
}
|
31
hosts/kilgharrah/hardware.nix
Normal file
31
hosts/kilgharrah/hardware.nix
Normal file
|
@ -0,0 +1,31 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
hardware.enableAllFirmware = true;
|
||||
hardware.cpu.intel.updateMicrocode = true;
|
||||
services.fwupd.enable = true;
|
||||
|
||||
services.xserver.videoDrivers = [ "nvidia" ];
|
||||
hardware.nvidia.open = false;
|
||||
|
||||
# # Downgrade to driver version 535 as 550 has problems with Wayland
|
||||
# hardware.nvidia.package =
|
||||
# let
|
||||
# rcu_patch = pkgs.fetchpatch {
|
||||
# url = "https://github.com/gentoo/gentoo/raw/c64caf53/x11-drivers/nvidia-drivers/files/nvidia-drivers-470.223.02-gpl-pfn_valid.patch";
|
||||
# hash = "sha256-eZiQQp2S/asE7MfGvfe6dA/kdCvek9SYa/FFGp24dVg=";
|
||||
# };
|
||||
# in
|
||||
# config.boot.kernelPackages.nvidiaPackages.mkDriver {
|
||||
# version = "535.154.05";
|
||||
# sha256_64bit = "sha256-fpUGXKprgt6SYRDxSCemGXLrEsIA6GOinp+0eGbqqJg=";
|
||||
# sha256_aarch64 = "sha256-G0/GiObf/BZMkzzET8HQjdIcvCSqB1uhsinro2HLK9k=";
|
||||
# openSha256 = "sha256-wvRdHguGLxS0mR06P5Qi++pDJBCF8pJ8hr4T8O6TJIo=";
|
||||
# settingsSha256 = "sha256-9wqoDEWY4I7weWW05F4igj1Gj9wjHsREFMztfEmqm10=";
|
||||
# persistencedSha256 = "sha256-d0Q3Lk80JqkS1B54Mahu2yY/WocOqFFbZVBh+ToGhaE=";
|
||||
# patches = [ rcu_patch ];
|
||||
# };
|
||||
|
||||
services.printing.drivers = [ pkgs.hplip ];
|
||||
}
|
||||
|
28
hosts/kilgharrah/networking.nix
Normal file
28
hosts/kilgharrah/networking.nix
Normal file
|
@ -0,0 +1,28 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
systemd.network.enable = true;
|
||||
networking.useDHCP = false;
|
||||
|
||||
systemd.network.networks."10-wan" = {
|
||||
matchConfig.Name = "enp2s0";
|
||||
networkConfig = {
|
||||
DHCP = "ipv4";
|
||||
IPv6AcceptRA = true;
|
||||
};
|
||||
linkConfig.RequiredForOnline = "routable";
|
||||
};
|
||||
|
||||
age.secrets.wireguard-peer-kilgharrah = {
|
||||
file = ../../secrets/wireguard-peer-kilgharrah.age;
|
||||
owner = "root";
|
||||
group = "systemd-network";
|
||||
mode = "640";
|
||||
};
|
||||
|
||||
birdsong.peering = {
|
||||
enable = true;
|
||||
privateKeyFile = config.age.secrets.wireguard-peer-kilgharrah.path;
|
||||
persistentKeepalive = 31;
|
||||
};
|
||||
}
|
72
hosts/orm/default.nix
Normal file
72
hosts/orm/default.nix
Normal file
|
@ -0,0 +1,72 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
./networking.nix
|
||||
];
|
||||
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
networking.hostName = "orm";
|
||||
networking.hostId = "00000000";
|
||||
networking.domain = "birdsong.network";
|
||||
|
||||
fountain.users.qenya.enable = true;
|
||||
fountain.admins = [ "qenya" ];
|
||||
qenya.base-server.enable = true;
|
||||
|
||||
qenya.services.distributed-builds = {
|
||||
enable = true;
|
||||
keyFile = "/etc/ssh/ssh_host_ed25519_key";
|
||||
builders = [ "kilgharrah" ];
|
||||
};
|
||||
nix.settings.max-jobs = 0;
|
||||
|
||||
randomcat.services.zfs.datasets = {
|
||||
"rpool_orm/state" = { mountpoint = "none"; };
|
||||
"rpool_orm/state/actual" = { mountpoint = "/var/lib/actual"; };
|
||||
"rpool_orm/state/postgresql" = { mountpoint = "/var/lib/postgresql"; };
|
||||
};
|
||||
|
||||
services.sanoid.datasets."rpool_orm/state" = {
|
||||
useTemplate = [ "production" ];
|
||||
recursive = "zfs";
|
||||
process_children_only = true;
|
||||
};
|
||||
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
package = pkgs.postgresql_17;
|
||||
dataDir = "/var/lib/postgresql/17";
|
||||
# managing imperatively instead of using ensureDatabases/ensureUsers
|
||||
|
||||
enableTCPIP = true;
|
||||
settings = {
|
||||
port = 5432;
|
||||
# TODO: fix SSL
|
||||
# ssl = true;
|
||||
};
|
||||
# only allow remote connections from within birdsong vpn
|
||||
# TODO: don't hardcode the IP addresses
|
||||
authentication = pkgs.lib.mkOverride 10 ''
|
||||
#type database DBuser auth-method
|
||||
local all all trust # used by nixos for local monitoring
|
||||
host sameuser all 10.127.0.0/16 scram-sha-256
|
||||
host sameuser all fd70:81ca:f8f::/48 scram-sha-256
|
||||
'';
|
||||
};
|
||||
networking.firewall.interfaces."wg-birdsong".allowedTCPPorts = [ 5432 ];
|
||||
|
||||
qenya.services.actual = {
|
||||
enable = true;
|
||||
domain = "actual.unspecified.systems";
|
||||
};
|
||||
fountain.services.web-redirect = {
|
||||
enable = true;
|
||||
domains = {
|
||||
"actual.qenya.tel" = "actual.unspecified.systems";
|
||||
};
|
||||
};
|
||||
|
||||
system.stateVersion = "23.11";
|
||||
}
|
40
hosts/orm/hardware-configuration.nix
Normal file
40
hosts/orm/hardware-configuration.nix
Normal file
|
@ -0,0 +1,40 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "rpool_orm/root";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/nix" =
|
||||
{ device = "rpool_orm/nix";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/var" =
|
||||
{ device = "rpool_orm/var";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/3739-E8C1";
|
||||
fsType = "vfat";
|
||||
options = [ "fmask=0077" "dmask=0077" ];
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-uuid/a0ac8f60-25f9-4dec-af70-e3f4cd36c575"; }
|
||||
];
|
||||
}
|
18
hosts/orm/networking.nix
Normal file
18
hosts/orm/networking.nix
Normal file
|
@ -0,0 +1,18 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
networking.useNetworkd = true;
|
||||
networking.interfaces.ens3.useDHCP = true;
|
||||
|
||||
age.secrets.wireguard-peer-orm = {
|
||||
file = ../../secrets/wireguard-peer-orm.age;
|
||||
owner = "root";
|
||||
group = "systemd-network";
|
||||
mode = "640";
|
||||
};
|
||||
|
||||
birdsong.peering = {
|
||||
enable = true;
|
||||
privateKeyFile = config.age.secrets.wireguard-peer-orm.path;
|
||||
};
|
||||
}
|
11
hosts/shaw/home.nix
Normal file
11
hosts/shaw/home.nix
Normal file
|
@ -0,0 +1,11 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
services.syncthing = {
|
||||
enable = true;
|
||||
extraOptions = [
|
||||
"--gui-address=:8385"
|
||||
"--home=/home/qenya/state/syncthing"
|
||||
];
|
||||
};
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ # Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
boot.loader.systemd-boot.editor = false;
|
||||
|
||||
networking.hostName = "tohru";
|
||||
networking.hostId = "31da19c1";
|
||||
networking.networkmanager.enable = true;
|
||||
|
||||
time.timeZone = "Europe/London";
|
||||
|
||||
i18n.defaultLocale = "en_GB.UTF-8";
|
||||
console.keyMap = "uk";
|
||||
|
||||
services.xserver.enable = true;
|
||||
services.xserver.displayManager.gdm.enable = true;
|
||||
services.xserver.desktopManager.gnome.enable = true;
|
||||
|
||||
services.xserver.xkb.layout = "gb";
|
||||
|
||||
services.printing.enable = true;
|
||||
|
||||
sound.enable = true;
|
||||
hardware.pulseaudio.enable = true;
|
||||
|
||||
# Enable touchpad support (enabled default in most desktopManager).
|
||||
services.xserver.libinput.enable = true;
|
||||
|
||||
# Define a user account. Don't forget to set a password with ‘passwd’.
|
||||
users.users.bluebird = {
|
||||
isNormalUser = true;
|
||||
extraGroups = [ "wheel" "networkmanager" ];
|
||||
packages = with pkgs; [
|
||||
tor-browser-bundle-bin
|
||||
firefox
|
||||
tree
|
||||
];
|
||||
};
|
||||
|
||||
# List packages installed in system profile. To search, run:
|
||||
# $ nix search wget
|
||||
environment.systemPackages = with pkgs; [
|
||||
# vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
|
||||
bitwarden
|
||||
git
|
||||
plocate
|
||||
wget
|
||||
];
|
||||
|
||||
# Some programs need SUID wrappers, can be configured further or are
|
||||
# started in user sessions.
|
||||
# programs.mtr.enable = true;
|
||||
# programs.gnupg.agent = {
|
||||
# enable = true;
|
||||
# enableSSHSupport = true;
|
||||
# };
|
||||
|
||||
# List services that you want to enable:
|
||||
|
||||
# Enable the OpenSSH daemon.
|
||||
# services.openssh.enable = true;
|
||||
|
||||
# Open ports in the firewall.
|
||||
# networking.firewall.allowedTCPPorts = [ ... ];
|
||||
# networking.firewall.allowedUDPPorts = [ ... ];
|
||||
# Or disable the firewall altogether.
|
||||
# networking.firewall.enable = false;
|
||||
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
hardware.enableAllFirmware = true;
|
||||
services.fwupd.enable = true;
|
||||
services.fstrim.enable = true;
|
||||
|
||||
boot.initrd.luks.devices = {
|
||||
"rpool".device = "/dev/nvme0n1p2";
|
||||
};
|
||||
|
||||
# This option defines the first version of NixOS you have installed on this particular machine,
|
||||
# and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
|
||||
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
|
||||
system.stateVersion = "23.11";
|
||||
}
|
||||
|
68
hosts/tohru/default.nix
Normal file
68
hosts/tohru/default.nix
Normal file
|
@ -0,0 +1,68 @@
|
|||
{ config, lib, pkgs, inputs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkForce;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./filesystems.nix
|
||||
./hardware.nix
|
||||
./networking.nix
|
||||
|
||||
./syncthing.nix
|
||||
];
|
||||
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
networking.hostName = "tohru";
|
||||
networking.hostId = "31da19c1";
|
||||
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "rtsx_pci_sdmmc" ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
|
||||
qenya.base-graphical.enable = true;
|
||||
|
||||
time.timeZone = "Europe/London";
|
||||
i18n.defaultLocale = "en_GB.UTF-8";
|
||||
console.keyMap = "uk";
|
||||
services.xserver.xkb.layout = "gb";
|
||||
|
||||
# tohru does not have the resources to run this under other load and is generally powered off when not in use.
|
||||
# instead, just run `nix-store --optimise` every so often.
|
||||
nix.optimise.automatic = mkForce false;
|
||||
|
||||
fountain.users.qenya.enable = true;
|
||||
fountain.admins = [ "qenya" ];
|
||||
age.secrets.user-password-tohru-qenya.file = ../../secrets/user-password-tohru-qenya.age;
|
||||
users.users.qenya.hashedPasswordFile = config.age.secrets.user-password-tohru-qenya.path;
|
||||
users.users.qenya.extraGroups = [
|
||||
"networkmanager" # UI wifi configuration
|
||||
"dialout" # access to serial ports
|
||||
];
|
||||
|
||||
nixpkgs.overlays = [ inputs.scoutshonour.overlays.default ];
|
||||
home-manager.users.qenya = { pkgs, ... }: {
|
||||
home.packages = with pkgs; [
|
||||
keepassxc
|
||||
amberol
|
||||
foliate
|
||||
nicotine-plus
|
||||
|
||||
# games
|
||||
openttd
|
||||
prismlauncher
|
||||
scoutshonour.digital-a-love-story
|
||||
scoutshonour.dont-take-it-personally-babe
|
||||
];
|
||||
};
|
||||
|
||||
qenya.services.distributed-builds = {
|
||||
enable = true;
|
||||
keyFile = "/etc/ssh/ssh_host_ed25519_key";
|
||||
builders = [ "kilgharrah" ];
|
||||
};
|
||||
|
||||
programs.evolution.enable = true; # not in home-manager yet; not declaratively configurable yet
|
||||
programs.steam.enable = true;
|
||||
|
||||
system.stateVersion = "23.11";
|
||||
}
|
51
hosts/tohru/filesystems.nix
Normal file
51
hosts/tohru/filesystems.nix
Normal file
|
@ -0,0 +1,51 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
boot.initrd.luks.devices = {
|
||||
"rpool".device = "/dev/nvme0n1p2";
|
||||
};
|
||||
|
||||
boot.supportedFilesystems = [ "ntfs" ]; # for USB drives
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "rpool/root";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/nix" = {
|
||||
device = "rpool/nix";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/var" = {
|
||||
device = "rpool/var";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/config" = {
|
||||
device = "rpool/config";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/home" = {
|
||||
device = "rpool/home";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/data" = {
|
||||
device = "rpool/data";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/data/syncthing" = {
|
||||
device = "rpool/data/syncthing";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/data/steam" = {
|
||||
device = "rpool/data/steam";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/7DD4-487E";
|
||||
fsType = "vfat";
|
||||
options = [ "fmask=0022" "dmask=0022" ];
|
||||
};
|
||||
};
|
||||
|
||||
swapDevices = [{ device = "/dev/disk/by-uuid/a066313e-2467-4e07-ad0c-aeb7ff3f8d97"; }];
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "rpool/root";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/nix" =
|
||||
{ device = "rpool/nix";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/var" =
|
||||
{ device = "rpool/var";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/home" =
|
||||
{ device = "rpool/home";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/7DD4-487E";
|
||||
fsType = "vfat";
|
||||
options = [ "fmask=0022" "dmask=0022" ];
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||
# still possible to use this option, but it's recommended to use it in conjunction
|
||||
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.eno2.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.wlo1.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
10
hosts/tohru/hardware.nix
Normal file
10
hosts/tohru/hardware.nix
Normal file
|
@ -0,0 +1,10 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
hardware.enableAllFirmware = true;
|
||||
hardware.cpu.intel.updateMicrocode = true;
|
||||
services.fwupd.enable = true;
|
||||
|
||||
services.printing.drivers = [ pkgs.hplip ];
|
||||
}
|
||||
|
21
hosts/tohru/networking.nix
Normal file
21
hosts/tohru/networking.nix
Normal file
|
@ -0,0 +1,21 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
networking.useNetworkd = true;
|
||||
systemd.network.wait-online.enable = false;
|
||||
|
||||
networking.networkmanager.enable = true;
|
||||
|
||||
age.secrets.wireguard-peer-tohru = {
|
||||
file = ../../secrets/wireguard-peer-tohru.age;
|
||||
owner = "root";
|
||||
group = "systemd-network";
|
||||
mode = "640";
|
||||
};
|
||||
|
||||
birdsong.peering = {
|
||||
enable = true;
|
||||
privateKeyFile = config.age.secrets.wireguard-peer-tohru.path;
|
||||
persistentKeepalive = 23;
|
||||
};
|
||||
}
|
53
hosts/tohru/syncthing.nix
Normal file
53
hosts/tohru/syncthing.nix
Normal file
|
@ -0,0 +1,53 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
services.syncthing = {
|
||||
enable = true;
|
||||
user = "qenya";
|
||||
dataDir = "/data/syncthing";
|
||||
openDefaultPorts = true;
|
||||
overrideDevices = true;
|
||||
overrideFolders = true;
|
||||
settings = {
|
||||
devices = {
|
||||
"kilgharrah" = { id = "RDT7IGD-76FZ6LY-37PPB2W-DWPQRPR-LZ4AXF7-4GIIHYJ-RVXUUSG-ZXPN3AZ"; };
|
||||
"latias" = { id = "EN4W2SB-LB4AAZQ-6AQIE7G-S3BSCSP-V2EUNMM-KAQEHW3-PPAPGBO-PXRPWAL"; };
|
||||
"shaw" = { id = "NC7WMZS-GQETJYR-IAYGD65-GHTSTVP-VAAG43K-W7N3LO5-C5OQMZ2-DTK6YA7"; };
|
||||
};
|
||||
folders = {
|
||||
"Sync" = {
|
||||
id = "uln2v-zwzwj";
|
||||
path = "~/Sync";
|
||||
devices = [ "kilgharrah" "shaw" ];
|
||||
};
|
||||
|
||||
"Documents" = {
|
||||
id = "alp59-7gs9s";
|
||||
path = "~/Documents";
|
||||
devices = [ "kilgharrah" "shaw" ];
|
||||
};
|
||||
"Music" = {
|
||||
id = "7xvkf-y62s7";
|
||||
path = "~/Music";
|
||||
devices = [ "kilgharrah" "shaw" ];
|
||||
};
|
||||
"Pictures" = {
|
||||
id = "tbmhx-ep7wk";
|
||||
path = "~/Pictures";
|
||||
devices = [ "kilgharrah" "shaw" ];
|
||||
};
|
||||
|
||||
"ES-DE" = {
|
||||
id = "c1cbh-llw94";
|
||||
path = "~/ES-DE";
|
||||
devices = [ "kilgharrah" "latias" "shaw" ];
|
||||
};
|
||||
"ROMs" = {
|
||||
id = "dcze4-v6act";
|
||||
path = "~/ROMs";
|
||||
devices = [ "kilgharrah" "latias" "shaw" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
63
hosts/yevaud/default.nix
Normal file
63
hosts/yevaud/default.nix
Normal file
|
@ -0,0 +1,63 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
./networking.nix
|
||||
|
||||
./experiments/birdsong-dns.nix
|
||||
# TODO: this breaks external IPv6 somehow
|
||||
# ./experiments/pennykettle.nix
|
||||
];
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
networking.hostName = "yevaud";
|
||||
networking.hostId = "09673d65";
|
||||
networking.domain = "birdsong.network";
|
||||
|
||||
fountain.users.qenya.enable = true;
|
||||
fountain.admins = [ "qenya" ];
|
||||
qenya.base-server.enable = true;
|
||||
|
||||
qenya.services.distributed-builds = {
|
||||
enable = true;
|
||||
keyFile = "/etc/ssh/ssh_host_ed25519_key";
|
||||
builders = [ "kilgharrah" ];
|
||||
};
|
||||
nix.settings.max-jobs = 0;
|
||||
|
||||
randomcat.services.zfs.datasets = {
|
||||
"rpool/state" = { mountpoint = "none"; };
|
||||
"rpool/state/forgejo" = { mountpoint = "/var/lib/forgejo"; };
|
||||
};
|
||||
|
||||
services.sanoid.datasets."rpool/state" = {
|
||||
useTemplate = [ "production" ];
|
||||
recursive = "zfs";
|
||||
};
|
||||
|
||||
qenya.services.forgejo = {
|
||||
enable = true;
|
||||
domain = "git.unspecified.systems";
|
||||
};
|
||||
fountain.services.web-redirect = {
|
||||
enable = true;
|
||||
domains = {
|
||||
"git.katherina.rocks" = "git.unspecified.systems";
|
||||
"git.qenya.tel" = "git.unspecified.systems";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
"birdsong.network" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/".return = "301 https://git.unspecified.systems/qenya/birdsong/";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
system.stateVersion = "23.11";
|
||||
}
|
32
hosts/yevaud/experiments/birdsong-dns.nix
Normal file
32
hosts/yevaud/experiments/birdsong-dns.nix
Normal file
|
@ -0,0 +1,32 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
services.bind = {
|
||||
# enable = true;
|
||||
cacheNetworks = [ "10.127.0.0/16" "fd70:81ca:0f8f::/48" ];
|
||||
forwarders = [ ];
|
||||
listenOn = [ config.birdsong.hosts.yevaud.ipv4 ];
|
||||
listenOnIpv6 = [ config.birdsong.hosts.yevaud.ipv6 ];
|
||||
zones = {
|
||||
"birdsong.internal" = {
|
||||
master = true;
|
||||
file = pkgs.writeText "birdsong.internal.zone" ''
|
||||
$TTL 60
|
||||
$ORIGIN birdsong.internal.
|
||||
|
||||
birdsong.internal. IN SOA ns.birdsong.internal. auto.qenya.tel. ( 2024122701 7200 3600 1209600 3600 )
|
||||
birdsong.internal. IN NS ns.birdsong.internal.
|
||||
|
||||
yevaud.c.birdsong.internal. IN A 10.127.1.1
|
||||
yevaud.c.birdsong.internal. IN AAAA fd70:81ca:0f8f:1::1
|
||||
|
||||
ns.birdsong.internal. IN A 10.127.1.1
|
||||
ns.birdsong.internal. IN AAAA fd70:81ca:0f8f:1::1
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
networking.resolvconf.useLocalResolver = false;
|
||||
networking.firewall.allowedTCPPorts = [ 53 ];
|
||||
networking.firewall.allowedUDPPorts = [ 53 ];
|
||||
}
|
85
hosts/yevaud/experiments/pennykettle.nix
Normal file
85
hosts/yevaud/experiments/pennykettle.nix
Normal file
|
@ -0,0 +1,85 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
networking.nat.enable = true;
|
||||
networking.nat.internalInterfaces = [ "ve-pennykettle1" ];
|
||||
networking.nat.externalInterface = "ens3";
|
||||
networking.firewall.allowedUDPPorts = [ 51821 ];
|
||||
|
||||
containers."pennykettle1" = {
|
||||
privateNetwork = true;
|
||||
extraVeths."ve-pennykettle1" = {
|
||||
hostAddress = "10.235.1.1";
|
||||
localAddress = "10.235.2.1";
|
||||
forwardPorts = [{ hostPort = 51821; }];
|
||||
};
|
||||
ephemeral = true;
|
||||
autoStart = true;
|
||||
bindMounts."/run/secrets/wg-key".hostPath = config.age.secrets.protonvpn-pennykettle1.path;
|
||||
|
||||
config = { config, pkgs, ... }: {
|
||||
system.stateVersion = "24.05";
|
||||
systemd.services."systemd-networkd".environment.SYSTEMD_LOG_LEVEL = "debug";
|
||||
environment.systemPackages = [ pkgs.wireguard-tools ];
|
||||
|
||||
networking.useDHCP = false;
|
||||
networking.useHostResolvConf = false;
|
||||
networking.firewall.allowedUDPPorts = [ 51821 ];
|
||||
systemd.network = {
|
||||
enable = true;
|
||||
|
||||
networks."10-ve" = {
|
||||
matchConfig.Name = "ve-pennykettle1";
|
||||
networkConfig.Address = "10.235.2.1/32";
|
||||
# linkConfig.RequiredForOnline = "routable";
|
||||
routes = [{
|
||||
routeConfig = {
|
||||
Gateway = "10.235.1.1";
|
||||
Destination = "217.138.216.162/32";
|
||||
};
|
||||
}];
|
||||
};
|
||||
|
||||
networks."30-protonvpn" = {
|
||||
matchConfig.Name = "wg-protonvpn";
|
||||
networkConfig = {
|
||||
DefaultRouteOnDevice = true;
|
||||
Address = [ "10.2.0.2/32" ];
|
||||
DNS = "10.2.0.1";
|
||||
};
|
||||
linkConfig = {
|
||||
RequiredForOnline = "yes";
|
||||
ActivationPolicy = "always-up";
|
||||
};
|
||||
};
|
||||
|
||||
netdevs."30-protonvpn" = {
|
||||
netdevConfig = {
|
||||
Name = "wg-protonvpn";
|
||||
Kind = "wireguard";
|
||||
Description = "WireGuard tunnel to ProtonVPN (DE#1; NAT: strict, no port forwarding)";
|
||||
};
|
||||
wireguardConfig = {
|
||||
ListenPort = 51821;
|
||||
PrivateKeyFile = "/run/secrets/wg-key";
|
||||
};
|
||||
wireguardPeers = [{
|
||||
wireguardPeerConfig = {
|
||||
PublicKey = "C+u+eQw5yWI2APCfVJwW6Ovj3g4IrTOfe+tMZnNz43s=";
|
||||
AllowedIPs = "0.0.0.0/0";
|
||||
Endpoint = "217.138.216.162:51820";
|
||||
PersistentKeepalive = 5;
|
||||
};
|
||||
}];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
age.secrets.protonvpn-pennykettle1 = {
|
||||
file = ../../../secrets/protonvpn-pennykettle1.age;
|
||||
owner = "root";
|
||||
group = "systemd-network";
|
||||
mode = "640";
|
||||
};
|
||||
}
|
40
hosts/yevaud/hardware-configuration.nix
Normal file
40
hosts/yevaud/hardware-configuration.nix
Normal file
|
@ -0,0 +1,40 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-amd" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "rpool/root";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/nix" =
|
||||
{ device = "rpool/nix";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/var" =
|
||||
{ device = "rpool/var";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/107D-5AB3";
|
||||
fsType = "vfat";
|
||||
options = [ "fmask=0077" "dmask=0077" ];
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-uuid/f8b6eb35-33ad-4e19-bf3d-cac5ec38a8dc"; }
|
||||
];
|
||||
}
|
18
hosts/yevaud/networking.nix
Normal file
18
hosts/yevaud/networking.nix
Normal file
|
@ -0,0 +1,18 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
networking.useNetworkd = true;
|
||||
networking.interfaces.ens3.useDHCP = true;
|
||||
|
||||
age.secrets.wireguard-peer-yevaud = {
|
||||
file = ../../secrets/wireguard-peer-yevaud.age;
|
||||
owner = "root";
|
||||
group = "systemd-network";
|
||||
mode = "640";
|
||||
};
|
||||
|
||||
birdsong.peering = {
|
||||
enable = true;
|
||||
privateKeyFile = config.age.secrets.wireguard-peer-yevaud.path;
|
||||
};
|
||||
}
|
29
keys.nix
Normal file
29
keys.nix
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
machines = {
|
||||
kilgharrah = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOgGF3gzzlMbxxk3UAAgHJ7sDdjqtrw7UW16M1XhXtz2 root@kilgharrah";
|
||||
elucredassa = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA+Y/vqGNc1wXUAg4XMAAcLupkggywj2LpYDwA16ONbH root@elucredassa";
|
||||
tohru = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOk8wuGzF0Y7SaH9aimo3SmCz99MTQwL+rEVhx0jsueU root@tohru";
|
||||
yevaud = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICHUAgyQhl390yUObLUI+jEbuNrZ2U6+8px628DolD+T root@yevaud";
|
||||
orm = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGc9rkcdOVWozBFj3kLVnSyUQQbyyH+UG+bLawanQkRQ root@orm";
|
||||
kalessin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOPt3iSSmgnlsv1/jafgZgI7o8UuXzcAL45hID2ThfS8 root@kalessin";
|
||||
shaw = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMC0AomCZZiUV/BCpImiV4p/vGvFaz5QNc+fJLXmS5p root@shaw";
|
||||
};
|
||||
|
||||
users = {
|
||||
qenya = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFjBuuxo+w3yED0aPnsNb8S90p/GgBqFEG9K4ETZ5Wkq qenya@kilgharrah"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJEmkV9arotms79lJPsLHkdzAac4eu3pYS08ym0sB/on qenya@tohru"
|
||||
];
|
||||
randomcat = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDHagOaeTR+/7FL9sErciMw30cmV/VW8HU7J3ZFU5nj9 janet@randomcat.org"
|
||||
];
|
||||
trungle = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAA57legzdIcYTVVri4Wc0CvgWefbRhmUqhu0F/5f8FB reuben@glenda-artix"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHAuYWPfYVKdjBY/gBMt2n11Seb+hMqjui1PQ6C4ph8i richard@tress"
|
||||
];
|
||||
gaelan = [
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDFbDvPKnPXe+58QgdgK8yZ3Ac9dkJdtHJ3pQwWhszM7McwCzCEO/b940K0orLjfeUruC+hGJZO8heIh0J6JwSK907aS2wpHofU9q7bMT0PYeuHrSb2iFrOFIkTIWpO8hnWad8TGKOlOdNTKEdB9zwxXEKTFb9QW1Z27Zql79W44jUvaOTb7gKUps37O77lHEJDModaRsXS2523pSbrTZKDwZ73+S0ECeNUwwzLUyOOUHfENEXnM18hWm8mV0iU7kxFcmS33z9rWlWPNiCXnBnSi5LPgBarYOAqQf56f9OisafKqvc3uX+yn0kGCDWglVGUkbhfSIP9+w+yv/h/NJWIJlJC92ndbktAqAQW4gb7lXYxpbdoWcmqEy97q0e2vyBdhcVXwZ+0q+U8I74m8trq36ieHDtLKYkiFBX6zvrLP4I5OZU+EecdV2HcMoU8HNa5u1mvG+oHaEgkR70a5cQtrPzWLS/OMLqvWL39vO7RNskzwWCSuWScxDGitr+BunRRbL4aKNkkPjdDlIqb/SfSrFikOo75f5Ku4I32nbM7SNpIjA4cHe50rx1UB8lT+RwHdxL99OdoxIPCe6OLA5uT8VGPXkvqd/ZIFOL2HaM+uPLaYbjwLrHlwSOLgGbehmsSD369EXv6NAc5wbzsSLJQhJ66d5unnzGjn4dRt9sbDw== gbs@canishe.com"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHId+2dJYiZK++p8lu9Bax0J29JjeuU4qcIBdLwEz3lm gbs@canishe.com"
|
||||
];
|
||||
};
|
||||
}
|
23
secrets.nix
Normal file
23
secrets.nix
Normal file
|
@ -0,0 +1,23 @@
|
|||
let
|
||||
keys = import ./keys.nix;
|
||||
|
||||
secrets = with keys; {
|
||||
ftp-userDb-qenya = [ machines.kilgharrah ] ++ keys.users.qenya;
|
||||
user-password-kilgharrah-qenya = [ machines.kilgharrah ] ++ keys.users.qenya;
|
||||
user-password-tohru-qenya = [ machines.tohru ] ++ keys.users.qenya;
|
||||
wireguard-peer-orm = [ machines.orm ] ++ keys.users.qenya;
|
||||
wireguard-peer-tohru = [ machines.tohru ] ++ keys.users.qenya;
|
||||
wireguard-peer-yevaud = [ machines.yevaud ] ++ keys.users.qenya;
|
||||
wireguard-peer-kalessin = [ machines.kalessin ] ++ keys.users.qenya;
|
||||
wireguard-peer-kilgharrah = [ machines.kilgharrah ] ++ keys.users.qenya;
|
||||
protonvpn-pennykettle1 = [ machines.yevaud ] ++ keys.users.qenya;
|
||||
};
|
||||
in
|
||||
builtins.listToAttrs (
|
||||
map
|
||||
(secretName: {
|
||||
name = "secrets/${secretName}.age";
|
||||
value.publicKeys = secrets."${secretName}";
|
||||
})
|
||||
(builtins.attrNames secrets)
|
||||
)
|
BIN
secrets/ftp-userDb-qenya.age
Normal file
BIN
secrets/ftp-userDb-qenya.age
Normal file
Binary file not shown.
9
secrets/protonvpn-pennykettle1.age
Normal file
9
secrets/protonvpn-pennykettle1.age
Normal file
|
@ -0,0 +1,9 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 uJfgGw +h4WiWyMlQZ5iaMFTl/whUD0vJnIN0GYeqRbZ0MIH0o
|
||||
eKio4DsSJlrvSAjmR0naDO/lmB78o7cy7QC9WZjHUa0
|
||||
-> ssh-ed25519 seJ9Iw xov8WY0TxEj5/wkWg1T0kmrbpXsNhDLnZwqyIg0eExA
|
||||
wu5QApQk6K8Fu5XMTrWY2veoYbJVuQmn3DJXewVB860
|
||||
-> ssh-ed25519 900ILw N6RbpHr4Vwgm0BUCuMXzVo3VEgrl29NF8ZJU5Far7yk
|
||||
KdA1dZXmcSF3cH9bVdmIbj7iZO3uuSY+isjswDzSu+Y
|
||||
--- YtnS9FqXVat2hi9BLvX+71HEZDw3zcxIQ7Dp5+iao4c
|
||||
¢¼ða'þš|<7C>‡N7N”†ÊT5]O¤0Säm<-1ë»ëª:d®„–›g¡^/ä†u7µïNû?XþMçûìÄì~Þs.9c¾C
|
BIN
secrets/user-password-kilgharrah-qenya.age
Normal file
BIN
secrets/user-password-kilgharrah-qenya.age
Normal file
Binary file not shown.
BIN
secrets/user-password-tohru-qenya.age
Normal file
BIN
secrets/user-password-tohru-qenya.age
Normal file
Binary file not shown.
9
secrets/wireguard-peer-kalessin.age
Normal file
9
secrets/wireguard-peer-kalessin.age
Normal file
|
@ -0,0 +1,9 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 QjA8rQ eBORfw+iHPPMYgYQc2gTD9j/QEr36fVFCGYtVX2bGBQ
|
||||
TH/XvVgv7ugjzL6a8bffLq/dj5IUbZtCXkJ+XefxURc
|
||||
-> ssh-ed25519 seJ9Iw fLYNcU2XjiryoOx1gEH9pDMOpfmLsvrcslplL2fFwCI
|
||||
Wn5KlABSx6mJYvVKO5zXq4VA0SIV5s5WztPIwGLFWG0
|
||||
-> ssh-ed25519 900ILw wW6lbItZyxelxyTXVLIkInWshc4DtOjGelcm4ixE8kg
|
||||
/F7kp3AS68QHBitbkZGm9CNF26uw+GtdrTTyYiW6/6E
|
||||
--- 4t+IrAJ6k/x8FMXiELoDXJICWv7QUcwBRmzKEt+/1+I
|
||||
å:wQ‘ÌO’ r«‡Å½ª:PŒ½Ë„¶ªÒæ9ÆG¸˜Tèr³“½cù|îÍ6|‹çíƒÅ4ïˆû†××}½ÒŸ3c©Î€-Jƒè°-Œ!
|
1
secrets/wireguard-peer-kalessin.pub
Normal file
1
secrets/wireguard-peer-kalessin.pub
Normal file
|
@ -0,0 +1 @@
|
|||
9vyIoXuu1UVjV+aFeuX9LoHRBeAAsiHbrLmYQY4nsQQ=
|
9
secrets/wireguard-peer-kilgharrah.age
Normal file
9
secrets/wireguard-peer-kilgharrah.age
Normal file
|
@ -0,0 +1,9 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 5PK5ag WsUZWedml5fBAIEog+puLADcitY0uKJttT7ABUIjnnY
|
||||
IZbF1yTctMOJWOW7A/EIlMC1pfpFR5TLghShF4wpXW8
|
||||
-> ssh-ed25519 seJ9Iw OHLAn4ZU6QZ/rv0kzh3q2A502XbNtCt05tJUSnv2MhY
|
||||
OQ2kxhsFGmCKHlVINHdbDRKbAOFWaSFmf/epGcUJLuE
|
||||
-> ssh-ed25519 900ILw CcGgENZiqjRLC7pJSzfluC38thwWX/iTeWc9dPgHcjw
|
||||
Q+IWIEfOaros+rDLJIbzdOndLZMACQjVqebIrYsjvnc
|
||||
--- uhddG2mrqw+pfDInK0hrzH6BuT2CfmUw/QAkhLD24YY
|
||||
<19>®:“ßg~4böuÚ’—%ªò¤¦!4K<>Ú“šâÓ‘^ÝÆ•¢ÆÁ`¥®A¨ƒîº«j!_åPó©³w#@"´¸7{‚˜ÿ%Yo
|
1
secrets/wireguard-peer-kilgharrah.pub
Normal file
1
secrets/wireguard-peer-kilgharrah.pub
Normal file
|
@ -0,0 +1 @@
|
|||
LXQVU0MFKVO/mml5krHnf6NcL4GxF6XFJmvpmjrLBFA=
|
10
secrets/wireguard-peer-orm.age
Normal file
10
secrets/wireguard-peer-orm.age
Normal file
|
@ -0,0 +1,10 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 l/RSAw d62ed4GntqcH7w0Qm7La/1GXBnWbAkrHekt3R/ssuwY
|
||||
4XrxbvJ4CjPJuJ7oGuoxuhb2/VTI6XUjvI0XQmamtPk
|
||||
-> ssh-ed25519 seJ9Iw ykj+pdFOkHdCxaotW+SxWQzK6VMMbSaREbx9r7rMIl0
|
||||
XEB7ic2SlNQf6C0M3rm9h9D04FYtDkeBobZWnbgQDck
|
||||
-> ssh-ed25519 900ILw 29vJoPdoyapdB47hK5p1u4daaJbNrwAv+7ndoPB6VCo
|
||||
m+sOCPiD3MbEJycIgLa24QU5ILna9UI5Luigvv9k2T4
|
||||
--- 7HDSsngCFsU9GywCc+8/txXsBwcoFWZ7D4/iTbSbtzs
|
||||
er\ñ#<23>ÌZÂfý\zd óèÚÄ×ÛÇÅð<C385>Wîu•‰(ºý´‘5ÙÇx_#NÌ«–ø¦<>
|
||||
0y—DDa+>‘FÓˆ«X^ÃÕu8e
|
1
secrets/wireguard-peer-orm.pub
Normal file
1
secrets/wireguard-peer-orm.pub
Normal file
|
@ -0,0 +1 @@
|
|||
birdLVh8roeZpcVo308Ums4l/aibhAxbi7MBsglkJyA=
|
9
secrets/wireguard-peer-tohru.age
Normal file
9
secrets/wireguard-peer-tohru.age
Normal file
|
@ -0,0 +1,9 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 yZzWlg o1Jax+v/jJ2ayNLw0Z97iA1sjZrK5t266LyZYaj/3nk
|
||||
rTjIt9vcSdkOohnDBbFMR5iJnJGlIEQU34h1SafofeI
|
||||
-> ssh-ed25519 seJ9Iw 2EsG0EUBCiaPk/mgADGydGGX72K1q9hKDj/abp8nvVw
|
||||
5CMR/jpg1o9uQ986L+An6x60SnUrVGVVXXo+CCU3UfE
|
||||
-> ssh-ed25519 900ILw InEzPKOEkoQ/tp4T3mo9/TMvWtLYqlsdkdV4fhkBLwg
|
||||
xCupfNr2jilKtPnjBYv234qUE6ont4ofgY3bwtQUY6I
|
||||
--- 4c4R1a8GkNXDS4zThBBIKvMrXK3zqNvc7hK8VWLCB4I
|
||||
Ù³
Û«‚›-®Ú®´ò¿ÙV+¿ 3~8þL±RÕ‚¬Ê2¶Rb6ç"ÂO‰<4F>ùpM•×áÃËOÆ5Cº–Žº&<26>Ç.EE³1_ó{
|
1
secrets/wireguard-peer-tohru.pub
Normal file
1
secrets/wireguard-peer-tohru.pub
Normal file
|
@ -0,0 +1 @@
|
|||
lk3PCQM1jmZoI8sM/rWSyKNuZOUnjox3n9L9geJD+18=
|
10
secrets/wireguard-peer-yevaud.age
Normal file
10
secrets/wireguard-peer-yevaud.age
Normal file
|
@ -0,0 +1,10 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 uJfgGw PrfPHcOs1dZCPi2rdkj1Ep2eAQS54LRiNizpfECwbD8
|
||||
JWjQDy22aRWJpLxCqmbO8+Qf7uUe419uwBHQSdlZkW8
|
||||
-> ssh-ed25519 seJ9Iw DMpu+V3zziwZNwGFl0VBddbAxOy3BjzqiH1ifNm50xA
|
||||
U+F1KGWiuwPGG8W2C3/bV870z4teKbPYS8Avhnfz/Jw
|
||||
-> ssh-ed25519 900ILw CtQ5lpYLMQXGbTWWmz2f4Ya/LWg1cYETOn9yq6p7eX4
|
||||
L1tS98YRFqe43XGBRxvnZFOzsC1crcL9kbHI2y5UFwE
|
||||
--- jHmFvmZH+RuZo+PFDyQyaiLi85Q8akJsOC0xpM0Raj4
|
||||
Ëz•~žê}ƒ_PÂTxÐÿûãÚ)P|Áÿ,ÛÄ%Z ò9sΦõQ(bm¸µ¸‰ò×ùûŸ¦o‡ÿY?¸VY¯
|
||||
aÀÖÅXR·
|
1
secrets/wireguard-peer-yevaud.pub
Normal file
1
secrets/wireguard-peer-yevaud.pub
Normal file
|
@ -0,0 +1 @@
|
|||
YPJsIs9x4wuWdFi/QRWSJbWvKE0GQAfVL4MNMqHygDw=
|
31
services/actual.nix
Normal file
31
services/actual.nix
Normal file
|
@ -0,0 +1,31 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkIf mkOption mkEnableOption types;
|
||||
cfg = config.qenya.services.actual;
|
||||
in
|
||||
{
|
||||
options.qenya.services.actual = {
|
||||
enable = mkEnableOption "Actual Budget";
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
${cfg.domain} = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/".proxyPass = "http://127.0.0.1:5006/";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
|
||||
services.actual.enable = true;
|
||||
};
|
||||
}
|
39
services/audiobookshelf.nix
Normal file
39
services/audiobookshelf.nix
Normal file
|
@ -0,0 +1,39 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.qenya.services.audiobookshelf;
|
||||
in
|
||||
{
|
||||
options.qenya.services.audiobookshelf = {
|
||||
enable = mkEnableOption "Audiobookshelf";
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
${cfg.domain} = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8234/";
|
||||
extraConfig = ''
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
|
||||
services.audiobookshelf.enable = true;
|
||||
services.audiobookshelf.port = 8234;
|
||||
};
|
||||
}
|
12
services/default.nix
Normal file
12
services/default.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
imports = [
|
||||
./actual.nix
|
||||
./audiobookshelf.nix
|
||||
./distributed-builds.nix
|
||||
./forgejo.nix
|
||||
./jellyfin.nix
|
||||
./navidrome.nix
|
||||
./remote-builder.nix
|
||||
./web-redirect.nix
|
||||
];
|
||||
}
|
54
services/distributed-builds.nix
Normal file
54
services/distributed-builds.nix
Normal file
|
@ -0,0 +1,54 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (builtins) elem;
|
||||
inherit (lib) mkIf mkEnableOption mkOption types optional;
|
||||
cfg = config.qenya.services.distributed-builds;
|
||||
in
|
||||
{
|
||||
options.qenya.services.distributed-builds = {
|
||||
enable = mkEnableOption "distributed builds";
|
||||
keyFile = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path to the OpenSSH private key to be used for distributed builds.
|
||||
'';
|
||||
};
|
||||
builders = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
List of builders to attempt to use for distributed builds.
|
||||
'';
|
||||
example = [ "kalessin" ];
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [{
|
||||
assertion = cfg ? keyFile;
|
||||
message = "must specify a private key to be used for distributed builds";
|
||||
}];
|
||||
|
||||
nix.distributedBuilds = true;
|
||||
nix.settings.builders-use-substitutes = true;
|
||||
|
||||
nix.buildMachines =
|
||||
(optional (elem "kalessin" cfg.builders) {
|
||||
hostName = config.birdsong.hosts."kalessin".ipv4;
|
||||
sshUser = "remotebuild";
|
||||
sshKey = cfg.keyFile;
|
||||
systems = [ "aarch64-linux" ];
|
||||
maxJobs = 2;
|
||||
supportedFeatures = [ "big-parallel" ];
|
||||
})
|
||||
++ (optional (elem "kilgharrah" cfg.builders) {
|
||||
hostName = config.birdsong.hosts."kilgharrah".ipv4;
|
||||
sshUser = "remotebuild";
|
||||
sshKey = cfg.keyFile;
|
||||
systems = [ "x86_64-linux" ];
|
||||
maxJobs = 12;
|
||||
supportedFeatures = [ "big-parallel" ];
|
||||
});
|
||||
};
|
||||
}
|
56
services/forgejo.nix
Normal file
56
services/forgejo.nix
Normal file
|
@ -0,0 +1,56 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.qenya.services.forgejo;
|
||||
in
|
||||
{
|
||||
options.qenya.services.forgejo = {
|
||||
enable = mkEnableOption "Forgejo";
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# TODO: email out
|
||||
# TODO: interface customisation
|
||||
|
||||
services = {
|
||||
nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
${cfg.domain} = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/".proxyPass = "http://[::1]:3000/";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
forgejo = {
|
||||
enable = true;
|
||||
settings = {
|
||||
DEFAULT.APP_NAME = cfg.domain;
|
||||
cache = {
|
||||
ADAPTER = "twoqueue";
|
||||
HOST = ''{"size": 100, "recent_ratio": 0.25, "ghost_ratio": 0.5}'';
|
||||
};
|
||||
database = {
|
||||
DB_TYPE = "sqlite3";
|
||||
SQLITE_JOURNAL_MODE = "WAL";
|
||||
};
|
||||
security.LOGIN_REMEMBER_DAYS = 365;
|
||||
server = {
|
||||
DOMAIN = cfg.domain;
|
||||
HTTP_PORT = 3000;
|
||||
ROOT_URL = "https://${cfg.domain}/";
|
||||
};
|
||||
service.DISABLE_REGISTRATION = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
};
|
||||
}
|
31
services/jellyfin.nix
Normal file
31
services/jellyfin.nix
Normal file
|
@ -0,0 +1,31 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.qenya.services.jellyfin;
|
||||
in
|
||||
{
|
||||
options.qenya.services.jellyfin = {
|
||||
enable = mkEnableOption "Jellyfin";
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
${cfg.domain} = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/".proxyPass = "http://127.0.0.1:8096/";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
|
||||
services.jellyfin.enable = true;
|
||||
};
|
||||
}
|
38
services/navidrome.nix
Normal file
38
services/navidrome.nix
Normal file
|
@ -0,0 +1,38 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkIf mkOption mkEnableOption types;
|
||||
cfg = config.qenya.services.navidrome;
|
||||
in
|
||||
{
|
||||
options.qenya.services.navidrome = {
|
||||
enable = mkEnableOption "Navidrome";
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
${cfg.domain} = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/".proxyPass = "http://127.0.0.1:4533/";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
|
||||
services.navidrome.enable = true;
|
||||
services.navidrome.settings = {
|
||||
MusicFolder = cfg.dataDir;
|
||||
BaseUrl = "https://${cfg.domain}";
|
||||
};
|
||||
};
|
||||
}
|
44
services/remote-builder.nix
Normal file
44
services/remote-builder.nix
Normal file
|
@ -0,0 +1,44 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkIf mkOption mkEnableOption types;
|
||||
cfg = config.qenya.services.remote-builder;
|
||||
in
|
||||
{
|
||||
options.qenya.services.remote-builder = {
|
||||
enable = mkEnableOption "remote builder";
|
||||
authorizedKeys = {
|
||||
keys = mkOption {
|
||||
type = types.listOf types.singleLineStr;
|
||||
default = [ ];
|
||||
description = ''
|
||||
A list of verbatim OpenSSH public keys that should be authorized to
|
||||
use this remote builder. See
|
||||
`users.users.<name>.openssh.authorizedKeys.keys`.
|
||||
'';
|
||||
};
|
||||
keyFiles = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default = [ ];
|
||||
description = ''
|
||||
A list of files each containing one OpenSSH public key that should be
|
||||
authorized to use this remote builder. See
|
||||
`users.users.<name>.openssh.authorizedKeys.keyFiles`.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.users.remotebuild = {
|
||||
isSystemUser = true;
|
||||
group = "nogroup";
|
||||
shell = "/bin/sh";
|
||||
openssh.authorizedKeys.keys = cfg.authorizedKeys.keys;
|
||||
openssh.authorizedKeys.keyFiles = cfg.authorizedKeys.keyFiles;
|
||||
};
|
||||
|
||||
nix.nrBuildUsers = 64;
|
||||
nix.settings.trusted-users = [ "remotebuild" ];
|
||||
};
|
||||
}
|
30
services/web-redirect.nix
Normal file
30
services/web-redirect.nix
Normal file
|
@ -0,0 +1,30 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkIf mkOption mkEnableOption types;
|
||||
cfg = config.fountain.services.web-redirect;
|
||||
in
|
||||
{
|
||||
options.fountain.services.web-redirect = {
|
||||
enable = mkEnableOption "Module to do simple 301 redirects from one domain to another";
|
||||
domains = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
description = "Mapping from source domain to destination domain";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = builtins.mapAttrs
|
||||
(name: value: {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/".return = "301 https://${value}$request_uri";
|
||||
})
|
||||
cfg.domains;
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
};
|
||||
}
|
9
shell.nix
Normal file
9
shell.nix
Normal file
|
@ -0,0 +1,9 @@
|
|||
let
|
||||
shell = (import
|
||||
(fetchTarball {
|
||||
url = "https://github.com/edolstra/flake-compat/archive/refs/tags/v1.0.1.tar.gz";
|
||||
sha256 = "0m9grvfsbwmvgwaxvdzv6cmyvjnlww004gfxjvcl806ndqaxzy4j";
|
||||
})
|
||||
{ src = ./.; }).shellNix;
|
||||
in
|
||||
shell.devShells.${builtins.currentSystem}
|
Loading…
Reference in a new issue