Compare commits
135 Commits
3459ce5058
...
attic
| Author | SHA1 | Date | |
|---|---|---|---|
| ef247cb3dd | |||
| cad04680c4 | |||
| a2d176a4fc | |||
| 1f813395ee | |||
| 0d5bce2a4f | |||
| 0c2f7cd1b2 | |||
| b80b31d3c3 | |||
| caacb4b7a7 | |||
| 25dba0ee19 | |||
| 4bed47ae43 | |||
| 7c4d2d53f2 | |||
| 9ac9613d67 | |||
| e657ebb134 | |||
| d1b07ec06b | |||
| 89621945f8 | |||
| e69fd5bf8f | |||
| c856b762e7 | |||
| b7f82f2d44 | |||
| 588e94dcf4 | |||
| fd1ead0b62 | |||
| 37bd7254b9 | |||
| 74e41de9d6 | |||
| 0bf0b8b88b | |||
| 702129d778 | |||
| 88c67dde84 | |||
| 8e3a0761e8 | |||
| a785890990 | |||
| b482a8c106 | |||
| efe50be604 | |||
| 99904d0066 | |||
| 55e44bc3d0 | |||
| da7ffa839b | |||
| 01af25a57e | |||
| bfc1bb2da9 | |||
| 0e59fa3518 | |||
| 7e812001f0 | |||
| 14c19b80ef | |||
| e8dd0cb5ff | |||
| dc9f5e969a | |||
| 03150667b6 | |||
| 1dfd7bc8a2 | |||
| fa649b1e2a | |||
| e34752c791 | |||
| 75031567bd | |||
| 800a95d431 | |||
| 932b05a42e | |||
| b5cc4d4609 | |||
| ba3d15d82a | |||
| e80fb7b3db | |||
| 84e1f6e573 | |||
| c4847bd39b | |||
| c0c1ec5c67 | |||
| 6739115cfb | |||
| 4606cc32ba | |||
| 2d27bf7505 | |||
| d07af6d101 | |||
| 4890dc20e0 | |||
| 8b01a9b240 | |||
| 8dfba8646c | |||
| 63c0f52955 | |||
| 5413a8e7db | |||
| 330c801e43 | |||
| 8ba08ce982 | |||
| 2b50aeba93 | |||
| c1aef574b1 | |||
| 52ed25f1b9 | |||
| 0446d18712 | |||
| d2bbbb827e | |||
| 6fba594625 | |||
| fa6e092c06 | |||
| 3a6dae2b82 | |||
| 62bb740634 | |||
| 577e0d21bc | |||
| b481a518f5 | |||
| f93b2c6908 | |||
| 890b24200e | |||
| d3259457de | |||
| 8eb42ee68b | |||
| 9d4c48badb | |||
| 9cf2b82e92 | |||
| 61ca918cca | |||
| ef61792da4 | |||
| 3dc97f4960 | |||
| f4a26a8d15 | |||
| 37782a26d5 | |||
| 1434bd2df1 | |||
| e49ea3a7c4 | |||
| 9a6cde1e89 | |||
| 35972b6d68 | |||
| b8021c1756 | |||
| 4b21489141 | |||
| a256ab7728 | |||
| da7ebe7baa | |||
| 1922bbbcfd | |||
| b17be86927 | |||
| ec73a63e09 | |||
| af26a004e5 | |||
| d83782f315 | |||
| 162b544249 | |||
| 0c58e62ed4 | |||
| 96de109d62 | |||
| 0efcf8f3fc | |||
| 2009180827 | |||
| 306ce8bc3f | |||
| b5dd983ba3 | |||
| 832894edfc | |||
| feb6270952 | |||
| b4dd2d4a92 | |||
| 38c2e5aece | |||
| 0ef689b750 | |||
| e72e19b7e8 | |||
| 03603119e5 | |||
| 71baa09bd2 | |||
| a02775a234 | |||
| 5800359214 | |||
| 0bd42f1850 | |||
| 40f0e5d2ac | |||
| f90b9f85fd | |||
| 5b084fffcc | |||
| 4dd6401f8c | |||
| 260bbc1ffd | |||
| c8132a67d0 | |||
| 3412d5caf9 | |||
| 1065cc4b59 | |||
| 154b37879b | |||
| a34238b3a9 | |||
| 42e2ebd294 | |||
| 378cf47683 | |||
| f68a4f4431 | |||
| 3c683e7b9e | |||
| 68bd70b525 | |||
| 2189ab9a1b | |||
| acbbb8a37a | |||
| d1e6d21d66 | |||
| 1a98e039fe |
28
.gitea/workflows/check-flake.yaml
Normal file
28
.gitea/workflows/check-flake.yaml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
name: Check Flake
|
||||||
|
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
env:
|
||||||
|
DEBIAN_FRONTEND: noninteractive
|
||||||
|
PATH: /run/current-system/sw/bin/
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-flake:
|
||||||
|
runs-on: nixos
|
||||||
|
steps:
|
||||||
|
- name: Checkout the repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- run: attic -V
|
||||||
|
|
||||||
|
- name: Setup Attic Cache
|
||||||
|
uses: https://git.neet.dev/zuckerberg/attic-action@v0.2.5
|
||||||
|
with:
|
||||||
|
endpoint: ${{ secrets.ATTIC_ENDPOINT }}
|
||||||
|
cache: ${{ secrets.ATTIC_CACHE }}
|
||||||
|
token: ${{ secrets.ATTIC_TOKEN }}
|
||||||
|
|
||||||
|
- name: Check Flake
|
||||||
|
run: nix flake check --all-systems --print-build-logs --log-format raw --show-trace
|
||||||
27
Makefile
Normal file
27
Makefile
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Lockfile utils
|
||||||
|
.PHONY: update-lockfile
|
||||||
|
update-lockfile:
|
||||||
|
nix flake update --commit-lock-file
|
||||||
|
|
||||||
|
.PHONY: update-lockfile-without-commit
|
||||||
|
update-lockfile-without-commit:
|
||||||
|
nix flake update
|
||||||
|
|
||||||
|
# Agenix utils
|
||||||
|
.PHONY: edit-secret
|
||||||
|
edit-secret:
|
||||||
|
cd secrets && agenix -e $(filter-out $@,$(MAKECMDGOALS))
|
||||||
|
|
||||||
|
.PHONY: rekey-secrets
|
||||||
|
rekey-secrets:
|
||||||
|
cd secrets && agenix -r
|
||||||
|
|
||||||
|
# NixOS utils
|
||||||
|
.PHONY: clean-old-nixos-profiles
|
||||||
|
clean-old-nixos-profiles:
|
||||||
|
doas nix-collect-garbage -d
|
||||||
|
|
||||||
|
# Garbage Collect
|
||||||
|
.PHONY: gc
|
||||||
|
gc:
|
||||||
|
nix store gc
|
||||||
@@ -6,7 +6,6 @@
|
|||||||
- `/network` - config for tailscale, and NixOS container with automatic vpn tunneling via PIA
|
- `/network` - config for tailscale, and NixOS container with automatic vpn tunneling via PIA
|
||||||
- `/pc` - config that a graphical desktop computer should have. Use `de.enable = true;` to enable everthing.
|
- `/pc` - config that a graphical desktop computer should have. Use `de.enable = true;` to enable everthing.
|
||||||
- `/server` - config that creates new nixos services or extends existing ones to meet my needs
|
- `/server` - config that creates new nixos services or extends existing ones to meet my needs
|
||||||
- `/ssh.nix` - all ssh public host and user keys for all `/machines`
|
|
||||||
- `/machines` - all my NixOS machines along with their machine unique configuration for hardware and services
|
- `/machines` - all my NixOS machines along with their machine unique configuration for hardware and services
|
||||||
- `/kexec` - a special machine for generating minimal kexec images. Does not import `/common`
|
- `/kexec` - a special machine for generating minimal kexec images. Does not import `/common`
|
||||||
- `/secrets` - encrypted shared secrets unlocked through `/machines` ssh host keys
|
- `/secrets` - encrypted shared secrets unlocked through `/machines` ssh host keys
|
||||||
|
|||||||
38
TODO.md
38
TODO.md
@@ -10,24 +10,12 @@
|
|||||||
- https://nixos.wiki/wiki/Comparison_of_NixOS_setups
|
- https://nixos.wiki/wiki/Comparison_of_NixOS_setups
|
||||||
|
|
||||||
### Housekeeping
|
### Housekeeping
|
||||||
- Format everything here using nixfmt
|
|
||||||
- Cleanup the line between hardware-configuration.nix and configuration.nix in machine config
|
- Cleanup the line between hardware-configuration.nix and configuration.nix in machine config
|
||||||
- CI https://gvolpe.com/blog/nixos-binary-cache-ci/
|
|
||||||
- remove `options.currentSystem`
|
- remove `options.currentSystem`
|
||||||
- allow `hostname` option for webservices to be null to disable configuring nginx
|
- allow `hostname` option for webservices to be null to disable configuring nginx
|
||||||
|
|
||||||
### NAS
|
### NAS
|
||||||
- helios64 extra led lights
|
|
||||||
- safely turn off NAS on power disconnect
|
- safely turn off NAS on power disconnect
|
||||||
- hardware de/encoding for rk3399 helios64 https://forum.pine64.org/showthread.php?tid=14018
|
|
||||||
- tor unlock
|
|
||||||
|
|
||||||
### bcachefs
|
|
||||||
- bcachefs health alerts via email
|
|
||||||
- bcachefs periodic snapshotting
|
|
||||||
- use mount.bcachefs command for mounting
|
|
||||||
- bcachefs native encryption
|
|
||||||
- just need a kernel module? https://github.com/firestack/bcachefs-tools-flake/blob/kf/dev/mvp/nixos/module/bcachefs.nix#L40
|
|
||||||
|
|
||||||
### Shell Comands
|
### Shell Comands
|
||||||
- tailexitnode = `sudo tailscale up --exit-node=<exit-node-ip> --exit-node-allow-lan-access=true`
|
- tailexitnode = `sudo tailscale up --exit-node=<exit-node-ip> --exit-node-allow-lan-access=true`
|
||||||
@@ -53,7 +41,6 @@
|
|||||||
- replace nextcloud with seafile
|
- replace nextcloud with seafile
|
||||||
|
|
||||||
### Archive
|
### Archive
|
||||||
- https://www.backblaze.com/b2/cloud-storage.html
|
|
||||||
- email
|
- email
|
||||||
- https://github.com/Disassembler0/dovecot-archive/blob/main/src/dovecot_archive.py
|
- https://github.com/Disassembler0/dovecot-archive/blob/main/src/dovecot_archive.py
|
||||||
- http://kb.unixservertech.com/software/dovecot/archiveserver
|
- http://kb.unixservertech.com/software/dovecot/archiveserver
|
||||||
@@ -62,7 +49,32 @@
|
|||||||
- https://christine.website/blog/paranoid-nixos-2021-07-18
|
- https://christine.website/blog/paranoid-nixos-2021-07-18
|
||||||
- https://nixos.wiki/wiki/Impermanence
|
- https://nixos.wiki/wiki/Impermanence
|
||||||
|
|
||||||
|
# Setup CI
|
||||||
|
- CI
|
||||||
|
- hydra
|
||||||
|
- https://docs.cachix.org/continuous-integration-setup/
|
||||||
|
- Binary Cache
|
||||||
|
- Maybe use cachix https://gvolpe.com/blog/nixos-binary-cache-ci/
|
||||||
|
- Self hosted binary cache? https://www.tweag.io/blog/2019-11-21-untrusted-ci/
|
||||||
|
- https://github.com/edolstra/nix-serve
|
||||||
|
- https://nixos.wiki/wiki/Binary_Cache
|
||||||
|
- https://discourse.nixos.org/t/introducing-attic-a-self-hostable-nix-binary-cache-server/24343
|
||||||
|
- Both
|
||||||
|
- https://garnix.io/
|
||||||
|
- https://nixbuild.net
|
||||||
|
|
||||||
|
|
||||||
|
# Secrets
|
||||||
|
- consider using headscale
|
||||||
|
- Replace luks over tor for remote unlock with luks over tailscale using ephemeral keys
|
||||||
|
- Rollover luks FDE passwords
|
||||||
|
- /secrets on personal computers should only be readable using a trusted ssh key, preferably requiring a yubikey
|
||||||
|
- Rollover shared yubikey secrets
|
||||||
|
- offsite backup yubikey, pw db, and ssh key with /secrets access
|
||||||
|
|
||||||
### Misc
|
### Misc
|
||||||
|
- for automated kernel upgrades on luks systems, need to kexec with initrd that contains luks key
|
||||||
|
- https://github.com/flowztul/keyexec/blob/master/etc/default/kexec-cryptroot
|
||||||
- https://github.com/pop-os/system76-scheduler
|
- https://github.com/pop-os/system76-scheduler
|
||||||
- improve email a little bit https://helloinbox.email
|
- improve email a little bit https://helloinbox.email
|
||||||
- remap razer keys https://github.com/sezanzeb/input-remapper
|
- remap razer keys https://github.com/sezanzeb/input-remapper
|
||||||
|
|||||||
@@ -4,11 +4,12 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.system.autoUpgrade;
|
cfg = config.system.autoUpgrade;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
system.autoUpgrade = {
|
system.autoUpgrade = {
|
||||||
flake = "git+https://git.neet.dev/zuckerberg/nix-config.git";
|
flake = "git+https://git.neet.dev/zuckerberg/nix-config.git";
|
||||||
flags = [ "--recreate-lock-file" ]; # ignore lock file, just pull the latest
|
flags = [ "--recreate-lock-file" "--no-write-lock-file" ]; # ignore lock file, just pull the latest
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
78
common/backups.nix
Normal file
78
common/backups.nix
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.backup;
|
||||||
|
hostname = config.networking.hostName;
|
||||||
|
|
||||||
|
mkRespository = group: "s3:s3.us-west-004.backblazeb2.com/D22TgIt0-main-backup/${group}";
|
||||||
|
|
||||||
|
mkBackup = group: paths: {
|
||||||
|
repository = mkRespository group;
|
||||||
|
inherit paths;
|
||||||
|
|
||||||
|
initialize = true;
|
||||||
|
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "daily";
|
||||||
|
RandomizedDelaySec = "1h";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraBackupArgs = [
|
||||||
|
''--exclude-if-present ".nobackup"''
|
||||||
|
];
|
||||||
|
|
||||||
|
pruneOpts = [
|
||||||
|
"--keep-daily 7" # one backup for each of the last n days
|
||||||
|
"--keep-weekly 5" # one backup for each of the last n weeks
|
||||||
|
"--keep-monthly 12" # one backup for each of the last n months
|
||||||
|
"--keep-yearly 75" # one backup for each of the last n years
|
||||||
|
];
|
||||||
|
|
||||||
|
environmentFile = "/run/agenix/backblaze-s3-backups";
|
||||||
|
passwordFile = "/run/agenix/restic-password";
|
||||||
|
};
|
||||||
|
|
||||||
|
# example usage: "sudo restic_samba unlock" (removes lockfile)
|
||||||
|
mkResticGroupCmd = group: pkgs.writeShellScriptBin "restic_${group}" ''
|
||||||
|
if [ "$EUID" -ne 0 ]
|
||||||
|
then echo "Run as root"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
. /run/agenix/backblaze-s3-backups
|
||||||
|
export AWS_SECRET_ACCESS_KEY
|
||||||
|
export AWS_ACCESS_KEY_ID
|
||||||
|
export RESTIC_PASSWORD_FILE=/run/agenix/restic-password
|
||||||
|
export RESTIC_REPOSITORY="${mkRespository group}"
|
||||||
|
exec ${pkgs.restic}/bin/restic "$@"
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.backup = {
|
||||||
|
group = lib.mkOption {
|
||||||
|
default = null;
|
||||||
|
type = lib.types.nullOr (lib.types.attrsOf (lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
paths = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
description = ''
|
||||||
|
Paths to backup
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf (cfg.group != null) {
|
||||||
|
services.restic.backups = lib.concatMapAttrs
|
||||||
|
(group: groupCfg: {
|
||||||
|
${group} = mkBackup group groupCfg.paths;
|
||||||
|
})
|
||||||
|
cfg.group;
|
||||||
|
|
||||||
|
age.secrets.backblaze-s3-backups.file = ../secrets/backblaze-s3-backups.age;
|
||||||
|
age.secrets.restic-password.file = ../secrets/restic-password.age;
|
||||||
|
|
||||||
|
environment.systemPackages = map mkResticGroupCmd (builtins.attrNames cfg.group);
|
||||||
|
};
|
||||||
|
}
|
||||||
17
common/binary-cache.nix
Normal file
17
common/binary-cache.nix
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
nix = {
|
||||||
|
settings = {
|
||||||
|
substituters = [
|
||||||
|
"https://cache.nixos.org/"
|
||||||
|
"https://nix-community.cachix.org"
|
||||||
|
"http://s0.koi-bebop.ts.net:28338/nixos"
|
||||||
|
];
|
||||||
|
trusted-public-keys = [
|
||||||
|
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||||||
|
"nixos:IDhKojUaMz+UIiri1/DQk9EpqDokih8dwxmp41uJnls="
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -3,24 +3,27 @@
|
|||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.bios;
|
cfg = config.bios;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.bios = {
|
options.bios = {
|
||||||
enable = mkEnableOption "enable bios boot";
|
enable = mkEnableOption "enable bios boot";
|
||||||
device = mkOption {
|
device = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
};
|
};
|
||||||
|
configurationLimit = mkOption {
|
||||||
|
default = 20;
|
||||||
|
type = types.int;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
# Use GRUB 2 for BIOS
|
|
||||||
boot.loader = {
|
boot.loader = {
|
||||||
timeout = 2;
|
timeout = 2;
|
||||||
grub = {
|
grub = {
|
||||||
enable = true;
|
enable = true;
|
||||||
device = cfg.device;
|
device = cfg.device;
|
||||||
version = 2;
|
|
||||||
useOSProber = true;
|
useOSProber = true;
|
||||||
configurationLimit = 20;
|
configurationLimit = cfg.configurationLimit;
|
||||||
theme = pkgs.nixos-grub2-theme;
|
theme = pkgs.nixos-grub2-theme;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,24 +3,27 @@
|
|||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.efi;
|
cfg = config.efi;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.efi = {
|
options.efi = {
|
||||||
enable = mkEnableOption "enable efi boot";
|
enable = mkEnableOption "enable efi boot";
|
||||||
|
configurationLimit = mkOption {
|
||||||
|
default = 20;
|
||||||
|
type = types.int;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
# Use GRUB2 for EFI
|
|
||||||
boot.loader = {
|
boot.loader = {
|
||||||
efi.canTouchEfiVariables = true;
|
efi.canTouchEfiVariables = true;
|
||||||
timeout = 2;
|
timeout = 2;
|
||||||
grub = {
|
grub = {
|
||||||
enable = true;
|
enable = true;
|
||||||
device = "nodev";
|
device = "nodev";
|
||||||
version = 2;
|
|
||||||
efiSupport = true;
|
efiSupport = true;
|
||||||
useOSProber = true;
|
useOSProber = true;
|
||||||
# memtest86.enable = true;
|
# memtest86.enable = true;
|
||||||
configurationLimit = 20;
|
configurationLimit = cfg.configurationLimit;
|
||||||
theme = pkgs.nixos-grub2-theme;
|
theme = pkgs.nixos-grub2-theme;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.firmware;
|
cfg = config.firmware;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.firmware.x86_64 = {
|
options.firmware.x86_64 = {
|
||||||
enable = mkEnableOption "enable x86_64 firmware";
|
enable = mkEnableOption "enable x86_64 firmware";
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
# TODO: use tailscale instead of tor https://gist.github.com/antifuchs/e30d58a64988907f282c82231dde2cbc
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.remoteLuksUnlock;
|
cfg = config.remoteLuksUnlock;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.remoteLuksUnlock = {
|
options.remoteLuksUnlock = {
|
||||||
enable = lib.mkEnableOption "enable luks root remote decrypt over ssh/tor";
|
enable = lib.mkEnableOption "enable luks root remote decrypt over ssh/tor";
|
||||||
enableTorUnlock = lib.mkOption {
|
enableTorUnlock = lib.mkOption {
|
||||||
@@ -32,11 +35,6 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
# boot.initrd.luks.devices.${cfg.device.name} = {
|
|
||||||
# device = cfg.device.path;
|
|
||||||
# allowDiscards = cfg.device.allowDiscards;
|
|
||||||
# };
|
|
||||||
|
|
||||||
# Unlock LUKS disk over ssh
|
# Unlock LUKS disk over ssh
|
||||||
boot.initrd.network.enable = true;
|
boot.initrd.network.enable = true;
|
||||||
boot.initrd.kernelModules = cfg.kernelModules;
|
boot.initrd.kernelModules = cfg.kernelModules;
|
||||||
@@ -61,33 +59,38 @@ in {
|
|||||||
copy_bin_and_libs ${pkgs.haveged}/bin/haveged
|
copy_bin_and_libs ${pkgs.haveged}/bin/haveged
|
||||||
'';
|
'';
|
||||||
boot.initrd.network.postCommands = lib.mkMerge [
|
boot.initrd.network.postCommands = lib.mkMerge [
|
||||||
(''
|
(
|
||||||
# Add nice prompt for giving LUKS passphrase over ssh
|
''
|
||||||
echo 'read -s -p "Unlock Passphrase: " passphrase && echo $passphrase > /crypt-ramfs/passphrase && exit' >> /root/.profile
|
# Add nice prompt for giving LUKS passphrase over ssh
|
||||||
'')
|
echo 'read -s -p "Unlock Passphrase: " passphrase && echo $passphrase > /crypt-ramfs/passphrase && exit' >> /root/.profile
|
||||||
|
''
|
||||||
|
)
|
||||||
|
|
||||||
(let torRc = (pkgs.writeText "tor.rc" ''
|
(
|
||||||
DataDirectory /etc/tor
|
let torRc = (pkgs.writeText "tor.rc" ''
|
||||||
SOCKSPort 127.0.0.1:9050 IsolateDestAddr
|
DataDirectory /etc/tor
|
||||||
SOCKSPort 127.0.0.1:9063
|
SOCKSPort 127.0.0.1:9050 IsolateDestAddr
|
||||||
HiddenServiceDir /etc/tor/onion/bootup
|
SOCKSPort 127.0.0.1:9063
|
||||||
HiddenServicePort 22 127.0.0.1:22
|
HiddenServiceDir /etc/tor/onion/bootup
|
||||||
''); in lib.mkIf cfg.enableTorUnlock ''
|
HiddenServicePort 22 127.0.0.1:22
|
||||||
echo "tor: preparing onion folder"
|
''); in
|
||||||
# have to do this otherwise tor does not want to start
|
lib.mkIf cfg.enableTorUnlock ''
|
||||||
chmod -R 700 /etc/tor
|
echo "tor: preparing onion folder"
|
||||||
|
# have to do this otherwise tor does not want to start
|
||||||
|
chmod -R 700 /etc/tor
|
||||||
|
|
||||||
echo "make sure localhost is up"
|
echo "make sure localhost is up"
|
||||||
ip a a 127.0.0.1/8 dev lo
|
ip a a 127.0.0.1/8 dev lo
|
||||||
ip link set lo up
|
ip link set lo up
|
||||||
|
|
||||||
echo "haveged: starting haveged"
|
echo "haveged: starting haveged"
|
||||||
haveged -F &
|
haveged -F &
|
||||||
|
|
||||||
echo "tor: starting tor"
|
echo "tor: starting tor"
|
||||||
tor -f ${torRc} --verify-config
|
tor -f ${torRc} --verify-config
|
||||||
tor -f ${torRc} &
|
tor -f ${torRc} &
|
||||||
'')
|
''
|
||||||
|
)
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
let
|
|
||||||
ssh = import ./ssh.nix;
|
|
||||||
sshUserKeys = ssh.users;
|
|
||||||
sshHigherTrustKeys = ssh.higherTrustUserKeys;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
./backups.nix
|
||||||
|
./binary-cache.nix
|
||||||
./flakes.nix
|
./flakes.nix
|
||||||
./auto-update.nix
|
./auto-update.nix
|
||||||
./shell.nix
|
./shell.nix
|
||||||
@@ -14,11 +11,14 @@ in
|
|||||||
./boot
|
./boot
|
||||||
./server
|
./server
|
||||||
./pc
|
./pc
|
||||||
|
./machine-info
|
||||||
|
./nix-builder.nix
|
||||||
|
./ssh.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
nix.flakes.enable = true;
|
nix.flakes.enable = true;
|
||||||
|
|
||||||
system.stateVersion = "21.11";
|
system.stateVersion = "23.11";
|
||||||
|
|
||||||
networking.useDHCP = false;
|
networking.useDHCP = false;
|
||||||
|
|
||||||
@@ -26,7 +26,13 @@ in
|
|||||||
networking.firewall.allowPing = true;
|
networking.firewall.allowPing = true;
|
||||||
|
|
||||||
time.timeZone = "America/Denver";
|
time.timeZone = "America/Denver";
|
||||||
i18n.defaultLocale = "en_US.UTF-8";
|
i18n = {
|
||||||
|
defaultLocale = "en_US.UTF-8";
|
||||||
|
extraLocaleSettings = {
|
||||||
|
LANGUAGE = "en_US.UTF-8";
|
||||||
|
LC_ALL = "en_US.UTF-8";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
services.openssh = {
|
services.openssh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
@@ -40,7 +46,8 @@ in
|
|||||||
wget
|
wget
|
||||||
kakoune
|
kakoune
|
||||||
htop
|
htop
|
||||||
git git-lfs
|
git
|
||||||
|
git-lfs
|
||||||
dnsutils
|
dnsutils
|
||||||
tmux
|
tmux
|
||||||
nethogs
|
nethogs
|
||||||
@@ -53,6 +60,10 @@ in
|
|||||||
helix
|
helix
|
||||||
lm_sensors
|
lm_sensors
|
||||||
picocom
|
picocom
|
||||||
|
lf
|
||||||
|
gnumake
|
||||||
|
tree
|
||||||
|
attic
|
||||||
];
|
];
|
||||||
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
@@ -65,17 +76,25 @@ in
|
|||||||
"dialout" # serial
|
"dialout" # serial
|
||||||
];
|
];
|
||||||
shell = pkgs.fish;
|
shell = pkgs.fish;
|
||||||
openssh.authorizedKeys.keys = sshUserKeys;
|
openssh.authorizedKeys.keys = config.machines.ssh.userKeys;
|
||||||
hashedPassword = "$6$TuDO46rILr$gkPUuLKZe3psexhs8WFZMpzgEBGksE.c3Tjh1f8sD0KMC4oV89K2pqAABfl.Lpxu2jVdr5bgvR5cWnZRnji/r/";
|
hashedPassword = "$6$TuDO46rILr$gkPUuLKZe3psexhs8WFZMpzgEBGksE.c3Tjh1f8sD0KMC4oV89K2pqAABfl.Lpxu2jVdr5bgvR5cWnZRnji/r/";
|
||||||
uid = 1000;
|
uid = 1000;
|
||||||
};
|
};
|
||||||
users.users.root = {
|
users.users.root = {
|
||||||
openssh.authorizedKeys.keys = sshHigherTrustKeys;
|
openssh.authorizedKeys.keys = config.machines.ssh.deployKeys;
|
||||||
};
|
};
|
||||||
nix.settings = {
|
nix.settings = {
|
||||||
trusted-users = [ "root" "googlebot" ];
|
trusted-users = [ "root" "googlebot" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# don't use sudo
|
||||||
|
security.doas.enable = true;
|
||||||
|
security.sudo.enable = false;
|
||||||
|
security.doas.extraRules = [
|
||||||
|
# don't ask for password every time
|
||||||
|
{ groups = [ "wheel" ]; persist = true; }
|
||||||
|
];
|
||||||
|
|
||||||
nix.gc.automatic = true;
|
nix.gc.automatic = true;
|
||||||
|
|
||||||
security.acme.acceptTerms = true;
|
security.acme.acceptTerms = true;
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.nix.flakes;
|
cfg = config.nix.flakes;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.nix.flakes = {
|
options.nix.flakes = {
|
||||||
enable = mkEnableOption "use nix flakes";
|
enable = mkEnableOption "use nix flakes";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
nix = {
|
nix = {
|
||||||
package = pkgs.nixFlakes;
|
|
||||||
extraOptions = ''
|
extraOptions = ''
|
||||||
experimental-features = nix-command flakes
|
experimental-features = nix-command flakes
|
||||||
'';
|
'';
|
||||||
|
|||||||
200
common/machine-info/default.nix
Normal file
200
common/machine-info/default.nix
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
# Gathers info about each machine to constuct overall configuration
|
||||||
|
# Ex: Each machine already trusts each others SSH fingerprint already
|
||||||
|
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
machines = config.machines.hosts;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./ssh.nix
|
||||||
|
./roles.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
options.machines = {
|
||||||
|
|
||||||
|
hosts = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf
|
||||||
|
(lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
|
||||||
|
hostNames = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
description = ''
|
||||||
|
List of hostnames for this machine. The first one is the default so it is the target of deployments.
|
||||||
|
Used for automatically trusting hosts for ssh connections.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
arch = lib.mkOption {
|
||||||
|
type = lib.types.enum [ "x86_64-linux" "aarch64-linux" ];
|
||||||
|
description = ''
|
||||||
|
The architecture of this machine.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemRoles = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.str; # TODO: maybe use an enum?
|
||||||
|
description = ''
|
||||||
|
The set of roles this machine holds. Affects secrets available. (TODO add service config as well using this info)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
hostKey = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = ''
|
||||||
|
The system ssh host key of this machine. Used for automatically trusting hosts for ssh connections
|
||||||
|
and for decrypting secrets with agenix.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
remoteUnlock = lib.mkOption {
|
||||||
|
default = null;
|
||||||
|
type = lib.types.nullOr (lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
|
||||||
|
hostKey = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = ''
|
||||||
|
The system ssh host key of this machine used for luks boot unlocking only.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
clearnetHost = lib.mkOption {
|
||||||
|
default = null;
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
description = ''
|
||||||
|
The hostname resolvable over clearnet used to luks boot unlock this machine
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
onionHost = lib.mkOption {
|
||||||
|
default = null;
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
description = ''
|
||||||
|
The hostname resolvable over tor used to luks boot unlock this machine
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
userKeys = lib.mkOption {
|
||||||
|
default = [ ];
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
description = ''
|
||||||
|
The list of user keys. Each key here can be used to log into all other systems as `googlebot`.
|
||||||
|
|
||||||
|
TODO: consider auto populating other programs that use ssh keys such as gitea
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
deployKeys = lib.mkOption {
|
||||||
|
default = [ ];
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
description = ''
|
||||||
|
The list of deployment keys. Each key here can be used to log into all other systems as `root`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
configurationPath = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
description = ''
|
||||||
|
The path to this machine's configuration directory.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
assertions = (lib.concatLists (lib.mapAttrsToList
|
||||||
|
(
|
||||||
|
name: cfg: [
|
||||||
|
{
|
||||||
|
assertion = builtins.length cfg.hostNames > 0;
|
||||||
|
message = ''
|
||||||
|
Error with config for ${name}
|
||||||
|
There must be at least one hostname.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = builtins.length cfg.systemRoles > 0;
|
||||||
|
message = ''
|
||||||
|
Error with config for ${name}
|
||||||
|
There must be at least one system role.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = cfg.remoteUnlock == null || cfg.remoteUnlock.hostKey != cfg.hostKey;
|
||||||
|
message = ''
|
||||||
|
Error with config for ${name}
|
||||||
|
Unlock hostkey and hostkey cannot be the same because unlock hostkey is in /boot, unencrypted.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = cfg.remoteUnlock == null || (cfg.remoteUnlock.clearnetHost != null || cfg.remoteUnlock.onionHost != null);
|
||||||
|
message = ''
|
||||||
|
Error with config for ${name}
|
||||||
|
At least one of clearnet host or onion host must be defined.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = cfg.remoteUnlock == null || cfg.remoteUnlock.clearnetHost == null || builtins.elem cfg.remoteUnlock.clearnetHost cfg.hostNames == false;
|
||||||
|
message = ''
|
||||||
|
Error with config for ${name}
|
||||||
|
Clearnet unlock hostname cannot be in the list of hostnames for security reasons.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = cfg.remoteUnlock == null || cfg.remoteUnlock.onionHost == null || lib.strings.hasSuffix ".onion" cfg.remoteUnlock.onionHost;
|
||||||
|
message = ''
|
||||||
|
Error with config for ${name}
|
||||||
|
Tor unlock hostname must be an onion address.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = builtins.elem "personal" cfg.systemRoles || builtins.length cfg.userKeys == 0;
|
||||||
|
message = ''
|
||||||
|
Error with config for ${name}
|
||||||
|
There must be at least one userkey defined for personal machines.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = builtins.elem "deploy" cfg.systemRoles || builtins.length cfg.deployKeys == 0;
|
||||||
|
message = ''
|
||||||
|
Error with config for ${name}
|
||||||
|
Only deploy machines are allowed to have deploy keys for security reasons.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
machines));
|
||||||
|
|
||||||
|
# Set per machine properties automatically using each of their `properties.nix` files respectively
|
||||||
|
machines.hosts =
|
||||||
|
let
|
||||||
|
properties = dir: lib.concatMapAttrs
|
||||||
|
(name: path: {
|
||||||
|
${name} =
|
||||||
|
import path
|
||||||
|
//
|
||||||
|
{ configurationPath = builtins.dirOf path; };
|
||||||
|
})
|
||||||
|
(propertiesFiles dir);
|
||||||
|
propertiesFiles = dir:
|
||||||
|
lib.foldl (lib.mergeAttrs) { } (propertiesFiles' dir);
|
||||||
|
propertiesFiles' = dir:
|
||||||
|
let
|
||||||
|
propFiles = lib.filter (p: baseNameOf p == "properties.nix") (lib.filesystem.listFilesRecursive dir);
|
||||||
|
dirName = path: builtins.baseNameOf (builtins.dirOf path);
|
||||||
|
in
|
||||||
|
builtins.map (p: { "${dirName p}" = p; }) propFiles;
|
||||||
|
in
|
||||||
|
properties ../../machines;
|
||||||
|
};
|
||||||
|
}
|
||||||
15
common/machine-info/moduleless.nix
Normal file
15
common/machine-info/moduleless.nix
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Allows getting machine-info outside the scope of nixos configuration
|
||||||
|
|
||||||
|
{ nixpkgs ? import <nixpkgs> { }
|
||||||
|
, assertionsModule ? <nixpkgs/nixos/modules/misc/assertions.nix>
|
||||||
|
}:
|
||||||
|
|
||||||
|
{
|
||||||
|
machines =
|
||||||
|
(nixpkgs.lib.evalModules {
|
||||||
|
modules = [
|
||||||
|
./default.nix
|
||||||
|
assertionsModule
|
||||||
|
];
|
||||||
|
}).config.machines;
|
||||||
|
}
|
||||||
19
common/machine-info/roles.nix
Normal file
19
common/machine-info/roles.nix
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
# Maps roles to their hosts
|
||||||
|
|
||||||
|
{
|
||||||
|
options.machines.roles = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf (lib.types.listOf lib.types.str);
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
machines.roles = lib.zipAttrs
|
||||||
|
(lib.mapAttrsToList
|
||||||
|
(host: cfg:
|
||||||
|
lib.foldl (lib.mergeAttrs) { }
|
||||||
|
(builtins.map (role: { ${role} = host; })
|
||||||
|
cfg.systemRoles))
|
||||||
|
config.machines.hosts);
|
||||||
|
};
|
||||||
|
}
|
||||||
44
common/machine-info/ssh.nix
Normal file
44
common/machine-info/ssh.nix
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
machines = config.machines;
|
||||||
|
|
||||||
|
sshkeys = keyType: lib.foldl (l: cfg: l ++ cfg.${keyType}) [ ] (builtins.attrValues machines.hosts);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.machines.ssh = {
|
||||||
|
userKeys = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
description = ''
|
||||||
|
List of user keys aggregated from all machines.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
deployKeys = lib.mkOption {
|
||||||
|
default = [ ];
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
description = ''
|
||||||
|
List of deploy keys aggregated from all machines.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
hostKeysByRole = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf (lib.types.listOf lib.types.str);
|
||||||
|
description = ''
|
||||||
|
Machine host keys divided into their roles.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
machines.ssh.userKeys = sshkeys "userKeys";
|
||||||
|
machines.ssh.deployKeys = sshkeys "deployKeys";
|
||||||
|
|
||||||
|
machines.ssh.hostKeysByRole = lib.mapAttrs
|
||||||
|
(role: hosts:
|
||||||
|
builtins.map
|
||||||
|
(host: machines.hosts.${host}.hostKey)
|
||||||
|
hosts)
|
||||||
|
machines.roles;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -7,7 +7,6 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./hosts.nix
|
|
||||||
./pia-openvpn.nix
|
./pia-openvpn.nix
|
||||||
./pia-wireguard.nix
|
./pia-wireguard.nix
|
||||||
./ping.nix
|
./ping.nix
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
{ config, lib, ... }:
|
|
||||||
|
|
||||||
with builtins;
|
|
||||||
|
|
||||||
let
|
|
||||||
# TODO: remove when all systems are updated to new enough nixpkgs
|
|
||||||
concatMapAttrs =
|
|
||||||
f: with lib; flip pipe [ (mapAttrs f) attrValues (foldl' mergeAttrs { }) ];
|
|
||||||
|
|
||||||
system = (import ../ssh.nix).system;
|
|
||||||
|
|
||||||
# hostnames that resolve on clearnet for LUKS unlocking
|
|
||||||
unlock-clearnet-hosts = {
|
|
||||||
ponyo = "unlock.ponyo.neet.dev";
|
|
||||||
s0 = "s0";
|
|
||||||
};
|
|
||||||
|
|
||||||
# hostnames that resolve on tor for LUKS unlocking
|
|
||||||
unlock-onion-hosts = {
|
|
||||||
liza = "5synsrjgvfzywruomjsfvfwhhlgxqhyofkzeqt2eisyijvjvebnu2xyd.onion";
|
|
||||||
router = "jxx2exuihlls2t6ncs7rvrjh2dssubjmjtclwr2ysvxtr4t7jv55xmqd.onion";
|
|
||||||
ponyo = "cfamr6artx75qvt7ho3rrbsc7mkucmv5aawebwflsfuorusayacffryd.onion";
|
|
||||||
s0 = "r3zvf7f2ppaeithzswigma46pajt3hqytmkg3rshgknbl3jbni455fqd.onion";
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
programs.ssh.knownHosts = {
|
|
||||||
ponyo = {
|
|
||||||
hostNames = [ "ponyo" "ponyo.neet.dev" "git.neet.dev" ];
|
|
||||||
publicKey = system.ponyo;
|
|
||||||
};
|
|
||||||
ponyo-unlock = {
|
|
||||||
hostNames = [ unlock-clearnet-hosts.ponyo unlock-onion-hosts.ponyo ];
|
|
||||||
publicKey = system.ponyo-unlock;
|
|
||||||
};
|
|
||||||
router = {
|
|
||||||
hostNames = [ "router" "192.168.1.228" ];
|
|
||||||
publicKey = system.router;
|
|
||||||
};
|
|
||||||
router-unlock = {
|
|
||||||
hostNames = [ unlock-onion-hosts.router ];
|
|
||||||
publicKey = system.router-unlock;
|
|
||||||
};
|
|
||||||
ray = {
|
|
||||||
hostNames = [ "ray" ];
|
|
||||||
publicKey = system.ray;
|
|
||||||
};
|
|
||||||
s0 = {
|
|
||||||
hostNames = [ "s0" ];
|
|
||||||
publicKey = system.s0;
|
|
||||||
};
|
|
||||||
s0-unlock = {
|
|
||||||
hostNames = [ unlock-onion-hosts.s0 ];
|
|
||||||
publicKey = system.s0-unlock;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# prebuilt cmds for easy ssh LUKS unlock
|
|
||||||
environment.shellAliases =
|
|
||||||
concatMapAttrs (host: addr: {"unlock-over-tor_${host}" = "torsocks ssh root@${addr}";}) unlock-onion-hosts
|
|
||||||
//
|
|
||||||
concatMapAttrs (host: addr: {"unlock_${host}" = "ssh root@${addr}";}) unlock-clearnet-hosts;
|
|
||||||
}
|
|
||||||
@@ -108,6 +108,6 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
age.secrets."pia-login.conf".file = ../../secrets/pia-login.conf;
|
age.secrets."pia-login.conf".file = ../../secrets/pia-login.age;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
# TODO implement this module such that the wireguard VPN doesn't have to live in a container
|
# TODO implement this module such that the wireguard VPN doesn't have to live in a container
|
||||||
# TODO don't add forward rules if the PIA port is the same as cfg.forwardedPort
|
# TODO don't add forward rules if the PIA port is the same as cfg.forwardedPort
|
||||||
# TODO verify signatures of PIA responses
|
# TODO verify signatures of PIA responses
|
||||||
|
# TODO `RuntimeMaxSec = "30d";` for pia-vpn-wireguard-init isn't allowed per the systemd logs. Find alternative.
|
||||||
|
|
||||||
with builtins;
|
with builtins;
|
||||||
with lib;
|
with lib;
|
||||||
@@ -72,7 +73,8 @@ let
|
|||||||
portForwarding = cfg.forwardPortForTransmission || cfg.forwardedPort != null;
|
portForwarding = cfg.forwardPortForTransmission || cfg.forwardedPort != null;
|
||||||
|
|
||||||
containerServiceName = "container@${config.vpn-container.containerName}.service";
|
containerServiceName = "container@${config.vpn-container.containerName}.service";
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.pia.wireguard = {
|
options.pia.wireguard = {
|
||||||
enable = mkEnableOption "Enable private internet access";
|
enable = mkEnableOption "Enable private internet access";
|
||||||
badPortForwardPorts = mkOption {
|
badPortForwardPorts = mkOption {
|
||||||
@@ -142,14 +144,14 @@ in {
|
|||||||
systemd.services.pia-vpn-wireguard-init = {
|
systemd.services.pia-vpn-wireguard-init = {
|
||||||
description = "Creates PIA VPN Wireguard Interface";
|
description = "Creates PIA VPN Wireguard Interface";
|
||||||
|
|
||||||
requires = [ "network-online.target" ];
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network.target" "network-online.target" ];
|
after = [ "network.target" "network-online.target" ];
|
||||||
before = [ containerServiceName ];
|
before = [ containerServiceName ];
|
||||||
requiredBy = [ containerServiceName ];
|
requiredBy = [ containerServiceName ];
|
||||||
partOf = [ containerServiceName ];
|
partOf = [ containerServiceName ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
path = with pkgs; [ wireguard-tools jq curl iproute ];
|
path = with pkgs; [ wireguard-tools jq curl iproute iputils ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
@@ -157,10 +159,15 @@ in {
|
|||||||
|
|
||||||
# restart once a month; PIA forwarded port expires after two months
|
# restart once a month; PIA forwarded port expires after two months
|
||||||
# because the container is "PartOf" this unit, it gets restarted too
|
# because the container is "PartOf" this unit, it gets restarted too
|
||||||
RuntimeMaxSec="30d";
|
RuntimeMaxSec = "30d";
|
||||||
};
|
};
|
||||||
|
|
||||||
script = ''
|
script = ''
|
||||||
|
echo Waiting for internet...
|
||||||
|
while ! ping -c 1 -W 1 1.1.1.1; do
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
# Prepare to connect by generating wg secrets and auth'ing with PIA since the container
|
# Prepare to connect by generating wg secrets and auth'ing with PIA since the container
|
||||||
# cannot do without internet to start with. NAT'ing the host's internet would address this
|
# cannot do without internet to start with. NAT'ing the host's internet would address this
|
||||||
# issue but is not ideal because then leaking network outside of the VPN is more likely.
|
# issue but is not ideal because then leaking network outside of the VPN is more likely.
|
||||||
@@ -213,7 +220,7 @@ in {
|
|||||||
vpn-container.config.systemd.services.pia-vpn-wireguard = {
|
vpn-container.config.systemd.services.pia-vpn-wireguard = {
|
||||||
description = "Initializes the PIA VPN WireGuard Tunnel";
|
description = "Initializes the PIA VPN WireGuard Tunnel";
|
||||||
|
|
||||||
requires = [ "network-online.target" ];
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network.target" "network-online.target" ];
|
after = [ "network.target" "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
@@ -351,6 +358,6 @@ in {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
age.secrets."pia-login.conf".file = ../../secrets/pia-login.conf;
|
age.secrets."pia-login.conf".file = ../../secrets/pia-login.age;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -11,34 +11,35 @@ let
|
|||||||
cfg = config.keepalive-ping;
|
cfg = config.keepalive-ping;
|
||||||
|
|
||||||
serviceTemplate = host:
|
serviceTemplate = host:
|
||||||
{
|
{
|
||||||
"keepalive-ping@${host}" = {
|
"keepalive-ping@${host}" = {
|
||||||
description = "Periodic ping keep alive for ${host} connection";
|
description = "Periodic ping keep alive for ${host} connection";
|
||||||
|
|
||||||
requires = [ "network-online.target" ];
|
requires = [ "network-online.target" ];
|
||||||
after = [ "network.target" "network-online.target" ];
|
after = [ "network.target" "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig.Restart="always";
|
serviceConfig.Restart = "always";
|
||||||
|
|
||||||
path = with pkgs; [ iputils ];
|
path = with pkgs; [ iputils ];
|
||||||
|
|
||||||
script = ''
|
script = ''
|
||||||
ping -i ${cfg.delay} ${host} &>/dev/null
|
ping -i ${cfg.delay} ${host} &>/dev/null
|
||||||
'';
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
combineAttrs = foldl recursiveUpdate {};
|
combineAttrs = foldl recursiveUpdate { };
|
||||||
|
|
||||||
serviceList = map serviceTemplate cfg.hosts;
|
serviceList = map serviceTemplate cfg.hosts;
|
||||||
|
|
||||||
services = combineAttrs serviceList;
|
services = combineAttrs serviceList;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.keepalive-ping = {
|
options.keepalive-ping = {
|
||||||
enable = mkEnableOption "Enable keep alive ping task";
|
enable = mkEnableOption "Enable keep alive ping task";
|
||||||
hosts = mkOption {
|
hosts = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = [];
|
default = [ ];
|
||||||
description = ''
|
description = ''
|
||||||
Hosts to ping periodically
|
Hosts to ping periodically
|
||||||
'';
|
'';
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ in
|
|||||||
config.services.tailscale.enable = mkDefault (!config.boot.isContainer);
|
config.services.tailscale.enable = mkDefault (!config.boot.isContainer);
|
||||||
|
|
||||||
# MagicDNS
|
# MagicDNS
|
||||||
config.networking.nameservers = mkIf cfg.enable [ "1.1.1.1" "8.8.8.8" "100.100.100.100" ];
|
config.networking.nameservers = mkIf cfg.enable [ "1.1.1.1" "8.8.8.8" ];
|
||||||
config.networking.search = mkIf cfg.enable [ "koi-bebop.ts.net" ];
|
config.networking.search = mkIf cfg.enable [ "koi-bebop.ts.net" ];
|
||||||
|
|
||||||
# exit node
|
# exit node
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ in
|
|||||||
|
|
||||||
config = mkOption {
|
config = mkOption {
|
||||||
type = types.anything;
|
type = types.anything;
|
||||||
default = {};
|
default = { };
|
||||||
example = ''
|
example = ''
|
||||||
{
|
{
|
||||||
services.nginx.enable = true;
|
services.nginx.enable = true;
|
||||||
@@ -70,10 +70,7 @@ in
|
|||||||
localAddress = "172.16.100.2";
|
localAddress = "172.16.100.2";
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
imports = allModules ++ [cfg.config];
|
imports = allModules ++ [ cfg.config ];
|
||||||
|
|
||||||
# speeds up evaluation
|
|
||||||
nixpkgs.pkgs = pkgs;
|
|
||||||
|
|
||||||
# networking.firewall.enable = mkForce false;
|
# networking.firewall.enable = mkForce false;
|
||||||
networking.firewall.trustedInterfaces = [
|
networking.firewall.trustedInterfaces = [
|
||||||
|
|||||||
60
common/nix-builder.nix
Normal file
60
common/nix-builder.nix
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
builderRole = "nix-builder";
|
||||||
|
builderUserName = "nix-builder";
|
||||||
|
|
||||||
|
machinesByRole = role: lib.filterAttrs (hostname: cfg: builtins.elem role cfg.systemRoles) config.machines.hosts;
|
||||||
|
otherMachinesByRole = role: lib.filterAttrs (hostname: cfg: hostname != config.networking.hostName) (machinesByRole role);
|
||||||
|
thisMachineHasRole = role: builtins.hasAttr config.networking.hostName (machinesByRole role);
|
||||||
|
|
||||||
|
builders = machinesByRole builderRole;
|
||||||
|
thisMachineIsABuilder = thisMachineHasRole builderRole;
|
||||||
|
|
||||||
|
# builders don't include themselves as a remote builder
|
||||||
|
otherBuilders = lib.filterAttrs (hostname: cfg: hostname != config.networking.hostName) builders;
|
||||||
|
in
|
||||||
|
lib.mkMerge [
|
||||||
|
# configure builder
|
||||||
|
(lib.mkIf thisMachineIsABuilder {
|
||||||
|
users.users.${builderUserName} = {
|
||||||
|
description = "Distributed Nix Build User";
|
||||||
|
group = builderUserName;
|
||||||
|
isSystemUser = true;
|
||||||
|
createHome = true;
|
||||||
|
home = "/var/lib/nix-builder";
|
||||||
|
useDefaultShell = true;
|
||||||
|
openssh.authorizedKeys.keys = builtins.map
|
||||||
|
(builderCfg: builderCfg.hostKey)
|
||||||
|
(builtins.attrValues config.machines.hosts);
|
||||||
|
};
|
||||||
|
users.groups.${builderUserName} = { };
|
||||||
|
|
||||||
|
nix.settings.trusted-users = [
|
||||||
|
builderUserName
|
||||||
|
];
|
||||||
|
})
|
||||||
|
|
||||||
|
# use each builder
|
||||||
|
{
|
||||||
|
nix.distributedBuilds = true;
|
||||||
|
|
||||||
|
nix.buildMachines = builtins.map
|
||||||
|
(builderCfg: {
|
||||||
|
hostName = builtins.elemAt builderCfg.hostNames 0;
|
||||||
|
system = builderCfg.arch;
|
||||||
|
protocol = "ssh-ng";
|
||||||
|
sshUser = builderUserName;
|
||||||
|
sshKey = "/etc/ssh/ssh_host_ed25519_key";
|
||||||
|
maxJobs = 3;
|
||||||
|
speedFactor = 10;
|
||||||
|
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
|
||||||
|
})
|
||||||
|
(builtins.attrValues otherBuilders);
|
||||||
|
|
||||||
|
# It is very likely that the builder's internet is faster or just as fast
|
||||||
|
nix.extraOptions = ''
|
||||||
|
builders-use-substitutes = true
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.de;
|
cfg = config.de;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
# enable pulseaudio support for packages
|
# enable pulseaudio support for packages
|
||||||
nixpkgs.config.pulseaudio = true;
|
nixpkgs.config.pulseaudio = true;
|
||||||
@@ -16,45 +17,6 @@ in {
|
|||||||
alsa.support32Bit = true;
|
alsa.support32Bit = true;
|
||||||
pulse.enable = true;
|
pulse.enable = true;
|
||||||
jack.enable = true;
|
jack.enable = true;
|
||||||
|
|
||||||
# use the example session manager (no others are packaged yet so this is enabled by default,
|
|
||||||
# no need to redefine it in your config for now)
|
|
||||||
#media-session.enable = true;
|
|
||||||
|
|
||||||
config.pipewire = {
|
|
||||||
"context.objects" = [
|
|
||||||
{
|
|
||||||
# A default dummy driver. This handles nodes marked with the "node.always-driver"
|
|
||||||
# properyty when no other driver is currently active. JACK clients need this.
|
|
||||||
factory = "spa-node-factory";
|
|
||||||
args = {
|
|
||||||
"factory.name" = "support.node.driver";
|
|
||||||
"node.name" = "Dummy-Driver";
|
|
||||||
"priority.driver" = 8000;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
factory = "adapter";
|
|
||||||
args = {
|
|
||||||
"factory.name" = "support.null-audio-sink";
|
|
||||||
"node.name" = "Microphone-Proxy";
|
|
||||||
"node.description" = "Microphone";
|
|
||||||
"media.class" = "Audio/Source/Virtual";
|
|
||||||
"audio.position" = "MONO";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
factory = "adapter";
|
|
||||||
args = {
|
|
||||||
"factory.name" = "support.null-audio-sink";
|
|
||||||
"node.name" = "Main-Output-Proxy";
|
|
||||||
"node.description" = "Main Output";
|
|
||||||
"media.class" = "Audio/Sink";
|
|
||||||
"audio.position" = "FL,FR";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
users.users.googlebot.extraGroups = [ "audio" ];
|
users.users.googlebot.extraGroups = [ "audio" ];
|
||||||
|
|||||||
@@ -17,39 +17,8 @@ let
|
|||||||
"PREFIX=$(out)"
|
"PREFIX=$(out)"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
in
|
||||||
nvidia-vaapi-driver = pkgs.stdenv.mkDerivation rec {
|
{
|
||||||
pname = "nvidia-vaapi-driver";
|
|
||||||
version = "0.0.5";
|
|
||||||
|
|
||||||
src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "elFarto";
|
|
||||||
repo = pname;
|
|
||||||
rev = "v${version}";
|
|
||||||
sha256 = "2bycqKolVoaHK64XYcReteuaON9TjzrFhaG5kty28YY=";
|
|
||||||
};
|
|
||||||
|
|
||||||
patches = [
|
|
||||||
./use-meson-v57.patch
|
|
||||||
];
|
|
||||||
|
|
||||||
nativeBuildInputs = with pkgs; [
|
|
||||||
meson
|
|
||||||
cmake
|
|
||||||
ninja
|
|
||||||
pkg-config
|
|
||||||
];
|
|
||||||
|
|
||||||
buildInputs = with pkgs; [
|
|
||||||
nv-codec-headers-11-1-5-1
|
|
||||||
libva
|
|
||||||
gst_all_1.gstreamer
|
|
||||||
gst_all_1.gst-plugins-bad
|
|
||||||
libglvnd
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
in {
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
# chromium with specific extensions + settings
|
# chromium with specific extensions + settings
|
||||||
programs.chromium = {
|
programs.chromium = {
|
||||||
@@ -92,7 +61,7 @@ in {
|
|||||||
enable = true;
|
enable = true;
|
||||||
extraPackages = with pkgs; [
|
extraPackages = with pkgs; [
|
||||||
intel-media-driver # LIBVA_DRIVER_NAME=iHD
|
intel-media-driver # LIBVA_DRIVER_NAME=iHD
|
||||||
vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
|
vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
|
||||||
# vaapiVdpau
|
# vaapiVdpau
|
||||||
libvdpau-va-gl
|
libvdpau-va-gl
|
||||||
nvidia-vaapi-driver
|
nvidia-vaapi-driver
|
||||||
|
|||||||
@@ -2,22 +2,24 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.de;
|
cfg = config.de;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./kde.nix
|
./kde.nix
|
||||||
./xfce.nix
|
# ./xfce.nix
|
||||||
./yubikey.nix
|
./yubikey.nix
|
||||||
./chromium.nix
|
./chromium.nix
|
||||||
# ./firefox.nix
|
./firefox.nix
|
||||||
./audio.nix
|
./audio.nix
|
||||||
# ./torbrowser.nix
|
# ./torbrowser.nix
|
||||||
./pithos.nix
|
./pithos.nix
|
||||||
./spotify.nix
|
|
||||||
./vscodium.nix
|
./vscodium.nix
|
||||||
./discord.nix
|
./discord.nix
|
||||||
./steam.nix
|
./steam.nix
|
||||||
./touchpad.nix
|
./touchpad.nix
|
||||||
./mount-samba.nix
|
./mount-samba.nix
|
||||||
|
./udev.nix
|
||||||
|
./virtualisation.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
options.de = {
|
options.de = {
|
||||||
@@ -36,22 +38,24 @@ in {
|
|||||||
mumble
|
mumble
|
||||||
tigervnc
|
tigervnc
|
||||||
bluez-tools
|
bluez-tools
|
||||||
vscodium
|
|
||||||
element-desktop
|
element-desktop
|
||||||
mpv
|
mpv
|
||||||
nextcloud-client
|
nextcloud-client
|
||||||
signal-desktop
|
signal-desktop
|
||||||
minecraft
|
|
||||||
gparted
|
gparted
|
||||||
libreoffice-fresh
|
libreoffice-fresh
|
||||||
thunderbird
|
thunderbird
|
||||||
spotifyd
|
spotify
|
||||||
spotify-qt
|
|
||||||
arduino
|
arduino
|
||||||
yt-dlp
|
yt-dlp
|
||||||
jellyfin-media-player
|
jellyfin-media-player
|
||||||
joplin-desktop
|
joplin-desktop
|
||||||
config.inputs.deploy-rs.packages.${config.currentSystem}.deploy-rs
|
config.inputs.deploy-rs.packages.${config.currentSystem}.deploy-rs
|
||||||
|
lxqt.pavucontrol-qt
|
||||||
|
barrier
|
||||||
|
|
||||||
|
# For Nix IDE
|
||||||
|
nixpkgs-fmt
|
||||||
];
|
];
|
||||||
|
|
||||||
# Networking
|
# Networking
|
||||||
@@ -65,12 +69,25 @@ in {
|
|||||||
];
|
];
|
||||||
# Printer discovery
|
# Printer discovery
|
||||||
services.avahi.enable = true;
|
services.avahi.enable = true;
|
||||||
services.avahi.nssmdns = true;
|
services.avahi.nssmdns4 = true;
|
||||||
|
|
||||||
programs.file-roller.enable = true;
|
programs.file-roller.enable = true;
|
||||||
|
|
||||||
# Security
|
# Security
|
||||||
services.gnome.gnome-keyring.enable = true;
|
services.gnome.gnome-keyring.enable = true;
|
||||||
security.pam.services.googlebot.enableGnomeKeyring = true;
|
security.pam.services.googlebot.enableGnomeKeyring = true;
|
||||||
|
|
||||||
|
# Android dev
|
||||||
|
programs.adb.enable = true;
|
||||||
|
|
||||||
|
# Mount personal SMB stores
|
||||||
|
services.mount-samba.enable = true;
|
||||||
|
|
||||||
|
# allow building ARM derivations
|
||||||
|
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
|
||||||
|
|
||||||
|
# for luks onlock over tor
|
||||||
|
services.tor.enable = true;
|
||||||
|
services.tor.client.enable = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.de;
|
cfg = config.de;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
users.users.googlebot.packages = [
|
users.users.googlebot.packages = [
|
||||||
pkgs.discord
|
pkgs.discord
|
||||||
|
|||||||
@@ -20,31 +20,6 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
firefox = pkgs.wrapFirefox somewhatPrivateFF {
|
firefox = pkgs.wrapFirefox somewhatPrivateFF {
|
||||||
desktopName = "Sneed Browser";
|
|
||||||
|
|
||||||
nixExtensions = [
|
|
||||||
(pkgs.fetchFirefoxAddon {
|
|
||||||
name = "ublock-origin";
|
|
||||||
url = "https://addons.mozilla.org/firefox/downloads/file/3719054/ublock_origin-1.33.2-an+fx.xpi";
|
|
||||||
sha256 = "XDpe9vW1R1iVBTI4AmNgAg1nk7BVQdIAMuqd0cnK5FE=";
|
|
||||||
})
|
|
||||||
(pkgs.fetchFirefoxAddon {
|
|
||||||
name = "sponsorblock";
|
|
||||||
url = "https://addons.mozilla.org/firefox/downloads/file/3720594/sponsorblock_skip_sponsorships_on_youtube-2.0.12.3-an+fx.xpi";
|
|
||||||
sha256 = "HRtnmZWyXN3MKo4AvSYgNJGkBEsa2RaMamFbkz+YzQg=";
|
|
||||||
})
|
|
||||||
(pkgs.fetchFirefoxAddon {
|
|
||||||
name = "KeePassXC-Browser";
|
|
||||||
url = "https://addons.mozilla.org/firefox/downloads/file/3720664/keepassxc_browser-1.7.6-fx.xpi";
|
|
||||||
sha256 = "3K404/eq3amHhIT0WhzQtC892he5I0kp2SvbzE9dbZg=";
|
|
||||||
})
|
|
||||||
(pkgs.fetchFirefoxAddon {
|
|
||||||
name = "https-everywhere";
|
|
||||||
url = "https://addons.mozilla.org/firefox/downloads/file/3716461/https_everywhere-2021.1.27-an+fx.xpi";
|
|
||||||
sha256 = "2gSXSLunKCwPjAq4Wsj0lOeV551r3G+fcm1oeqjMKh8=";
|
|
||||||
})
|
|
||||||
];
|
|
||||||
|
|
||||||
extraPolicies = {
|
extraPolicies = {
|
||||||
CaptivePortal = false;
|
CaptivePortal = false;
|
||||||
DisableFirefoxStudies = true;
|
DisableFirefoxStudies = true;
|
||||||
@@ -71,14 +46,8 @@ let
|
|||||||
TopSites = false;
|
TopSites = false;
|
||||||
};
|
};
|
||||||
UserMessaging = {
|
UserMessaging = {
|
||||||
ExtensionRecommendations = false;
|
ExtensionRecommendations = false;
|
||||||
SkipOnboarding = true;
|
SkipOnboarding = true;
|
||||||
};
|
|
||||||
WebsiteFilter = {
|
|
||||||
Block = [
|
|
||||||
"http://paradigminteractive.io/"
|
|
||||||
"https://paradigminteractive.io/"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,17 +2,14 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.de;
|
cfg = config.de;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
# kde plasma
|
services.displayManager.sddm.enable = true;
|
||||||
services.xserver = {
|
services.displayManager.sddm.wayland.enable = true;
|
||||||
enable = true;
|
services.desktopManager.plasma6.enable = true;
|
||||||
desktopManager.plasma5.enable = true;
|
|
||||||
displayManager.sddm.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# kde apps
|
# kde apps
|
||||||
nixpkgs.config.firefox.enablePlasmaBrowserIntegration = true;
|
|
||||||
users.users.googlebot.packages = with pkgs; [
|
users.users.googlebot.packages = with pkgs; [
|
||||||
# akonadi
|
# akonadi
|
||||||
# kmail
|
# kmail
|
||||||
|
|||||||
@@ -1,36 +1,50 @@
|
|||||||
# mounts the samba share on s0 over tailscale
|
# mounts the samba share on s0 over tailscale
|
||||||
|
|
||||||
{ config, lib, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.mount-samba;
|
cfg = config.services.mount-samba;
|
||||||
|
|
||||||
# prevents hanging on network split
|
# prevents hanging on network split and other similar niceties to ensure a stable connection
|
||||||
network_opts = "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s,nostrictsync,cache=loose,handlecache,handletimeout=30000,rwpidforward,mapposix,soft,resilienthandles,echo_interval=10,noblocksend";
|
network_opts = "nostrictsync,cache=strict,handlecache,handletimeout=30000,rwpidforward,mapposix,soft,resilienthandles,echo_interval=10,noblocksend,fsc";
|
||||||
|
|
||||||
|
systemd_opts = "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s";
|
||||||
user_opts = "uid=${toString config.users.users.googlebot.uid},file_mode=0660,dir_mode=0770,user";
|
user_opts = "uid=${toString config.users.users.googlebot.uid},file_mode=0660,dir_mode=0770,user";
|
||||||
auth_opts = "credentials=/run/agenix/smb-secrets";
|
auth_opts = "sec=ntlmv2i,credentials=/run/agenix/smb-secrets";
|
||||||
version_opts = "vers=2.1";
|
version_opts = "vers=3.1.1";
|
||||||
|
|
||||||
opts = "${network_opts},${user_opts},${version_opts},${auth_opts}";
|
public_user_opts = "gid=${toString config.users.groups.users.gid}";
|
||||||
in {
|
|
||||||
|
opts = "${systemd_opts},${network_opts},${user_opts},${version_opts},${auth_opts}";
|
||||||
|
in
|
||||||
|
{
|
||||||
options.services.mount-samba = {
|
options.services.mount-samba = {
|
||||||
enable = lib.mkEnableOption "enable mounting samba shares";
|
enable = lib.mkEnableOption "enable mounting samba shares";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf (cfg.enable && config.services.tailscale.enable) {
|
config = lib.mkIf (cfg.enable && config.services.tailscale.enable) {
|
||||||
fileSystems."/mnt/public" = {
|
fileSystems."/mnt/public" = {
|
||||||
device = "//s0.koi-bebop.ts.net/public";
|
device = "//s0.koi-bebop.ts.net/public";
|
||||||
fsType = "cifs";
|
fsType = "cifs";
|
||||||
options = [ opts ];
|
options = [ "${opts},${public_user_opts}" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/mnt/private" = {
|
fileSystems."/mnt/private" = {
|
||||||
device = "//s0.koi-bebop.ts.net/googlebot";
|
device = "//s0.koi-bebop.ts.net/googlebot";
|
||||||
fsType = "cifs";
|
fsType = "cifs";
|
||||||
options = [ opts ];
|
options = [ opts ];
|
||||||
};
|
};
|
||||||
|
|
||||||
age.secrets.smb-secrets.file = ../../secrets/smb-secrets.age;
|
age.secrets.smb-secrets.file = ../../secrets/smb-secrets.age;
|
||||||
|
|
||||||
|
environment.shellAliases = {
|
||||||
|
# remount storage
|
||||||
|
remount_public = "sudo systemctl restart mnt-public.mount";
|
||||||
|
remount_private = "sudo systemctl restart mnt-private.mount";
|
||||||
|
|
||||||
|
# Encrypted Vault
|
||||||
|
vault_unlock = "${pkgs.gocryptfs}/bin/gocryptfs /mnt/private/.vault/ /mnt/vault/";
|
||||||
|
vault_lock = "umount /mnt/vault/";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.de;
|
cfg = config.de;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
nixpkgs.overlays = [
|
nixpkgs.overlays = [
|
||||||
(self: super: {
|
(self: super: {
|
||||||
@@ -11,7 +12,7 @@ in {
|
|||||||
version = "1.5.1";
|
version = "1.5.1";
|
||||||
src = super.fetchFromGitHub {
|
src = super.fetchFromGitHub {
|
||||||
owner = pname;
|
owner = pname;
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = version;
|
rev = version;
|
||||||
sha256 = "il7OAALpHFZ6wjco9Asp04zWHCD8Ni+iBdiJWcMiQA4=";
|
sha256 = "il7OAALpHFZ6wjco9Asp04zWHCD8Ni+iBdiJWcMiQA4=";
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
{ lib, config, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.spotifyd;
|
|
||||||
toml = pkgs.formats.toml {};
|
|
||||||
spotifydConf = toml.generate "spotify.conf" cfg.settings;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
disabledModules = [
|
|
||||||
"services/audio/spotifyd.nix"
|
|
||||||
];
|
|
||||||
|
|
||||||
options = {
|
|
||||||
services.spotifyd = {
|
|
||||||
enable = mkEnableOption "spotifyd, a Spotify playing daemon";
|
|
||||||
|
|
||||||
settings = mkOption {
|
|
||||||
default = {};
|
|
||||||
type = toml.type;
|
|
||||||
example = { global.bitrate = 320; };
|
|
||||||
description = ''
|
|
||||||
Configuration for Spotifyd. For syntax and directives, see
|
|
||||||
<link xlink:href="https://github.com/Spotifyd/spotifyd#Configuration"/>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
users = mkOption {
|
|
||||||
type = with types; listOf str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Usernames to be added to the "spotifyd" group, so that they
|
|
||||||
can start and interact with the userspace daemon.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
|
|
||||||
# username specific stuff because i'm lazy...
|
|
||||||
services.spotifyd.users = [ "googlebot" ];
|
|
||||||
users.users.googlebot.packages = with pkgs; [
|
|
||||||
spotify
|
|
||||||
spotify-tui
|
|
||||||
];
|
|
||||||
|
|
||||||
users.groups.spotifyd = {
|
|
||||||
members = cfg.users;
|
|
||||||
};
|
|
||||||
|
|
||||||
age.secrets.spotifyd = {
|
|
||||||
file = ../../secrets/spotifyd.age;
|
|
||||||
group = "spotifyd";
|
|
||||||
mode = "0440"; # group can read
|
|
||||||
};
|
|
||||||
|
|
||||||
# spotifyd to read secrets and run as user service
|
|
||||||
services.spotifyd = {
|
|
||||||
settings.global = {
|
|
||||||
username_cmd = "sed '1q;d' /run/agenix/spotifyd";
|
|
||||||
password_cmd = "sed '2q;d' /run/agenix/spotifyd";
|
|
||||||
bitrate = 320;
|
|
||||||
backend = "pulseaudio";
|
|
||||||
device_name = config.networking.hostName;
|
|
||||||
device_type = "computer";
|
|
||||||
# on_song_change_hook = "command_to_run_on_playback_events"
|
|
||||||
autoplay = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.user.services.spotifyd-daemon = {
|
|
||||||
enable = true;
|
|
||||||
wantedBy = [ "graphical-session.target" ];
|
|
||||||
partOf = [ "graphical-session.target" ];
|
|
||||||
description = "spotifyd, a Spotify playing daemon";
|
|
||||||
environment.SHELL = "/bin/sh";
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = "${pkgs.spotifyd}/bin/spotifyd --no-daemon --config-path ${spotifydConf}";
|
|
||||||
Restart = "always";
|
|
||||||
CacheDirectory = "spotifyd";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.de;
|
cfg = config.de;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
programs.steam.enable = true;
|
programs.steam.enable = true;
|
||||||
hardware.steam-hardware.enable = true; # steam controller
|
hardware.steam-hardware.enable = true; # steam controller
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.de;
|
cfg = config.de;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
nixpkgs.overlays = [
|
nixpkgs.overlays = [
|
||||||
(self: super: {
|
(self: super: {
|
||||||
|
|||||||
@@ -2,13 +2,14 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.de.touchpad;
|
cfg = config.de.touchpad;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.de.touchpad = {
|
options.de.touchpad = {
|
||||||
enable = lib.mkEnableOption "enable touchpad";
|
enable = lib.mkEnableOption "enable touchpad";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
services.xserver.libinput.enable = true;
|
services.libinput.enable = true;
|
||||||
services.xserver.libinput.touchpad.naturalScrolling = true;
|
services.libinput.touchpad.naturalScrolling = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
25
common/pc/udev.nix
Normal file
25
common/pc/udev.nix
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.de;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.udev.extraRules = ''
|
||||||
|
# depthai
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="03e7", MODE="0666"
|
||||||
|
|
||||||
|
# Moonlander
|
||||||
|
# Rules for Oryx web flashing and live training
|
||||||
|
KERNEL=="hidraw*", ATTRS{idVendor}=="16c0", MODE="0664", GROUP="plugdev"
|
||||||
|
KERNEL=="hidraw*", ATTRS{idVendor}=="3297", MODE="0664", GROUP="plugdev"
|
||||||
|
# Wally Flashing rules for the Moonlander and Planck EZ
|
||||||
|
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE:="0666", SYMLINK+="stm32_dfu"
|
||||||
|
'';
|
||||||
|
services.udev.packages = [ pkgs.platformio ];
|
||||||
|
|
||||||
|
users.groups.plugdev = {
|
||||||
|
members = [ "googlebot" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
diff --git a/meson.build b/meson.build
|
|
||||||
index dace367..8c0e290 100644
|
|
||||||
--- a/meson.build
|
|
||||||
+++ b/meson.build
|
|
||||||
@@ -8,7 +8,7 @@ project(
|
|
||||||
'warning_level=0',
|
|
||||||
],
|
|
||||||
license: 'MIT',
|
|
||||||
- meson_version: '>= 0.58.0',
|
|
||||||
+ meson_version: '>= 0.57.0',
|
|
||||||
)
|
|
||||||
|
|
||||||
cc = meson.get_compiler('c')
|
|
||||||
@@ -47,8 +47,3 @@ shared_library(
|
|
||||||
gnu_symbol_visibility: 'hidden',
|
|
||||||
)
|
|
||||||
|
|
||||||
-meson.add_devenv(environment({
|
|
||||||
- 'NVD_LOG': '1',
|
|
||||||
- 'LIBVA_DRIVER_NAME': 'nvidia',
|
|
||||||
- 'LIBVA_DRIVERS_PATH': meson.project_build_root(),
|
|
||||||
-}))
|
|
||||||
23
common/pc/virtualisation.nix
Normal file
23
common/pc/virtualisation.nix
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.de;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
# AppVMs
|
||||||
|
virtualisation.appvm.enable = true;
|
||||||
|
virtualisation.appvm.user = "googlebot";
|
||||||
|
|
||||||
|
# Use podman instead of docker
|
||||||
|
virtualisation.podman.enable = true;
|
||||||
|
virtualisation.podman.dockerCompat = true;
|
||||||
|
|
||||||
|
# virt-manager
|
||||||
|
virtualisation.libvirtd.enable = true;
|
||||||
|
programs.dconf.enable = true;
|
||||||
|
virtualisation.spiceUSBRedirection.enable = true;
|
||||||
|
environment.systemPackages = with pkgs; [ virt-manager ];
|
||||||
|
users.users.googlebot.extraGroups = [ "libvirtd" "adbusers" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -4,8 +4,20 @@ let
|
|||||||
cfg = config.de;
|
cfg = config.de;
|
||||||
|
|
||||||
extensions = with pkgs.vscode-extensions; [
|
extensions = with pkgs.vscode-extensions; [
|
||||||
# bbenoist.Nix # nix syntax support
|
bbenoist.nix # nix syntax support
|
||||||
# arrterian.nix-env-selector # nix dev envs
|
arrterian.nix-env-selector # nix dev envs
|
||||||
|
dart-code.dart-code
|
||||||
|
dart-code.flutter
|
||||||
|
golang.go
|
||||||
|
jnoortheen.nix-ide
|
||||||
|
ms-vscode.cpptools
|
||||||
|
] ++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
|
||||||
|
{
|
||||||
|
name = "platformio-ide";
|
||||||
|
publisher = "platformio";
|
||||||
|
version = "3.1.1";
|
||||||
|
sha256 = "g9yTG3DjVUS2w9eHGAai5LoIfEGus+FPhqDnCi4e90Q=";
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
vscodium-with-extensions = pkgs.vscode-with-extensions.override {
|
vscodium-with-extensions = pkgs.vscode-with-extensions.override {
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.de;
|
cfg = config.de;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
services.xserver = {
|
services.xserver = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.de;
|
cfg = config.de;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
# yubikey
|
# yubikey
|
||||||
services.pcscd.enable = true;
|
services.pcscd.enable = true;
|
||||||
|
|||||||
87
common/server/actualbudget.nix
Normal file
87
common/server/actualbudget.nix
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
# Starting point:
|
||||||
|
# https://github.com/aldoborrero/mynixpkgs/commit/c501c1e32dba8f4462dcecb57eee4b9e52038e27
|
||||||
|
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.actual-server;
|
||||||
|
stateDir = "/var/lib/${cfg.stateDirName}";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.actual-server = {
|
||||||
|
enable = lib.mkEnableOption "Actual Server";
|
||||||
|
|
||||||
|
hostname = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "localhost";
|
||||||
|
description = "Hostname for the Actual Server.";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 25448;
|
||||||
|
description = "Port on which the Actual Server should listen.";
|
||||||
|
};
|
||||||
|
|
||||||
|
stateDirName = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "actual-server";
|
||||||
|
description = "Name of the directory under /var/lib holding the server's data.";
|
||||||
|
};
|
||||||
|
|
||||||
|
upload = {
|
||||||
|
fileSizeSyncLimitMB = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.int;
|
||||||
|
default = null;
|
||||||
|
description = "File size limit in MB for synchronized files.";
|
||||||
|
};
|
||||||
|
|
||||||
|
syncEncryptedFileSizeLimitMB = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.int;
|
||||||
|
default = null;
|
||||||
|
description = "File size limit in MB for synchronized encrypted files.";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSizeLimitMB = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.int;
|
||||||
|
default = null;
|
||||||
|
description = "File size limit in MB for file uploads.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
systemd.services.actual-server = {
|
||||||
|
description = "Actual Server";
|
||||||
|
after = [ "network.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${pkgs.actual-server}/bin/actual-server";
|
||||||
|
Restart = "always";
|
||||||
|
StateDirectory = cfg.stateDirName;
|
||||||
|
WorkingDirectory = stateDir;
|
||||||
|
DynamicUser = true;
|
||||||
|
UMask = "0007";
|
||||||
|
};
|
||||||
|
environment = {
|
||||||
|
NODE_ENV = "production";
|
||||||
|
ACTUAL_PORT = toString cfg.port;
|
||||||
|
|
||||||
|
# Actual is actually very bad at configuring it's own paths despite that information being readily available
|
||||||
|
ACTUAL_USER_FILES = "${stateDir}/user-files";
|
||||||
|
ACTUAL_SERVER_FILES = "${stateDir}/server-files";
|
||||||
|
ACTUAL_DATA_DIR = stateDir;
|
||||||
|
|
||||||
|
ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB = toString (cfg.upload.fileSizeSyncLimitMB or "");
|
||||||
|
ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SIZE_LIMIT_MB = toString (cfg.upload.syncEncryptedFileSizeLimitMB or "");
|
||||||
|
ACTUAL_UPLOAD_FILE_SIZE_LIMIT_MB = toString (cfg.upload.fileSizeLimitMB or "");
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts.${cfg.hostname} = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/".proxyPass = "http://localhost:${toString cfg.port}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
40
common/server/atticd.nix
Normal file
40
common/server/atticd.nix
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.atticd;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.atticd = {
|
||||||
|
credentialsFile = "/run/agenix/atticd-credentials";
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
listen = "[::]:28338";
|
||||||
|
|
||||||
|
# Speed things up
|
||||||
|
require-proof-of-possession = false;
|
||||||
|
|
||||||
|
chunking = {
|
||||||
|
# Disable chunking for performance (I have plenty of space)
|
||||||
|
nar-size-threshold = 0;
|
||||||
|
|
||||||
|
# Chunking is disabled due to poor performance so these values don't matter but are required anyway.
|
||||||
|
# One day, when I move away from ZFS maybe this will perform well enough.
|
||||||
|
# nar-size-threshold = 64 * 1024; # 64 KiB
|
||||||
|
min-size = 16 * 1024; # 16 KiB
|
||||||
|
avg-size = 64 * 1024; # 64 KiB
|
||||||
|
max-size = 256 * 1024; # 256 KiB
|
||||||
|
};
|
||||||
|
|
||||||
|
# Disable compression for performance (I have plenty of space)
|
||||||
|
compression.type = "none";
|
||||||
|
|
||||||
|
garbage-collection = {
|
||||||
|
default-retention-period = "6 months";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
age.secrets.atticd-credentials.file = ../../secrets/atticd-credentials.age;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -3,9 +3,9 @@
|
|||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.ceph;
|
cfg = config.ceph;
|
||||||
in {
|
in
|
||||||
options.ceph = {
|
{
|
||||||
};
|
options.ceph = { };
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
# ceph.enable = true;
|
# ceph.enable = true;
|
||||||
|
|||||||
53
common/server/dashy.nix
Normal file
53
common/server/dashy.nix
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.dashy;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.dashy = {
|
||||||
|
enable = mkEnableOption "dashy";
|
||||||
|
imageTag = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "latest";
|
||||||
|
};
|
||||||
|
port = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 56815;
|
||||||
|
};
|
||||||
|
configFile = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
description = "Path to the YAML configuration file";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
virtualisation.oci-containers.containers = {
|
||||||
|
dashy = {
|
||||||
|
image = "lissy93/dashy:${cfg.imageTag}";
|
||||||
|
environment = {
|
||||||
|
TZ = "${config.time.timeZone}";
|
||||||
|
};
|
||||||
|
ports = [
|
||||||
|
"127.0.0.1:${toString cfg.port}:80"
|
||||||
|
];
|
||||||
|
volumes = [
|
||||||
|
"${cfg.configFile}:/app/public/conf.yml"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.enable = true;
|
||||||
|
services.nginx.virtualHosts."s0.koi-bebop.ts.net" = {
|
||||||
|
default = true;
|
||||||
|
addSSL = true;
|
||||||
|
serverAliases = [ "s0" ];
|
||||||
|
sslCertificate = "/secret/ssl/s0.koi-bebop.ts.net.crt";
|
||||||
|
sslCertificateKey = "/secret/ssl/s0.koi-bebop.ts.net.key";
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://localhost:${toString cfg.port}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -18,5 +18,10 @@
|
|||||||
./nextcloud.nix
|
./nextcloud.nix
|
||||||
./iodine.nix
|
./iodine.nix
|
||||||
./searx.nix
|
./searx.nix
|
||||||
|
./gitea-actions-runner.nix
|
||||||
|
./dashy.nix
|
||||||
|
./librechat.nix
|
||||||
|
./actualbudget.nix
|
||||||
|
./atticd.nix
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
137
common/server/gitea-actions-runner.nix
Normal file
137
common/server/gitea-actions-runner.nix
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
{ config, pkgs, lib, allModules, ... }:
|
||||||
|
|
||||||
|
# Gitea Actions Runner. Starts 'host' runner that runs directly on the host inside of a nixos container
|
||||||
|
# This is useful for providing a real Nix/OS builder to gitea.
|
||||||
|
# Warning, NixOS containers are not secure. For example, the container shares the /nix/store
|
||||||
|
# Therefore, this should not be used to run untrusted code.
|
||||||
|
# To enable, assign a machine the 'gitea-actions-runner' system role
|
||||||
|
|
||||||
|
# TODO: skipping running inside of nixos container for now because of issues getting docker/podman running
|
||||||
|
|
||||||
|
let
|
||||||
|
runnerRole = "gitea-actions-runner";
|
||||||
|
runners = config.machines.roles.${runnerRole};
|
||||||
|
thisMachineIsARunner = builtins.elem config.networking.hostName runners;
|
||||||
|
|
||||||
|
containerName = "gitea-runner";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
config = lib.mkIf (thisMachineIsARunner && !config.boot.isContainer) {
|
||||||
|
# containers.${containerName} = {
|
||||||
|
# ephemeral = true;
|
||||||
|
# autoStart = true;
|
||||||
|
|
||||||
|
# # for podman
|
||||||
|
# enableTun = true;
|
||||||
|
|
||||||
|
# # privateNetwork = true;
|
||||||
|
# # hostAddress = "172.16.101.1";
|
||||||
|
# # localAddress = "172.16.101.2";
|
||||||
|
|
||||||
|
# bindMounts =
|
||||||
|
# {
|
||||||
|
# "/run/agenix/gitea-actions-runner-token" = {
|
||||||
|
# hostPath = "/run/agenix/gitea-actions-runner-token";
|
||||||
|
# isReadOnly = true;
|
||||||
|
# };
|
||||||
|
# "/var/lib/gitea-runner" = {
|
||||||
|
# hostPath = "/var/lib/gitea-runner";
|
||||||
|
# isReadOnly = false;
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
|
||||||
|
# extraFlags = [
|
||||||
|
# # Allow podman
|
||||||
|
# ''--system-call-filter=thisystemcalldoesnotexistforsure''
|
||||||
|
# ];
|
||||||
|
|
||||||
|
# additionalCapabilities = [
|
||||||
|
# "CAP_SYS_ADMIN"
|
||||||
|
# ];
|
||||||
|
|
||||||
|
# config = {
|
||||||
|
# imports = allModules;
|
||||||
|
|
||||||
|
# # speeds up evaluation
|
||||||
|
# nixpkgs.pkgs = pkgs;
|
||||||
|
|
||||||
|
# networking.hostName = lib.mkForce containerName;
|
||||||
|
|
||||||
|
# # don't use remote builders
|
||||||
|
# nix.distributedBuilds = lib.mkForce false;
|
||||||
|
|
||||||
|
# environment.systemPackages = with pkgs; [
|
||||||
|
# git
|
||||||
|
# # Gitea Actions rely heavily on node. Include it because it would be installed anyway.
|
||||||
|
# nodejs
|
||||||
|
# ];
|
||||||
|
|
||||||
|
# services.gitea-actions-runner.instances.inst = {
|
||||||
|
# enable = true;
|
||||||
|
# name = config.networking.hostName;
|
||||||
|
# url = "https://git.neet.dev/";
|
||||||
|
# tokenFile = "/run/agenix/gitea-actions-runner-token";
|
||||||
|
# labels = [
|
||||||
|
# "ubuntu-latest:docker://node:18-bullseye"
|
||||||
|
# "nixos:host"
|
||||||
|
# ];
|
||||||
|
# };
|
||||||
|
|
||||||
|
# # To allow building on the host, must override the the service's config so it doesn't use a dynamic user
|
||||||
|
# systemd.services.gitea-runner-inst.serviceConfig.DynamicUser = lib.mkForce false;
|
||||||
|
# users.users.gitea-runner = {
|
||||||
|
# home = "/var/lib/gitea-runner";
|
||||||
|
# group = "gitea-runner";
|
||||||
|
# isSystemUser = true;
|
||||||
|
# createHome = true;
|
||||||
|
# };
|
||||||
|
# users.groups.gitea-runner = { };
|
||||||
|
|
||||||
|
# virtualisation.podman.enable = true;
|
||||||
|
# boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
|
||||||
|
# networking.nat.enable = true;
|
||||||
|
# networking.nat.internalInterfaces = [
|
||||||
|
# "ve-${containerName}"
|
||||||
|
# ];
|
||||||
|
# networking.ip_forward = true;
|
||||||
|
|
||||||
|
# don't use remote builders
|
||||||
|
nix.distributedBuilds = lib.mkForce false;
|
||||||
|
|
||||||
|
services.gitea-actions-runner.instances.inst = {
|
||||||
|
enable = true;
|
||||||
|
name = config.networking.hostName;
|
||||||
|
url = "https://git.neet.dev/";
|
||||||
|
tokenFile = "/run/agenix/gitea-actions-runner-token";
|
||||||
|
labels = [
|
||||||
|
"ubuntu-latest:docker://node:18-bullseye"
|
||||||
|
"nixos:host"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
git
|
||||||
|
# Gitea Actions rely heavily on node. Include it because it would be installed anyway.
|
||||||
|
nodejs
|
||||||
|
attic
|
||||||
|
];
|
||||||
|
|
||||||
|
# To allow building on the host, must override the the service's config so it doesn't use a dynamic user
|
||||||
|
systemd.services.gitea-runner-inst.serviceConfig.DynamicUser = lib.mkForce false;
|
||||||
|
users.users.gitea-runner = {
|
||||||
|
home = "/var/lib/gitea-runner";
|
||||||
|
group = "gitea-runner";
|
||||||
|
isSystemUser = true;
|
||||||
|
createHome = true;
|
||||||
|
};
|
||||||
|
users.groups.gitea-runner = { };
|
||||||
|
|
||||||
|
virtualisation.podman.enable = true;
|
||||||
|
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
|
||||||
|
|
||||||
|
age.secrets.gitea-actions-runner-token.file = ../../secrets/gitea-actions-runner-token.age;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
{ lib, config, ... }:
|
{ lib, pkgs, config, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.gitea;
|
cfg = config.services.gitea;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.services.gitea = {
|
options.services.gitea = {
|
||||||
hostname = lib.mkOption {
|
hostname = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
@@ -11,12 +12,14 @@ in {
|
|||||||
};
|
};
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
services.gitea = {
|
services.gitea = {
|
||||||
domain = cfg.hostname;
|
|
||||||
rootUrl = "https://${cfg.hostname}/";
|
|
||||||
appName = cfg.hostname;
|
appName = cfg.hostname;
|
||||||
# lfs.enable = true;
|
lfs.enable = true;
|
||||||
dump.enable = true;
|
# dump.enable = true;
|
||||||
settings = {
|
settings = {
|
||||||
|
server = {
|
||||||
|
ROOT_URL = "https://${cfg.hostname}/";
|
||||||
|
DOMAIN = cfg.hostname;
|
||||||
|
};
|
||||||
other = {
|
other = {
|
||||||
SHOW_FOOTER_VERSION = false;
|
SHOW_FOOTER_VERSION = false;
|
||||||
};
|
};
|
||||||
@@ -28,15 +31,44 @@ in {
|
|||||||
};
|
};
|
||||||
session = {
|
session = {
|
||||||
COOKIE_SECURE = true;
|
COOKIE_SECURE = true;
|
||||||
|
PROVIDER = "db";
|
||||||
|
SESSION_LIFE_TIME = 259200; # 3 days
|
||||||
|
GC_INTERVAL_TIME = 259200; # 3 days
|
||||||
|
};
|
||||||
|
mailer = {
|
||||||
|
ENABLED = true;
|
||||||
|
MAILER_TYPE = "smtp";
|
||||||
|
SMTP_ADDR = "mail.neet.dev";
|
||||||
|
SMTP_PORT = "465";
|
||||||
|
IS_TLS_ENABLED = true;
|
||||||
|
USER = "robot@runyan.org";
|
||||||
|
FROM = "no-reply@neet.dev";
|
||||||
|
};
|
||||||
|
actions = {
|
||||||
|
ENABLED = true;
|
||||||
|
};
|
||||||
|
indexer = {
|
||||||
|
REPO_INDEXER_ENABLED = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
mailerPasswordFile = "/run/agenix/robots-email-pw";
|
||||||
};
|
};
|
||||||
|
age.secrets.robots-email-pw = {
|
||||||
|
file = ../../secrets/robots-email-pw.age;
|
||||||
|
owner = config.services.gitea.user;
|
||||||
|
};
|
||||||
|
|
||||||
|
# backups
|
||||||
|
backup.group."gitea".paths = [
|
||||||
|
config.services.gitea.stateDir
|
||||||
|
];
|
||||||
|
|
||||||
services.nginx.enable = true;
|
services.nginx.enable = true;
|
||||||
services.nginx.virtualHosts.${cfg.hostname} = {
|
services.nginx.virtualHosts.${cfg.hostname} = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
proxyPass = "http://localhost:${toString cfg.httpPort}";
|
proxyPass = "http://localhost:${toString cfg.settings.server.HTTP_PORT}";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,6 +20,6 @@ in
|
|||||||
hydraURL = "https://${domain}";
|
hydraURL = "https://${domain}";
|
||||||
useSubstitutes = true;
|
useSubstitutes = true;
|
||||||
notificationSender = notifyEmail;
|
notificationSender = notifyEmail;
|
||||||
buildMachinesFiles = [];
|
buildMachinesFiles = [ ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,8 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.icecast;
|
cfg = config.services.icecast;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.services.icecast = {
|
options.services.icecast = {
|
||||||
mount = lib.mkOption {
|
mount = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.iodine.server;
|
cfg = config.services.iodine.server;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
# iodine DNS-based vpn
|
# iodine DNS-based vpn
|
||||||
services.iodine.server = {
|
services.iodine.server = {
|
||||||
|
|||||||
62
common/server/librechat.nix
Normal file
62
common/server/librechat.nix
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.librechat;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.librechat = {
|
||||||
|
enable = mkEnableOption "librechat";
|
||||||
|
port = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 3080;
|
||||||
|
};
|
||||||
|
host = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
example = "example.com";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
virtualisation.oci-containers.containers = {
|
||||||
|
librechat = {
|
||||||
|
image = "ghcr.io/danny-avila/librechat:v0.6.6";
|
||||||
|
environment = {
|
||||||
|
HOST = "0.0.0.0";
|
||||||
|
MONGO_URI = "mongodb://host.containers.internal:27017/LibreChat";
|
||||||
|
ENDPOINTS = "openAI,google,bingAI,gptPlugins";
|
||||||
|
};
|
||||||
|
environmentFiles = [
|
||||||
|
"/run/agenix/librechat-env-file"
|
||||||
|
];
|
||||||
|
ports = [
|
||||||
|
"${toString cfg.port}:3080"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
age.secrets.librechat-env-file.file = ../../secrets/librechat-env-file.age;
|
||||||
|
|
||||||
|
services.mongodb.enable = true;
|
||||||
|
services.mongodb.bind_ip = "0.0.0.0";
|
||||||
|
|
||||||
|
# easier podman maintenance
|
||||||
|
virtualisation.oci-containers.backend = "podman";
|
||||||
|
virtualisation.podman.dockerSocket.enable = true;
|
||||||
|
virtualisation.podman.dockerCompat = true;
|
||||||
|
|
||||||
|
# For mongodb access
|
||||||
|
networking.firewall.trustedInterfaces = [
|
||||||
|
"podman0" # for librechat
|
||||||
|
];
|
||||||
|
|
||||||
|
services.nginx.virtualHosts.${cfg.host} = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://localhost:${toString cfg.port}";
|
||||||
|
proxyWebsockets = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -15,7 +15,8 @@ let
|
|||||||
"bsd.ninja"
|
"bsd.ninja"
|
||||||
"bsd.rocks"
|
"bsd.rocks"
|
||||||
];
|
];
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
# kresd doesn't work with tailscale MagicDNS
|
# kresd doesn't work with tailscale MagicDNS
|
||||||
mailserver.localDnsResolver = false;
|
mailserver.localDnsResolver = false;
|
||||||
@@ -32,20 +33,41 @@ in {
|
|||||||
inherit domains;
|
inherit domains;
|
||||||
loginAccounts = {
|
loginAccounts = {
|
||||||
"jeremy@runyan.org" = {
|
"jeremy@runyan.org" = {
|
||||||
hashedPasswordFile = "/run/agenix/email-pw";
|
hashedPasswordFile = "/run/agenix/hashed-email-pw";
|
||||||
# catchall for all domains
|
# catchall for all domains
|
||||||
aliases = map (domain: "@${domain}") domains;
|
aliases = map (domain: "@${domain}") domains;
|
||||||
};
|
};
|
||||||
|
"cris@runyan.org" = {
|
||||||
|
hashedPasswordFile = "/run/agenix/cris-hashed-email-pw";
|
||||||
|
aliases = [ "chris@runyan.org" ];
|
||||||
|
};
|
||||||
|
"robot@runyan.org" = {
|
||||||
|
aliases = [
|
||||||
|
"no-reply@neet.dev"
|
||||||
|
"robot@neet.dev"
|
||||||
|
];
|
||||||
|
sendOnly = true;
|
||||||
|
hashedPasswordFile = "/run/agenix/hashed-robots-email-pw";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
rejectRecipients = [
|
rejectRecipients = [
|
||||||
"george@runyan.org"
|
"george@runyan.org"
|
||||||
"joslyn@runyan.org"
|
"joslyn@runyan.org"
|
||||||
"damon@runyan.org"
|
"damon@runyan.org"
|
||||||
"jonas@runyan.org"
|
"jonas@runyan.org"
|
||||||
|
"simon@neet.dev"
|
||||||
];
|
];
|
||||||
certificateScheme = 3; # use let's encrypt for certs
|
forwards = {
|
||||||
|
"amazon@runyan.org" = [
|
||||||
|
"jeremy@runyan.org"
|
||||||
|
"cris@runyan.org"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
certificateScheme = "acme-nginx"; # use let's encrypt for certs
|
||||||
};
|
};
|
||||||
age.secrets.email-pw.file = ../../secrets/email-pw.age;
|
age.secrets.hashed-email-pw.file = ../../secrets/hashed-email-pw.age;
|
||||||
|
age.secrets.cris-hashed-email-pw.file = ../../secrets/cris-hashed-email-pw.age;
|
||||||
|
age.secrets.hashed-robots-email-pw.file = ../../secrets/hashed-robots-email-pw.age;
|
||||||
|
|
||||||
# sendmail to use xxx@domain instead of xxx@mail.domain
|
# sendmail to use xxx@domain instead of xxx@mail.domain
|
||||||
services.postfix.origin = "$mydomain";
|
services.postfix.origin = "$mydomain";
|
||||||
@@ -60,10 +82,12 @@ in {
|
|||||||
sender_dependent_relayhost_maps = "hash:/var/lib/postfix/conf/sender_relay";
|
sender_dependent_relayhost_maps = "hash:/var/lib/postfix/conf/sender_relay";
|
||||||
smtp_sender_dependent_authentication = "yes";
|
smtp_sender_dependent_authentication = "yes";
|
||||||
};
|
};
|
||||||
services.postfix.mapFiles.sender_relay = let
|
services.postfix.mapFiles.sender_relay =
|
||||||
relayHost = "[smtp.mailgun.org]:587";
|
let
|
||||||
in pkgs.writeText "sender_relay"
|
relayHost = "[smtp.mailgun.org]:587";
|
||||||
(concatStringsSep "\n" (map (domain: "@${domain} ${relayHost}") domains));
|
in
|
||||||
|
pkgs.writeText "sender_relay"
|
||||||
|
(concatStringsSep "\n" (map (domain: "@${domain} ${relayHost}") domains));
|
||||||
services.postfix.mapFiles.sasl_relay_passwd = "/run/agenix/sasl_relay_passwd";
|
services.postfix.mapFiles.sasl_relay_passwd = "/run/agenix/sasl_relay_passwd";
|
||||||
age.secrets.sasl_relay_passwd.file = ../../secrets/sasl_relay_passwd.age;
|
age.secrets.sasl_relay_passwd.file = ../../secrets/sasl_relay_passwd.age;
|
||||||
|
|
||||||
@@ -79,5 +103,10 @@ in {
|
|||||||
$config['smtp_pass'] = "%p";
|
$config['smtp_pass'] = "%p";
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# backups
|
||||||
|
backup.group."email".paths = [
|
||||||
|
config.mailserver.mailDirectory
|
||||||
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,8 @@
|
|||||||
let
|
let
|
||||||
cfg = config.services.matrix;
|
cfg = config.services.matrix;
|
||||||
certs = config.security.acme.certs;
|
certs = config.security.acme.certs;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.services.matrix = {
|
options.services.matrix = {
|
||||||
enable = lib.mkEnableOption "enable matrix";
|
enable = lib.mkEnableOption "enable matrix";
|
||||||
element-web = {
|
element-web = {
|
||||||
@@ -62,15 +63,15 @@ in {
|
|||||||
settings = {
|
settings = {
|
||||||
server_name = cfg.host;
|
server_name = cfg.host;
|
||||||
enable_registration = cfg.enable_registration;
|
enable_registration = cfg.enable_registration;
|
||||||
listeners = [ {
|
listeners = [{
|
||||||
bind_addresses = ["127.0.0.1"];
|
bind_addresses = [ "127.0.0.1" ];
|
||||||
port = cfg.port;
|
port = cfg.port;
|
||||||
tls = false;
|
tls = false;
|
||||||
resources = [ {
|
resources = [{
|
||||||
compress = true;
|
compress = true;
|
||||||
names = [ "client" "federation" ];
|
names = [ "client" "federation" ];
|
||||||
} ];
|
}];
|
||||||
} ];
|
}];
|
||||||
turn_uris = [
|
turn_uris = [
|
||||||
"turn:${cfg.turn.host}:${toString cfg.turn.port}?transport=udp"
|
"turn:${cfg.turn.host}:${toString cfg.turn.port}?transport=udp"
|
||||||
"turn:${cfg.turn.host}:${toString cfg.turn.port}?transport=tcp"
|
"turn:${cfg.turn.host}:${toString cfg.turn.port}?transport=tcp"
|
||||||
@@ -120,7 +121,7 @@ in {
|
|||||||
services.nginx = {
|
services.nginx = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
virtualHosts.${cfg.host} = {
|
virtualHosts.${cfg.host} = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
listen = [
|
listen = [
|
||||||
@@ -137,7 +138,8 @@ in {
|
|||||||
];
|
];
|
||||||
locations."/".proxyPass = "http://localhost:${toString cfg.port}";
|
locations."/".proxyPass = "http://localhost:${toString cfg.port}";
|
||||||
};
|
};
|
||||||
virtualHosts.${cfg.turn.host} = { # get TLS cert for TURN server
|
virtualHosts.${cfg.turn.host} = {
|
||||||
|
# get TLS cert for TURN server
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
let
|
let
|
||||||
cfg = config.services.murmur;
|
cfg = config.services.murmur;
|
||||||
certs = config.security.acme.certs;
|
certs = config.security.acme.certs;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.services.murmur.domain = lib.mkOption {
|
options.services.murmur.domain = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,22 +3,28 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.nextcloud;
|
cfg = config.services.nextcloud;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
services.nextcloud = {
|
services.nextcloud = {
|
||||||
https = true;
|
https = true;
|
||||||
package = pkgs.nextcloud25;
|
package = pkgs.nextcloud29;
|
||||||
hostName = "neet.cloud";
|
hostName = "neet.cloud";
|
||||||
config.dbtype = "sqlite";
|
config.dbtype = "sqlite";
|
||||||
config.adminuser = "jeremy";
|
config.adminuser = "jeremy";
|
||||||
config.adminpassFile = "/run/agenix/nextcloud-pw";
|
config.adminpassFile = "/run/agenix/nextcloud-pw";
|
||||||
autoUpdateApps.enable = true;
|
autoUpdateApps.enable = true;
|
||||||
enableBrokenCiphersForSSE = false;
|
|
||||||
};
|
};
|
||||||
age.secrets.nextcloud-pw = {
|
age.secrets.nextcloud-pw = {
|
||||||
file = ../../secrets/nextcloud-pw.age;
|
file = ../../secrets/nextcloud-pw.age;
|
||||||
owner = "nextcloud";
|
owner = "nextcloud";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# backups
|
||||||
|
backup.group."nextcloud".paths = [
|
||||||
|
config.services.nextcloud.home
|
||||||
|
];
|
||||||
|
|
||||||
services.nginx.virtualHosts.${config.services.nextcloud.hostName} = {
|
services.nginx.virtualHosts.${config.services.nextcloud.hostName} = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ let
|
|||||||
nginxWithRTMP = pkgs.nginx.override {
|
nginxWithRTMP = pkgs.nginx.override {
|
||||||
modules = [ pkgs.nginxModules.rtmp ];
|
modules = [ pkgs.nginxModules.rtmp ];
|
||||||
};
|
};
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.services.nginx.stream = {
|
options.services.nginx.stream = {
|
||||||
enable = lib.mkEnableOption "enable nginx rtmp/hls/dash video streaming";
|
enable = lib.mkEnableOption "enable nginx rtmp/hls/dash video streaming";
|
||||||
port = lib.mkOption {
|
port = lib.mkOption {
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.nginx;
|
cfg = config.services.nginx;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
recommendedGzipSettings = true;
|
recommendedGzipSettings = true;
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ with lib;
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.owncast;
|
cfg = config.services.owncast;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.services.owncast = {
|
options.services.owncast = {
|
||||||
hostname = lib.mkOption {
|
hostname = lib.mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ let
|
|||||||
cp -ar $src $out
|
cp -ar $src $out
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.services.privatebin = {
|
options.services.privatebin = {
|
||||||
enable = lib.mkEnableOption "enable privatebin";
|
enable = lib.mkEnableOption "enable privatebin";
|
||||||
host = lib.mkOption {
|
host = lib.mkOption {
|
||||||
@@ -30,7 +31,7 @@ in {
|
|||||||
group = "privatebin";
|
group = "privatebin";
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
};
|
};
|
||||||
users.groups.privatebin = {};
|
users.groups.privatebin = { };
|
||||||
|
|
||||||
services.nginx.enable = true;
|
services.nginx.enable = true;
|
||||||
services.nginx.virtualHosts.${cfg.host} = {
|
services.nginx.virtualHosts.${cfg.host} = {
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
let
|
let
|
||||||
cfg = config.services.radio;
|
cfg = config.services.radio;
|
||||||
radioPackage = config.inputs.radio.packages.${config.currentSystem}.radio;
|
radioPackage = config.inputs.radio.packages.${config.currentSystem}.radio;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.services.radio = {
|
options.services.radio = {
|
||||||
enable = lib.mkEnableOption "enable radio";
|
enable = lib.mkEnableOption "enable radio";
|
||||||
user = lib.mkOption {
|
user = lib.mkOption {
|
||||||
@@ -56,11 +57,11 @@ in {
|
|||||||
home = cfg.dataDir;
|
home = cfg.dataDir;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
};
|
};
|
||||||
users.groups.${cfg.group} = {};
|
users.groups.${cfg.group} = { };
|
||||||
systemd.services.radio = {
|
systemd.services.radio = {
|
||||||
enable = true;
|
enable = true;
|
||||||
after = ["network.target"];
|
after = [ "network.target" ];
|
||||||
wantedBy = ["multi-user.target"];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig.ExecStart = "${radioPackage}/bin/radio ${config.services.icecast.listen.address}:${toString config.services.icecast.listen.port} ${config.services.icecast.mount} 5500";
|
serviceConfig.ExecStart = "${radioPackage}/bin/radio ${config.services.icecast.listen.address}:${toString config.services.icecast.listen.port} ${config.services.icecast.mount} 5500";
|
||||||
serviceConfig.User = cfg.user;
|
serviceConfig.User = cfg.user;
|
||||||
serviceConfig.Group = cfg.group;
|
serviceConfig.Group = cfg.group;
|
||||||
|
|||||||
@@ -25,9 +25,7 @@
|
|||||||
printing = cups
|
printing = cups
|
||||||
printcap name = cups
|
printcap name = cups
|
||||||
|
|
||||||
# horrible files
|
hide files = /.nobackup/.DS_Store/._.DS_Store/
|
||||||
veto files = /._*/.DS_Store/ /._*/._.DS_Store/
|
|
||||||
delete veto files = yes
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
shares = {
|
shares = {
|
||||||
@@ -77,6 +75,13 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# backups
|
||||||
|
backup.group."samba".paths = [
|
||||||
|
config.services.samba.shares.googlebot.path
|
||||||
|
config.services.samba.shares.cris.path
|
||||||
|
config.services.samba.shares.public.path
|
||||||
|
];
|
||||||
|
|
||||||
# Windows discovery of samba server
|
# Windows discovery of samba server
|
||||||
services.samba-wsdd = {
|
services.samba-wsdd = {
|
||||||
enable = true;
|
enable = true;
|
||||||
@@ -92,7 +97,7 @@
|
|||||||
# Printer discovery
|
# Printer discovery
|
||||||
# (is this needed?)
|
# (is this needed?)
|
||||||
services.avahi.enable = true;
|
services.avahi.enable = true;
|
||||||
services.avahi.nssmdns = true;
|
services.avahi.nssmdns4 = true;
|
||||||
|
|
||||||
# printer sharing
|
# printer sharing
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
@@ -110,6 +115,6 @@
|
|||||||
# samba user for share
|
# samba user for share
|
||||||
users.users.cris.isSystemUser = true;
|
users.users.cris.isSystemUser = true;
|
||||||
users.users.cris.group = "cris";
|
users.users.cris.group = "cris";
|
||||||
users.groups.cris = {};
|
users.groups.cris = { };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -2,19 +2,20 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.searx;
|
cfg = config.services.searx;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
services.searx = {
|
services.searx = {
|
||||||
environmentFile = "/run/agenix/searx";
|
environmentFile = "/run/agenix/searx";
|
||||||
settings = {
|
settings = {
|
||||||
server.port = 43254;
|
server.port = 43254;
|
||||||
server.secret_key = "@SEARX_SECRET_KEY@";
|
server.secret_key = "@SEARX_SECRET_KEY@";
|
||||||
engines = [ {
|
engines = [{
|
||||||
name = "wolframalpha";
|
name = "wolframalpha";
|
||||||
shortcut = "wa";
|
shortcut = "wa";
|
||||||
api_key = "@WOLFRAM_API_KEY@";
|
api_key = "@WOLFRAM_API_KEY@";
|
||||||
engine = "wolframalpha_api";
|
engine = "wolframalpha_api";
|
||||||
} ];
|
}];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
services.nginx.virtualHosts."search.neet.space" = {
|
services.nginx.virtualHosts."search.neet.space" = {
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.thelounge;
|
cfg = config.services.thelounge;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.services.thelounge = {
|
options.services.thelounge = {
|
||||||
fileUploadBaseUrl = lib.mkOption {
|
fileUploadBaseUrl = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
@@ -28,7 +29,7 @@ in {
|
|||||||
reverseProxy = true;
|
reverseProxy = true;
|
||||||
maxHistory = -1;
|
maxHistory = -1;
|
||||||
https.enable = false;
|
https.enable = false;
|
||||||
# theme = "thelounge-theme-solarized";
|
# theme = "thelounge-theme-solarized";
|
||||||
prefetch = false;
|
prefetch = false;
|
||||||
prefetchStorage = false;
|
prefetchStorage = false;
|
||||||
fileUpload = {
|
fileUpload = {
|
||||||
@@ -42,6 +43,10 @@ in {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
backup.group."thelounge".paths = [
|
||||||
|
"/var/lib/thelounge/"
|
||||||
|
];
|
||||||
|
|
||||||
# the lounge client
|
# the lounge client
|
||||||
services.nginx.virtualHosts.${cfg.host} = {
|
services.nginx.virtualHosts.${cfg.host} = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
networking.firewall.allowedUDPPorts = [ rtp-port ];
|
networking.firewall.allowedUDPPorts = [ rtp-port ];
|
||||||
networking.firewall.allowedTCPPortRanges = [ {
|
networking.firewall.allowedTCPPortRanges = [{
|
||||||
from = webrtc-peer-lower-port;
|
from = webrtc-peer-lower-port;
|
||||||
to = webrtc-peer-upper-port;
|
to = webrtc-peer-upper-port;
|
||||||
} ];
|
}];
|
||||||
networking.firewall.allowedUDPPortRanges = [ {
|
networking.firewall.allowedUDPPortRanges = [{
|
||||||
from = webrtc-peer-lower-port;
|
from = webrtc-peer-lower-port;
|
||||||
to = webrtc-peer-upper-port;
|
to = webrtc-peer-upper-port;
|
||||||
} ];
|
}];
|
||||||
|
|
||||||
virtualisation.docker.enable = true;
|
virtualisation.docker.enable = true;
|
||||||
|
|
||||||
@@ -49,12 +49,12 @@ in
|
|||||||
ports = [
|
ports = [
|
||||||
"${toStr ingest-port}:8084"
|
"${toStr ingest-port}:8084"
|
||||||
];
|
];
|
||||||
# imageFile = pkgs.dockerTools.pullImage {
|
# imageFile = pkgs.dockerTools.pullImage {
|
||||||
# imageName = "projectlightspeed/ingest";
|
# imageName = "projectlightspeed/ingest";
|
||||||
# finalImageTag = "version-0.1.4";
|
# finalImageTag = "version-0.1.4";
|
||||||
# imageDigest = "sha256:9fc51833b7c27a76d26e40f092b9cec1ac1c4bfebe452e94ad3269f1f73ff2fc";
|
# imageDigest = "sha256:9fc51833b7c27a76d26e40f092b9cec1ac1c4bfebe452e94ad3269f1f73ff2fc";
|
||||||
# sha256 = "19kxl02x0a3i6hlnsfcm49hl6qxnq2f3hfmyv1v8qdaz58f35kd5";
|
# sha256 = "19kxl02x0a3i6hlnsfcm49hl6qxnq2f3hfmyv1v8qdaz58f35kd5";
|
||||||
# };
|
# };
|
||||||
};
|
};
|
||||||
"lightspeed-react" = {
|
"lightspeed-react" = {
|
||||||
workdir = "/var/lib/lightspeed-react";
|
workdir = "/var/lib/lightspeed-react";
|
||||||
@@ -62,12 +62,12 @@ in
|
|||||||
ports = [
|
ports = [
|
||||||
"${toStr web-port}:80"
|
"${toStr web-port}:80"
|
||||||
];
|
];
|
||||||
# imageFile = pkgs.dockerTools.pullImage {
|
# imageFile = pkgs.dockerTools.pullImage {
|
||||||
# imageName = "projectlightspeed/react";
|
# imageName = "projectlightspeed/react";
|
||||||
# finalImageTag = "version-0.1.3";
|
# finalImageTag = "version-0.1.3";
|
||||||
# imageDigest = "sha256:b7c58425f1593f7b4304726b57aa399b6e216e55af9c0962c5c19333fae638b6";
|
# imageDigest = "sha256:b7c58425f1593f7b4304726b57aa399b6e216e55af9c0962c5c19333fae638b6";
|
||||||
# sha256 = "0d2jh7mr20h7dxgsp7ml7cw2qd4m8ja9rj75dpy59zyb6v0bn7js";
|
# sha256 = "0d2jh7mr20h7dxgsp7ml7cw2qd4m8ja9rj75dpy59zyb6v0bn7js";
|
||||||
# };
|
# };
|
||||||
};
|
};
|
||||||
"lightspeed-webrtc" = {
|
"lightspeed-webrtc" = {
|
||||||
workdir = "/var/lib/lightspeed-webrtc";
|
workdir = "/var/lib/lightspeed-webrtc";
|
||||||
@@ -79,15 +79,18 @@ in
|
|||||||
"${toStr webrtc-peer-lower-port}-${toStr webrtc-peer-upper-port}:${toStr webrtc-peer-lower-port}-${toStr webrtc-peer-upper-port}/udp"
|
"${toStr webrtc-peer-lower-port}-${toStr webrtc-peer-upper-port}:${toStr webrtc-peer-lower-port}-${toStr webrtc-peer-upper-port}/udp"
|
||||||
];
|
];
|
||||||
cmd = [
|
cmd = [
|
||||||
"lightspeed-webrtc" "--addr=0.0.0.0" "--ip=${domain}"
|
"lightspeed-webrtc"
|
||||||
"--ports=${toStr webrtc-peer-lower-port}-${toStr webrtc-peer-upper-port}" "run"
|
"--addr=0.0.0.0"
|
||||||
|
"--ip=${domain}"
|
||||||
|
"--ports=${toStr webrtc-peer-lower-port}-${toStr webrtc-peer-upper-port}"
|
||||||
|
"run"
|
||||||
];
|
];
|
||||||
# imageFile = pkgs.dockerTools.pullImage {
|
# imageFile = pkgs.dockerTools.pullImage {
|
||||||
# imageName = "projectlightspeed/webrtc";
|
# imageName = "projectlightspeed/webrtc";
|
||||||
# finalImageTag = "version-0.1.2";
|
# finalImageTag = "version-0.1.2";
|
||||||
# imageDigest = "sha256:ddf8b3dd294485529ec11d1234a3fc38e365a53c4738998c6bc2c6930be45ecf";
|
# imageDigest = "sha256:ddf8b3dd294485529ec11d1234a3fc38e365a53c4738998c6bc2c6930be45ecf";
|
||||||
# sha256 = "1bdy4ak99fjdphj5bsk8rp13xxmbqdhfyfab14drbyffivg9ad2i";
|
# sha256 = "1bdy4ak99fjdphj5bsk8rp13xxmbqdhfyfab14drbyffivg9ad2i";
|
||||||
# };
|
# };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import ./module.nix ({ name, description, serviceConfig }:
|
import ./module.nix ({ name, description, serviceConfig }:
|
||||||
|
|
||||||
{
|
{
|
||||||
systemd.user.services.${name} = {
|
systemd.user.services.${name} = {
|
||||||
inherit description serviceConfig;
|
inherit description serviceConfig;
|
||||||
wantedBy = [ "default.target" ];
|
wantedBy = [ "default.target" ];
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import ./module.nix ({ name, description, serviceConfig }:
|
import ./module.nix ({ name, description, serviceConfig }:
|
||||||
|
|
||||||
{
|
{
|
||||||
systemd.user.services.${name} = {
|
systemd.user.services.${name} = {
|
||||||
Unit = {
|
Unit = {
|
||||||
Description = description;
|
Description = description;
|
||||||
};
|
};
|
||||||
|
|
||||||
Service = serviceConfig;
|
Service = serviceConfig;
|
||||||
|
|
||||||
Install = {
|
Install = {
|
||||||
WantedBy = [ "default.target" ];
|
WantedBy = [ "default.target" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
})
|
||||||
})
|
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.zerobin;
|
cfg = config.services.zerobin;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.services.zerobin = {
|
options.services.zerobin = {
|
||||||
host = lib.mkOption {
|
host = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
shellInit = ''
|
shellInit = ''
|
||||||
# disable annoying fish shell greeting
|
# disable annoying fish shell greeting
|
||||||
set fish_greeting
|
set fish_greeting
|
||||||
|
|
||||||
|
alias sudo="doas"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -28,10 +30,12 @@
|
|||||||
myip = "dig +short myip.opendns.com @resolver1.opendns.com";
|
myip = "dig +short myip.opendns.com @resolver1.opendns.com";
|
||||||
|
|
||||||
# https://linuxreviews.org/HOWTO_Test_Disk_I/O_Performance
|
# https://linuxreviews.org/HOWTO_Test_Disk_I/O_Performance
|
||||||
io_seq_read = "nix run nixpkgs#fio -- --name TEST --eta-newline=5s --filename=temp.file --rw=read --size=2g --io_size=10g --blocksize=1024k --ioengine=libaio --fsync=10000 --iodepth=32 --direct=1 --numjobs=1 --runtime=60 --group_reporting; rm temp.file";
|
io_seq_read = "${pkgs.fio}/bin/fio --name TEST --eta-newline=5s --filename=temp.file --rw=read --size=2g --io_size=10g --blocksize=1024k --ioengine=libaio --fsync=10000 --iodepth=32 --direct=1 --numjobs=1 --runtime=60 --group_reporting; rm temp.file";
|
||||||
io_seq_write = "nix run nixpkgs#fio -- --name TEST --eta-newline=5s --filename=temp.file --rw=write --size=2g --io_size=10g --blocksize=1024k --ioengine=libaio --fsync=10000 --iodepth=32 --direct=1 --numjobs=1 --runtime=60 --group_reporting; rm temp.file";
|
io_seq_write = "${pkgs.fio}/bin/fio --name TEST --eta-newline=5s --filename=temp.file --rw=write --size=2g --io_size=10g --blocksize=1024k --ioengine=libaio --fsync=10000 --iodepth=32 --direct=1 --numjobs=1 --runtime=60 --group_reporting; rm temp.file";
|
||||||
io_rand_read = "nix run nixpkgs#fio -- --name TEST --eta-newline=5s --filename=temp.file --rw=randread --size=2g --io_size=10g --blocksize=4k --ioengine=libaio --fsync=1 --iodepth=1 --direct=1 --numjobs=32 --runtime=60 --group_reporting; rm temp.file";
|
io_rand_read = "${pkgs.fio}/bin/fio --name TEST --eta-newline=5s --filename=temp.file --rw=randread --size=2g --io_size=10g --blocksize=4k --ioengine=libaio --fsync=1 --iodepth=1 --direct=1 --numjobs=32 --runtime=60 --group_reporting; rm temp.file";
|
||||||
io_rand_write = "nix run nixpkgs#fio -- --name TEST --eta-newline=5s --filename=temp.file --rw=randrw --size=2g --io_size=10g --blocksize=4k --ioengine=libaio --fsync=1 --iodepth=1 --direct=1 --numjobs=1 --runtime=60 --group_reporting; rm temp.file";
|
io_rand_write = "${pkgs.fio}/bin/fio --name TEST --eta-newline=5s --filename=temp.file --rw=randrw --size=2g --io_size=10g --blocksize=4k --ioengine=libaio --fsync=1 --iodepth=1 --direct=1 --numjobs=1 --runtime=60 --group_reporting; rm temp.file";
|
||||||
|
|
||||||
|
llsblk = "lsblk -o +uuid,fsType";
|
||||||
};
|
};
|
||||||
|
|
||||||
nixpkgs.overlays = [
|
nixpkgs.overlays = [
|
||||||
|
|||||||
@@ -1,40 +1,38 @@
|
|||||||
rec {
|
{ config, lib, pkgs, ... }:
|
||||||
users = [
|
|
||||||
|
{
|
||||||
|
programs.ssh.knownHosts = lib.filterAttrs (n: v: v != null) (lib.concatMapAttrs
|
||||||
|
(host: cfg: {
|
||||||
|
${host} = {
|
||||||
|
hostNames = cfg.hostNames;
|
||||||
|
publicKey = cfg.hostKey;
|
||||||
|
};
|
||||||
|
"${host}-remote-unlock" =
|
||||||
|
if cfg.remoteUnlock != null then {
|
||||||
|
hostNames = builtins.filter (h: h != null) [ cfg.remoteUnlock.clearnetHost cfg.remoteUnlock.onionHost ];
|
||||||
|
publicKey = cfg.remoteUnlock.hostKey;
|
||||||
|
} else null;
|
||||||
|
})
|
||||||
|
config.machines.hosts);
|
||||||
|
|
||||||
|
# prebuilt cmds for easy ssh LUKS unlock
|
||||||
|
environment.shellAliases =
|
||||||
|
let
|
||||||
|
unlockHosts = unlockType: lib.concatMapAttrs
|
||||||
|
(host: cfg:
|
||||||
|
if cfg.remoteUnlock != null && cfg.remoteUnlock.${unlockType} != null then {
|
||||||
|
${host} = cfg.remoteUnlock.${unlockType};
|
||||||
|
} else { })
|
||||||
|
config.machines.hosts;
|
||||||
|
in
|
||||||
|
lib.concatMapAttrs (host: addr: { "unlock-over-tor_${host}" = "torsocks ssh root@${addr}"; }) (unlockHosts "onionHost")
|
||||||
|
//
|
||||||
|
lib.concatMapAttrs (host: addr: { "unlock_${host}" = "ssh root@${addr}"; }) (unlockHosts "clearnetHost");
|
||||||
|
|
||||||
|
# TODO: Old ssh keys I will remove some day...
|
||||||
|
machines.ssh.userKeys = [
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMVR/R3ZOsv7TZbICGBCHdjh1NDT8SnswUyINeJOC7QG"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMVR/R3ZOsv7TZbICGBCHdjh1NDT8SnswUyINeJOC7QG"
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE0dcqL/FhHmv+a1iz3f9LJ48xubO7MZHy35rW9SZOYM"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE0dcqL/FhHmv+a1iz3f9LJ48xubO7MZHy35rW9SZOYM"
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHSkKiRUUmnErOKGx81nyge/9KqjkPh8BfDk0D3oP586" # nat
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHSkKiRUUmnErOKGx81nyge/9KqjkPh8BfDk0D3oP586" # nat
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFeTK1iARlNIKP/DS8/ObBm9yUM/3L1Ub4XI5A2r9OzP" # ray
|
|
||||||
] ++ higherTrustUserKeys;
|
|
||||||
system = {
|
|
||||||
ponyo = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMBBlTAIp38RhErU1wNNV5MBeb+WGH0mhF/dxh5RsAXN";
|
|
||||||
ponyo-unlock = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC9LQuuImgWlkjDhEEIbM1wOd+HqRv1RxvYZuLXPSdRi";
|
|
||||||
ray = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDQM8hwKRgl8cZj7UVYATSLYu4LhG7I0WFJ9m2iWowiB";
|
|
||||||
router = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFr2IHmWFlaLaLp5dGoSmFEYKA/eg2SwGXAogaOmLsHL";
|
|
||||||
router-unlock = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJOw5dTPmtKqiPBH6VKyz5MYBubn8leAh5Eaw7s/O85c";
|
|
||||||
s0 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAwiXcUFtAvZCayhu4+AIcF+Ktrdgv9ee/mXSIhJbp4q";
|
|
||||||
s0-unlock = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFNiceeFMos5ZXcYem4yFxh8PiZNNnuvhlyLbQLrgIZH";
|
|
||||||
};
|
|
||||||
|
|
||||||
higherTrustUserKeys = [
|
|
||||||
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIEaGIwLiUa6wQLlEF+keQOIYy/tCmJvV6eENzUQjSqW2AAAABHNzaDo=" # ray fido
|
|
||||||
];
|
|
||||||
|
|
||||||
# groups
|
|
||||||
systems = with system; [
|
|
||||||
ponyo
|
|
||||||
ray
|
|
||||||
router
|
|
||||||
s0
|
|
||||||
];
|
|
||||||
personal = with system; [
|
|
||||||
ray
|
|
||||||
];
|
|
||||||
servers = with system; [
|
|
||||||
ponyo
|
|
||||||
router
|
|
||||||
s0
|
|
||||||
];
|
|
||||||
storage = with system; [
|
|
||||||
s0
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
209
flake.lock
generated
209
flake.lock
generated
@@ -3,16 +3,20 @@
|
|||||||
"agenix": {
|
"agenix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"darwin": "darwin",
|
"darwin": "darwin",
|
||||||
|
"home-manager": "home-manager",
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"systems": [
|
||||||
|
"systems"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1675176355,
|
"lastModified": 1716561646,
|
||||||
"narHash": "sha256-Qjxh5cmN56siY97mzmBLI1+cdjXSPqmfPVsKxBvHmwI=",
|
"narHash": "sha256-UIGtLO89RxKt7RF2iEgPikSdU53r6v/6WYB0RW3k89I=",
|
||||||
"owner": "ryantm",
|
"owner": "ryantm",
|
||||||
"repo": "agenix",
|
"repo": "agenix",
|
||||||
"rev": "b7ffcfe77f817d9ee992640ba1f270718d197f28",
|
"rev": "c2fc0762bbe8feb06a2e59a364fa81b3a57671c9",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -21,27 +25,34 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"archivebox": {
|
"attic": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
|
"crane": "crane",
|
||||||
|
"flake-compat": [
|
||||||
|
"flake-compat"
|
||||||
|
],
|
||||||
"flake-utils": [
|
"flake-utils": [
|
||||||
"flake-utils"
|
"flake-utils"
|
||||||
],
|
],
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"nixpkgs-stable": [
|
||||||
|
"nixpkgs"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1648612759,
|
"lastModified": 1717279440,
|
||||||
"narHash": "sha256-SJwlpD2Wz3zFoX2mIYCQfwIOYHaOdeiWGFeDXsLGM84=",
|
"narHash": "sha256-kH04ReTjxOpQumgWnqy40vvQLSnLGxWP6RF3nq5Esrk=",
|
||||||
"ref": "refs/heads/master",
|
"owner": "zhaofengli",
|
||||||
"rev": "39d338b9b24159d8ef3309eecc0d32a2a9f102b5",
|
"repo": "attic",
|
||||||
"revCount": 2,
|
"rev": "717cc95983cdc357bc347d70be20ced21f935843",
|
||||||
"type": "git",
|
"type": "github"
|
||||||
"url": "https://git.neet.dev/zuckerberg/archivebox.git"
|
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"type": "git",
|
"owner": "zhaofengli",
|
||||||
"url": "https://git.neet.dev/zuckerberg/archivebox.git"
|
"repo": "attic",
|
||||||
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"blobs": {
|
"blobs": {
|
||||||
@@ -60,6 +71,27 @@
|
|||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"crane": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"attic",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1717025063,
|
||||||
|
"narHash": "sha256-dIubLa56W9sNNz0e8jGxrX3CAkPXsq7snuFA/Ie6dn8=",
|
||||||
|
"owner": "ipetkov",
|
||||||
|
"repo": "crane",
|
||||||
|
"rev": "480dff0be03dac0e51a8dfc26e882b0d123a450e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "ipetkov",
|
||||||
|
"repo": "crane",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dailybuild_modules": {
|
"dailybuild_modules": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": [
|
"flake-utils": [
|
||||||
@@ -76,11 +108,11 @@
|
|||||||
"rev": "1290ddd9a2ff2bf2d0f702750768312b80efcd34",
|
"rev": "1290ddd9a2ff2bf2d0f702750768312b80efcd34",
|
||||||
"revCount": 19,
|
"revCount": 19,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.neet.dev/zuckerberg/dailybuild_modules.git"
|
"url": "https://git.neet.dev/zuckerberg/dailybot.git"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.neet.dev/zuckerberg/dailybuild_modules.git"
|
"url": "https://git.neet.dev/zuckerberg/dailybot.git"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"darwin": {
|
"darwin": {
|
||||||
@@ -91,11 +123,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1673295039,
|
"lastModified": 1700795494,
|
||||||
"narHash": "sha256-AsdYgE8/GPwcelGgrntlijMg4t3hLFJFCRF3tL5WVjA=",
|
"narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=",
|
||||||
"owner": "lnl7",
|
"owner": "lnl7",
|
||||||
"repo": "nix-darwin",
|
"repo": "nix-darwin",
|
||||||
"rev": "87b9d090ad39b25b2400029c64825fc2a8868943",
|
"rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -107,21 +139,22 @@
|
|||||||
},
|
},
|
||||||
"deploy-rs": {
|
"deploy-rs": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-compat": "flake-compat",
|
"flake-compat": [
|
||||||
|
"flake-compat"
|
||||||
|
],
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
"utils": [
|
"utils": [
|
||||||
"simple-nixos-mailserver",
|
"flake-utils"
|
||||||
"utils"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1674127017,
|
"lastModified": 1718194053,
|
||||||
"narHash": "sha256-QO1xF7stu5ZMDLbHN30LFolMAwY6TVlzYvQoUs1RD68=",
|
"narHash": "sha256-FaGrf7qwZ99ehPJCAwgvNY5sLCqQ3GDiE/6uLhxxwSY=",
|
||||||
"owner": "serokell",
|
"owner": "serokell",
|
||||||
"repo": "deploy-rs",
|
"repo": "deploy-rs",
|
||||||
"rev": "8c9ea9605eed20528bf60fae35a2b613b901fd77",
|
"rev": "3867348fa92bc892eba5d9ddb2d7a97b9e127a8a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -133,11 +166,11 @@
|
|||||||
"flake-compat": {
|
"flake-compat": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1668681692,
|
"lastModified": 1696426674,
|
||||||
"narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=",
|
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||||
"owner": "edolstra",
|
"owner": "edolstra",
|
||||||
"repo": "flake-compat",
|
"repo": "flake-compat",
|
||||||
"rev": "009399224d5e398d03b22badca40a37ac85412a1",
|
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -147,12 +180,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-utils": {
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": [
|
||||||
|
"systems"
|
||||||
|
]
|
||||||
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1667395993,
|
"lastModified": 1710146030,
|
||||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "flake-utils",
|
"repo": "flake-utils",
|
||||||
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -161,6 +199,27 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"home-manager": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"agenix",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1703113217,
|
||||||
|
"narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nix-index-database": {
|
"nix-index-database": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -168,11 +227,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1677382901,
|
"lastModified": 1716772633,
|
||||||
"narHash": "sha256-2idFWlTVG+qUZkU2/W50amGSIxmN56igIkMAXKbv4S4=",
|
"narHash": "sha256-Idcye44UW+EgjbjCoklf2IDF+XrehV6CVYvxR1omst4=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "nix-index-database",
|
"repo": "nix-index-database",
|
||||||
"rev": "4306fa7c12e098360439faac1a2e6b8e509ec97c",
|
"rev": "ff80cb4a11bb87f3ce8459be6f16a25ac86eb2ac",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -181,35 +240,52 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixos-hardware": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1677823547,
|
"lastModified": 1717248095,
|
||||||
"narHash": "sha256-xD2qco8Pw8HAXgjf9OSi2H2N20WaTrtvgcl21525kVE=",
|
"narHash": "sha256-e8X2eWjAHJQT82AAN+mCI0B68cIDBJpqJ156+VRrFO0=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixos-hardware",
|
||||||
"rev": "78c4d33c16092e535bc4ba1284ba49e3e138483a",
|
"rev": "7b49d3967613d9aacac5b340ef158d493906ba79",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"ref": "master",
|
"ref": "master",
|
||||||
|
"repo": "nixos-hardware",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1717144377,
|
||||||
|
"narHash": "sha256-F/TKWETwB5RaR8owkPPi+SPJh83AQsm6KrQAlJ8v/uA=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "805a384895c696f802a9bf5bf4720f37385df547",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-24.05",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs-22_05": {
|
"nixpkgs-frigate": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1654936503,
|
"lastModified": 1695825837,
|
||||||
"narHash": "sha256-soKzdhI4jTHv/rSbh89RdlcJmrPgH8oMb/PLqiqIYVQ=",
|
"narHash": "sha256-4Ne11kNRnQsmSJCRSSNkFRSnHC4Y5gPDBIQGjjPfJiU=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "dab6df51387c3878cdea09f43589a15729cae9f4",
|
"rev": "5cfafa12d57374f48bcc36fda3274ada276cf69e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"id": "nixpkgs",
|
"owner": "NixOS",
|
||||||
"ref": "nixos-22.05",
|
"repo": "nixpkgs",
|
||||||
"type": "indirect"
|
"rev": "5cfafa12d57374f48bcc36fda3274ada276cf69e",
|
||||||
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"radio": {
|
"radio": {
|
||||||
@@ -256,53 +332,64 @@
|
|||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"agenix": "agenix",
|
"agenix": "agenix",
|
||||||
"archivebox": "archivebox",
|
"attic": "attic",
|
||||||
"dailybuild_modules": "dailybuild_modules",
|
"dailybuild_modules": "dailybuild_modules",
|
||||||
"deploy-rs": "deploy-rs",
|
"deploy-rs": "deploy-rs",
|
||||||
|
"flake-compat": "flake-compat",
|
||||||
"flake-utils": "flake-utils",
|
"flake-utils": "flake-utils",
|
||||||
"nix-index-database": "nix-index-database",
|
"nix-index-database": "nix-index-database",
|
||||||
|
"nixos-hardware": "nixos-hardware",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
|
"nixpkgs-frigate": "nixpkgs-frigate",
|
||||||
"radio": "radio",
|
"radio": "radio",
|
||||||
"radio-web": "radio-web",
|
"radio-web": "radio-web",
|
||||||
"simple-nixos-mailserver": "simple-nixos-mailserver"
|
"simple-nixos-mailserver": "simple-nixos-mailserver",
|
||||||
|
"systems": "systems"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"simple-nixos-mailserver": {
|
"simple-nixos-mailserver": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"blobs": "blobs",
|
"blobs": "blobs",
|
||||||
|
"flake-compat": [
|
||||||
|
"flake-compat"
|
||||||
|
],
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
"nixpkgs-22_05": "nixpkgs-22_05",
|
"nixpkgs-24_05": [
|
||||||
"utils": "utils"
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"utils": [
|
||||||
|
"flake-utils"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1655930346,
|
"lastModified": 1718084203,
|
||||||
"narHash": "sha256-ht56HHOzEhjeIgAv5ZNFjSVX/in1YlUs0HG9c1EUXTM=",
|
"narHash": "sha256-Cx1xoVfSMv1XDLgKg08CUd1EoTYWB45VmB9XIQzhmzI=",
|
||||||
"owner": "simple-nixos-mailserver",
|
"owner": "simple-nixos-mailserver",
|
||||||
"repo": "nixos-mailserver",
|
"repo": "nixos-mailserver",
|
||||||
"rev": "f535d8123c4761b2ed8138f3d202ea710a334a1d",
|
"rev": "29916981e7b3b5782dc5085ad18490113f8ff63b",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "simple-nixos-mailserver",
|
"owner": "simple-nixos-mailserver",
|
||||||
"ref": "nixos-22.05",
|
"ref": "master",
|
||||||
"repo": "nixos-mailserver",
|
"repo": "nixos-mailserver",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"utils": {
|
"systems": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1605370193,
|
"lastModified": 1681028828,
|
||||||
"narHash": "sha256-YyMTf3URDL/otKdKgtoMChu4vfVL3vCMkRqpGifhUn0=",
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
"owner": "numtide",
|
"owner": "nix-systems",
|
||||||
"repo": "flake-utils",
|
"repo": "default",
|
||||||
"rev": "5021eac20303a61fafe17224c087f5519baed54d",
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "numtide",
|
"owner": "nix-systems",
|
||||||
"repo": "flake-utils",
|
"repo": "default",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
289
flake.nix
289
flake.nix
@@ -1,132 +1,199 @@
|
|||||||
{
|
{
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/master";
|
# nixpkgs
|
||||||
# nixpkgs-patch-howdy.url = "https://github.com/NixOS/nixpkgs/pull/216245.diff";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
|
||||||
# nixpkgs-patch-howdy.flake = false;
|
nixpkgs-frigate.url = "github:NixOS/nixpkgs/5cfafa12d57374f48bcc36fda3274ada276cf69e";
|
||||||
|
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
# Common Utils Among flake inputs
|
||||||
|
systems.url = "github:nix-systems/default";
|
||||||
|
flake-utils = {
|
||||||
|
url = "github:numtide/flake-utils";
|
||||||
|
inputs.systems.follows = "systems";
|
||||||
|
};
|
||||||
|
flake-compat = {
|
||||||
|
url = "github:edolstra/flake-compat";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
|
||||||
# mail server
|
# NixOS hardware
|
||||||
simple-nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver/nixos-22.05";
|
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
||||||
simple-nixos-mailserver.inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
|
|
||||||
# agenix
|
# Mail Server
|
||||||
agenix.url = "github:ryantm/agenix";
|
simple-nixos-mailserver = {
|
||||||
agenix.inputs.nixpkgs.follows = "nixpkgs";
|
url = "gitlab:simple-nixos-mailserver/nixos-mailserver/master";
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.follows = "nixpkgs";
|
||||||
|
nixpkgs-24_05.follows = "nixpkgs";
|
||||||
|
flake-compat.follows = "flake-compat";
|
||||||
|
utils.follows = "flake-utils";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# radio
|
# Agenix
|
||||||
radio.url = "git+https://git.neet.dev/zuckerberg/radio.git?ref=main&rev=5bf607fed977d41a269942a7d1e92f3e6d4f2473";
|
agenix = {
|
||||||
radio.inputs.nixpkgs.follows = "nixpkgs";
|
url = "github:ryantm/agenix";
|
||||||
radio.inputs.flake-utils.follows = "flake-utils";
|
inputs = {
|
||||||
radio-web.url = "git+https://git.neet.dev/zuckerberg/radio-web.git";
|
nixpkgs.follows = "nixpkgs";
|
||||||
radio-web.flake = false;
|
systems.follows = "systems";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# drastikbot
|
# Radio
|
||||||
dailybuild_modules.url = "git+https://git.neet.dev/zuckerberg/dailybuild_modules.git";
|
radio = {
|
||||||
dailybuild_modules.inputs.nixpkgs.follows = "nixpkgs";
|
url = "git+https://git.neet.dev/zuckerberg/radio.git?ref=main&rev=5bf607fed977d41a269942a7d1e92f3e6d4f2473";
|
||||||
dailybuild_modules.inputs.flake-utils.follows = "flake-utils";
|
inputs = {
|
||||||
|
nixpkgs.follows = "nixpkgs";
|
||||||
|
flake-utils.follows = "flake-utils";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
radio-web = {
|
||||||
|
url = "git+https://git.neet.dev/zuckerberg/radio-web.git";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
|
||||||
# archivebox
|
# Dailybot
|
||||||
archivebox.url = "git+https://git.neet.dev/zuckerberg/archivebox.git";
|
dailybuild_modules = {
|
||||||
archivebox.inputs.nixpkgs.follows = "nixpkgs";
|
url = "git+https://git.neet.dev/zuckerberg/dailybot.git";
|
||||||
archivebox.inputs.flake-utils.follows = "flake-utils";
|
inputs = {
|
||||||
|
nixpkgs.follows = "nixpkgs";
|
||||||
|
flake-utils.follows = "flake-utils";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# nixos config deployment
|
# NixOS deployment
|
||||||
deploy-rs.url = "github:serokell/deploy-rs";
|
deploy-rs = {
|
||||||
deploy-rs.inputs.nixpkgs.follows = "nixpkgs";
|
url = "github:serokell/deploy-rs";
|
||||||
deploy-rs.inputs.utils.follows = "simple-nixos-mailserver/utils";
|
inputs = {
|
||||||
|
nixpkgs.follows = "nixpkgs";
|
||||||
|
flake-compat.follows = "flake-compat";
|
||||||
|
utils.follows = "flake-utils";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# prebuilt nix-index database
|
# Prebuilt nix-index database
|
||||||
nix-index-database.url = "github:Mic92/nix-index-database";
|
nix-index-database = {
|
||||||
nix-index-database.inputs.nixpkgs.follows = "nixpkgs";
|
url = "github:Mic92/nix-index-database";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Attic
|
||||||
|
attic = {
|
||||||
|
url = "github:zhaofengli/attic";
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.follows = "nixpkgs";
|
||||||
|
nixpkgs-stable.follows = "nixpkgs";
|
||||||
|
flake-utils.follows = "flake-utils";
|
||||||
|
flake-compat.follows = "flake-compat";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, ... }@inputs: {
|
outputs = { self, nixpkgs, ... }@inputs:
|
||||||
|
|
||||||
nixosConfigurations =
|
|
||||||
let
|
let
|
||||||
modules = system: with inputs; [
|
machines = (import ./common/machine-info/moduleless.nix
|
||||||
./common
|
{
|
||||||
simple-nixos-mailserver.nixosModule
|
inherit nixpkgs;
|
||||||
agenix.nixosModules.default
|
assertionsModule = "${nixpkgs}/nixos/modules/misc/assertions.nix";
|
||||||
dailybuild_modules.nixosModule
|
}).machines.hosts;
|
||||||
archivebox.nixosModule
|
|
||||||
nix-index-database.nixosModules.nix-index
|
|
||||||
({ lib, ... }: {
|
|
||||||
config.environment.systemPackages = [
|
|
||||||
agenix.packages.${system}.agenix
|
|
||||||
];
|
|
||||||
|
|
||||||
# because nixos specialArgs doesn't work for containers... need to pass in inputs a different way
|
|
||||||
options.inputs = lib.mkOption { default = inputs; };
|
|
||||||
options.currentSystem = lib.mkOption { default = system; };
|
|
||||||
})
|
|
||||||
];
|
|
||||||
|
|
||||||
mkSystem = system: nixpkgs: path:
|
|
||||||
let
|
|
||||||
allModules = modules system;
|
|
||||||
|
|
||||||
# allow patching nixpkgs, remove this hack once this is solved: https://github.com/NixOS/nix/issues/3920
|
|
||||||
patchedNixpkgsSrc = nixpkgs.legacyPackages.${system}.applyPatches {
|
|
||||||
name = "nixpkgs-patched";
|
|
||||||
src = nixpkgs;
|
|
||||||
patches = [
|
|
||||||
# inputs.nixpkgs-patch-howdy
|
|
||||||
];
|
|
||||||
};
|
|
||||||
patchedNixpkgs = nixpkgs.lib.fix (self: (import "${patchedNixpkgsSrc}/flake.nix").outputs { self=nixpkgs; });
|
|
||||||
|
|
||||||
in patchedNixpkgs.lib.nixosSystem {
|
|
||||||
inherit system;
|
|
||||||
modules = allModules ++ [path];
|
|
||||||
|
|
||||||
specialArgs = {
|
|
||||||
inherit allModules;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
"ray" = mkSystem "x86_64-linux" nixpkgs ./machines/ray/configuration.nix;
|
nixosConfigurations =
|
||||||
# "nat" = mkSystem "aarch64-linux" nixpkgs ./machines/nat/configuration.nix;
|
let
|
||||||
"ponyo" = mkSystem "x86_64-linux" nixpkgs ./machines/ponyo/configuration.nix;
|
modules = system: hostname: with inputs; [
|
||||||
"router" = mkSystem "x86_64-linux" nixpkgs ./machines/router/configuration.nix;
|
./common
|
||||||
"s0" = mkSystem "x86_64-linux" nixpkgs ./machines/storage/s0/configuration.nix;
|
simple-nixos-mailserver.nixosModule
|
||||||
};
|
agenix.nixosModules.default
|
||||||
|
dailybuild_modules.nixosModule
|
||||||
|
nix-index-database.nixosModules.nix-index
|
||||||
|
attic.nixosModules.atticd
|
||||||
|
self.nixosModules.kernel-modules
|
||||||
|
({ lib, ... }: {
|
||||||
|
config = {
|
||||||
|
nixpkgs.overlays = [ self.overlays.default ];
|
||||||
|
|
||||||
packages = let
|
environment.systemPackages = [
|
||||||
mkKexec = system:
|
agenix.packages.${system}.agenix
|
||||||
(nixpkgs.lib.nixosSystem {
|
];
|
||||||
inherit system;
|
|
||||||
modules = [ ./machines/ephemeral/kexec.nix ];
|
|
||||||
}).config.system.build.kexec_tarball;
|
|
||||||
mkIso = system:
|
|
||||||
(nixpkgs.lib.nixosSystem {
|
|
||||||
inherit system;
|
|
||||||
modules = [ ./machines/ephemeral/iso.nix ];
|
|
||||||
}).config.system.build.isoImage;
|
|
||||||
in {
|
|
||||||
"x86_64-linux"."kexec" = mkKexec "x86_64-linux";
|
|
||||||
"x86_64-linux"."iso" = mkIso "x86_64-linux";
|
|
||||||
"aarch64-linux"."kexec" = mkKexec "aarch64-linux";
|
|
||||||
"aarch64-linux"."iso" = mkIso "aarch64-linux";
|
|
||||||
};
|
|
||||||
|
|
||||||
deploy.nodes =
|
networking.hostName = hostname;
|
||||||
let
|
};
|
||||||
mkDeploy = configName: hostname: {
|
|
||||||
inherit hostname;
|
# because nixos specialArgs doesn't work for containers... need to pass in inputs a different way
|
||||||
magicRollback = false;
|
options.inputs = lib.mkOption { default = inputs; };
|
||||||
sshUser = "root";
|
options.currentSystem = lib.mkOption { default = system; };
|
||||||
profiles.system.path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.${configName};
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
mkSystem = system: nixpkgs: path: hostname:
|
||||||
|
let
|
||||||
|
allModules = modules system hostname;
|
||||||
|
|
||||||
|
# allow patching nixpkgs, remove this hack once this is solved: https://github.com/NixOS/nix/issues/3920
|
||||||
|
patchedNixpkgsSrc = nixpkgs.legacyPackages.${system}.applyPatches {
|
||||||
|
name = "nixpkgs-patched";
|
||||||
|
src = nixpkgs;
|
||||||
|
patches = [
|
||||||
|
./patches/gamepadui.patch
|
||||||
|
];
|
||||||
|
};
|
||||||
|
patchedNixpkgs = nixpkgs.lib.fix (self: (import "${patchedNixpkgsSrc}/flake.nix").outputs { self = nixpkgs; });
|
||||||
|
|
||||||
|
in
|
||||||
|
patchedNixpkgs.lib.nixosSystem {
|
||||||
|
inherit system;
|
||||||
|
modules = allModules ++ [ path ];
|
||||||
|
|
||||||
|
specialArgs = {
|
||||||
|
inherit allModules;
|
||||||
|
lib = self.lib;
|
||||||
|
nixos-hardware = inputs.nixos-hardware;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
nixpkgs.lib.mapAttrs
|
||||||
|
(hostname: cfg:
|
||||||
|
mkSystem cfg.arch nixpkgs cfg.configurationPath hostname)
|
||||||
|
machines;
|
||||||
|
|
||||||
|
packages =
|
||||||
|
let
|
||||||
|
mkKexec = system:
|
||||||
|
(nixpkgs.lib.nixosSystem {
|
||||||
|
inherit system;
|
||||||
|
modules = [ ./machines/ephemeral/kexec.nix ];
|
||||||
|
}).config.system.build.kexec_tarball;
|
||||||
|
mkIso = system:
|
||||||
|
(nixpkgs.lib.nixosSystem {
|
||||||
|
inherit system;
|
||||||
|
modules = [ ./machines/ephemeral/iso.nix ];
|
||||||
|
}).config.system.build.isoImage;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
"x86_64-linux"."kexec" = mkKexec "x86_64-linux";
|
||||||
|
"x86_64-linux"."iso" = mkIso "x86_64-linux";
|
||||||
|
"aarch64-linux"."kexec" = mkKexec "aarch64-linux";
|
||||||
|
"aarch64-linux"."iso" = mkIso "aarch64-linux";
|
||||||
};
|
};
|
||||||
|
|
||||||
in {
|
overlays.default = import ./overlays { inherit inputs; };
|
||||||
s0 = mkDeploy "s0" "s0";
|
nixosModules.kernel-modules = import ./overlays/kernel-modules;
|
||||||
router = mkDeploy "router" "192.168.1.228";
|
|
||||||
ponyo = mkDeploy "ponyo" "ponyo.neet.dev";
|
|
||||||
};
|
|
||||||
|
|
||||||
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) inputs.deploy-rs.lib;
|
deploy.nodes =
|
||||||
};
|
let
|
||||||
|
mkDeploy = configName: arch: hostname: {
|
||||||
|
inherit hostname;
|
||||||
|
magicRollback = false;
|
||||||
|
sshUser = "root";
|
||||||
|
profiles.system.path = inputs.deploy-rs.lib.${arch}.activate.nixos self.nixosConfigurations.${configName};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
nixpkgs.lib.mapAttrs
|
||||||
|
(hostname: cfg:
|
||||||
|
mkDeploy hostname cfg.arch (builtins.head cfg.hostNames))
|
||||||
|
machines;
|
||||||
|
|
||||||
|
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) inputs.deploy-rs.lib;
|
||||||
|
|
||||||
|
lib = nixpkgs.lib.extend (final: prev: import ./lib { lib = nixpkgs.lib; });
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
56
lib/default.nix
Normal file
56
lib/default.nix
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
# Passthrough trace for debugging
|
||||||
|
pTrace = v: traceSeq v v;
|
||||||
|
# find the total sum of a int list
|
||||||
|
sum = foldr (x: y: x + y) 0;
|
||||||
|
# splits a list of length two into two params then they're passed to a func
|
||||||
|
splitPair = f: pair: f (head pair) (last pair);
|
||||||
|
# Finds the max value in a list
|
||||||
|
maxList = foldr max 0;
|
||||||
|
# Sorts a int list. Greatest value first
|
||||||
|
sortList = sort (x: y: x > y);
|
||||||
|
# Cuts a list in half and returns the two parts in a list
|
||||||
|
cutInHalf = l: [ (take (length l / 2) l) (drop (length l / 2) l) ];
|
||||||
|
# Splits a list into a list of lists with length cnt
|
||||||
|
chunksOf = cnt: l:
|
||||||
|
if length l > 0 then
|
||||||
|
[ (take cnt l) ] ++ chunksOf cnt (drop cnt l)
|
||||||
|
else [ ];
|
||||||
|
# same as intersectLists but takes an array of lists to intersect instead of just two
|
||||||
|
intersectManyLists = ll: foldr intersectLists (head ll) ll;
|
||||||
|
# converts a boolean to a int (c style)
|
||||||
|
boolToInt = b: if b then 1 else 0;
|
||||||
|
# drops the last element of a list
|
||||||
|
dropLast = l: take (length l - 1) l;
|
||||||
|
# transposes a matrix
|
||||||
|
transpose = ll:
|
||||||
|
let
|
||||||
|
outerSize = length ll;
|
||||||
|
innerSize = length (elemAt ll 0);
|
||||||
|
in
|
||||||
|
genList (i: genList (j: elemAt (elemAt ll j) i) outerSize) innerSize;
|
||||||
|
# attriset recursiveUpdate but for a list of attrisets
|
||||||
|
combineAttrs = foldl recursiveUpdate { };
|
||||||
|
# visits every single attriset element of an attriset recursively
|
||||||
|
# and accumulates the result of every visit in a flat list
|
||||||
|
recurisveVisitAttrs = f: set:
|
||||||
|
let
|
||||||
|
visitor = n: v:
|
||||||
|
if isAttrs v then [ (f n v) ] ++ recurisveVisitAttrs f v
|
||||||
|
else [ (f n v) ];
|
||||||
|
in
|
||||||
|
concatLists (map (name: visitor name set.${name}) (attrNames set));
|
||||||
|
# merges two lists of the same size (similar to map but both lists are inputs per iteration)
|
||||||
|
mergeLists = f: a: imap0 (i: f (elemAt a i));
|
||||||
|
map2D = f: ll:
|
||||||
|
let
|
||||||
|
outerSize = length ll;
|
||||||
|
innerSize = length (elemAt ll 0);
|
||||||
|
getElem = x: y: elemAt (elemAt ll y) x;
|
||||||
|
in
|
||||||
|
genList (y: genList (x: f x y (getElem x y)) innerSize) outerSize;
|
||||||
|
}
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
#! /usr/bin/env nix-shell
|
|
||||||
#! nix-shell -i bash -p bash
|
|
||||||
|
|
||||||
nix flake update --commit-lock-file
|
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
{ pkgs, modulesPath, ... }:
|
{ config, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(modulesPath + "/installer/cd-dvd/channel.nix")
|
(modulesPath + "/installer/cd-dvd/channel.nix")
|
||||||
|
../../common/machine-info
|
||||||
|
../../common/ssh.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "e1000" "e1000e" "virtio_pci" "r8169" ];
|
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "e1000" "e1000e" "virtio_pci" "r8169" ];
|
||||||
boot.kernelParams = [
|
boot.kernelParams = [
|
||||||
"panic=30" "boot.panic_on_fail" # reboot the machine upon fatal boot issues
|
"panic=30"
|
||||||
|
"boot.panic_on_fail" # reboot the machine upon fatal boot issues
|
||||||
"console=ttyS0,115200" # enable serial console
|
"console=ttyS0,115200" # enable serial console
|
||||||
"console=tty1"
|
"console=tty1"
|
||||||
];
|
];
|
||||||
@@ -15,13 +18,16 @@
|
|||||||
|
|
||||||
boot.kernelPackages = pkgs.linuxPackages_latest;
|
boot.kernelPackages = pkgs.linuxPackages_latest;
|
||||||
|
|
||||||
|
system.stateVersion = "21.11";
|
||||||
|
|
||||||
# hardware.enableAllFirmware = true;
|
# hardware.enableAllFirmware = true;
|
||||||
# nixpkgs.config.allowUnfree = true;
|
# nixpkgs.config.allowUnfree = true;
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
cryptsetup
|
cryptsetup
|
||||||
btrfs-progs
|
btrfs-progs
|
||||||
git git-lfs
|
git
|
||||||
|
git-lfs
|
||||||
wget
|
wget
|
||||||
htop
|
htop
|
||||||
dnsutils
|
dnsutils
|
||||||
@@ -36,10 +42,12 @@
|
|||||||
|
|
||||||
services.openssh = {
|
services.openssh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
challengeResponseAuthentication = false;
|
settings = {
|
||||||
passwordAuthentication = false;
|
KbdInteractiveAuthentication = false;
|
||||||
|
PasswordAuthentication = false;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.getty.autologinUser = "root";
|
services.getty.autologinUser = "root";
|
||||||
users.users.root.openssh.authorizedKeys.keys = (import ../../common/ssh.nix).users;
|
users.users.root.openssh.authorizedKeys.keys = config.machines.ssh.userKeys;
|
||||||
}
|
}
|
||||||
57
machines/ephemeral/sdimg.nix
Normal file
57
machines/ephemeral/sdimg.nix
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
{ config, modulesPath, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
pinecube-uboot = pkgs.buildUBoot {
|
||||||
|
defconfig = "pinecube_defconfig";
|
||||||
|
extraMeta.platforms = [ "armv7l-linux" ];
|
||||||
|
filesToInstall = [ "u-boot-sunxi-with-spl.bin" ];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
(modulesPath + "/installer/sd-card/sd-image.nix")
|
||||||
|
./minimal.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
sdImage.populateFirmwareCommands = "";
|
||||||
|
sdImage.populateRootCommands = ''
|
||||||
|
mkdir -p ./files/boot
|
||||||
|
${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
|
||||||
|
'';
|
||||||
|
sdImage.postBuildCommands = ''
|
||||||
|
dd if=${pinecube-uboot}/u-boot-sunxi-with-spl.bin of=$img bs=1024 seek=8 conv=notrunc
|
||||||
|
'';
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
networking.hostName = "pinecube";
|
||||||
|
|
||||||
|
boot.loader.grub.enable = false;
|
||||||
|
boot.loader.generic-extlinux-compatible.enable = true;
|
||||||
|
boot.consoleLogLevel = 7;
|
||||||
|
|
||||||
|
# cma is 64M by default which is waay too much and we can't even unpack initrd
|
||||||
|
boot.kernelParams = [ "console=ttyS0,115200n8" "cma=32M" ];
|
||||||
|
|
||||||
|
boot.kernelModules = [ "spi-nor" ]; # Not sure why this doesn't autoload. Provides SPI NOR at /dev/mtd0
|
||||||
|
boot.extraModulePackages = [ config.boot.kernelPackages.rtl8189es ];
|
||||||
|
|
||||||
|
zramSwap.enable = true; # 128MB is not much to work with
|
||||||
|
|
||||||
|
sound.enable = true;
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
ffmpeg
|
||||||
|
(v4l_utils.override { withGUI = false; })
|
||||||
|
usbutils
|
||||||
|
];
|
||||||
|
|
||||||
|
services.getty.autologinUser = lib.mkForce "googlebot";
|
||||||
|
users.users.googlebot = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = [ "wheel" "networkmanager" "video" ];
|
||||||
|
openssh.authorizedKeys.keys = config.machines.ssh.userKeys;
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.wireless.enable = true;
|
||||||
|
}
|
||||||
13
machines/howl/default.nix
Normal file
13
machines/howl/default.nix
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./hardware-configuration.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
# don't use remote builders
|
||||||
|
nix.distributedBuilds = lib.mkForce false;
|
||||||
|
|
||||||
|
de.enable = true;
|
||||||
|
de.touchpad.enable = true;
|
||||||
|
}
|
||||||
58
machines/howl/hardware-configuration.nix
Normal file
58
machines/howl/hardware-configuration.nix
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
{ config, lib, pkgs, modulesPath, nixos-hardware, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
nixos-hardware.nixosModules.framework-13-7040-amd
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.kernelPackages = pkgs.linuxPackages_latest;
|
||||||
|
|
||||||
|
hardware.framework.amd-7040.preventWakeOnAC = true;
|
||||||
|
services.fwupd.enable = true;
|
||||||
|
# fingerprint reader has initially shown to be more of a nuisance than a help
|
||||||
|
# it makes sddm log in fail most of the time and take several minutes to finish
|
||||||
|
services.fprintd.enable = false;
|
||||||
|
|
||||||
|
# boot
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "sd_mod" ];
|
||||||
|
boot.initrd.kernelModules = [ "dm-snapshot" ];
|
||||||
|
boot.kernelModules = [ "kvm-amd" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
# thunderbolt
|
||||||
|
services.hardware.bolt.enable = true;
|
||||||
|
|
||||||
|
# firmware
|
||||||
|
firmware.x86_64.enable = true;
|
||||||
|
|
||||||
|
# disks
|
||||||
|
remoteLuksUnlock.enable = true;
|
||||||
|
boot.initrd.luks.devices."enc-pv" = {
|
||||||
|
device = "/dev/disk/by-uuid/c801586b-f0a2-465c-8dae-532e61b83fee";
|
||||||
|
allowDiscards = true;
|
||||||
|
};
|
||||||
|
fileSystems."/" =
|
||||||
|
{
|
||||||
|
device = "/dev/disk/by-uuid/95db6950-a7bc-46cf-9765-3ea675ccf014";
|
||||||
|
fsType = "btrfs";
|
||||||
|
};
|
||||||
|
fileSystems."/boot" =
|
||||||
|
{
|
||||||
|
device = "/dev/disk/by-uuid/B087-2C20";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [ "fmask=0022" "dmask=0022" ];
|
||||||
|
};
|
||||||
|
swapDevices =
|
||||||
|
[{ device = "/dev/disk/by-uuid/49fbdf62-eef4-421b-aac3-c93494afd23c"; }];
|
||||||
|
|
||||||
|
# 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.wlp1s0.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
}
|
||||||
26
machines/howl/properties.nix
Normal file
26
machines/howl/properties.nix
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
hostNames = [
|
||||||
|
"howl"
|
||||||
|
];
|
||||||
|
|
||||||
|
arch = "x86_64-linux";
|
||||||
|
|
||||||
|
systemRoles = [
|
||||||
|
"personal"
|
||||||
|
];
|
||||||
|
|
||||||
|
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEQi3q8jU6vRruExAL60J7GFO1gS8HsmXVJuKRT4ljrG";
|
||||||
|
|
||||||
|
userKeys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKPnLt84bKhUgFxjQf10+Htro9Lo1Pabqm8mGalBUniv"
|
||||||
|
];
|
||||||
|
|
||||||
|
deployKeys = [
|
||||||
|
# TODO
|
||||||
|
];
|
||||||
|
|
||||||
|
remoteUnlock = {
|
||||||
|
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN0N80r0Sl2WlJaUqfxZPkOtYyGumFazkIqq7eq3Gd2o";
|
||||||
|
onionHost = "ll6yjnkh4psmfwmtkmqoutl4gq4elqzbmjxv4s6gpgoavyi3kwhjvnqd.onion";
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -12,12 +12,14 @@
|
|||||||
boot.extraModulePackages = [ ];
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
fileSystems."/" =
|
fileSystems."/" =
|
||||||
{ device = "/dev/disk/by-uuid/02a8c0c7-fd4e-4443-a83c-2d0b63848779";
|
{
|
||||||
|
device = "/dev/disk/by-uuid/02a8c0c7-fd4e-4443-a83c-2d0b63848779";
|
||||||
fsType = "btrfs";
|
fsType = "btrfs";
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/boot" =
|
fileSystems."/boot" =
|
||||||
{ device = "/dev/disk/by-uuid/0C95-1290";
|
{
|
||||||
|
device = "/dev/disk/by-uuid/0C95-1290";
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
9
machines/phil/default.nix
Normal file
9
machines/phil/default.nix
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./hardware-configuration.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.hostName = "phil";
|
||||||
|
}
|
||||||
46
machines/phil/hardware-configuration.nix
Normal file
46
machines/phil/hardware-configuration.nix
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# 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")
|
||||||
|
];
|
||||||
|
|
||||||
|
# because grub just doesn't work for some reason
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
|
||||||
|
remoteLuksUnlock.enable = true;
|
||||||
|
remoteLuksUnlock.enableTorUnlock = false;
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [ "xhci_pci" ];
|
||||||
|
boot.initrd.kernelModules = [ "dm-snapshot" ];
|
||||||
|
boot.kernelModules = [ ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
boot.initrd.luks.devices."enc-pv" = {
|
||||||
|
device = "/dev/disk/by-uuid/d26c1820-4c39-4615-98c2-51442504e194";
|
||||||
|
allowDiscards = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/" =
|
||||||
|
{
|
||||||
|
device = "/dev/disk/by-uuid/851bfde6-93cd-439e-9380-de28aa87eda9";
|
||||||
|
fsType = "btrfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" =
|
||||||
|
{
|
||||||
|
device = "/dev/disk/by-uuid/F185-C4E5";
|
||||||
|
fsType = "vfat";
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices =
|
||||||
|
[{ device = "/dev/disk/by-uuid/d809e3a1-3915-405a-a200-4429c5efdf87"; }];
|
||||||
|
|
||||||
|
networking.interfaces.enp0s6.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
|
||||||
|
}
|
||||||
20
machines/phil/properties.nix
Normal file
20
machines/phil/properties.nix
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
hostNames = [
|
||||||
|
"phil"
|
||||||
|
"phil.neet.dev"
|
||||||
|
];
|
||||||
|
|
||||||
|
arch = "aarch64-linux";
|
||||||
|
|
||||||
|
systemRoles = [
|
||||||
|
"server"
|
||||||
|
"nix-builder"
|
||||||
|
];
|
||||||
|
|
||||||
|
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlgRPpuUkZqe8/lHugRPm/m2vcN9psYhh5tENHZt9I2";
|
||||||
|
|
||||||
|
remoteUnlock = {
|
||||||
|
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK0RodotOXLMy/w70aa096gaNqPBnfgiXR5ZAH4+wGzd";
|
||||||
|
clearnetHost = "unlock.phil.neet.dev";
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,13 +1,11 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports =[
|
imports = [
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.hostName = "ponyo";
|
# system.autoUpgrade.enable = true;
|
||||||
|
|
||||||
system.autoUpgrade.enable = true;
|
|
||||||
|
|
||||||
# p2p mesh network
|
# p2p mesh network
|
||||||
services.tailscale.exitNode = true;
|
services.tailscale.exitNode = true;
|
||||||
@@ -52,6 +50,9 @@
|
|||||||
file = ../../secrets/wolframalpha.age;
|
file = ../../secrets/wolframalpha.age;
|
||||||
owner = config.services.drastikbot.user;
|
owner = config.services.drastikbot.user;
|
||||||
};
|
};
|
||||||
|
backup.group."dailybot".paths = [
|
||||||
|
config.services.drastikbot.dataDir
|
||||||
|
];
|
||||||
|
|
||||||
# music radio
|
# music radio
|
||||||
vpn-container.enable = true;
|
vpn-container.enable = true;
|
||||||
@@ -61,18 +62,33 @@
|
|||||||
host = "radio.runyan.org";
|
host = "radio.runyan.org";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
pia.wireguard.badPortForwardPorts = [];
|
pia.wireguard.badPortForwardPorts = [ ];
|
||||||
services.nginx.virtualHosts."radio.runyan.org" = {
|
services.nginx.virtualHosts = {
|
||||||
enableACME = true;
|
"radio.runyan.org" = {
|
||||||
forceSSL = true;
|
enableACME = true;
|
||||||
locations = {
|
forceSSL = true;
|
||||||
"/stream.mp3" = {
|
locations = {
|
||||||
proxyPass = "http://vpn.containers:8001/stream.mp3";
|
"/stream.mp3" = {
|
||||||
extraConfig = ''
|
proxyPass = "http://vpn.containers:8001/stream.mp3";
|
||||||
add_header Access-Control-Allow-Origin *;
|
extraConfig = ''
|
||||||
'';
|
add_header Access-Control-Allow-Origin *;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"/".root = config.inputs.radio-web;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"radio.neet.space" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations = {
|
||||||
|
"/stream.mp3" = {
|
||||||
|
proxyPass = "http://vpn.containers:8001/stream.mp3";
|
||||||
|
extraConfig = ''
|
||||||
|
add_header Access-Control-Allow-Origin *;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"/".root = config.inputs.radio-web;
|
||||||
};
|
};
|
||||||
"/".root = config.inputs.radio-web;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -95,7 +111,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
# pin postgresql for matrix (will need to migrate eventually)
|
# pin postgresql for matrix (will need to migrate eventually)
|
||||||
services.postgresql.package = pkgs.postgresql_11;
|
services.postgresql.package = pkgs.postgresql_15;
|
||||||
|
|
||||||
# iodine DNS-based vpn
|
# iodine DNS-based vpn
|
||||||
services.iodine.server.enable = true;
|
services.iodine.server.enable = true;
|
||||||
@@ -135,4 +151,11 @@
|
|||||||
# owncast live streaming
|
# owncast live streaming
|
||||||
services.owncast.enable = true;
|
services.owncast.enable = true;
|
||||||
services.owncast.hostname = "live.neet.dev";
|
services.owncast.hostname = "live.neet.dev";
|
||||||
|
|
||||||
|
# librechat
|
||||||
|
services.librechat.enable = true;
|
||||||
|
services.librechat.host = "chat.neet.dev";
|
||||||
|
|
||||||
|
services.actual-server.enable = true;
|
||||||
|
services.actual-server.hostname = "actual.runyan.org";
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
imports =
|
imports =
|
||||||
[ (modulesPath + "/profiles/qemu-guest.nix")
|
[
|
||||||
|
(modulesPath + "/profiles/qemu-guest.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" ];
|
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" ];
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
bios = {
|
bios = {
|
||||||
enable = true;
|
enable = true;
|
||||||
device = "/dev/sda";
|
device = "/dev/sda";
|
||||||
|
configurationLimit = 3; # Save room in /nix/store
|
||||||
};
|
};
|
||||||
|
|
||||||
remoteLuksUnlock.enable = true;
|
remoteLuksUnlock.enable = true;
|
||||||
@@ -22,12 +24,14 @@
|
|||||||
boot.initrd.luks.devices."enc-pv2".device = "/dev/disk/by-uuid/e52b01b3-81c8-4bb2-ae7e-a3d9c793cb00"; # expanded disk
|
boot.initrd.luks.devices."enc-pv2".device = "/dev/disk/by-uuid/e52b01b3-81c8-4bb2-ae7e-a3d9c793cb00"; # expanded disk
|
||||||
|
|
||||||
fileSystems."/" =
|
fileSystems."/" =
|
||||||
{ device = "/dev/mapper/enc-pv";
|
{
|
||||||
|
device = "/dev/mapper/enc-pv";
|
||||||
fsType = "btrfs";
|
fsType = "btrfs";
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/boot" =
|
fileSystems."/boot" =
|
||||||
{ device = "/dev/disk/by-uuid/d3a3777d-1e70-47fa-a274-804dc70ee7fd";
|
{
|
||||||
|
device = "/dev/disk/by-uuid/d3a3777d-1e70-47fa-a274-804dc70ee7fd";
|
||||||
fsType = "ext4";
|
fsType = "ext4";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
29
machines/ponyo/properties.nix
Normal file
29
machines/ponyo/properties.nix
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
hostNames = [
|
||||||
|
"ponyo"
|
||||||
|
"ponyo.neet.dev"
|
||||||
|
"git.neet.dev"
|
||||||
|
];
|
||||||
|
|
||||||
|
arch = "x86_64-linux";
|
||||||
|
|
||||||
|
systemRoles = [
|
||||||
|
"server"
|
||||||
|
"email-server"
|
||||||
|
"iodine"
|
||||||
|
"pia"
|
||||||
|
"nextcloud"
|
||||||
|
"dailybot"
|
||||||
|
"gitea"
|
||||||
|
"librechat"
|
||||||
|
];
|
||||||
|
|
||||||
|
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMBBlTAIp38RhErU1wNNV5MBeb+WGH0mhF/dxh5RsAXN";
|
||||||
|
|
||||||
|
remoteUnlock = {
|
||||||
|
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC9LQuuImgWlkjDhEEIbM1wOd+HqRv1RxvYZuLXPSdRi";
|
||||||
|
|
||||||
|
clearnetHost = "unlock.ponyo.neet.dev";
|
||||||
|
onionHost = "cfamr6artx75qvt7ho3rrbsc7mkucmv5aawebwflsfuorusayacffryd.onion";
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./hardware-configuration.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
networking.hostName = "ray";
|
|
||||||
|
|
||||||
# for luks onlock over tor
|
|
||||||
services.tor.enable = true;
|
|
||||||
services.tor.client.enable = true;
|
|
||||||
|
|
||||||
# services.howdy.enable = true;
|
|
||||||
|
|
||||||
hardware.openrazer.enable = true;
|
|
||||||
hardware.openrazer.users = [ "googlebot" ];
|
|
||||||
hardware.openrazer.devicesOffOnScreensaver = false;
|
|
||||||
users.users.googlebot.packages = [ pkgs.polychromatic ];
|
|
||||||
|
|
||||||
# depthai
|
|
||||||
services.udev.extraRules = ''
|
|
||||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="03e7", MODE="0666"
|
|
||||||
'';
|
|
||||||
|
|
||||||
# virt-manager
|
|
||||||
virtualisation.libvirtd.enable = true;
|
|
||||||
programs.dconf.enable = true;
|
|
||||||
virtualisation.spiceUSBRedirection.enable = true;
|
|
||||||
environment.systemPackages = with pkgs; [ virt-manager ];
|
|
||||||
users.users.googlebot.extraGroups = [ "libvirtd" ];
|
|
||||||
|
|
||||||
# allow building ARM derivations
|
|
||||||
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
|
|
||||||
|
|
||||||
services.spotifyd.enable = true;
|
|
||||||
|
|
||||||
virtualisation.docker.enable = true;
|
|
||||||
|
|
||||||
services.mount-samba.enable = true;
|
|
||||||
|
|
||||||
de.enable = true;
|
|
||||||
de.touchpad.enable = true;
|
|
||||||
}
|
|
||||||
@@ -1,62 +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
|
|
||||||
efi.enable = true;
|
|
||||||
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "usbhid" "usb_storage" "sd_mod" ];
|
|
||||||
boot.initrd.kernelModules = [ "dm-snapshot" ];
|
|
||||||
|
|
||||||
# kernel
|
|
||||||
boot.kernelModules = [ "kvm-amd" ];
|
|
||||||
boot.extraModulePackages = [ ];
|
|
||||||
|
|
||||||
# firmware
|
|
||||||
firmware.x86_64.enable = true;
|
|
||||||
hardware.enableAllFirmware = true;
|
|
||||||
|
|
||||||
# gpu
|
|
||||||
services.xserver.videoDrivers = [ "nvidia" ];
|
|
||||||
hardware.nvidia = {
|
|
||||||
modesetting.enable = true; # for nvidia-vaapi-driver
|
|
||||||
prime = {
|
|
||||||
reverseSync.enable = true;
|
|
||||||
offload.enableOffloadCmd = true;
|
|
||||||
nvidiaBusId = "PCI:1:0:0";
|
|
||||||
amdgpuBusId = "PCI:4:0:0";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# disks
|
|
||||||
remoteLuksUnlock.enable = true;
|
|
||||||
boot.initrd.luks.devices."enc-pv" = {
|
|
||||||
device = "/dev/disk/by-uuid/c1822e5f-4137-44e1-885f-954e926583ce";
|
|
||||||
allowDiscards = true;
|
|
||||||
};
|
|
||||||
fileSystems."/" =
|
|
||||||
{ device = "/dev/vg/root";
|
|
||||||
fsType = "btrfs";
|
|
||||||
options = [ "subvol=root" ];
|
|
||||||
};
|
|
||||||
fileSystems."/home" =
|
|
||||||
{ device = "/dev/vg/root";
|
|
||||||
fsType = "btrfs";
|
|
||||||
options = [ "subvol=home" ];
|
|
||||||
};
|
|
||||||
fileSystems."/boot" =
|
|
||||||
{ device = "/dev/disk/by-uuid/2C85-2B59";
|
|
||||||
fsType = "vfat";
|
|
||||||
};
|
|
||||||
swapDevices =
|
|
||||||
[ { device = "/dev/vg/swap"; }
|
|
||||||
];
|
|
||||||
|
|
||||||
# high-resolution display
|
|
||||||
hardware.video.hidpi.enable = lib.mkDefault true;
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./hardware-configuration.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
networking.hostName = "router";
|
|
||||||
|
|
||||||
system.autoUpgrade.enable = true;
|
|
||||||
|
|
||||||
services.tailscale.exitNode = true;
|
|
||||||
|
|
||||||
networking.useDHCP = lib.mkForce true;
|
|
||||||
}
|
|
||||||
38
machines/router/default.nix
Normal file
38
machines/router/default.nix
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./hardware-configuration.nix
|
||||||
|
./router.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
# https://dataswamp.org/~solene/2022-08-03-nixos-with-live-usb-router.html
|
||||||
|
# https://github.com/mdlayher/homelab/blob/391cfc0de06434e4dee0abe2bec7a2f0637345ac/nixos/routnerr-2/configuration.nix
|
||||||
|
# https://github.com/skogsbrus/os/blob/master/sys/router.nix
|
||||||
|
# http://trac.gateworks.com/wiki/wireless/wifi
|
||||||
|
|
||||||
|
system.autoUpgrade.enable = true;
|
||||||
|
|
||||||
|
services.tailscale.exitNode = true;
|
||||||
|
|
||||||
|
router.enable = true;
|
||||||
|
router.privateSubnet = "192.168.3";
|
||||||
|
|
||||||
|
services.iperf3.enable = true;
|
||||||
|
|
||||||
|
# networking.useDHCP = lib.mkForce true;
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
# networking.usePredictableInterfaceNames = true;
|
||||||
|
|
||||||
|
powerManagement.cpuFreqGovernor = "ondemand";
|
||||||
|
|
||||||
|
|
||||||
|
services.irqbalance.enable = true;
|
||||||
|
|
||||||
|
# services.miniupnpd = {
|
||||||
|
# enable = true;
|
||||||
|
# externalInterface = "eth0";
|
||||||
|
# internalIPs = [ "br0" ];
|
||||||
|
# };
|
||||||
|
}
|
||||||
BIN
machines/router/firmware/mediatek/mt7916_eeprom.bin
Normal file
BIN
machines/router/firmware/mediatek/mt7916_eeprom.bin
Normal file
Binary file not shown.
BIN
machines/router/firmware/mediatek/mt7916_rom_patch.bin
Normal file
BIN
machines/router/firmware/mediatek/mt7916_rom_patch.bin
Normal file
Binary file not shown.
BIN
machines/router/firmware/mediatek/mt7916_wa.bin
Normal file
BIN
machines/router/firmware/mediatek/mt7916_wa.bin
Normal file
Binary file not shown.
BIN
machines/router/firmware/mediatek/mt7916_wm.bin
Normal file
BIN
machines/router/firmware/mediatek/mt7916_wm.bin
Normal file
Binary file not shown.
223
machines/router/generate_hostapd_config.sh
Executable file
223
machines/router/generate_hostapd_config.sh
Executable file
@@ -0,0 +1,223 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# TODO allow adding custom parameters to ht_capab, vht_capab
|
||||||
|
# TODO detect bad channel numbers (preferably not at runtime)
|
||||||
|
# TODO error if 160mhz is not supported
|
||||||
|
# TODO 'b' only goes up to 40mhz
|
||||||
|
|
||||||
|
# gets the phy number using the input interface
|
||||||
|
# Ex: get_phy_number("wlan0") -> "1"
|
||||||
|
get_phy_number() {
|
||||||
|
local interface=$1
|
||||||
|
phy=$(iw dev "$interface" info | awk '/phy/ {gsub(/#/,"");print $2}')
|
||||||
|
if [[ -z "$phy" ]]; then
|
||||||
|
echo "Error: interface not found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
phy=phy$phy
|
||||||
|
}
|
||||||
|
|
||||||
|
get_ht_cap_mask() {
|
||||||
|
ht_cap_mask=0
|
||||||
|
|
||||||
|
for cap in $(iw phy "$phy" info | grep 'Capabilities:' | cut -d: -f2); do
|
||||||
|
ht_cap_mask="$(($ht_cap_mask | $cap))"
|
||||||
|
done
|
||||||
|
|
||||||
|
local cap_rx_stbc
|
||||||
|
cap_rx_stbc=$((($ht_cap_mask >> 8) & 3))
|
||||||
|
ht_cap_mask="$(( ($ht_cap_mask & ~(0x300)) | ($cap_rx_stbc << 8) ))"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_vht_cap_mask() {
|
||||||
|
vht_cap_mask=0
|
||||||
|
for cap in $(iw phy "$phy" info | awk -F "[()]" '/VHT Capabilities/ { print $2 }'); do
|
||||||
|
vht_cap_mask="$(($vht_cap_mask | $cap))"
|
||||||
|
done
|
||||||
|
|
||||||
|
local cap_rx_stbc
|
||||||
|
cap_rx_stbc=$((($vht_cap_mask >> 8) & 7))
|
||||||
|
vht_cap_mask="$(( ($vht_cap_mask & ~(0x700)) | ($cap_rx_stbc << 8) ))"
|
||||||
|
}
|
||||||
|
|
||||||
|
mac80211_add_capabilities() {
|
||||||
|
local __var="$1"; shift
|
||||||
|
local __mask="$1"; shift
|
||||||
|
local __out= oifs
|
||||||
|
|
||||||
|
oifs="$IFS"
|
||||||
|
IFS=:
|
||||||
|
for capab in "$@"; do
|
||||||
|
set -- $capab
|
||||||
|
[ "$(($4))" -gt 0 ] || continue
|
||||||
|
[ "$(($__mask & $2))" -eq "$((${3:-$2}))" ] || continue
|
||||||
|
__out="$__out[$1]"
|
||||||
|
done
|
||||||
|
IFS="$oifs"
|
||||||
|
|
||||||
|
export -n -- "$__var=$__out"
|
||||||
|
}
|
||||||
|
|
||||||
|
add_special_ht_capabilities() {
|
||||||
|
case "$hwmode" in
|
||||||
|
a)
|
||||||
|
case "$(( ($channel / 4) % 2 ))" in
|
||||||
|
1) ht_capab="$ht_capab[HT40+]";;
|
||||||
|
0) ht_capab="$ht_capab[HT40-]";;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if [ "$channel" -lt 7 ]; then
|
||||||
|
ht_capab="$ht_capab[HT40+]"
|
||||||
|
else
|
||||||
|
ht_capab="$ht_capab[HT40-]"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
add_special_vht_capabilities() {
|
||||||
|
local cap_ant
|
||||||
|
[ "$(($vht_cap_mask & 0x800))" -gt 0 ] && {
|
||||||
|
cap_ant="$(( ( ($vht_cap_mask >> 16) & 3 ) + 1 ))"
|
||||||
|
[ "$cap_ant" -gt 1 ] && vht_capab="$vht_capab[SOUNDING-DIMENSION-$cap_ant]"
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "$(($vht_cap_mask & 0x1000))" -gt 0 ] && {
|
||||||
|
cap_ant="$(( ( ($vht_cap_mask >> 13) & 3 ) + 1 ))"
|
||||||
|
[ "$cap_ant" -gt 1 ] && vht_capab="$vht_capab[BF-ANTENNA-$cap_ant]"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$(($vht_cap_mask & 12))" -eq 4 ]; then
|
||||||
|
vht_capab="$vht_capab[VHT160]"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local vht_max_mpdu_hw=3895
|
||||||
|
[ "$(($vht_cap_mask & 3))" -ge 1 ] && \
|
||||||
|
vht_max_mpdu_hw=7991
|
||||||
|
[ "$(($vht_cap_mask & 3))" -ge 2 ] && \
|
||||||
|
vht_max_mpdu_hw=11454
|
||||||
|
[ "$vht_max_mpdu_hw" != 3895 ] && \
|
||||||
|
vht_capab="$vht_capab[MAX-MPDU-$vht_max_mpdu_hw]"
|
||||||
|
|
||||||
|
# maximum A-MPDU length exponent
|
||||||
|
local vht_max_a_mpdu_len_exp_hw=0
|
||||||
|
[ "$(($vht_cap_mask & 58720256))" -ge 8388608 ] && \
|
||||||
|
vht_max_a_mpdu_len_exp_hw=1
|
||||||
|
[ "$(($vht_cap_mask & 58720256))" -ge 16777216 ] && \
|
||||||
|
vht_max_a_mpdu_len_exp_hw=2
|
||||||
|
[ "$(($vht_cap_mask & 58720256))" -ge 25165824 ] && \
|
||||||
|
vht_max_a_mpdu_len_exp_hw=3
|
||||||
|
[ "$(($vht_cap_mask & 58720256))" -ge 33554432 ] && \
|
||||||
|
vht_max_a_mpdu_len_exp_hw=4
|
||||||
|
[ "$(($vht_cap_mask & 58720256))" -ge 41943040 ] && \
|
||||||
|
vht_max_a_mpdu_len_exp_hw=5
|
||||||
|
[ "$(($vht_cap_mask & 58720256))" -ge 50331648 ] && \
|
||||||
|
vht_max_a_mpdu_len_exp_hw=6
|
||||||
|
[ "$(($vht_cap_mask & 58720256))" -ge 58720256 ] && \
|
||||||
|
vht_max_a_mpdu_len_exp_hw=7
|
||||||
|
vht_capab="$vht_capab[MAX-A-MPDU-LEN-EXP$vht_max_a_mpdu_len_exp_hw]"
|
||||||
|
|
||||||
|
local vht_link_adapt_hw=0
|
||||||
|
[ "$(($vht_cap_mask & 201326592))" -ge 134217728 ] && \
|
||||||
|
vht_link_adapt_hw=2
|
||||||
|
[ "$(($vht_cap_mask & 201326592))" -ge 201326592 ] && \
|
||||||
|
vht_link_adapt_hw=3
|
||||||
|
[ "$vht_link_adapt_hw" != 0 ] && \
|
||||||
|
vht_capab="$vht_capab[VHT-LINK-ADAPT-$vht_link_adapt_hw]"
|
||||||
|
}
|
||||||
|
|
||||||
|
calculate_channel_offsets() {
|
||||||
|
vht_oper_chwidth=0
|
||||||
|
vht_oper_centr_freq_seg0_idx=
|
||||||
|
|
||||||
|
local idx="$channel"
|
||||||
|
case "$channelWidth" in
|
||||||
|
40)
|
||||||
|
case "$(( ($channel / 4) % 2 ))" in
|
||||||
|
1) idx=$(($channel + 2));;
|
||||||
|
0) idx=$(($channel - 2));;
|
||||||
|
esac
|
||||||
|
vht_oper_centr_freq_seg0_idx=$idx
|
||||||
|
;;
|
||||||
|
80)
|
||||||
|
case "$(( ($channel / 4) % 4 ))" in
|
||||||
|
1) idx=$(($channel + 6));;
|
||||||
|
2) idx=$(($channel + 2));;
|
||||||
|
3) idx=$(($channel - 2));;
|
||||||
|
0) idx=$(($channel - 6));;
|
||||||
|
esac
|
||||||
|
vht_oper_chwidth=1
|
||||||
|
vht_oper_centr_freq_seg0_idx=$idx
|
||||||
|
;;
|
||||||
|
160)
|
||||||
|
case "$channel" in
|
||||||
|
36|40|44|48|52|56|60|64) idx=50;;
|
||||||
|
100|104|108|112|116|120|124|128) idx=114;;
|
||||||
|
esac
|
||||||
|
vht_oper_chwidth=2
|
||||||
|
vht_oper_centr_freq_seg0_idx=$idx
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
he_oper_chwidth=$vht_oper_chwidth
|
||||||
|
he_oper_centr_freq_seg0_idx=$vht_oper_centr_freq_seg0_idx
|
||||||
|
}
|
||||||
|
|
||||||
|
interface=$1
|
||||||
|
channel=$2
|
||||||
|
hwmode=$3
|
||||||
|
channelWidth=$4
|
||||||
|
|
||||||
|
get_phy_number $interface
|
||||||
|
get_ht_cap_mask
|
||||||
|
get_vht_cap_mask
|
||||||
|
|
||||||
|
mac80211_add_capabilities vht_capab $vht_cap_mask \
|
||||||
|
RXLDPC:0x10::1 \
|
||||||
|
SHORT-GI-80:0x20::1 \
|
||||||
|
SHORT-GI-160:0x40::1 \
|
||||||
|
TX-STBC-2BY1:0x80::1 \
|
||||||
|
SU-BEAMFORMER:0x800::1 \
|
||||||
|
SU-BEAMFORMEE:0x1000::1 \
|
||||||
|
MU-BEAMFORMER:0x80000::1 \
|
||||||
|
MU-BEAMFORMEE:0x100000::1 \
|
||||||
|
VHT-TXOP-PS:0x200000::1 \
|
||||||
|
HTC-VHT:0x400000::1 \
|
||||||
|
RX-ANTENNA-PATTERN:0x10000000::1 \
|
||||||
|
TX-ANTENNA-PATTERN:0x20000000::1 \
|
||||||
|
RX-STBC-1:0x700:0x100:1 \
|
||||||
|
RX-STBC-12:0x700:0x200:1 \
|
||||||
|
RX-STBC-123:0x700:0x300:1 \
|
||||||
|
RX-STBC-1234:0x700:0x400:1 \
|
||||||
|
|
||||||
|
mac80211_add_capabilities ht_capab $ht_cap_mask \
|
||||||
|
LDPC:0x1::1 \
|
||||||
|
GF:0x10::1 \
|
||||||
|
SHORT-GI-20:0x20::1 \
|
||||||
|
SHORT-GI-40:0x40::1 \
|
||||||
|
TX-STBC:0x80::1 \
|
||||||
|
RX-STBC1:0x300::1 \
|
||||||
|
MAX-AMSDU-7935:0x800::1 \
|
||||||
|
|
||||||
|
# TODO this is active when the driver doesn't support it?
|
||||||
|
# DSSS_CCK-40:0x1000::1 \
|
||||||
|
|
||||||
|
# TODO these are active when the driver doesn't support them?
|
||||||
|
# RX-STBC1:0x300:0x100:1 \
|
||||||
|
# RX-STBC12:0x300:0x200:1 \
|
||||||
|
# RX-STBC123:0x300:0x300:1 \
|
||||||
|
|
||||||
|
add_special_ht_capabilities
|
||||||
|
add_special_vht_capabilities
|
||||||
|
|
||||||
|
echo ht_capab=$ht_capab
|
||||||
|
echo vht_capab=$vht_capab
|
||||||
|
|
||||||
|
if [ "$channelWidth" != "20" ]; then
|
||||||
|
calculate_channel_offsets
|
||||||
|
echo he_oper_chwidth=$he_oper_chwidth
|
||||||
|
echo vht_oper_chwidth=$vht_oper_chwidth
|
||||||
|
echo he_oper_centr_freq_seg0_idx=$he_oper_centr_freq_seg0_idx
|
||||||
|
echo vht_oper_centr_freq_seg0_idx=$vht_oper_centr_freq_seg0_idx
|
||||||
|
fi
|
||||||
@@ -10,7 +10,8 @@
|
|||||||
|
|
||||||
# Enable serial output
|
# Enable serial output
|
||||||
boot.kernelParams = [
|
boot.kernelParams = [
|
||||||
"panic=30" "boot.panic_on_fail" # reboot the machine upon fatal boot issues
|
"panic=30"
|
||||||
|
"boot.panic_on_fail" # reboot the machine upon fatal boot issues
|
||||||
"console=ttyS0,115200n8" # enable serial console
|
"console=ttyS0,115200n8" # enable serial console
|
||||||
];
|
];
|
||||||
boot.loader.grub.extraConfig = "
|
boot.loader.grub.extraConfig = "
|
||||||
@@ -21,7 +22,6 @@
|
|||||||
|
|
||||||
# firmware
|
# firmware
|
||||||
firmware.x86_64.enable = true;
|
firmware.x86_64.enable = true;
|
||||||
hardware.enableAllFirmware = true;
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|
||||||
# boot
|
# boot
|
||||||
@@ -34,16 +34,17 @@
|
|||||||
remoteLuksUnlock.enable = true;
|
remoteLuksUnlock.enable = true;
|
||||||
boot.initrd.luks.devices."enc-pv".device = "/dev/disk/by-uuid/9b090551-f78e-45ca-8570-196ed6a4af0c";
|
boot.initrd.luks.devices."enc-pv".device = "/dev/disk/by-uuid/9b090551-f78e-45ca-8570-196ed6a4af0c";
|
||||||
fileSystems."/" =
|
fileSystems."/" =
|
||||||
{ device = "/dev/disk/by-uuid/421c82b9-d67c-4811-8824-8bb57cb10fce";
|
{
|
||||||
|
device = "/dev/disk/by-uuid/421c82b9-d67c-4811-8824-8bb57cb10fce";
|
||||||
fsType = "btrfs";
|
fsType = "btrfs";
|
||||||
};
|
};
|
||||||
fileSystems."/boot" =
|
fileSystems."/boot" =
|
||||||
{ device = "/dev/disk/by-uuid/d97f324f-3a2e-4b84-ae2a-4b3d1209c689";
|
{
|
||||||
|
device = "/dev/disk/by-uuid/d97f324f-3a2e-4b84-ae2a-4b3d1209c689";
|
||||||
fsType = "ext3";
|
fsType = "ext3";
|
||||||
};
|
};
|
||||||
swapDevices =
|
swapDevices =
|
||||||
[ { device = "/dev/disk/by-uuid/45bf58dd-67eb-45e4-9a98-246e23fa7abd"; }
|
[{ device = "/dev/disk/by-uuid/45bf58dd-67eb-45e4-9a98-246e23fa7abd"; }];
|
||||||
];
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = "x86_64-linux";
|
nixpkgs.hostPlatform = "x86_64-linux";
|
||||||
}
|
}
|
||||||
|
|||||||
21
machines/router/properties.nix.disabled
Normal file
21
machines/router/properties.nix.disabled
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
hostNames = [
|
||||||
|
"router"
|
||||||
|
"192.168.1.228"
|
||||||
|
];
|
||||||
|
|
||||||
|
arch = "x86_64-linux";
|
||||||
|
|
||||||
|
systemRoles = [
|
||||||
|
"server"
|
||||||
|
"wireless"
|
||||||
|
"router"
|
||||||
|
];
|
||||||
|
|
||||||
|
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFr2IHmWFlaLaLp5dGoSmFEYKA/eg2SwGXAogaOmLsHL";
|
||||||
|
|
||||||
|
remoteUnlock = {
|
||||||
|
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJOw5dTPmtKqiPBH6VKyz5MYBubn8leAh5Eaw7s/O85c";
|
||||||
|
onionHost = "jxx2exuihlls2t6ncs7rvrjh2dssubjmjtclwr2ysvxtr4t7jv55xmqd.onion";
|
||||||
|
};
|
||||||
|
}
|
||||||
205
machines/router/router.nix
Normal file
205
machines/router/router.nix
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.router;
|
||||||
|
inherit (lib) mapAttrs' genAttrs nameValuePair mkOption types mkIf mkEnableOption;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.router = {
|
||||||
|
enable = mkEnableOption "router";
|
||||||
|
|
||||||
|
privateSubnet = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "192.168.1";
|
||||||
|
description = "IP block (/24) to use for the private subnet";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
networking.ip_forward = true;
|
||||||
|
|
||||||
|
networking.interfaces.enp1s0.useDHCP = true;
|
||||||
|
|
||||||
|
networking.nat = {
|
||||||
|
enable = true;
|
||||||
|
internalInterfaces = [
|
||||||
|
"br0"
|
||||||
|
];
|
||||||
|
externalInterface = "enp1s0";
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.bridges = {
|
||||||
|
br0 = {
|
||||||
|
interfaces = [
|
||||||
|
"enp2s0"
|
||||||
|
"wlp4s0"
|
||||||
|
"wlan1"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.interfaces = {
|
||||||
|
br0 = {
|
||||||
|
useDHCP = false;
|
||||||
|
ipv4.addresses = [
|
||||||
|
{
|
||||||
|
address = "${cfg.privateSubnet}.1";
|
||||||
|
prefixLength = 24;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall = {
|
||||||
|
enable = true;
|
||||||
|
trustedInterfaces = [ "br0" "tailscale0" ];
|
||||||
|
|
||||||
|
interfaces = {
|
||||||
|
enp1s0 = {
|
||||||
|
allowedTCPPorts = [ ];
|
||||||
|
allowedUDPPorts = [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.dnsmasq = {
|
||||||
|
enable = true;
|
||||||
|
extraConfig = ''
|
||||||
|
# sensible behaviours
|
||||||
|
domain-needed
|
||||||
|
bogus-priv
|
||||||
|
no-resolv
|
||||||
|
|
||||||
|
# upstream name servers
|
||||||
|
server=1.1.1.1
|
||||||
|
server=8.8.8.8
|
||||||
|
|
||||||
|
# local domains
|
||||||
|
expand-hosts
|
||||||
|
domain=home
|
||||||
|
local=/home/
|
||||||
|
|
||||||
|
# Interfaces to use DNS on
|
||||||
|
interface=br0
|
||||||
|
|
||||||
|
# subnet IP blocks to use DHCP on
|
||||||
|
dhcp-range=${cfg.privateSubnet}.10,${cfg.privateSubnet}.254,24h
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
services.hostapd = {
|
||||||
|
enable = true;
|
||||||
|
radios = {
|
||||||
|
# 2.4GHz
|
||||||
|
wlp4s0 = {
|
||||||
|
band = "2g";
|
||||||
|
noScan = true;
|
||||||
|
channel = 6;
|
||||||
|
countryCode = "US";
|
||||||
|
wifi4 = {
|
||||||
|
capabilities = [ "LDPC" "GF" "SHORT-GI-20" "SHORT-GI-40" "TX-STBC" "RX-STBC1" "MAX-AMSDU-7935" "HT40+" ];
|
||||||
|
};
|
||||||
|
wifi5 = {
|
||||||
|
operatingChannelWidth = "20or40";
|
||||||
|
capabilities = [ "MAX-A-MPDU-LEN-EXP0" ];
|
||||||
|
};
|
||||||
|
wifi6 = {
|
||||||
|
enable = true;
|
||||||
|
singleUserBeamformer = true;
|
||||||
|
singleUserBeamformee = true;
|
||||||
|
multiUserBeamformer = true;
|
||||||
|
operatingChannelWidth = "20or40";
|
||||||
|
};
|
||||||
|
networks = {
|
||||||
|
wlp4s0 = {
|
||||||
|
ssid = "CXNK00BF9176";
|
||||||
|
authentication.saePasswordsFile = "/run/agenix/hostapd-pw-CXNK00BF9176";
|
||||||
|
};
|
||||||
|
# wlp4s0-1 = {
|
||||||
|
# ssid = "- Experimental 5G Tower by AT&T";
|
||||||
|
# authentication.saePasswordsFile = "/run/agenix/hostapd-pw-experimental-tower";
|
||||||
|
# };
|
||||||
|
# wlp4s0-2 = {
|
||||||
|
# ssid = "FBI Surveillance Van 2";
|
||||||
|
# authentication.saePasswordsFile = "/run/agenix/hostapd-pw-experimental-tower";
|
||||||
|
# };
|
||||||
|
};
|
||||||
|
settings = {
|
||||||
|
he_oper_centr_freq_seg0_idx = 8;
|
||||||
|
vht_oper_centr_freq_seg0_idx = 8;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# 5GHz
|
||||||
|
wlan1 = {
|
||||||
|
band = "5g";
|
||||||
|
noScan = true;
|
||||||
|
channel = 128;
|
||||||
|
countryCode = "US";
|
||||||
|
wifi4 = {
|
||||||
|
capabilities = [ "LDPC" "GF" "SHORT-GI-20" "SHORT-GI-40" "TX-STBC" "RX-STBC1" "MAX-AMSDU-7935" "HT40-" ];
|
||||||
|
};
|
||||||
|
wifi5 = {
|
||||||
|
operatingChannelWidth = "160";
|
||||||
|
capabilities = [ "RXLDPC" "SHORT-GI-80" "SHORT-GI-160" "TX-STBC-2BY1" "SU-BEAMFORMER" "SU-BEAMFORMEE" "MU-BEAMFORMER" "MU-BEAMFORMEE" "RX-ANTENNA-PATTERN" "TX-ANTENNA-PATTERN" "RX-STBC-1" "SOUNDING-DIMENSION-3" "BF-ANTENNA-3" "VHT160" "MAX-MPDU-11454" "MAX-A-MPDU-LEN-EXP7" ];
|
||||||
|
};
|
||||||
|
wifi6 = {
|
||||||
|
enable = true;
|
||||||
|
singleUserBeamformer = true;
|
||||||
|
singleUserBeamformee = true;
|
||||||
|
multiUserBeamformer = true;
|
||||||
|
operatingChannelWidth = "160";
|
||||||
|
};
|
||||||
|
networks = {
|
||||||
|
wlan1 = {
|
||||||
|
ssid = "CXNK00BF9176";
|
||||||
|
authentication.saePasswordsFile = "/run/agenix/hostapd-pw-CXNK00BF9176";
|
||||||
|
};
|
||||||
|
# wlan1-1 = {
|
||||||
|
# ssid = "- Experimental 5G Tower by AT&T";
|
||||||
|
# authentication.saePasswordsFile = "/run/agenix/hostapd-pw-experimental-tower";
|
||||||
|
# };
|
||||||
|
# wlan1-2 = {
|
||||||
|
# ssid = "FBI Surveillance Van 5";
|
||||||
|
# authentication.saePasswordsFile = "/run/agenix/hostapd-pw-experimental-tower";
|
||||||
|
# };
|
||||||
|
};
|
||||||
|
settings = {
|
||||||
|
vht_oper_centr_freq_seg0_idx = 114;
|
||||||
|
he_oper_centr_freq_seg0_idx = 114;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
age.secrets.hostapd-pw-experimental-tower.file = ../../secrets/hostapd-pw-experimental-tower.age;
|
||||||
|
age.secrets.hostapd-pw-CXNK00BF9176.file = ../../secrets/hostapd-pw-CXNK00BF9176.age;
|
||||||
|
|
||||||
|
hardware.firmware = [
|
||||||
|
pkgs.mt7916-firmware
|
||||||
|
];
|
||||||
|
|
||||||
|
nixpkgs.overlays = [
|
||||||
|
(self: super: {
|
||||||
|
mt7916-firmware = pkgs.stdenvNoCC.mkDerivation {
|
||||||
|
pname = "mt7916-firmware";
|
||||||
|
version = "custom-feb-02-23";
|
||||||
|
src = ./firmware/mediatek; # from here https://github.com/openwrt/mt76/issues/720#issuecomment-1413537674
|
||||||
|
dontBuild = true;
|
||||||
|
installPhase = ''
|
||||||
|
for i in \
|
||||||
|
mt7916_eeprom.bin \
|
||||||
|
mt7916_rom_patch.bin \
|
||||||
|
mt7916_wa.bin \
|
||||||
|
mt7916_wm.bin;
|
||||||
|
do
|
||||||
|
install -D -pm644 $i $out/lib/firmware/mediatek/$i
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
meta = with lib; {
|
||||||
|
license = licenses.unfreeRedistributableFirmware;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user