177 Commits

Author SHA1 Message Date
Shelvacu
a459afdad2 verify system, no more oopsies hopefully 2024-09-11 09:32:57 -07:00
Shelvacu
94e08bc6fe wip 2024-09-10 23:46:16 -07:00
Shelvacu
def7296ec7 formatter run 2024-09-10 20:05:01 -07:00
shelvacu
c31446e3cb coopdx: put baserom in the right spot 2024-09-07 17:28:17 -07:00
Shelvacu
b707e6ae8d add sm64coopdx 2024-09-05 15:10:25 -07:00
Shelvacu
420a2d8d02 aaaaaaa 2024-09-04 23:37:53 -07:00
Shelvacu
0c546acefd nixvim initial 2024-09-04 15:59:08 -07:00
Shelvacu
1b13226c50 F O R M A T 2024-09-03 04:29:32 -07:00
Shelvacu
4876654145 fix initial ps1 2024-09-02 22:57:11 -07:00
shelvacu
9ed4e80418 add bootstrap 2024-09-02 22:44:09 -07:00
shelvacu
46ec04a967 update flake inputs 2024-09-02 02:44:28 -07:00
Shelvacu
311fbb0904 Merge branch 'master' of git.uninsane.org:shelvacu/nix-stuff 2024-09-02 02:24:35 -07:00
Shelvacu
6453c4cdf0 give all the machines different color shells. yay! 2024-09-02 01:50:35 -07:00
Shelvacu
1a74b58b44 stuff 2024-09-01 10:30:31 -07:00
Shelvacu
4f256663ae reorg 2024-08-29 19:35:53 -07:00
shelvacu
4c6df8c5e5 unify some inputs 2024-08-29 09:18:43 -07:00
shelvacu
7312aab991 update flake 2024-08-28 23:11:43 -07:00
shelvacu
c56a26ff6d all is now all all 2024-08-28 22:43:46 -07:00
Shelvacu
88af0f1e93 add curl 2024-08-28 17:17:27 -07:00
Shelvacu
1b3aa80fe9 Merge branch 'restricted-inputs' 2024-08-28 17:15:01 -07:00
shelvacu
fccda582ef gimp 2024-08-23 10:49:20 -07:00
Shelvacu
8b9e199a23 give all configurations a restricted set of inputs 2024-08-21 19:13:43 -07:00
Shelvacu
addf748d1f wip 2024-08-21 17:11:38 -07:00
Shelvacu
b7b281604b add git version info to all vacu builds 2024-08-21 17:08:41 -07:00
Shelvacu
6782539b4a slash timeouts in haproxy 2024-08-21 16:32:32 -07:00
Shelvacu
0637a617e8 fw: remove librenms 2024-08-18 18:11:09 -07:00
shelvacu
4fc5864466 make into-nix-cache auto-sudo 2024-08-18 18:03:17 -07:00
shelvacu
e6e0fe6e47 Merge branch 'master' of git.uninsane.org:shelvacu/nix-stuff 2024-08-18 17:23:10 -07:00
Shelvacu
3e7bb2d2f8 compute-deck: add some modules to initrd, just in case 2024-08-18 16:08:55 -07:00
Shelvacu
c197b31a5f and fix compute-deck 2024-08-18 15:37:17 -07:00
Shelvacu
a1e4e2aa91 reorganize nix-on-droid config and set nixpkgs & vacu in flake registry 2024-08-18 15:30:39 -07:00
root
94d28b7f57 disable patches 2024-08-17 21:43:39 -07:00
root
03fc273124 stuff 2024-08-17 20:33:13 -07:00
root
8d9de94083 fix compute deck 2024-08-17 20:32:22 -07:00
Shelvacu
359be2b446 stuff 2024-08-17 15:49:54 -07:00
Shelvacu
9c8fdd958f wip home manager 2024-08-12 14:58:38 -07:00
Shelvacu
f248b0cb52 add root cert for vnopn router 2024-08-12 14:38:53 -07:00
Shelvacu
2740141b2b lets package a bunch of useless shit whaddya say 2024-08-12 14:20:40 -07:00
Shelvacu
7665e92138 add snmpb for some reason 2024-08-11 17:34:50 -07:00
root
0a4350f191 fix jl-stats 2024-08-11 11:55:40 -07:00
root
b0d9d1a987 add git-lfs 2024-08-06 11:11:40 -07:00
root
e5a12a1f17 wip jellyfin 2024-08-06 10:33:21 -07:00
root
9d8a096916 stuff 2024-08-04 16:26:35 -07:00
root
2f498e49c7 stuff 2024-07-29 17:29:28 -07:00
root
a351665606 stuff 2024-07-29 17:29:15 -07:00
Shelvacu
cd1865dbc5 update flake inputs 2024-07-27 23:29:45 -07:00
root
2458df3d17 add allWithBuildDeps to flake 2024-07-27 20:48:37 -07:00
Shelvacu
daaa70e148 stuff 2024-07-25 17:45:02 -07:00
Shelvacu
0d20e797ba stuff 2024-07-25 17:40:04 -07:00
Shelvacu
0354a47c12 mess with apex stuff some more 2024-07-21 18:49:17 -07:00
root
797ec7dd07 reorganize packages 2024-07-21 15:53:12 -07:00
root
09561eca09 add opencl stuff 2024-07-21 12:39:12 -07:00
Shelvacu
d5d28c940e stuff 2024-07-21 12:31:50 -07:00
Shelvacu
0d2d0688f7 try to integrate vacufuncs (didnt work) 2024-07-20 15:48:37 -07:00
Shelvacu
e8d2b3aa63 stuff 2024-07-20 15:48:37 -07:00
Shelvacu
7cab530d40 add inkscape and libreoffice 2024-07-17 18:10:24 -07:00
Shelvacu
c79ca06af3 add opencl support 2024-07-17 18:10:24 -07:00
Shelvacu
876dbb2dc9 add work laptop to known hosts 2024-07-16 13:08:06 -07:00
Shelvacu
3c77d14e9b workaround for too-small efi partitions :( 2024-07-15 01:02:33 -07:00
Shelvacu
546247a569 stuff 2024-07-15 00:29:54 -07:00
Shelvacu
e6ff9373dd add ostiary known host 2024-07-15 00:07:04 -07:00
Shelvacu
4d66f3d9a2 halfway add vacufuncs to nix-on-droid config 2024-07-14 23:31:36 -07:00
Shelvacu
86bf3807bc enable commands for nixos 2024-07-14 18:41:18 -07:00
Shelvacu
332f6aeb76 stuff 2024-07-13 11:01:49 -07:00
Shelvacu
4eeaa337b9 stuff 2024-07-11 15:55:27 -07:00
Shelvacu
22f6270a06 stuff 2024-07-11 15:53:56 -07:00
Shelvacu
18387da12a stuff 2024-07-11 15:53:17 -07:00
Shelvacu
3e8df621c7 stuff 2024-07-11 15:49:59 -07:00
Shelvacu
78ffdde588 move common into a folder 2024-07-11 13:59:23 -07:00
Shelvacu
16fc9d93ad stuff 2024-07-10 16:47:25 -07:00
Shelvacu
500ab33b1b mar is no longer working here 2024-07-10 13:47:34 -07:00
Shelvacu
7920bacadd stuff 2024-07-05 23:59:03 -07:00
Shelvacu
61149ff1dd stuff 2024-07-05 23:22:23 -07:00
Shelvacu
be44048523 stuff 2024-07-05 23:09:25 -07:00
Shelvacu
e9e0c87752 stuff 2024-07-05 23:07:39 -07:00
Shelvacu
ee29b1a997 stuff 2024-07-05 23:05:57 -07:00
Shelvacu
20b5803eb9 stuff 2024-07-05 23:04:48 -07:00
Shelvacu
d03709f9d2 stuff 2024-07-05 23:02:56 -07:00
Shelvacu
265c0abd68 stuff 2024-07-05 22:31:29 -07:00
Shelvacu
582ac9ec34 stuff 2024-07-05 22:30:00 -07:00
Shelvacu
7b554988b8 stuff 2024-07-05 22:29:05 -07:00
Shelvacu
4e333b948e stuff 2024-07-05 22:28:13 -07:00
Shelvacu
543f7dec34 stuff 2024-07-05 22:25:50 -07:00
Shelvacu
568bbc1d89 stuff 2024-07-05 22:22:38 -07:00
Shelvacu
8be73f95d0 stuff 2024-07-05 22:15:49 -07:00
Shelvacu
17b63089e6 move postgres data dir 2024-07-05 21:34:06 -07:00
Shelvacu
a4b195c389 stuff 2024-07-04 19:55:55 -07:00
root
d77d0d720a stuff 2024-07-04 15:10:22 -07:00
root
6807f5c960 agpl3 doesnt exist anymore?? 2024-07-04 15:07:17 -07:00
Shelvacu
7e6cf686bb stuff 2024-07-03 19:08:22 -07:00
Shelvacu
f37b6a4a46 stuff 2024-07-03 18:52:11 -07:00
Shelvacu
7211ffb30a stuff 2024-07-03 18:49:48 -07:00
Shelvacu
4ced20fb2d stuff 2024-07-03 18:35:12 -07:00
Shelvacu
f5af9886f5 stuff 2024-07-03 18:24:40 -07:00
Shelvacu
383b57bace stuff 2024-07-03 18:21:40 -07:00
Shelvacu
4eb20970b6 stuff 2024-07-03 18:08:05 -07:00
Shelvacu
0288181706 add migadu creds 2024-07-03 17:57:23 -07:00
Shelvacu
a0f11550c5 stuff 2024-07-03 17:51:25 -07:00
Shelvacu
80b2ff8951 stuff 2024-07-03 17:47:37 -07:00
Shelvacu
d7b37b0353 stuff 2024-07-03 17:42:04 -07:00
Shelvacu
ab5168632e stuff 2024-07-03 17:39:55 -07:00
Shelvacu
569043b6ca stuff 2024-07-03 17:36:30 -07:00
Shelvacu
620fec48ea give up and update everything to 24.05 2024-07-03 17:35:22 -07:00
Shelvacu
3d734769cd stuff 2024-07-03 17:32:34 -07:00
Shelvacu
14fce1d271 stuff 2024-07-03 17:30:11 -07:00
Shelvacu
d09117418f stuff 2024-07-03 17:29:05 -07:00
Shelvacu
0c4c590dc3 stuff 2024-07-03 17:28:17 -07:00
Shelvacu
06d40673dd stuff 2024-07-03 17:23:48 -07:00
Shelvacu
63e44f4766 stuff 2024-07-03 17:19:03 -07:00
Shelvacu
4b54a38998 stuff 2024-07-03 16:54:59 -07:00
Shelvacu
e9c0ba445c stuff 2024-07-03 16:51:57 -07:00
Shelvacu
13564a3655 stuff 2024-07-03 16:50:35 -07:00
Shelvacu
c30b275bb7 stuff 2024-07-03 16:48:37 -07:00
Shelvacu
f809262290 stuff 2024-07-03 16:41:37 -07:00
Shelvacu
789dc5397d stuff 2024-07-03 16:39:50 -07:00
Shelvacu
5464a052ed Merge branch 'liam-relay' of git.uninsane.org:shelvacu/nix-stuff into liam-relay 2024-07-03 16:19:35 -07:00
Shelvacu
7d0c463de1 stuff 2024-07-03 16:17:11 -07:00
Shelvacu
ce37f30c39 stuff 2024-07-03 16:02:57 -07:00
Shelvacu
52a54f1b50 stuff 2024-07-03 15:52:46 -07:00
Shelvacu
a5585d8bb7 stuff 2024-07-01 21:46:35 -07:00
Shelvacu
4f31ae0727 stuff 2024-07-01 21:45:34 -07:00
Shelvacu
08a778a4d5 stuff 2024-07-01 21:43:31 -07:00
Shelvacu
26194a2994 stuff 2024-07-01 21:39:14 -07:00
Shelvacu
7055fe0678 stuff 2024-07-01 21:34:31 -07:00
Shelvacu
a0cd2fb6a2 stuff 2024-07-01 21:34:13 -07:00
Shelvacu
cba177bc03 stuff 2024-07-01 21:31:52 -07:00
Shelvacu
18f1c074de stuff 2024-07-01 21:20:22 -07:00
Shelvacu
c08442e624 stuff 2024-07-01 21:18:53 -07:00
Shelvacu
540531634b stuff 2024-07-01 21:14:16 -07:00
Shelvacu
e39fe28776 stuff 2024-07-01 21:13:33 -07:00
Shelvacu
5bbf66e323 stuff 2024-07-01 21:12:13 -07:00
Shelvacu
992c0301e3 stuff 2024-07-01 21:07:04 -07:00
Shelvacu
603cb25f95 stuff 2024-07-01 21:04:52 -07:00
Shelvacu
be2071785d stuff 2024-07-01 21:01:10 -07:00
Shelvacu
2977a455db stuff 2024-07-01 20:59:46 -07:00
Shelvacu
b3d3ff1c96 stuff 2024-07-01 20:50:37 -07:00
Shelvacu
9a79e42184 stuff 2024-07-01 20:48:08 -07:00
Shelvacu
4fbbbaad24 stuff 2024-07-01 20:41:47 -07:00
Shelvacu
f363261a26 stuff 2024-07-01 20:40:10 -07:00
Shelvacu
9b62f51b4e stuff 2024-07-01 20:36:49 -07:00
Shelvacu
52d81bc607 stuff 2024-07-01 20:34:50 -07:00
Shelvacu
4624dbea90 stuff 2024-07-01 20:33:10 -07:00
Shelvacu
df117c4eed stuff 2024-07-01 20:30:38 -07:00
Shelvacu
35edf8667b stuff 2024-07-01 20:28:47 -07:00
Shelvacu
7d773121c4 stuff 2024-07-01 20:28:32 -07:00
Shelvacu
b544246cf0 stuff 2024-07-01 19:43:34 -07:00
Shelvacu
a39ee64db6 stuff 2024-07-01 19:42:57 -07:00
Shelvacu
e54d387104 stuff 2024-07-01 19:42:14 -07:00
Shelvacu
56dee4d47c stuff 2024-07-01 19:41:15 -07:00
Shelvacu
044359ac25 this is my first official try 2024-07-01 19:39:02 -07:00
Shelvacu
3f5200b574 wip 2024-07-01 16:43:20 -07:00
Shelvacu
702d48e825 stuff 2024-07-01 16:38:01 -07:00
Shelvacu
6d6ab0baf4 wip 2024-07-01 16:36:59 -07:00
Shelvacu
e304d4d20b stuff 2024-06-29 15:47:06 -07:00
Shelvacu
95d8f3b836 stuff 2024-06-29 15:45:51 -07:00
Shelvacu
aadbf8e874 stuff 2024-06-29 15:43:54 -07:00
Shelvacu
9d9ee9b083 stuff 2024-06-29 15:41:11 -07:00
Shelvacu
b918fff3dd stuff 2024-06-29 14:47:17 -07:00
Shelvacu
0e15d716f0 stuff 2024-06-29 14:33:52 -07:00
Shelvacu
b45f539fb1 stuff 2024-06-29 14:33:24 -07:00
Shelvacu
0b63217f7b stuff 2024-06-29 14:06:54 -07:00
Shelvacu
73b465bd30 stuff 2024-06-29 14:06:44 -07:00
Shelvacu
55338e81ac stuff 2024-06-29 14:02:56 -07:00
Shelvacu
6e005ff10f stuff 2024-06-29 13:35:19 -07:00
Shelvacu
2f5cc60b00 stuff 2024-06-29 13:28:18 -07:00
Shelvacu
a6f8543ac9 stuff 2024-06-29 13:22:58 -07:00
Shelvacu
d7cff14bae stuff 2024-06-29 13:05:36 -07:00
Shelvacu
9049153ff4 stuff 2024-06-29 13:04:17 -07:00
shelvacu
0756e0d8bf stuff 2024-06-28 17:15:30 -07:00
shelvacu
691a54cbfc stuff 2024-06-28 16:36:24 -07:00
shelvacu
2434e6693f stuff 2024-06-28 16:26:14 -07:00
shelvacu
77e3232ad7 stuff 2024-06-28 16:19:28 -07:00
shelvacu
782aea9f1a stuff 2024-06-28 16:18:54 -07:00
shelvacu
64c6bcbe7a stuff 2024-06-28 16:18:38 -07:00
shelvacu
4d4a6c13cc stuff 2024-06-28 16:16:05 -07:00
shelvacu
217fba6035 stuff 2024-06-28 16:07:34 -07:00
shelvacu
e7a60417a2 stuff 2024-06-28 16:07:16 -07:00
73 changed files with 4505 additions and 1546 deletions

View File

@@ -1,13 +1,31 @@
more just notes for now
---
deploy:
```sh
nixos-rebuild switch --flake .#triple-dezert --target-host trip.shelvacu.com --use-remote-sudo
```
---
build flake on remote machine, including eval:
```sh
git add . && ssh trip nix flake check $(nix flake archive --to ssh://trip --json | jq .path -r)
```
```
---
search for string in closure
```sh
rg search_str $(nix path-info --recursive ./result)
```
or
```sh
rg search_str $(nix path-info --recursive .#qb.trip)
```

View File

@@ -1,289 +0,0 @@
{ config, pkgs, lib, inputs, ... }: let
inherit (lib) mkOption types flip concatMapStringsSep optionalString concatStringsSep readFile mapAttrsToList literalExpression;
inherit (builtins) attrValues;
cfg = config.vacu;
knownHosts = attrValues cfg.ssh.knownHosts;
knownHostsText = (flip (concatMapStringsSep "\n") knownHosts
(h: assert h.hostNames != [];
optionalString h.certAuthority "@cert-authority " + concatStringsSep "," h.hostNames + " "
+ (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile)
)) + "\n";
packageNames = lib.splitString "\n" ''
nixos-rebuild
nano
vim
wget
screen
tmux
lsof
htop
mosh
dnsutils
iperf3
nmap
rsync
ethtool
sshfs
ddrescue
pciutils
ncdu
nix-index
git
pv
unzip
file
ripgrep
jq
units
tree
rclone
iputils
ssh-to-age
sops
inetutils
neovim
diffutils
findutils
utillinux
tzdata
hostname
man
gnugrep
gnused
gnutar
bzip2
gzip
xz
zip
unzip
openssh
dig
bash
termscp
git'';
plainPackageOpts = map (name: { name = name; value = { enable = lib.mkDefault true; }; }) packageNames;
packageOpts = lib.recursiveUpdate (builtins.listToAttrs plainPackageOpts) {
nix-search-cli.package = inputs.nix-search-cli.packages.${pkgs.system}.default;
nix-search-cli.enable = lib.mkDefault true;
nix-inspect.package = inputs.nix-inspect.packages.${pkgs.system}.default;
nix-inspect.enable = lib.mkDefault true;
};
in {
imports = [ ./package-set.nix ];
options = {
vacu.ssh.authorizedKeys = mkOption {
type = types.listOf types.str;
};
vacu.ssh.config = mkOption {
type = types.lines;
};
# Straight copied from nixpkgs
# https://github.com/NixOS/nixpkgs/blob/46397778ef1f73414b03ed553a3368f0e7e33c2f/nixos/modules/programs/ssh.nix
vacu.ssh.knownHosts = mkOption {
default = {};
type = types.attrsOf (types.submodule ({ name, config, options, ... }: {
options = {
certAuthority = mkOption {
type = types.bool;
default = false;
description = ''
This public key is an SSH certificate authority, rather than an
individual host's key.
'';
};
hostNames = mkOption {
type = types.listOf types.str;
default = [ name ] ++ config.extraHostNames;
defaultText = literalExpression "[ ${name} ] ++ config.${options.extraHostNames}";
description = ''
A list of host names and/or IP numbers used for accessing
the host's ssh service. This list includes the name of the
containing `knownHosts` attribute by default
for convenience. If you wish to configure multiple host keys
for the same host use multiple `knownHosts`
entries with different attribute names and the same
`hostNames` list.
'';
};
extraHostNames = mkOption {
type = types.listOf types.str;
default = [];
description = ''
A list of additional host names and/or IP numbers used for
accessing the host's ssh service. This list is ignored if
`hostNames` is set explicitly.
'';
};
publicKey = mkOption {
default = null;
type = types.nullOr types.str;
example = "ecdsa-sha2-nistp521 AAAAE2VjZHN...UEPg==";
description = ''
The public key data for the host. You can fetch a public key
from a running SSH server with the {command}`ssh-keyscan`
command. The public key should not include any host names, only
the key type and the key itself.
'';
};
publicKeyFile = mkOption {
default = null;
type = types.nullOr types.path;
description = ''
The path to the public key file for the host. The public
key file is read at build time and saved in the Nix store.
You can fetch a public key file from a running SSH server
with the {command}`ssh-keyscan` command. The content
of the file should follow the same format as described for
the `publicKey` option. Only a single key
is supported. If a host has multiple keys, use
{option}`programs.ssh.knownHostsFiles` instead.
'';
};
};
}));
description = ''
The set of system-wide known SSH hosts. To make simple setups more
convenient the name of an attribute in this set is used as a host name
for the entry. This behaviour can be disabled by setting
`hostNames` explicitly. You can use
`extraHostNames` to add additional host names without
disabling this default.
'';
example = literalExpression ''
{
myhost = {
extraHostNames = [ "myhost.mydomain.com" "10.10.1.4" ];
publicKeyFile = ./pubkeys/myhost_ssh_host_dsa_key.pub;
};
"myhost2.net".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILIRuJ8p1Fi+m6WkHV0KWnRfpM1WxoW8XAS+XvsSKsTK";
"myhost2.net/dsa" = {
hostNames = [ "myhost2.net" ];
publicKeyFile = ./pubkeys/myhost2_ssh_host_dsa_key.pub;
};
}
'';
};
vacu.nix.extraSubstituters = mkOption { type = types.listOf types.str; };
vacu.nix.extraTrustedKeys = mkOption { type = types.listOf types.str; };
};
config = {
vacu.packages = packageOpts;
vacu.nix.extraSubstituters = [
"https://nixcache.shelvacu.com/"
"https://nix-community.cachix.org/"
];
vacu.nix.extraTrustedKeys = [
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
"nixcache.shelvacu.com:73u5ZGBpPRoVZfgNJQKYYBt9K9Io/jPwgUfuOLsJbsM="
];
assertions = flip mapAttrsToList cfg.ssh.knownHosts (name: data: {
assertion = (data.publicKey == null && data.publicKeyFile != null) ||
(data.publicKey != null && data.publicKeyFile == null);
message = "knownHost ${name} must contain either a publicKey or publicKeyFile";
});
vacu.ssh.authorizedKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC4LYvUe9dsQb9OaTDFI4QKPtMmOHOGLwWsXsEmcJW86" # Termux on pixel6pro
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHcYwYy9/0Gu/GsqS72Nkz6OkId+zevqXA/aTIcvqflp" # t460s windows
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFsErA6M9LSHj2hPlLuHD8Lpei7WjMup1JxI1vxA6B8W" # pixel6pro nix-on-droid
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKoy1TrmfhBGWtVedgOM1FB1oD2UdodN3LkBnnLx6Tug" # compute-deck
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICVeSzDkGTueZijB0xUa08e06ovAEwwZK/D+Cc7bo91g" # triple-dezert
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOtwtao/TXbiuQOYJbousRPVesVcb/2nP0PCFUec0Nv8" # triple-dezert (root)
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAxAFFxQMXAgi+0cmGaNE/eAkVfEl91wafUqFIuAkI5I" # compute-deck (root)
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDcRDekd8ZOYfQS5X95/yNof3wFYIbHqWeq4jY0+ywQX" # pro1x nix-on-droid
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExSObd1lZprdqAFLqFhtxDEckV0q/vZZIYqrYFKfkoC" # devver
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGHLPOxRd68+DJ/bYmqn0wsgwwIcMSMyuU1Ya16hCb/m" # fw (root)
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINQ2c0GzlVMjV06CS7bWbCaAbzG2+7g5FCg/vClJPe0C" # fw
];
vacu.ssh.config = ''
Host deckvacu
User deck
Host rsb
User user
HostName finaltask.xyz
Port 2222
Host awoo
HostName 45.142.157.71
Host trip
HostName trip.shelvacu.com
Port 6922
Host liam
HostName 178.128.79.152
Host pluto
HostName pluto.somevideogam.es
Host *
User shelvacu
GlobalKnownHostsFile ${pkgs.writeText "known_hosts" knownHostsText}
'';
vacu.ssh.knownHosts = {
#public hosts
"github.com".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
"gitlab.com".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf";
#colin's stuff
"uninsane.org" = {
extraHostNames = [ "git.uninsane.org" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfdSmFkrVT6DhpgvFeQKm3Fh9VKZ9DbLYOPOJWYQ0E8";
};
"desko" = {
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFw9NoRaYrM6LbDd3aFBc4yyBlxGQn8HjeHd/dZ3CfHk";
};
#daymocker's stuff
"pluto" = {
extraHostNames = [ "74.208.184.137" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICpHY4fLZ1hNuB2oRQM7R3b4eQyIHbFB45ZYp3XCELLg";
};
#personal hosts
"zigbee-hub" = {
extraHostNames = [ "10.78.79.114" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBJxwUYddOxgViJDOiokfaQ6CsCx/Sw+b3IisdJv8zFN root@zigbee-hub";
};
trip = {
extraHostNames = [ "triple-dezert" "trip.shelvacu.com" "[trip.shelvacu.com]:6922" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGUQux9V0mSF5IauoO1z311NXR7ymEbwRMzT+OaaNQr+";
};
servacu = {
extraHostNames = [ "mail.dis8.net" "servacu.shelvacu.com" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE+E6na7np0HnBV2X7owno+Fg+bNNRSHLxO6n1JzdUTV";
};
finaltask = {
extraHostNames = [ "rsb" "finaltask.xyz" "[finaltask.xyz]:2222" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTx8WBNNKBVRV98HgDChpd59SHbreJ87SXU+zOKan6y";
};
compute-deck = {
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGt43GmXCxkl5QjgPQ/QimW11lKfXmV4GFWvlxQSf4TQ";
};
"2esrever" = {
extraHostNames = [ "10.4.5.218" "10.244.46.71" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH0LnPrJxAdffZ//uRe3NBiIfFCBNMLqKVylkyU0llvT";
};
awoo = {
extraHostNames = [ "45.142.157.71" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOQaDjjfSK8jnk9aFIiYH9LZO4nLY/oeAc7BKIPUXMh1";
};
deckvacu = {
publicKey = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEa8qpFkIlLLJkH8rmEAn6/MZ9ilCGmEQWC3CeFae7r1kOqfwRk0nq0oyOGJ50uIh+PpwEh3rbgq6mLfpRfsFmM=";
};
liam = {
extraHostNames = [ "liam.dis8.net" "178.128.79.152" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHOqJYVHOIFmEA5uRbbirIupWvyBLAFwic/8EZQRdN/c";
};
devver = {
extraHostNames = [ "devver.t2d.lan" "10.78.79.10" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFeFaH2tzWIiCPdKNmxl3NqCnPTdmVIOBinauUAEl+UU";
};
fw = {
extraHostNames = [ "fw.t2d.lan" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA6lX25mCy35tf1NpcHMAdeRgvT7l0Dw0FWBH3eX4TE2";
};
};
};
}

View File

@@ -1,81 +0,0 @@
{ lib, pkgs, config, inputs, utils, ... }:
{
imports = [ ./common-config.nix ];
options.vacu.acmeCertDependencies = lib.mkOption {
default = {};
example = ''
vacu.acmeCertDependencies."mail.example.com" = [ "postfix.service" ];
'';
type = lib.types.attrsOf (lib.types.listOf utils.systemdUtils.lib.unitNameType);
};
config = let
for-systemd-services = lib.concatMapAttrs
(cert: units:
{
"acme-selfsigned-${cert}" = {
wantedBy = units;
before = units;
};
}
)
config.vacu.acmeCertDependencies;
for-security-acme-certs = lib.concatMapAttrs
(cert: units:
{
${cert}.reloadServices = units;
}
)
config.vacu.acmeCertDependencies;
in {
console = {
keyMap = lib.mkDefault "us";
};
vacu.packages."xorg-xev" = {
enable = config.services.xserver.enable;
package = pkgs.xorg.xev;
};
environment.systemPackages = config.vacu.packageList;
i18n.defaultLocale = lib.mkDefault "en_US.UTF-8";
time.timeZone = "America/Los_Angeles";
users.users.shelvacu = {
openssh.authorizedKeys.keys = config.vacu.ssh.authorizedKeys;
isNormalUser = true;
extraGroups = [ "wheel" ];
};
systemd.services = for-systemd-services;
security.acme.certs = for-security-acme-certs;
services.openssh = {
# require public key authentication for better security
settings.PasswordAuthentication = false;
settings.KbdInteractiveAuthentication = false;
settings.PermitRootLogin = "prohibit-password";
};
nix.settings.trusted-users = [ "shelvacu" ];
security.sudo.wheelNeedsPassword = lib.mkDefault false;
programs.screen = {
screenrc = ''
defscrollback 10000
termcapinfo xterm* ti@:te@
'';
} // (if config.system.nixos.release == "23.11" then {} else { enable = true; });
programs.tmux.enable = true;
programs.tmux.extraConfig = "setw mouse";
programs.tmux.clock24 = true;
nix.settings = {
experimental-features = [ "nix-command" "flakes" ];
substituters = config.vacu.nix.extraSubstituters;
trusted-public-keys = config.vacu.nix.extraTrustedKeys;
};
nixpkgs.config.allowUnfree = lib.mkDefault true;
programs.mosh.enable = lib.mkDefault true;
programs.ssh.extraConfig = config.vacu.ssh.config;
};
}

View File

@@ -1,37 +0,0 @@
{ pkgs, inputs }: (with pkgs; [
inputs.nix-search-cli.packages.${pkgs.system}.default
inputs.nix-inspect.packages.${pkgs.system}.default
nixos-rebuild
nano
vim
wget
screen
tmux
lsof
htop
mosh
dnsutils
iperf3
nmap
rsync
ethtool
sshfs
ddrescue
pciutils
ncdu
nix-index
git
pv
unzip
file
ripgrep
jq
units
tree
rclone
iputils
ssh-to-age
sops
inetutils
neovim
])

View File

@@ -0,0 +1,9 @@
# todo: rename this module
# stuff that does actual configuring (so can't be in ./module.nix) but works in nixos module, home-manager modules, and nix-on-droid modules
{ inputs, ... }:
{
nix.registry.vacu.to = {
type = "path";
path = inputs.self.outPath;
};
}

7
common/home.nix Normal file
View File

@@ -0,0 +1,7 @@
{ ... }:
let
in
{
imports = [ ./common-but-not.nix ];
}

292
common/module.nix Normal file
View File

@@ -0,0 +1,292 @@
{
config,
pkgs,
lib,
inputs,
...
}:
let
inherit (lib) mkOption types;
inherit (inputs) self;
in
{
imports = [
./package-set.nix
./shell
./ssh.nix
./nix.nix
./verify-system
];
options = {
vacu.rootCAs = mkOption { type = types.listOf types.str; };
vacu.versionId = mkOption {
type = types.str;
readOnly = true;
};
vacu.versionInfo = mkOption { readOnly = true; };
vacu.hostName = mkOption { type = types.str; };
vacu.shortHostName = mkOption {
type = types.str;
default = config.vacu.hostName;
};
vacu.nixvimPkg = mkOption { readOnly = true; };
};
config = {
vacu.packages =
(with pkgs; [
home-manager
nixos-rebuild
which
nano
vim
wget
screen
tmux
lsof
htop
mosh
dnsutils
iperf3
nmap
rsync
ethtool
sshfs
ddrescue
pciutils
ncdu
nix-index
git
pv
unzip
file
ripgrep
jq
units
tree
rclone
iputils
ssh-to-age
sops
inetutils
neovim
diffutils
findutils
utillinux
tzdata
hostname
man
gnugrep
gnused
gnutar
bzip2
gzip
xz
zip
unzip
openssh
dig
bash
termscp
usbutils
ruby
psutils
killall
git
curl
])
++ [
inputs.nix-search-cli.packages.${pkgs.system}.default
inputs.nix-inspect.packages.${pkgs.system}.default
];
vacu.nixvimPkg = inputs.nixvim.legacyPackages.${pkgs.system}.makeNixvimWithModule {
extraSpecialArgs = {
inherit inputs;
};
module = {
imports = [ ../nixvim ];
};
};
vacu.versionId = toString (self.shortRev or self.dirtyShortRev);
vacu.versionInfo = {
id = self.rev or self.dirtyRev;
flakePath = self.outPath;
inherit inputs; # inputs = lib.mapAttrs (i: i.outPath) inputs;
};
vacu.nix.caches.nixcache-shelvacu = {
url = "https://nixcache.shelvacu.com/";
keys = [ "nixcache.shelvacu.com:73u5ZGBpPRoVZfgNJQKYYBt9K9Io/jPwgUfuOLsJbsM=" ];
};
vacu.nix.caches.nix-community = {
url = "https://nix-community.cachix.org/";
keys = [ "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" ];
};
vacu.nix.caches.nix-on-droid = {
url = "https://nix-on-droid.cachix.org/";
keys = [ "nix-on-droid.cachix.org-1:56snoMJTXmDRC1Ei24CmKoUqvHJ9XCp+nidK7qkMQrU=" ];
};
vacu.nix.caches.nixos = {
url = "https://cache.nixos.org/";
keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
};
vacu.rootCAs = [
''
-----BEGIN CERTIFICATE-----
MIIBnjCCAUWgAwIBAgIBBTAKBggqhkjOPQQDAjAgMQswCQYDVQQGEwJVUzERMA8G
A1UEAxMIdm5vcG4gQ0EwHhcNMjQwODEyMjExNTQwWhcNMzQwODEwMjExNTQwWjAg
MQswCQYDVQQGEwJVUzERMA8GA1UEAxMIdm5vcG4gQ0EwWTATBgcqhkjOPQIBBggq
hkjOPQMBBwNCAARqRbSeq00FfYUGeCHVkzwrjrydI56T12xy+iut0c4PemSuhyxC
AgfdKYtDqMNZmSqMaLihzkBenD0bN5i0ndjho3AwbjAPBgNVHRMBAf8EBTADAQH/
MCwGA1UdHgEB/wQiMCCgGDAKhwgKTkwA///8ADAKgggudDJkLmxhbqEEMAKBADAO
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFAjSkbJQCQc1WP6nIP5iLDIKGFrdMAoG
CCqGSM49BAMCA0cAMEQCIFtyawkZqFhvzgmqG/mYNNO6DdsQTPQ46x/08yrEiiF4
AiA+FwAPqX+CBkaSdIhuhv1kIecmvacnDL5kpyB+9nDodw==
-----END CERTIFICATE-----
''
];
vacu.ssh.authorizedKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC4LYvUe9dsQb9OaTDFI4QKPtMmOHOGLwWsXsEmcJW86" # Termux on pixel6pro
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHcYwYy9/0Gu/GsqS72Nkz6OkId+zevqXA/aTIcvqflp" # t460s windows
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFsErA6M9LSHj2hPlLuHD8Lpei7WjMup1JxI1vxA6B8W" # pixel6pro nix-on-droid
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKoy1TrmfhBGWtVedgOM1FB1oD2UdodN3LkBnnLx6Tug" # compute-deck
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICVeSzDkGTueZijB0xUa08e06ovAEwwZK/D+Cc7bo91g" # triple-dezert
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOtwtao/TXbiuQOYJbousRPVesVcb/2nP0PCFUec0Nv8" # triple-dezert (root)
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAxAFFxQMXAgi+0cmGaNE/eAkVfEl91wafUqFIuAkI5I" # compute-deck (root)
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDcRDekd8ZOYfQS5X95/yNof3wFYIbHqWeq4jY0+ywQX" # pro1x nix-on-droid
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExSObd1lZprdqAFLqFhtxDEckV0q/vZZIYqrYFKfkoC" # devver
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGHLPOxRd68+DJ/bYmqn0wsgwwIcMSMyuU1Ya16hCb/m" # fw (root)
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINQ2c0GzlVMjV06CS7bWbCaAbzG2+7g5FCg/vClJPe0C" # fw
];
vacu.ssh.config = ''
Host deckvacu
User deck
Host rsb
User user
HostName finaltask.xyz
Port 2222
Host awoo
HostName 45.142.157.71
Host trip
HostName trip.shelvacu.com
Port 6922
Host liam
HostName 178.128.79.152
Host pluto
HostName pluto.somevideogam.es
Host *
User shelvacu
GlobalKnownHostsFile ${pkgs.writeText "known_hosts" config.vacu.ssh.knownHostsText}
'';
vacu.ssh.knownHosts = {
#public hosts
"github.com".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
"gitlab.com".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf";
"git.sr.ht".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMZvRd4EtM7R+IHVMWmDkVU3VLQTSwQDSAvW0t2Tkj60";
#colin's stuff
"uninsane.org" = {
extraHostNames = [ "git.uninsane.org" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfdSmFkrVT6DhpgvFeQKm3Fh9VKZ9DbLYOPOJWYQ0E8";
};
"desko" = {
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFw9NoRaYrM6LbDd3aFBc4yyBlxGQn8HjeHd/dZ3CfHk";
};
#daymocker's stuff
"pluto" = {
extraHostNames = [ "74.208.184.137" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICpHY4fLZ1hNuB2oRQM7R3b4eQyIHbFB45ZYp3XCELLg";
};
#powerhouse hosts
"ostiary" = {
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBSYyd1DGPXGaV4mD34tUbXvbtIi/Uv2otoMUsCkxRse";
};
"habitat" = {
# previously known as zigbee-hub
extraHostNames = [ "10.78.79.114" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBJxwUYddOxgViJDOiokfaQ6CsCx/Sw+b3IisdJv8zFN";
};
"vnopn" = {
extraHostNames = [
"10.78.79.1"
"vnopn.t2d.lan"
];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEMgJE8shlTYF3nxKR/aILd1SzwDwhtCrjz9yHL7lgSZ";
};
#work laptop
"tebbs-MBP" = {
extraHostNames = [ "10.244.10.3" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKO/ks07zSByDH/qmDrghtBSFwWnze2s62zEmtXwaMJe";
};
#personal hosts
trip = {
extraHostNames = [
"triple-dezert"
"trip.shelvacu.com"
"[trip.shelvacu.com]:6922"
];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGUQux9V0mSF5IauoO1z311NXR7ymEbwRMzT+OaaNQr+";
};
servacu = {
extraHostNames = [
"mail.dis8.net"
"servacu.shelvacu.com"
];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE+E6na7np0HnBV2X7owno+Fg+bNNRSHLxO6n1JzdUTV";
};
finaltask = {
extraHostNames = [
"rsb"
"finaltask.xyz"
"[finaltask.xyz]:2222"
];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTx8WBNNKBVRV98HgDChpd59SHbreJ87SXU+zOKan6y";
};
compute-deck = {
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGt43GmXCxkl5QjgPQ/QimW11lKfXmV4GFWvlxQSf4TQ";
};
"2esrever" = {
extraHostNames = [
"10.4.5.218"
"10.244.46.71"
];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH0LnPrJxAdffZ//uRe3NBiIfFCBNMLqKVylkyU0llvT";
};
awoo = {
extraHostNames = [ "45.142.157.71" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOQaDjjfSK8jnk9aFIiYH9LZO4nLY/oeAc7BKIPUXMh1";
};
deckvacu = {
publicKey = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEa8qpFkIlLLJkH8rmEAn6/MZ9ilCGmEQWC3CeFae7r1kOqfwRk0nq0oyOGJ50uIh+PpwEh3rbgq6mLfpRfsFmM=";
};
liam = {
extraHostNames = [
"liam.dis8.net"
"178.128.79.152"
];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHOqJYVHOIFmEA5uRbbirIupWvyBLAFwic/8EZQRdN/c";
};
devver = {
extraHostNames = [
"devver.t2d.lan"
"10.78.79.10"
];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFeFaH2tzWIiCPdKNmxl3NqCnPTdmVIOBinauUAEl+UU";
};
fw = {
extraHostNames = [ "fw.t2d.lan" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA6lX25mCy35tf1NpcHMAdeRgvT7l0Dw0FWBH3eX4TE2";
};
};
};
}

21
common/nix-on-droid.nix Normal file
View File

@@ -0,0 +1,21 @@
{ config, lib, ... }:
let
inherit (lib) mkDefault;
in
{
imports = [
./module.nix
./common-but-not.nix
];
environment.packages = config.vacu.packageList;
environment.etc."ssh/ssh_config".text = config.vacu.ssh.config;
nix.substituters = lib.mkForce config.vacu.nix.substituterUrls;
nix.trustedPublicKeys = lib.mkForce config.vacu.nix.trustedKeys;
vacu.shell.functionsDir = "${config.user.home}/.nix-profile/share/vacufuncs";
environment.etc.bashrc.text = config.vacu.shell.interactiveLines;
environment.etc.profile.text = config.vacu.shell.interactiveLines;
environment.etc."vacu.json".text = builtins.toJSON config.vacu.versionInfo;
vacu.hostName = mkDefault "nix-on-droid";
vacu.shortHostName = mkDefault "nod";
}

36
common/nix.nix Normal file
View File

@@ -0,0 +1,36 @@
{ lib, config, ... }:
let
inherit (lib) mkOption types;
caches = builtins.attrValues config.vacu.nix.caches;
enabledCaches = builtins.filter (c: c.enable) caches;
in
{
options = {
vacu.nix.caches = mkOption {
type = types.attrsOf (
types.submodule (
{ name, ... }:
{
options = {
url = mkOption { type = types.str; };
keys = mkOption {
type = types.listOf types.str;
default = [ ];
};
enable = mkOption {
default = true;
type = types.bool;
};
};
}
)
);
};
vacu.nix.substituterUrls = mkOption { readOnly = true; };
vacu.nix.trustedKeys = mkOption { readOnly = true; };
vacu.nix.plainOptions = mkOption { };
};
config.vacu.nix.substituterUrls = map (c: c.url) enabledCaches;
config.vacu.nix.trustedKeys = builtins.concatMap (c: c.keys) enabledCaches;
config.vacu.nix.plainOptions.allowUnfree = true;
}

114
common/nixos.nix Normal file
View File

@@ -0,0 +1,114 @@
{
lib,
pkgs,
config,
inputs,
utils,
...
}:
{
imports = [
./module.nix
./common-but-not.nix
./verify-system/nixos.nix
];
options.vacu.underTest = lib.mkOption {
default = false;
type = lib.types.bool;
};
options.vacu.acmeCertDependencies = lib.mkOption {
default = { };
example = ''
vacu.acmeCertDependencies."mail.example.com" = [ "postfix.service" ];
'';
type = lib.types.attrsOf (lib.types.listOf utils.systemdUtils.lib.unitNameType);
};
config =
let
for-systemd-services = lib.concatMapAttrs (cert: units: {
"acme-selfsigned-${cert}" = {
wantedBy = units;
before = units;
};
}) config.vacu.acmeCertDependencies;
for-security-acme-certs = lib.concatMapAttrs (cert: units: {
${cert}.reloadServices = units;
}) config.vacu.acmeCertDependencies;
in
{
console = {
keyMap = lib.mkDefault "us";
};
networking.hostName = config.vacu.hostName;
vacu.packages."xorg-xev" = {
enable = config.services.xserver.enable;
package = pkgs.xorg.xev;
};
environment.systemPackages = config.vacu.packageList;
programs.git = {
enable = true;
lfs.enable = true;
};
system.nixos.tags = [
"vacu${config.vacu.versionId}"
config.vacu.hostName
];
environment.etc."vacu.json".text = builtins.toJSON config.vacu.versionInfo;
i18n.defaultLocale = lib.mkDefault "en_US.UTF-8";
time.timeZone = "America/Los_Angeles";
users.users.shelvacu = {
openssh.authorizedKeys.keys = config.vacu.ssh.authorizedKeys;
isNormalUser = true;
extraGroups = [ "wheel" ];
};
systemd.services = for-systemd-services;
security.acme.certs = for-security-acme-certs;
services.openssh = {
# require public key authentication for better security
settings.PasswordAuthentication = false;
settings.KbdInteractiveAuthentication = false;
settings.PermitRootLogin = "prohibit-password";
};
nix.settings.trusted-users = [ "shelvacu" ];
security.sudo.wheelNeedsPassword = lib.mkDefault false;
programs.screen = {
screenrc = ''
defscrollback 10000
termcapinfo xterm* ti@:te@
maptimeout 5
'';
} // (if config.system.nixos.release == "23.11" then { } else { enable = true; });
programs.tmux.enable = true;
programs.tmux.extraConfig = "setw mouse";
programs.tmux.clock24 = true;
nix.settings = {
experimental-features = [
"nix-command"
"flakes"
];
substituters = lib.mkForce config.vacu.nix.substituterUrls;
extra-substituters = lib.mkForce [ ];
trusted-public-keys = lib.mkForce config.vacu.nix.trustedKeys;
extra-trusted-public-keys = lib.mkForce [ ];
};
nixpkgs.config.allowUnfree = lib.mkDefault true;
programs.mosh.enable = lib.mkDefault true;
programs.ssh.extraConfig = config.vacu.ssh.config;
security.pki.certificates = config.vacu.rootCAs;
# commands.nix
environment.pathsToLink = [ "/share/vacufuncs" ];
vacu.shell.functionsDir = "/run/current-system/sw/share/vacufuncs";
programs.bash.interactiveShellInit = config.vacu.shell.interactiveLines;
programs.bash.promptInit = lib.mkForce "";
};
}

76
common/package-set.nix Normal file
View File

@@ -0,0 +1,76 @@
{
config,
pkgs,
lib,
...
}:
let
inherit (lib) mkOption types;
pkgOptions = builtins.attrValues config.vacu.packages;
enabledOptions = builtins.filter (o: o.enable) pkgOptions;
enabledPkgs = builtins.map (o: o.package) enabledOptions;
packagesSetType = types.attrsOf (
types.submodule (
{
name,
config,
options,
...
}:
{
options = {
enable = mkOption {
type = types.bool;
description = "Will this package be installed (included in environment.systemPackages)";
};
package = mkOption {
type = types.package;
default = pkgs.${name};
defaultText = "pkgs.${name}";
};
};
}
)
);
packageListToSet = (
from:
let
keyvals = map (
val:
if builtins.isString val then
{
name = val;
value = {
package = pkgs."${val}";
enable = lib.mkDefault true;
};
}
else
{
name = val.name;
value = {
package = val;
enable = lib.mkDefault true;
};
}
) from;
in
builtins.listToAttrs keyvals
);
in
{
options = {
vacu.packages = mkOption {
default = { };
type = types.coercedTo (types.listOf (
types.either types.str types.package
)) packageListToSet packagesSetType;
};
vacu.packageList = mkOption {
type = types.listOf types.package;
readOnly = true;
};
};
config.vacu.packageList = enabledPkgs;
}

97
common/shell/default.nix Normal file
View File

@@ -0,0 +1,97 @@
{
config,
lib,
pkgs,
vaculib,
...
}:
let
inherit (lib) mkOption types;
cfg = config.vacu.shell;
writeShellFunction =
name: text:
pkgs.writeTextFile {
inherit name;
executable = false;
destination = "/share/vacufuncs/${name}";
text = ''
${text}
'';
checkPhase = ''
${pkgs.stdenv.shellDryRun} "$target"
'';
};
vacureload = writeShellFunction "vacureload" ''
declare -gA vacuShellFunctionsLoaded
if ! [[ -f ${cfg.functionsDir}/vacureload ]]; then
echo "vacureload: I think that's my cue to leave (${cfg.functionsDir}/vacureload not found, assuming vacureload-less config has been loaded and unloading myself)" 1>&2
for funcname in "''${!vacuShellFunctionsLoaded[@]}"; do
unset -f $funcname
done
return
fi
for funcname in "''${!vacuShellFunctionsLoaded[@]}"; do
if ! [[ -f ${cfg.functionsDir}/$funcname ]]; then
unset -f $funcname
fi
done
for fullPath in ${cfg.functionsDir}/*; do
local funcname="$(basename "$fullPath")"
local followedPath="$(readlink -f "$fullPath")"
if [[ "''${vacuShellFunctionsLoaded[$funcname]}" != "$followedPath" ]]; then
unset -f $funcname
eval "function ''${funcname}() { if [[ -f '$fullPath' ]]; then eval "'"$'"(cat '$fullPath')"'"'"; else echo '$funcname is no longer there, kindly removing myself.' 1>&2; unset $funcname; return 1; fi }"
vacuShellFunctionsLoaded[$funcname]=$followedPath
fi
unset followedPath
unset funcname
done
__set_idempotents
'';
set_idempotents = writeShellFunction "__set_idempotents" cfg.idempotentShellLines;
in
{
imports = [
./not-aliases.nix
./ps1.nix
];
options = {
vacu.shell.functionsDir = mkOption { type = types.path; };
vacu.shell.interactiveLines = mkOption {
type = types.lines;
default = "";
};
vacu.shell.idempotentShellLines = mkOption {
type = types.lines;
default = "";
};
vacu.shell.color = mkOption { type = types.enum (builtins.attrNames vaculib.shellColors); };
};
config = {
_module.args.vaculib = {
writeShellFunction = writeShellFunction;
# https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
shellColors = {
black = 30;
red = 31;
green = 32;
yellow = 33;
blue = 34;
magenta = 35;
cyan = 36;
white = 37;
};
};
vacu.shell.interactiveLines = ''
if [[ $- == *i* ]] && [[ -f ${cfg.functionsDir}/vacureload ]]; then
function __vacushell_load() { eval "$(cat ${cfg.functionsDir}/vacureload)"; }
__vacushell_load
unset __vacushell_load
fi
'';
vacu.packages = [
vacureload
set_idempotents
];
};
}

View File

@@ -0,0 +1,52 @@
# These are the things that might in a simpler time go in ~/.bashrc as aliases. But they're not aliases, cuz aliases are bad
{
pkgs,
vaculib,
config,
...
}:
let
inherit (pkgs) writeScriptBin;
inherit (vaculib) writeShellFunction;
in
{
vacu.packages = [
(writeScriptBin "ms" ''
set -e
if [[ $# != 1 ]]; then
echo "wrong number of args" 1>&2
exit 1
fi
set -x
mosh -- $1 screen -Rd
'')
(writeScriptBin "mss" ''
set -e
if [[ $# != 1 ]]; then
echo "wrong number of args" 1>&2
exit 1
fi
set -x
mosh -- $1 sudo screen -Rd
'')
(writeScriptBin "rmln" ''
set -eo pipefail
for arg in "$@"; do
if [[ "$arg" != "-*" ]] && [[ ! -L "$arg" ]]; then
echo "$0: $arg is not a symlink" 1>&2
exit 1
fi
done
rm "$@"
'')
(writeShellFunction "nd" ''
declare -a args
args=("$@")
mkdir "''${args[@]}" && cd "''${args[-1]}"
'')
(writeShellFunction "td" ''pushd $(mktemp "$@")'')
(writeShellFunction "nvim-plain" ''${pkgs.neovim}/bin/nvim "$@"'')
(writeShellFunction "nvim-nixvim" ''${config.vacu.nixvimPkg}/bin/nvim "$@"'')
(writeShellFunction "nvim" ''nvim-plain "$@"'')
];
}

36
common/shell/ps1.nix Normal file
View File

@@ -0,0 +1,36 @@
{
config,
lib,
vaculib,
...
}:
let
cfg = config.vacu.shell;
# https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
colors = vaculib.shellColors;
# https://man.archlinux.org/man/bash.1#PROMPTING
# \[ and \] begins and ends "a sequence of non-printing characters"
set_color = colornum: ''\[\e[1;${toString colornum}m\]'';
set_inverted_color = colornum: ''\[\e[1;37;${toString (colornum + 10)}m\]'';
reset_color = ''\[\e[0m\]'';
colornum = colors.${cfg.color};
root_text = root: lib.optionalString root "ROOT@";
final = root: if root then (set_inverted_color colors.red) + "!!" else "$";
default_ps1 =
root:
''\n''
+ (set_color colornum)
+ ''${root_text root}${config.vacu.shortHostName}:\w''
+ (final root)
+ reset_color
+ " ";
in
{
vacu.shell.idempotentShellLines = ''
if [ $UID = 0 ]; then
export PS1=${lib.escapeShellArg (default_ps1 true)}
else
export PS1=${lib.escapeShellArg (default_ps1 false)}
fi
'';
}

147
common/ssh.nix Normal file
View File

@@ -0,0 +1,147 @@
{
pkgs,
lib,
config,
...
}:
let
inherit (lib)
mkOption
types
flip
concatMapStringsSep
optionalString
concatStringsSep
readFile
mapAttrsToList
literalExpression
;
inherit (builtins) attrValues;
cfg = config.vacu;
knownHosts = attrValues cfg.ssh.knownHosts;
knownHostsText =
(flip (concatMapStringsSep "\n") knownHosts (
h:
assert h.hostNames != [ ];
optionalString h.certAuthority "@cert-authority "
+ concatStringsSep "," h.hostNames
+ " "
+ (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile)
))
+ "\n";
in
{
options = {
vacu.ssh.knownHostsText = mkOption {
type = types.str;
readOnly = true;
default = knownHostsText;
};
vacu.ssh.authorizedKeys = mkOption { type = types.listOf types.str; };
vacu.ssh.config = mkOption { type = types.lines; };
# Straight copied from nixpkgs
# https://github.com/NixOS/nixpkgs/blob/46397778ef1f73414b03ed553a3368f0e7e33c2f/nixos/modules/programs/ssh.nix
vacu.ssh.knownHosts = mkOption {
default = { };
type = types.attrsOf (
types.submodule (
{
name,
config,
options,
...
}:
{
options = {
certAuthority = mkOption {
type = types.bool;
default = false;
description = ''
This public key is an SSH certificate authority, rather than an
individual host's key.
'';
};
hostNames = mkOption {
type = types.listOf types.str;
default = [ name ] ++ config.extraHostNames;
defaultText = literalExpression "[ ${name} ] ++ config.${options.extraHostNames}";
description = ''
A list of host names and/or IP numbers used for accessing
the host's ssh service. This list includes the name of the
containing `knownHosts` attribute by default
for convenience. If you wish to configure multiple host keys
for the same host use multiple `knownHosts`
entries with different attribute names and the same
`hostNames` list.
'';
};
extraHostNames = mkOption {
type = types.listOf types.str;
default = [ ];
description = ''
A list of additional host names and/or IP numbers used for
accessing the host's ssh service. This list is ignored if
`hostNames` is set explicitly.
'';
};
publicKey = mkOption {
default = null;
type = types.nullOr types.str;
example = "ecdsa-sha2-nistp521 AAAAE2VjZHN...UEPg==";
description = ''
The public key data for the host. You can fetch a public key
from a running SSH server with the {command}`ssh-keyscan`
command. The public key should not include any host names, only
the key type and the key itself.
'';
};
publicKeyFile = mkOption {
default = null;
type = types.nullOr types.path;
description = ''
The path to the public key file for the host. The public
key file is read at build time and saved in the Nix store.
You can fetch a public key file from a running SSH server
with the {command}`ssh-keyscan` command. The content
of the file should follow the same format as described for
the `publicKey` option. Only a single key
is supported. If a host has multiple keys, use
{option}`programs.ssh.knownHostsFiles` instead.
'';
};
};
}
)
);
description = ''
The set of system-wide known SSH hosts. To make simple setups more
convenient the name of an attribute in this set is used as a host name
for the entry. This behaviour can be disabled by setting
`hostNames` explicitly. You can use
`extraHostNames` to add additional host names without
disabling this default.
'';
example = literalExpression ''
{
myhost = {
extraHostNames = [ "myhost.mydomain.com" "10.10.1.4" ];
publicKeyFile = ./pubkeys/myhost_ssh_host_dsa_key.pub;
};
"myhost2.net".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILIRuJ8p1Fi+m6WkHV0KWnRfpM1WxoW8XAS+XvsSKsTK";
"myhost2.net/dsa" = {
hostNames = [ "myhost2.net" ];
publicKeyFile = ./pubkeys/myhost2_ssh_host_dsa_key.pub;
};
}
'';
};
config.assertions = lib.flip lib.mapAttrsToList config.vacu.ssh.knownHosts (
name: data: {
assertion =
(data.publicKey == null && data.publicKeyFile != null)
|| (data.publicKey != null && data.publicKeyFile == null);
message = "knownHost ${name} must contain either a publicKey or publicKeyFile";
}
);
};
}

View File

@@ -0,0 +1,35 @@
{ pkgs, lib, config, ... }: let
inherit (lib) mkOption mkEnableOption types;
cfg = config.vacu.verifySystem;
in {
options.vacu.verifySystem = {
enable = (mkEnableOption "verify system is what is expected") // { default = true; };
verifiers = mkOption {
default = {};
type = types.attrsOf (types.submodule ({ name, config, ... }: {
options = {
enable = mkEnableOption "Enable system ident check ${name}";
name = mkOption { type = types.str; default = name; };
script = mkOption { type = types.lines; default = "## system ident check ${config.name}"; };
};
}));
};
verifyAllScript = let
verifiers = (builtins.attrValues cfg.verifiers);
enabled = builtins.filter (s: s.enable) verifiers;
files = map (s: pkgs.writeText "vacu-verify-system-${s.name}.sh" s.script) enabled;
script = ''
## vacu verify-system
for f in ${lib.concatStringsSep " " files}; do
echo "verifying system with $f"
if ! source $f; then
echo "ERR: $f failed" >&2
return 1
fi
done
'';
scriptFile = pkgs.writeText "vacu-verify-system-all.sh" script;
in mkOption { readOnly = true; default = scriptFile; };
};
}

View File

@@ -0,0 +1,55 @@
{ lib, config, pkgs, ... }: let
inherit (lib) mkOption types;
in {
options.vacu.verifySystem.expectedMac = mkOption { type = types.nullOr (types.strMatching "[A-Fa-f0-9]{2}(:[A-Fa-f0-9]{2}){5}"); default = null; };
config = lib.mkIf config.vacu.verifySystem.enable {
# system.activationScripts."00-verify-system" = {
# text = "if ! source ${config.vacu.verifySystem.verifyAllScript}; then exit $?; fi";
# supportsDryActivation = true;
# };
system.extraSystemBuilderCmds = ''
mv $out/bin/switch-to-configuration $out/bin/.switch-to-configuration-unverified
cat <<EOF > $out/bin/switch-to-configuration
#!${pkgs.bash}/bin/bash
oldpath="$PATH"
export PATH="${pkgs.coreutils}/bin"
if ! source ${config.vacu.verifySystem.verifyAllScript}; then exit \$?; fi
export PATH="$oldpath"
exec $out/bin/.switch-to-configuration-unverified "\$@"
EOF
${pkgs.coreutils}/bin/chmod a+x $out/bin/switch-to-configuration
'';
vacu.verifySystem.verifiers = {
hostname = {
enable = lib.mkDefault true;
script = ''
expected=${config.networking.hostName}
actual=$(cat /proc/sys/kernel/hostname)
if [[ "$expected" != "$actual" ]]; then
echo "ERR: unexpected hostname; Trying to deploy to $expected but this is $actual" >&2
return 1
fi
'';
};
expectedMac = {
enable = config.vacu.verifySystem.expectedMac != null;
script = ''
expected=${lib.toUpper config.vacu.verifySystem.expectedMac}
declare -a actual=($(${pkgs.iproute2}/bin/ip -j link | ${pkgs.jq}/bin/jq 'map(.address | ascii_upcase) | join("\n")' -r))
for ifMac in "''${actual[@]}"; do
if [[ "$ifMac" == "$expected" ]]; then
# all is well
return 0
fi
done
echo "ERR: Interface MAC address $expected not present, this may not be the system you intend to deploy to." >&2
echo " Found MAC addresses: ''${actual[*]}" >&2
return 1
'';
};
};
};
}

View File

@@ -1,6 +1,7 @@
{ ... }: {
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
{ ... }:
{
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
services.blueman.enable = true;
services.blueman.enable = true;
}

View File

@@ -1,18 +1,24 @@
{ config, pkgs, lib, jovian, inputs, ... }:
{
config,
pkgs,
lib,
jovian,
inputs,
...
}:
{
imports = [
inputs.jovian.nixosModules.jovian
inputs.disko.nixosModules.default
inputs.homeManager.nixosModules.default
# inputs.disko.nixosModules.default
inputs.home-manager.nixosModules.default
./hardware.nix
./partitioning.nix
./home.nix
./bluetooth.nix
./partitioning.nix
./padtype.nix
../common-nixos-config.nix
../common/nixos.nix
];
system.nixos.tags = [ "host-${config.networking.hostName}" ];
boot.loader.systemd-boot.enable = false;
boot.loader.efi.efiSysMountPoint = "/boot/EFI";
@@ -23,7 +29,9 @@
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
networking.hostName = "compute-deck";
vacu.hostName = "compute-deck";
vacu.shortHostName = "cd";
vacu.shell.color = "blue";
networking.hostId = "e595d9b0";
boot.supportedFilesystems = [ "zfs" ];
@@ -55,22 +63,22 @@
rustup
];
boot.kernelPatches = [
{
name = "gadget";
patch = null;
extraStructuredConfig = with lib.kernel; {
USB_ETH=module;
USB_GADGET=yes;
USB_LIBCOMPOSITE=yes;
USB_CONFIGFS=yes;
USB_DWC3=module;
USB_DWC3_PCI=module;
USB_DWC3_DUAL_ROLE=yes;
USB_DWC3_HOST=no;
USB_DWC3_GADGET=no;
USB_ROLE_SWITCH=yes;
};
}
];
# boot.kernelPatches = [
# {
# name = "gadget";
# patch = null;
# extraStructuredConfig = with lib.kernel; {
# USB_ETH=module;
# USB_GADGET=yes;
# USB_LIBCOMPOSITE=yes;
# USB_CONFIGFS=yes;
# USB_DWC3=module;
# USB_DWC3_PCI=module;
# USB_DWC3_DUAL_ROLE=yes;
# USB_DWC3_HOST=no;
# USB_DWC3_GADGET=no;
# USB_ROLE_SWITCH=yes;
# };
# }
# ];
}

View File

@@ -1,51 +1,60 @@
{ config, lib, pkgs, modulesPath, ... }:
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot.initrd.availableKernelModules = [ "nvme" "usbhid" "sdhci_pci" ];
boot.initrd.availableKernelModules = [
"nvme"
"xhci_pci"
"usbhid"
"sdhci_pci"
"dwc3_pci"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
/*
fileSystems."/" =
{ device = "/dev/disk/by-uuid/63f25199-ee0b-4991-8861-c3ba3b464ef2";
fsType = "btrfs";
options = [ "subvol=root" ];
};
/*
fileSystems."/" =
{ device = "/dev/disk/by-uuid/63f25199-ee0b-4991-8861-c3ba3b464ef2";
fsType = "btrfs";
options = [ "subvol=root" ];
};
fileSystems."/home" =
{ device = "/dev/disk/by-uuid/63f25199-ee0b-4991-8861-c3ba3b464ef2";
fsType = "btrfs";
options = [ "subvol=home" ];
};
fileSystems."/home" =
{ device = "/dev/disk/by-uuid/63f25199-ee0b-4991-8861-c3ba3b464ef2";
fsType = "btrfs";
options = [ "subvol=home" ];
};
fileSystems."/nix" =
{ device = "/dev/disk/by-uuid/63f25199-ee0b-4991-8861-c3ba3b464ef2";
fsType = "btrfs";
options = [ "subvol=nix" ];
};
fileSystems."/nix" =
{ device = "/dev/disk/by-uuid/63f25199-ee0b-4991-8861-c3ba3b464ef2";
fsType = "btrfs";
options = [ "subvol=nix" ];
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/63f25199-ee0b-4991-8861-c3ba3b464ef2";
fsType = "btrfs";
options = [ "subvol=boot" ];
};
*/
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/63f25199-ee0b-4991-8861-c3ba3b464ef2";
fsType = "btrfs";
options = [ "subvol=boot" ];
};
*/
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/2aad8cab-7b97-47de-8608-fe9f12e211a4";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/2aad8cab-7b97-47de-8608-fe9f12e211a4";
fsType = "ext4";
};
fileSystems."/boot/EFI" =
{ device = "/dev/disk/by-uuid/C268-79C8";
fsType = "vfat";
};
fileSystems."/boot/EFI" = {
device = "/dev/disk/by-uuid/C268-79C8";
fsType = "vfat";
};
swapDevices = [ ];

View File

@@ -2,9 +2,7 @@
{
home-manager.users.shelvacu = {
# these make vscode-remote work
imports = [
inputs.vscode-server.homeModules.default
];
imports = [ inputs.vscode-server.homeModules.default ];
services.vscode-server.enable = true;
home.stateVersion = "23.11";

View File

@@ -1,8 +1,10 @@
{ inputs, ... }: let
{ inputs, ... }:
let
padtype-pkg = inputs.padtype.packages."x86_64-linux".default;
in {
in
{
environment.systemPackages = [ padtype-pkg ];
systemd.services."padtype" = {
wantedBy = [ "multi-user.target" ];
script = "${padtype-pkg}/bin/padtype";

View File

@@ -1,5 +1,6 @@
{ ... }:
{ inputs, ... }:
{
imports = [ inputs.disko.nixosModules.default ];
disko.devices.disk.blarg = {
device = "/dev/disk/by-id/nvme-Micron_2400_MTFDKBK2T0QFM_230341951668_1-part11";
content = {
@@ -13,20 +14,29 @@
subvolumes = {
"/root" = {
mountpoint = "/";
mountOptions = [ "compress=zstd" "noatime" ];
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/home" = {
mountpoint = "/home";
mountOptions = [ "compress=zstd" "noatime" ];
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [ "compress=zstd" "noatime" ];
mountOptions = [
"compress=zstd"
"noatime"
];
};
# "/swap" = {
# mountpoint = "/.swapvol";
# swap.swapfile.size = "20M";
# };
# "/swap" = {
# mountpoint = "/.swapvol";
# swap.swapfile.size = "20M";
# };
};
};
};

103
coopdx.nix Normal file
View File

@@ -0,0 +1,103 @@
{
callPackage,
fetchFromGitHub,
autoPatchelfHook,
zlib,
curl,
libcxx,
stdenvNoCC,
nixpkgs ? <nixpkgs>,
writeTextFile,
lib,
bash,
enableTextureFix ? true,
enableDiscord ? false,
}:
let
libc_hack = writeTextFile {
name = "libc-hack";
# https://stackoverflow.com/questions/21768542/libc-h-no-such-file-or-directory-when-compiling-nanomsg-pipeline-sample
text = ''
#include <unistd.h>
#include <string.h>
#include <pthread.h>
'';
destination = "/include/libc.h";
};
target = stdenvNoCC.targetPlatform;
bits =
if target.is64bit then
"64"
else if target.is32bit then
"32"
else
throw "unspported bits";
pname = "sm64coopdx";
version = "1.0.3";
region = "us"; # dx removed support for other regions
in
(callPackage "${nixpkgs}/pkgs/games/sm64ex/generic.nix" {
inherit pname version region;
src = fetchFromGitHub {
owner = "coop-deluxe";
repo = pname;
rev = "v${version}";
hash = "sha256-cIH3escLFMcHgtFxeSKIo5nZXvaknti+EVt72uB4XXc=";
};
extraNativeBuildInputs = [ autoPatchelfHook ];
extraBuildInputs = [
zlib
curl
libcxx
libc_hack
];
# Normally there's no need to set TARGET_ARCH, but if we don't it adds -march=native which is impure
compileFlags = [
"BREW_PREFIX=/not-exist"
"TARGET_ARCH=generic"
"TARGET_BITS=${bits}"
"DISCORD_SDK=${if enableDiscord then "1" else "0"}"
"TEXTURE_FIX=${if enableTextureFix then "1" else "0"}"
];
extraMeta = {
mainProgram = pname;
homepage = "https://sm64coopdx.com/";
description = "Super Mario 64 online co-op mod, forked from sm64ex";
};
}).overrideAttrs
{
installPhase =
let
sharedLib = target.extensions.sharedLibrary;
in
''
runHook preInstall
local built=$PWD/build/${region}_pc
mkdir -p $out/share/${pname}
cp $built/${pname} $out/share/${pname}/${pname}-unwrapped
cp -r $built/{dynos,lang,mods,palettes} $out/share/${pname}
cp ./baserom.*.z64 $out/share/
${lib.optionalString enableDiscord ''
cp $built/libdiscord_game_sdk${sharedLib} $out/share/${pname}
''}
mkdir -p $out/bin
(
echo '#!${bash}/bin/bash'
echo "cd $out/share/${pname}"
echo 'exec ./${pname}-unwrapped "$@"'
) > $out/bin/${pname}
chmod a+x $out/bin/${pname}
runHook postInstall
'';
}

93
deterministic-certs.nix Normal file
View File

@@ -0,0 +1,93 @@
{
nixpkgs ? import <nixpkgs>,
}:
let
pkgs = nixpkgs;
lib = nixpkgs.lib;
defaultCertTemplate = {
serial = 1;
activation_date = "1970-01-01 00:00:00 UTC";
expiration_date = "2500-01-01 00:00:00 UTC";
};
keyValToConfigLines = (
key: value:
if (builtins.isString value) || (builtins.isPath value) then
"${key} = \"${value}\""
else if builtins.isInt value then
"${key} = ${builtins.toString value}"
else if builtins.isList value then
map (innerValue: keyValToConfigLines key innerValue)
else if builtins.isBool value then
(if value then "${key}" else "# no ${key}")
else
throw "don't know how to handle ${builtins.typeOf value}"
);
mkTemplateConfig =
config:
lib.concatStringsSep "\n" (
lib.lists.flatten (lib.attrsets.mapAttrsToList keyValToConfigLines config)
);
certCfg = pkgs.writeText "deterministic-cert.cfg" ''
serial = 1
activation_date = "1970-01-01 00:00:00 UTC"
expiration_date = "2500-01-01 00:00:00 UTC"
'';
privKeyFile =
name:
let
keySizeBits = 256;
keySizeHex = builtins.toString (keySizeBits / 4);
in
pkgs.runCommand "deterministic-privkey-${name}.pem" { } ''
seed=$(echo ${lib.escapeShellArg (builtins.toJSON name)} | ${pkgs.ruby_3_2}/bin/ruby -rjson -e 'name = JSON.parse(STDIN.gets); print name.unpack("H*")[0].ljust(${keySizeHex}, "0")')
${pkgs.gnutls}/bin/certtool --generate-privkey --outfile=$out --key-type=rsa --sec-param=high --seed=$seed
'';
generateCert =
{
name,
config,
args,
preCommands ? "",
}:
let
deriv = pkgs.runCommand "deterministic-cert-${name}" { } ''
mkdir -p $out
cd $out
ln -s ${privKeyFile name} privkey.pem
ln -s ${
pkgs.writeText "${name}-template.cfg" (mkTemplateConfig (defaultCertTemplate // config))
} template.cfg
${preCommands}
${pkgs.gnutls}/bin/certtool ${lib.escapeShellArgs args} --load-privkey=privkey.pem --outfile=cert.pem --template=template.cfg
'';
in
deriv
// {
privateKeyPath = "${deriv}/privkey.pem";
certificatePath = "${deriv}/cert.pem";
};
in
{
inherit privKeyFile;
selfSigned =
name: config:
generateCert {
inherit name config;
args = [ "--generate-self-signed" ];
};
caSigned =
name: ca: config:
generateCert {
inherit name config;
preCommands = ''
ln -s ${ca.privateKeyPath} ca-privkey.pem
ln -s ${ca.certificatePath} ca-cert.pem
'';
args = [
"--generate-certificate"
"--load-ca-certificate=ca-cert.pem"
"--load-ca-privkey=ca-privkey.pem"
];
};
}

View File

@@ -1,20 +1,39 @@
{ config, pkgs, lib, inputs, modulesPath, ... }:
{
config,
pkgs,
lib,
inputs,
modulesPath,
...
}:
{
imports = [
inputs.homeManager.nixosModules.default
../common-nixos-config.nix
inputs.home-manager.nixosModules.default
../common/nixos.nix
(modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [ "virtio_pci" "usbhid" "virtio_blk" "9pnet_virtio" "9p" "autofs4" ];
boot.initrd.availableKernelModules = [
"virtio_pci"
"usbhid"
"virtio_blk"
"9pnet_virtio"
"9p"
"autofs4"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" "9pnet_virtio" "9p" "autofs4" ];
boot.kernelModules = [
"kvm-intel"
"9pnet_virtio"
"9p"
"autofs4"
];
boot.extraModulePackages = [ ];
system.nixos.tags = [ "host-${config.networking.hostName}" ];
networking.hostName = "devver";
vacu.hostName = "devver";
vacu.shortHostName = "dvr";
vacu.shell.color = "green";
boot.loader.external.enable = true;
boot.loader.external.installHook = pkgs.writeShellScript "vacuDirectBootInstaller" ''
PATH="$PATH:${pkgs.coreutils}/bin:${pkgs.gnused}/bin"
@@ -51,7 +70,7 @@
services.openssh.enable = true;
vacu.packages.nix-inspect.enable = false; #its broken for some reason I don't understand
vacu.packages.nix-inspect.enable = false; # its broken for some reason I don't understand
system.stateVersion = "23.11";
}

1157
flake.lock generated

File diff suppressed because it is too large Load Diff

402
flake.nix
View File

@@ -2,40 +2,71 @@
description = "Config for triple-dezert server";
inputs = {
nixpkgs-unstable.url = "nixpkgs/nixos-unstable"; #todo: put this back to -small once jovian-nixos is fixed
nixpkgs.url = "nixpkgs/nixos-23.11-small";
nixpkgs2405.url = "nixpkgs/nixos-24.05-small";
nixpkgs.url = "nixpkgs/nixos-24.05-small";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
nixvim = {
url = "github:nix-community/nixvim/nixos-24.05";
inputs.nixpkgs.follows = "nixpkgs";
};
nixvim-unstable = {
url = "github:nix-community/nixvim";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
nix-inspect = {
url = "github:bluskript/nix-inspect";
#inputs.nixpkgs.follows = "nixpkgs";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-inspect-unstable = {
url = "github:bluskript/nix-inspect";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
vscode-server-unstable = {
url = "github:nix-community/nixos-vscode-server";
inputs.nixpkgs.follows = "nixpkgs-unstable";
inputs.flake-utils.follows = "flake-utils";
};
vscode-server = {
url = "github:nix-community/nixos-vscode-server";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "flake-utils";
};
nix-on-droid = {
url = "github:nix-community/nix-on-droid/release-23.05";
url = "github:nix-community/nix-on-droid";
inputs.nixpkgs.follows = "nixpkgs";
inputs.home-manager.follows = "home-manager";
};
jovian = {
jovian-unstable = {
# there is no stable jovian :cry:
url = "github:Jovian-Experiments/Jovian-NixOS";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
disko = {
disko-unstable = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
homeManager = {
url = "github:nix-community/home-manager/master";
home-manager = {
url = "github:nix-community/home-manager/release-24.05";
inputs.nixpkgs.follows = "nixpkgs";
};
home-manager-unstable = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
nix-search-cli-unstable = {
url = "github:peterldowns/nix-search-cli";
inputs.nixpkgs.follows = "nixpkgs-unstable";
inputs.flake-utils.follows = "flake-utils";
};
nix-search-cli = {
url = "github:peterldowns/nix-search-cli";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "flake-utils";
};
padtype = {
padtype-unstable = {
url = "gitlab:shelvacu/padtype";
inputs.nixpkgs.follows = "nixpkgs";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
sops-nix = {
url = "github:Mic92/sops-nix";
@@ -44,111 +75,262 @@
microvm = {
url = "github:astro/microvm.nix";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "flake-utils";
};
nixos-hardware.url = "github:nixos/nixos-hardware";
most-winningest = {
url = "github:captain-jean-luc/most-winningest";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "flake-utils";
};
};
outputs = { self, nixpkgs, nix-on-droid, ... }@inputs: {
debug.isoDeriv = (import "${inputs.nixpkgs}/nixos/release-small.nix" { nixpkgs = ({ revCount = 0; } // inputs.nixpkgs); });
nixosConfigurations.triple-dezert = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./triple-dezert ];
specialArgs = { inherit inputs; };
};
nixosConfigurations.compute-deck = inputs.nixpkgs-unstable.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./compute-deck ];
specialArgs = { inherit inputs; };
};
nixosConfigurations.liam = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./liam ];
specialArgs = { inherit inputs; };
};
nixosConfigurations.lp0 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./lp0 ];
specialArgs = { inherit inputs; };
};
nixosConfigurations.shel-installer = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./installer.nix ];
specialArgs = { inherit inputs; };
};
nixosConfigurations.devver = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./devver ];
specialArgs = { inherit inputs; };
};
nixosConfigurations.fw = inputs.nixpkgs2405.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./fw ];
specialArgs = { inherit inputs; };
};
nixOnDroidConfigurations.default = nix-on-droid.lib.nixOnDroidConfiguration {
modules = [ ./nix-on-droid.nix ];
extraSpecialArgs = { inherit inputs; };
};
checks = nixpkgs.lib.genAttrs [ "x86_64-linux" ] (system:
let
pkgs = nixpkgs.legacyPackages.${system};
config = {
node.pkgs = pkgs;
node.pkgsReadOnly = false;
node.specialArgs.selfPackages = self.packages.${system};
node.specialArgs.inputs = inputs;
outputs =
{
self,
nixpkgs,
nix-on-droid,
home-manager,
...
}@inputs:
let
blarg = {
config.allowUnfree = true;
};
pkgs = import nixpkgs ({ system = "x86_64-linux"; } // blarg);
aarchpkgs = import nixpkgs ({ system = "aarch64-linux"; } // blarg);
defaultInputs = {
inherit (inputs)
self
nix-search-cli
nix-inspect
nixvim
;
};
defaultArgs = {
inputs = defaultInputs;
};
in
{
debug.isoDeriv = (
import "${inputs.nixpkgs}/nixos/release-small.nix" {
nixpkgs = ({ revCount = 0; } // inputs.nixpkgs);
}
);
nixosConfigurations.triple-dezert = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./triple-dezert ];
specialArgs = {
inputs = defaultInputs // {
inherit (inputs) most-winningest;
};
};
};
nixosConfigurations.compute-deck = inputs.nixpkgs-unstable.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./compute-deck ];
specialArgs = {
inputs = {
jovian = inputs.jovian-unstable;
home-manager = inputs.home-manager-unstable;
vscode-server = inputs.vscode-server-unstable;
disko = inputs.disko-unstable;
padtype = inputs.padtype-unstable;
nix-search-cli = inputs.nix-search-cli-unstable;
nix-inspect = inputs.nix-inspect-unstable;
nixvim = inputs.nixvim-unstable;
self = inputs.self;
};
};
};
nixosConfigurations.liam = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./liam ];
specialArgs = {
inputs = defaultInputs // {
inherit (inputs) sops-nix;
};
};
};
nixosConfigurations.lp0 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./lp0 ];
specialArgs = defaultArgs;
};
nixosConfigurations.shel-installer = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./installer.nix ];
specialArgs = defaultArgs;
};
nixosConfigurations.devver = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./devver ];
specialArgs = {
inputs = defaultInputs // {
inherit (inputs) home-manager;
};
};
};
nixosConfigurations.fw = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./fw ];
specialArgs = {
inputs = defaultInputs // {
inherit (inputs) nixos-hardware;
};
};
};
nixOnDroidConfigurations.default = nix-on-droid.lib.nixOnDroidConfiguration {
modules = [ ./nix-on-droid ];
extraSpecialArgs = {
inputs = defaultInputs // {
inherit (inputs) nixpkgs;
};
};
pkgs = import nixpkgs { system = "aarch64-linux"; };
};
homeConfigurations."nix-on-droid" = home-manager.lib.homeManagerConfiguration {
modules = [
./home/nix-on-droid.nix
{ _module.args.inputs = defaultInputs; }
];
pkgs = import nixpkgs { system = "aarch64-linux"; };
};
checks = nixpkgs.lib.genAttrs [ "x86_64-linux" ] (
system:
let
pkgs = import nixpkgs { inherit system; };
config = {
node.pkgs = pkgs;
node.pkgsReadOnly = false;
node.specialArgs.selfPackages = self.packages.${system};
};
in
{
liam = nixpkgs.lib.nixos.runTest {
hostPkgs = pkgs;
imports = [
config
./tests/liam.nix
{ node.specialArgs.inputs = self.nixosConfigurations.liam._module.specialArgs.inputs; }
];
};
trip = nixpkgs.lib.nixos.runTest {
hostPkgs = pkgs;
imports = [
config
./tests/triple-dezert.nix
{ node.specialArgs.inputs = self.nixosConfigurations.triple-dezert._module.specialArgs.inputs; }
];
};
}
);
nixosModules.common = import ./common/module.nix;
packages.x86_64-linux.sm64coopdx = pkgs.callPackage ./coopdx.nix { inherit nixpkgs; };
packages.x86_64-linux.snmpb = pkgs.libsForQt5.callPackage ./packages/snmpb/package.nix { };
packages.x86_64-linux.snmp-mibs-downloader =
pkgs.callPackage ./packages/snmp-mibs-downloader.nix
{ };
packages.x86_64-linux.digitalOceanImage = import ./generic-digitalocean-nixos.nix {
inherit inputs;
};
packages.x86_64-linux.authorizedKeys = pkgs.writeText "authorizedKeys" (
pkgs.lib.concatStringsSep "\n" self.nixosConfigurations.fw.config.vacu.ssh.authorizedKeys
);
packages.aarch64-linux.authorizedKeys =
let
pkgs = aarchpkgs;
in
pkgs.writeText "authorizedKeys" (
pkgs.lib.concatStringsSep "\n" self.nixOnDroidConfigurations.default.config.vacu.ssh.authorizedKeys
);
qb = # qb is "quick build"
let
toplevelOf = name: self.nixosConfigurations.${name}.config.system.build.toplevel;
deterministicCerts = import ./deterministic-certs.nix { nixpkgs = pkgs; };
in
rec {
fw = toplevelOf "fw";
triple-dezert = toplevelOf "triple-dezert";
trip = triple-dezert;
compute-deck = toplevelOf "compute-deck";
cd = compute-deck;
liam = toplevelOf "liam";
lp0 = toplevelOf "lp0";
devver = toplevelOf "devver";
shel-installer = toplevelOf "shel-installer";
iso = self.nixosConfigurations.shel-installer.config.system.build.isoImage;
do = self.packages.x86_64-linux.digitalOceanImage;
snmpb = self.packages.x86_64-linux.snmpb;
check-triple-dezert = self.checks.x86_64-linux.trip.driver;
check-trip = check-triple-dezert;
check-liam = self.checks.x86_64-linux.liam.driver;
nix-on-droid = self.nixOnDroidConfigurations.default.activationPackage;
nod = nix-on-droid;
nod-bootstrap-x86_64 = inputs.nix-on-droid.packages.x86_64-linux.bootstrapZip-x86_64;
nod-bootstrap-aarch64 = inputs.nix-on-droid.packages.x86_64-linux.bootstrapZip-aarch64;
inherit (self.packages.x86_64-linux) authorizedKeys sm64coopdx;
authorizedKeysAarch = self.packages.aarch64-linux.authorizedKeys;
ak = authorizedKeys;
coopdx = sm64coopdx;
dc-priv = deterministicCerts.privKeyFile "test";
dc-cert = deterministicCerts.selfSigned "test" { };
};
all =
pkgs.runCommand "nix-stuff-all"
{
__structuredAttrs = true;
links = self.qb;
}
''
mkdir $out
cd $out
eval "$(${pkgs.jq}/bin/jq '.links | to_entries | map("ln -s "+.value+" "+.key) | join("\n")' /build/.attrs.json -r)"
'';
allPure = self.all.overrideAttrs (prev: {
links = removeAttrs prev.links [
"nix-on-droid"
"nod"
"nod-bootstrap-x86_64"
"nod-bootstrap-aarch64"
];
});
allWithBuildDeps =
let
info = pkgs.closureInfo { rootPaths = [ self.all.drvPath ]; };
in
self.all.overrideAttrs (prev: {
links = prev.links // {
build-deps = info;
};
});
}
// (inputs.flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import nixpkgs { inherit system; };
in
{
liam = nixpkgs.lib.nixos.runTest {
hostPkgs = pkgs;
imports = [ config ./tests/liam.nix ];
};
trip = nixpkgs.lib.nixos.runTest {
hostPkgs = pkgs;
imports = [ config ./tests/triple-dezert.nix ];
};
formatter = pkgs.nixfmt-rfc-style;
}
);
nixosModules.common = import ./common-config.nix;
packages.x86_64-linux.digitalOceanImage = import ./generic-digitalocean-nixos.nix { inherit inputs; };
qb = /* qb is "quick build" */ let
toplevelOf = name: self.nixosConfigurations.${name}.config.system.build.toplevel;
in rec {
# nix-on-droid is impure >:(
# nod = self.nixOnDroidConfigurations.default.activationPackage;
fw = toplevelOf "fw";
triple-dezert = toplevelOf "triple-dezert";
trip = triple-dezert;
compute-deck = toplevelOf "compute-deck";
cd = compute-deck;
liam = toplevelOf "liam";
lp0 = toplevelOf "lp0";
devver = toplevelOf "devver";
shel-installer = toplevelOf "shel-installer";
iso = self.nixosConfigurations.shel-installer.config.system.build.isoImage;
do = self.packages.x86_64-linux.digitalOceanImage;
check-triple-dezert = self.checks.x86_64-linux.trip.driver;
check-trip = check-triple-dezert;
check-liam = self.checks.x86_64-linux.liam.driver;
};
all = let
pkgs = nixpkgs.legacyPackages.x86_64-linux;
symlinkCommands = pkgs.lib.mapAttrsToList (name: pkg: "ln -s ${pkg} ${name}") self.qb;
in pkgs.runCommand "nix-stuff-all" {} ''
mkdir $out
cd $out
${pkgs.lib.concatStringsSep "\n" symlinkCommands}
'';
};
));
}

5
fw/android.nix Normal file
View File

@@ -0,0 +1,5 @@
{ pkgs, ... }:
{
vacu.packages = pkgs.androidStudioPackages.stable.all;
users.users.shelvacu.extraGroups = [ "kvm" ];
}

64
fw/apex.nix Normal file
View File

@@ -0,0 +1,64 @@
# everything to interact with my apex flex, pcsc stuff, fido2 stuff, etc
{ pkgs, ... }:
{
# apparently this is already enabled??
# nixpkgs.overlays = [ ( final: prev: {
# libfido2 = prev.libfido2.override { withPcsclite = true; };
# } ) ];
vacu.packages = with pkgs; [
libfido2
pcsclite
pcsc-tools
scmccid
opensc
];
services.pcscd.enable = true;
# conflicts with pcscd, see https://stackoverflow.com/questions/55144458/unable-to-claim-usb-interface-device-or-resource-busy-stuck
boot.blacklistedKernelModules = [
"pn533_usb"
"pn533"
"nfc"
];
# bunch of stuff from https://wiki.nixos.org/wiki/Web_eID
# Tell p11-kit to load/proxy opensc-pkcs11.so, providing all available slots
# (PIN1 for authentication/decryption, PIN2 for signing).
# environment.etc."pkcs11/modules/opensc-pkcs11".text = ''
# module: ${pkgs.opensc}/lib/opensc-pkcs11.so
# '';
# environment.etc."opensc.conf".text = ''
# app default {
# reader_driver pcsc {
# enable_pinpad = false;
# }
# }
# '';
environment.systemPackages = [
# Wrapper script to tell to Chrome/Chromium to use p11-kit-proxy to load
# security devices, so they can be used for TLS client auth.
# Each user needs to run this themselves, it does not work on a system level
# due to a bug in Chromium:
#
# https://bugs.chromium.org/p/chromium/issues/detail?id=16387
(pkgs.writeShellScriptBin "setup-browser-eid" ''
NSSDB="''${HOME}/.pki/nssdb"
mkdir -p ''${NSSDB}
${pkgs.nssTools}/bin/modutil -force -dbdir sql:$NSSDB -add p11-kit-proxy \
-libfile ${pkgs.p11-kit}/lib/p11-kit-proxy.so
'')
];
programs.firefox.enable = true;
#programs.firefox.policies.SecurityDevices.p11-kit-proxy = "${pkgs.p11-kit}/lib/p11-kit-proxy.so";
# trying CTAP-bridge
services.udev.extraRules = ''
KERNEL=="hidg[0-9]", SUBSYSTEM=="hidg", SYMLINK+="ctaphid", MODE+="0666", TAG+="uaccess"
KERNEL=="ccidg[0-9]", SUBSYSTEM=="ccidg", SYMLINK+="ccidsc", MODE+="0666", TAG+="uaccess"
'';
}

View File

@@ -1,31 +1,65 @@
{ config, inputs, pkgs, lib, ... }: {
imports = [
../common-nixos-config.nix
{
config,
inputs,
pkgs,
lib,
...
}:
{
imports = [
../common/nixos.nix
inputs.nixos-hardware.nixosModules.framework-16-7040-amd
./apex.nix
./android.nix
];
system.nixos.tags = [ "host-${config.networking.hostName}" ];
vacu.hostName = "fw"; # Define your hostname.
vacu.shell.color = "magenta";
vacu.verifySystem.expectedMac = "e8:65:38:52:5c:59";
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
networking.networkmanager.enable = true;
# boot.kernelParams = [ "nvme.noacpi=1" ]; # DONT DO IT: breaks shit even more
vacu.packages.bitwarden-desktop.enable = true;
vacu.packages.nheko.enable = true;
vacu.packages.librewolf.enable = true;
vacu.packages.brave.enable = true;
vacu.packages.thunderbird.enable = true;
vacu.packages.wl-clipboard.enable = true;
vacu.packages.nextcloud-client.enable = true;
vacu.packages.signal-desktop.enable = true;
vacu.packages.fw-ectool.enable = true;
vacu.packages.framework-tool.enable = true;
vacu.packages.iio-sensor-proxy.enable = true;
vacu.packages.power-profiles-daemon.enable = true;
vacu.packages.acpi.enable = true;
vacu.packages.jellyfin-media-player.enable = true;
vacu.packages.vlc.enable = true;
vacu.packages.dmidecode.enable = true;
vacu.packages.prismlauncher.enable = true;
vacu.packages.ffmpeg_7-full.enable = true;
services.fprintd.enable = false; # kinda broken
vacu.packages = with pkgs; [
bitwarden-desktop
nheko
librewolf
brave
thunderbird
wl-clipboard
nextcloud-client
signal-desktop
fw-ectool
framework-tool
iio-sensor-proxy
power-profiles-daemon
acpi
jellyfin-media-player
vlc
dmidecode
prismlauncher
ffmpeg_7-full
wireshark
obsidian
dino
aircrack-ng
libreoffice-qt6-fresh
gimp
# null actually means everything https://github.com/NixOS/nixpkgs/commit/5efd65b2d94b0ac0cf155e013b6747fa22bc04c3
(inkscape-with-extensions.override { inkscapeExtensions = null; })
libsmi
net-snmp
];
services.fwupd.enable = true;
#fwupd gets confused by the multiple EFI partitions, I think I just have to pick one
#update: it didn't work, I dunno why. Leaving this here anyways
services.fwupd.daemonSettings.EspLocation = lib.mkForce "/boot0";
networking.firewall.enable = false;
services.xserver.enable = true;
services.displayManager.sddm.enable = true;
@@ -47,7 +81,6 @@
}
];
networking.hostName = "fw"; # Define your hostname.
networking.hostId = "c6e309d5";
boot.zfs.extraPools = [ "fw" ];
boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
@@ -55,33 +88,50 @@
services.openssh.enable = true;
system.stateVersion = "23.11"; # Did you read the comment?
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "usbhid" "sd_mod" ];
boot.initrd.availableKernelModules = [
"nvme"
"xhci_pci"
"thunderbolt"
"usb_storage"
"usbhid"
"sd_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "fw/root";
fsType = "zfs";
};
fileSystems."/" = {
device = "fw/root";
fsType = "zfs";
};
fileSystems."/boot0" =
{ device = "/dev/disk/by-label/BOOT0";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
fileSystems."/boot0" = {
device = "/dev/disk/by-label/BOOT0";
fsType = "vfat";
options = [
"fmask=0022"
"dmask=0022"
];
};
fileSystems."/boot1" =
{ device = "/dev/disk/by-label/BOOT1";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
fileSystems."/boot1" = {
device = "/dev/disk/by-label/BOOT1";
fsType = "vfat";
options = [
"fmask=0022"
"dmask=0022"
];
};
hardware.cpu.amd.updateMicrocode = true;
hardware.enableAllFirmware = true;
hardware.opengl = {
driSupport = true;
driSupport32Bit = true;
extraPackages = [
pkgs.rocmPackages.clr.icd
pkgs.amdvlk
];
};
programs.nix-ld.enable = true;
programs.steam = {
@@ -98,4 +148,6 @@
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
services.blueman.enable = true;
services.postgresql.enable = true; # for development
}

View File

@@ -1,10 +1,15 @@
{ inputs, system ? "x86_64-linux" }:
{
inputs,
system ? "x86_64-linux",
}:
let
pkgs = inputs.nixpkgs.legacyPackages.${system};
config = { config, ... }: {
imports = [ "${inputs.nixpkgs}/nixos/modules/virtualisation/digital-ocean-image.nix" ];
pkgs = inputs.nixpkgs.legacyPackages.${system};
config =
{ config, ... }:
{
imports = [ "${inputs.nixpkgs}/nixos/modules/virtualisation/digital-ocean-image.nix" ];
system.stateVersion = config.system.nixos.release;
};
system.stateVersion = config.system.nixos.release;
};
in
(pkgs.nixos config).digitalOceanImage
(pkgs.nixos config).digitalOceanImage

7
home/nix-on-droid.nix Normal file
View File

@@ -0,0 +1,7 @@
{ ... }:
{
imports = [ ../common/home.nix ];
home.stateVersion = "24.05";
home.homeDirectory = "/data/data/com.termux.nix/files/home";
home.username = "nix-on-droid";
}

View File

@@ -1,12 +1,21 @@
{ config, inputs, modulesPath, lib, ... }: {
{
config,
inputs,
modulesPath,
lib,
...
}:
{
imports = [
"${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix"
./common-nixos-config.nix
./common/nixos.nix
];
# this is an installer image, created anew every time. There's no state we need to worry about messing up
system.stateVersion = config.system.nixos.version;
system.stateVersion = config.system.nixos.version;
isoImage.isoBaseName = "nixos-shel-installer";
services.openssh.settings.PermitRootLogin = lib.mkForce "yes";
vacu.hostName = "vacuInstaller";
vacu.shell.color = "red";
# boot.kernelPatches = [{
# name = "foo";
# patch = null;

View File

@@ -1,57 +1,70 @@
{ modulesPath, config, lib, ... }: {
{
modulesPath,
config,
lib,
...
}:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
(modulesPath + "/virtualisation/digital-ocean-config.nix")
../common-nixos-config.nix
../common/nixos.nix
./nginx.nix
./sops.nix
./dovecot.nix
./mail.nix
./dkim.nix
./sieve.nix
./network.nix
];
options = let
mkReadOnly = val: lib.options.mkOption { default = val; readOnly = true; };
in {
vacu.liam = {
shel_domains = mkReadOnly [
"shelvacu.com"
"dis8.net"
"mail.dis8.net"
"jean-luc.org"
"in.jean-luc.org"
"vacu.store"
];
julie_domains = mkReadOnly [
"violingifts.com"
"theviolincase.com"
"shop.theviolincase.com"
];
domains = mkReadOnly (config.vacu.liam.shel_domains ++ config.vacu.liam.julie_domains);
reservedIpLocal = mkReadOnly "10.46.0.7";
options =
let
mkReadOnly =
val:
lib.options.mkOption {
default = val;
readOnly = true;
};
in
{
vacu.liam = {
shel_domains = mkReadOnly [
"shelvacu.com"
"dis8.net"
"mail.dis8.net"
"jean-luc.org"
"in.jean-luc.org"
"vacu.store"
];
julie_domains = mkReadOnly [
"violingifts.com"
"theviolincase.com"
"shop.theviolincase.com"
];
domains = mkReadOnly (config.vacu.liam.shel_domains ++ config.vacu.liam.julie_domains);
relayhost = lib.options.mkOption {
type = lib.types.str;
# mailhop is duocircle
default = "[outbound.mailhop.org]:587 [relay.dynu.com]:587";
};
reservedIpLocal = mkReadOnly "10.46.0.7";
};
};
};
config = {
system.nixos.tags = [ "host-${config.networking.hostName}" ];
networking.hostName = "liam";
vacu.hostName = "liam";
vacu.shell.color = "cyan";
networking.domain = "dis8.net";
# networking.interfaces."ens3".useDHCP = false;
# from `curl -fsSL http://169.254.169.254/metadata/v1.json | jq '.interfaces.public[0].anchor_ipv4'`
# {
# "ip_address": "10.46.0.7",
# "netmask": "255.255.0.0",
# "gateway": "10.46.0.1"
# }
services.openssh.enable = true;
virtualisation.digitalOcean.setSshKeys = false;
users.users.root.openssh.authorizedKeys.keys = config.users.users.shelvacu.openssh.authorizedKeys.keys;
users.users.root.openssh.authorizedKeys.keys =
config.users.users.shelvacu.openssh.authorizedKeys.keys;
system.stateVersion = "23.11";
};
}
}

View File

@@ -1,7 +1,13 @@
{ config, pkgs, lib, ... }:
{
config,
pkgs,
lib,
...
}:
let
inherit (config.vacu.liam) domains;
in {
inherit (config.vacu.liam) domains;
in
{
services.opendkim = {
enable = true;
keyPath = "/run/secrets/dkimkeys";
@@ -15,4 +21,4 @@ in {
systemd.services.postfix.after = [ "opendkim.service" ];
}
# 2024-03-liam._domainkey
# v=DKIM1; k=rsa; s=email; p=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqoFR9cwOb+IpvaqrI55zlouWMUk5hjKHQARajqeOev2I6Gc3QIvU8btyhKCJu7pwxr+DxK/9HeqTmweCSXZmLlVZ6LjW80aAg+8l2DyMKZPaTowSQcExfNMwHqI1ByUPx49LQQEzvwv8Lx3To2+JghZNXHUx7gcraoCUQnRNzCMoMsGF25Yyt4piW6SXKWsbWHVXaL2i953PtT6agJYqssnBqPx6wqibrkeB9MbtSw97L5oQDaDLmJzEK54vRjFFV4X6/Q1d3D6M5PH0XGm6WEhrNEPgMAAZ6rBqi+AoXUz9E9B+kE/Zc6krCTiV0Y1uL83RCILaEJIjRsHqgrGRYEIBUb4Z5d4CgB3szixzaFTmG+XAgDLGnAHRNGeOn0bUmj35miLUopzGJgHCUQYjaaXMH4FSQMYBFPVqZ1aSiZO0EC/mbLlFbBy51RYPJQK0IusN4IqaBYw6jZYMEVlLWkNb34bfNtPKwoG4T3UjxmSRpfiNCFjYd4DaOz/FBAvUL9bx+qU7O6EZRtslROaWN18uSt20hBH0SpvEovj7vBgWWqXG/chNS7YSSaf3Tlb3I5NbqbmvwFF0t8uuEtN0Wh26qMuOKx70K90B9FpJBpfIk/w8FQ80kP6spbMN1v1T5fA7oZMV1fOn1IezH4wE5Yk/3dS+OXJ4YiLH/hWfjecCAwEAAQ==
# v=DKIM1; k=rsa; s=email; p=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqoFR9cwOb+IpvaqrI55zlouWMUk5hjKHQARajqeOev2I6Gc3QIvU8btyhKCJu7pwxr+DxK/9HeqTmweCSXZmLlVZ6LjW80aAg+8l2DyMKZPaTowSQcExfNMwHqI1ByUPx49LQQEzvwv8Lx3To2+JghZNXHUx7gcraoCUQnRNzCMoMsGF25Yyt4piW6SXKWsbWHVXaL2i953PtT6agJYqssnBqPx6wqibrkeB9MbtSw97L5oQDaDLmJzEK54vRjFFV4X6/Q1d3D6M5PH0XGm6WEhrNEPgMAAZ6rBqi+AoXUz9E9B+kE/Zc6krCTiV0Y1uL83RCILaEJIjRsHqgrGRYEIBUb4Z5d4CgB3szixzaFTmG+XAgDLGnAHRNGeOn0bUmj35miLUopzGJgHCUQYjaaXMH4FSQMYBFPVqZ1aSiZO0EC/mbLlFbBy51RYPJQK0IusN4IqaBYw6jZYMEVlLWkNb34bfNtPKwoG4T3UjxmSRpfiNCFjYd4DaOz/FBAvUL9bx+qU7O6EZRtslROaWN18uSt20hBH0SpvEovj7vBgWWqXG/chNS7YSSaf3Tlb3I5NbqbmvwFF0t8uuEtN0Wh26qMuOKx70K90B9FpJBpfIk/w8FQ80kP6spbMN1v1T5fA7oZMV1fOn1IezH4wE5Yk/3dS+OXJ4YiLH/hWfjecCAwEAAQ==

View File

@@ -1,4 +1,9 @@
{ config, pkgs, lib, ... }:
{
config,
pkgs,
lib,
...
}:
{
networking.firewall.allowedTCPPorts = [ 993 ];
systemd.tmpfiles.settings.whatever."/var/lib/mail".d = {
@@ -17,7 +22,11 @@
sslServerKey = config.security.acme.certs."liam.dis8.net".directory + "/key.pem";
sslServerCert = config.security.acme.certs."liam.dis8.net".directory + "/full.pem";
enablePAM = false;
protocols = lib.mkForce [ "imap" "lmtp" "sieve" ];
protocols = lib.mkForce [
"imap"
"lmtp"
"sieve"
];
modules = [ pkgs.dovecot_pigeonhole ];
mailUser = "vmail";
mailGroup = "vmail";
@@ -75,13 +84,13 @@
userdb {
driver = passwd-file
args = username_format=%n /run/secrets/dovecot-passwd
args = username_format=%n ${config.sops.secrets."dovecot-passwd".path}
override_fields = uid=${config.services.dovecot2.mailUser} gid=${config.services.dovecot2.mailGroup} user=%n
}
passdb {
driver = passwd-file
args = username_format=%n /run/secrets/dovecot-passwd
args = username_format=%n ${config.sops.secrets."dovecot-passwd".path}
override_fields = user=%n
}
@@ -93,4 +102,4 @@
# mail_debug = yes
'';
};
}
}

View File

@@ -1,10 +1,25 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
inherit (config.vacu.liam) shel_domains julie_domains domains;
fqdn = config.networking.fqdn;
dovecot_transport = "lmtp:unix:private/dovecot-lmtp";
in {
networking.firewall.allowedTCPPorts = [ 25 465 ];
inherit (config.vacu.liam)
shel_domains
julie_domains
domains
relayhost
;
debug = false;
fqdn = config.networking.fqdn;
dovecot_transport = "lmtp:unix:private/dovecot-lmtp";
in
{
networking.firewall.allowedTCPPorts = [
25
465
];
vacu.acmeCertDependencies."liam.dis8.net" = [ "postfix.service" ];
services.postfix = {
@@ -13,17 +28,18 @@ in {
# this goes into virtual_alias_maps
# "Note: for historical reasons, virtual_alias_maps apply to recipients in all domain classes, not only the virtual alias domain class."
virtual = ''
julie@shelvacu.com julie
mom@shelvacu.com julie
mar@shelvacu.com mar
psv@shelvacu.com psv
'' + (lib.concatMapStringsSep "\n" (d: "@${d} shelvacu") shel_domains) + "\n"
+ (lib.concatMapStringsSep "\n" (d: "@${d} julie") julie_domains);
virtual =
''
julie@shelvacu.com julie
mom@shelvacu.com julie
psv@shelvacu.com psv
''
+ (lib.concatMapStringsSep "\n" (d: "@${d} shelvacu") shel_domains)
+ "\n"
+ (lib.concatMapStringsSep "\n" (d: "@${d} julie") julie_domains);
transport = ''
shelvacu@${fqdn} ${dovecot_transport}
mar@${fqdn} ${dovecot_transport}
julie@${fqdn} ${dovecot_transport}
psv@${fqdn} ${dovecot_transport}
backup@${fqdn} ${dovecot_transport}
@@ -35,16 +51,30 @@ in {
rootAlias = "shelvacu";
enableSubmission = false;
enableSubmissions = true;
mapFiles.header_checks = pkgs.writeText "header-checks" ("/./ INFO checker headers\n" + (lib.concatMapStringsSep "\n" (d: "/^(from|x-original-from|return-path|mail-?from):.*@${lib.escape [ "." ] d}\\s*>?\\s*$/ REJECT") domains));
mapFiles.sender_access = pkgs.writeText "sender-access" (lib.concatMapStringsSep "\n" (d: "${d} REJECT") domains);
mapFiles.header_checks = pkgs.writeText "header-checks" (
"/./ INFO checker headers\n"
+ (lib.concatMapStringsSep "\n" (
d: "/^(from|x-original-from|return-path|mail-?from):.*@${lib.escape [ "." ] d}\\s*>?\\s*$/ REJECT"
) domains)
);
mapFiles.sender_access = pkgs.writeText "sender-access" (
lib.concatMapStringsSep "\n" (d: "${d} REJECT") domains
);
# hack to get postfix to add a X-Original-To header
mapFiles.add_envelope_to = pkgs.writeText "addenvelopeto" "/(.+)/ PREPEND X-Envelope-To: $1";
mapFiles.sender_transport = pkgs.writeText "sender-transport" "@shelvacu.com relayservice";
mapFiles.sender_relay = pkgs.writeText "sender-relay" "@shelvacu.com ${relayhost}";
# verbatim appended to main.cf
extraConfig = ''
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
inet_protocols = ipv4
virtual_alias_domains =
${lib.concatStringsSep ",\n " domains}
sender_dependent_default_transport_maps = hash:/etc/postfix/sender_transport
sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay
header_checks = pcre:/etc/postfix/header_checks
smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/sender_access
smtpd_recipient_restrictions = check_recipient_access pcre:/etc/postfix/add_envelope_to
@@ -69,13 +99,38 @@ in {
smtpd_tls_dh1024_param_file = ${lib.optionalString config.services.dovecot2.enableDHE config.security.dhparams.params.dovecot2.path}
# smtp_bind_address = 10.46.0.7
${lib.optionalString config.services.opendkim.enable (assert (config.services.opendkim.socket == "local:/run/opendkim/opendkim.sock"); ''
smtpd_milters = unix:/run/opendkim/opendkim.sock
non_smtpd_milters = unix:/run/opendkim/opendkim.sock
'')}
# inet_interfaces = all
# inet_protocols = ipv4
${lib.optionalString config.services.opendkim.enable (
assert (config.services.opendkim.socket == "local:/run/opendkim/opendkim.sock");
''
smtpd_milters = unix:/run/opendkim/opendkim.sock
non_smtpd_milters = unix:/run/opendkim/opendkim.sock
''
)}
'';
masterConfig."relayservice" = {
command = "smtp";
type = "unix";
args = [
"-o"
"smtp_sasl_auth_enable=yes"
"-o"
"smtp_sasl_security_options=noanonymous"
"-o"
"smtp_tls_security_level=secure"
"-o"
"smtp_sasl_password_maps=texthash:${config.sops.secrets.relay_creds.path}"
"-o"
"smtp_tls_wrappermode=no"
#"-o" "relayhost=${relayhost}"
] ++ (if debug then [ "-v" ] else [ ]);
};
masterConfig.qmgr = lib.mkIf debug { args = [ "-v" ]; };
masterConfig.cleanup = lib.mkIf debug { args = [ "-v" ]; };
masterConfig.smtpd = lib.mkIf debug { args = [ "-v" ]; };
submissionsOptions = {
smtpd_tls_key_file = config.security.acme.certs."liam.dis8.net".directory + "/key.pem";
smtpd_tls_cert_file = config.security.acme.certs."liam.dis8.net".directory + "/full.pem";
@@ -102,6 +157,5 @@ in {
tls_preempt_cipherlist = "no";
};
};
}

32
liam/network.nix Normal file
View File

@@ -0,0 +1,32 @@
{ lib, config, ... }:
let
# from `curl -fsSL http://169.254.169.254/metadata/v1.json | jq '.interfaces.public[0].anchor_ipv4'`
# {
# "ip_address": "10.46.0.7",
# "netmask": "255.255.0.0",
# "gateway": "10.46.0.1"
# }
interface_conf = {
useDHCP = true;
ipv4.addresses = [
{
address = "10.46.0.7";
prefixLength = 24;
}
];
ipv4.routes = [
{
address = "0.0.0.0";
prefixLength = 0;
via = "10.46.0.1";
options.scope = "global";
options.src = "10.46.0.7";
options.metric = "1200";
}
];
};
in
{
networking.interfaces."ens3" = lib.mkIf (!config.vacu.underTest) interface_conf;
networking.interfaces."eth0" = lib.mkIf (config.vacu.underTest) interface_conf;
}

View File

@@ -1,16 +1,19 @@
{ config, ... }:
let
domains = [
"smtp.shelvacu.com"
"imap.shelvacu.com"
"mail.shelvacu.com"
"autoconfig.shelvacu.com"
"mail.dis8.net"
"liam.dis8.net"
];
domains = [
"smtp.shelvacu.com"
"imap.shelvacu.com"
"mail.shelvacu.com"
"autoconfig.shelvacu.com"
"mail.dis8.net"
"liam.dis8.net"
];
in
{
networking.firewall.allowedTCPPorts = [ 80 443 ];
networking.firewall.allowedTCPPorts = [
80
443
];
security.acme.acceptTerms = true;
security.acme.defaults.webroot = "/var/lib/acme/acme-challenge";
security.acme.defaults.email = "shelvacu@gmail.com";
@@ -31,4 +34,4 @@ in
default = true;
};
};
}
}

View File

@@ -1,4 +1,12 @@
{ config, pkgs, lib, ... }: with lib.strings; with lib.lists; let
{
config,
pkgs,
lib,
...
}:
with lib.strings;
with lib.lists;
let
email_folders = [
"24nm-domain@shelvacu.com"
"agora@shelvacu.com"
@@ -18,7 +26,7 @@
"jean-luc@jean-luc.org"
"mariceayukawa@jean-luc.org"
"snow@jean-luc.org"
"capt@in.jean-luc.org"
];
domain_folders = [
@@ -32,42 +40,70 @@
"xn--tulp-yoa.info"
];
valid_ish_domain = domain: match "[a-z0-9][a-z0-9-]*(\\.[a-z0-9][a-z0-9-]*)+" domain != null;
mk_domain_folder_name = domain: assert valid_ish_domain domain; concatStringsSep "." (reverseList (splitString "." domain));
mk_email_folder_name = email: let
parts = splitString "@" email;
domain_part = assert (length parts) == 2; elemAt parts 1;
user_part = assert (length parts) == 2; elemAt parts 0;
domain_folder = mk_domain_folder_name domain_part;
folder_name = domain_folder + ".@" + user_part;
in folder_name;
mk_domain_folder_name =
domain:
assert valid_ish_domain domain;
concatStringsSep "." (reverseList (splitString "." domain));
mk_email_folder_name =
email:
let
parts = splitString "@" email;
domain_part =
assert (length parts) == 2;
elemAt parts 1;
user_part =
assert (length parts) == 2;
elemAt parts 0;
domain_folder = mk_domain_folder_name domain_part;
folder_name = domain_folder + ".@" + user_part;
in
folder_name;
is_quoteable = s: match "[ -~]*" s != null;
sieve_quote_string = s: assert is_quoteable s; "\"" + (replaceStrings ["\"" "\\"] ["\\\"" "\\\\"] s) + "\"";
email_filters = map (e:
''
elsif header :is "X-Envelope-To" ${sieve_quote_string e} {
fileinto :create ${sieve_quote_string (mk_email_folder_name e)};
}
''
) email_folders;
domain_filters = map (d:
''
elsif header :matches "X-Envelope-To" ${sieve_quote_string ("*@" + d)} {
fileinto :create ${sieve_quote_string (mk_domain_folder_name d)};
}
''
) domain_folders;
sieve_quote_string =
s:
assert is_quoteable s;
"\""
+ (replaceStrings
[
"\""
"\\"
]
[
"\\\""
"\\\\"
]
s
)
+ "\"";
email_filters = map (e: ''
elsif header :is "X-Envelope-To" ${sieve_quote_string e} {
fileinto :create ${sieve_quote_string (mk_email_folder_name e)};
}
'') email_folders;
domain_filters = map (d: ''
elsif header :matches "X-Envelope-To" ${sieve_quote_string ("*@" + d)} {
fileinto :create ${sieve_quote_string (mk_domain_folder_name d)};
}
'') domain_folders;
sieve_text = ''
require ["fileinto", "mailbox"];
if header :is "X-Envelope-To" "brandcrowd@shelvacu.com" {
discard;
if header :is "Delivered-To" "shelvacu@liam.dis8.net" {
if header :is "X-Envelope-To" "brandcrowd@shelvacu.com" {
discard;
}
elsif header :is "X-Envelope-To" "gmailfwd-fc2e10bec8b2@shelvacu.com" {
fileinto :create "gmail";
}
${concatStrings email_filters}
${concatStrings domain_filters}
}
elsif header :is "X-Envelope-To" "gmailfwd-fc2e10bec8b2@shelvacu.com" {
fileinto :create "gmail";
}
${concatStrings email_filters}
${concatStrings domain_filters}
'';
in {
services.dovecot2.sieveScripts.before = pkgs.writeText "blargsieve" sieve_text;
}
in
{
services.dovecot2.sieve.extensions = [
"fileinto"
"mailbox"
];
services.dovecot2.sieve.scripts.before = pkgs.writeText "blargsieve" sieve_text;
}

View File

@@ -1,8 +1,11 @@
{ inputs, lib, config, ... }:
{
imports = [
inputs.sops-nix.nixosModules.sops
];
inputs,
lib,
config,
...
}:
{
imports = [ inputs.sops-nix.nixosModules.sops ];
options.vacu.secretsFolder = lib.mkOption {
type = lib.types.path;
@@ -20,5 +23,9 @@
restartUnits = [ "opendkim.service" ];
owner = config.services.opendkim.user;
};
sops.secrets.relay_creds = {
restartUnits = [ "postfix.service" ];
owner = config.services.postfix.user;
};
};
}
}

View File

@@ -1,7 +1,7 @@
{ config, pkgs, ... }:
{
imports = [
../common-nixos-config.nix
../common/nixos.nix
./hardware-config.nix
];
@@ -9,7 +9,9 @@
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking.hostName = "lp0onfire"; # Define your hostname.
vacu.hostName = "lp0onfire"; # Define your hostname.
vacu.shortHostName = "lp0";
vacu.shell.color = "green";
# Set your time zone.
time.timeZone = "America/Los_Angeles";
@@ -53,7 +55,7 @@
# system.autoUpgrade.enable = true;
# system.autoUpgrade.allowReboot = true;
# system.autoUpgrade.channel = https://nixos.org/channels/nixos-22.05-small;
nixpkgs.config.allowUnfree = true;
services.zerotierone = {
enable = true;
@@ -73,4 +75,3 @@
# internalInterfaces = [ "ztrf26rjvk" ];
# };
}

View File

@@ -1,27 +1,37 @@
# 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, ... }:
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" ];
boot.initrd.availableKernelModules = [
"xhci_pci"
"ahci"
"usb_storage"
"usbhid"
"sd_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/51a9c6de-3231-469f-a292-ada7d2531d63";
fsType = "ext4";
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/51a9c6de-3231-469f-a292-ada7d2531d63";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/36B4-78A2";
fsType = "vfat";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/36B4-78A2";
fsType = "vfat";
};
swapDevices = [ ];

View File

@@ -1,19 +1,27 @@
{ config, lib, pkgs, inputs, ... }:
{
config,
lib,
pkgs,
inputs,
...
}:
{
imports = [ ./common-config.nix ];
environment.packages = config.vacu.packageList;
imports = [
../common/nix-on-droid.nix
./flake-registry.nix
];
vacu.shell.color = "white";
environment.etc."resolv.conf".text = lib.mkForce ''
nameserver 10.78.79.1
# nameserver 10.78.79.1
nameserver 9.9.9.10
nameserver 149.112.112.10
options timeout:1 attempts:5
'';
environment.etc."ssh/ssh_config".text = config.vacu.ssh.config;
# Backup etc files instead of failing to activate generation if a file already exists in /etc
environment.etcBackupExtension = ".bak";
@@ -24,10 +32,8 @@
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
nix.substituters = config.vacu.nix.extraSubstituters;
nix.trustedPublicKeys = config.vacu.nix.extraTrustedKeys;
environment.sessionVariables."PS1" = "\\w $ ";
#environment.sessionVariables."PS1" = "\\w $ ";
# Set your time zone
time.timeZone = "America/Los_Angeles";

View File

@@ -0,0 +1,9 @@
# To make `nix run nixpkgs#hello` and such use the same nixpkgs used to build this, so that it doesn't take forever
{ inputs, ... }:
{
nix.registry.nixpkgs.to = {
type = "path";
path = inputs.nixpkgs.outPath;
};
nix.nixPath = [ "nixpkgs=flake:nixpkgs" ];
}

29
nixvim/default.nix Normal file
View File

@@ -0,0 +1,29 @@
{ ... }:
let
in
{
plugins.comment.enable = true;
plugins.surround.enable = true;
plugins.lsp = {
enable = true;
onAttach = builtins.readFile ./nixd-init.lua;
servers = {
bashls.enable = true;
jsonls.enable = true;
# nil-ls.enable = true;
nixd = {
enable = true;
};
pyright.enable = true;
tsserver.enable = true;
lua-ls.enable = true;
rust-analyzer = {
enable = true;
installCargo = false;
installRustc = false;
};
html.enable = true;
yamlls.enable = true;
};
};
}

22
nixvim/nixd-init.lua Normal file
View File

@@ -0,0 +1,22 @@
--@param client vim.lsp.Client
local function init_per_dir_nixd(client)
if client.workspace_folders == nil then
return
end
local path = client.workspace_folders[1].name
local command = client.config.cmd[1]
local name = string.gsub(command, "(.*/)(.*)", "%2")
local is_nixd = name == "nixd"
local is_nix_stuff = (path == '/home/shelvacu/dev/nix-stuff' or path == '/home/shelvacu/nix-stuff' or path == '/data/data/com.termux.nix/files/home/nix-stuff')
if is_nixd and is_nix_stuff then
local get_flake = "(builtins.getFlake \"" .. path .. "\")"
client.config.settings["nixd"].options = {
nixos = { expr = get_flake .. ".nixosConfigurations.fw.options", },
["home-manager"] = { expr = get_flake .. ".homeConfigurations.\"nix-on-droid\".options", },
["nix-on-droid"] = { expr = get_flake .. ".nixOnDroidConfigurations.default.options", },
}
client.notify("workspace/didChangeConfiguration", { settings = client.config.settings, })
end
end
init_per_dir_nixd(client)

View File

@@ -1,32 +0,0 @@
{ config, pkgs, lib, ... }: let
inherit (lib) mkOption types;
pkgOptions = builtins.attrValues config.vacu.packages;
enabledOptions = builtins.filter (o: o.enable) pkgOptions;
enabledPkgs = builtins.map (o: o.package) enabledOptions;
in {
options = {
vacu.packages = mkOption {
default = {};
type = types.attrsOf (types.submodule ({ name, config, options, ... }: {
options = {
enable = mkOption {
type = types.bool;
default = true;
description = "Will this package be installed (included in environment.systemPackages)";
};
package = mkOption {
type = types.package;
default = pkgs.${name};
defaultText = "pkgs.${name}";
};
};
}));
};
vacu.packageList = mkOption {
type = types.listOf types.package;
readOnly = true;
};
};
config.vacu.packageList = enabledPkgs;
}

View File

@@ -0,0 +1,124 @@
{
bash,
coreutils,
gzip,
gnutar,
unzip,
wget,
gnupatch,
fetchFromGitLab,
fetchurl,
#libsmi,
#resholve,
stdenv,
writeText,
lib,
}@args:
stdenv.mkDerivation (
self:
let
# this script depends on an old version of libsmi's smistrip
libsmi = stdenv.mkDerivation rec {
pname = "libsmi";
version = "0.4.8";
src = fetchurl {
url = "https://www.ibr.cs.tu-bs.de/projects/libsmi/download/${pname}-${version}.tar.gz";
hash = "sha256-8EilJw9BvIiww7Co/nDKTXFqRrUxoOyqqHxGL0nXSEk=";
};
env.NIX_CFLAGS_COMPILE = "-std=gnu90";
#env.CFLAGS="-Wno-error";
#env.NIX_DEBUG="7";
hardeningDisable = [ "format" ];
meta = with lib; {
description = "A Library to Access SMI MIB Information";
homepage = "https://www.ibr.cs.tu-bs.de/projects/libsmi/index.html";
license = licenses.free;
platforms = lib.platforms.linux ++ lib.platforms.darwin;
};
};
in
rec {
pname = "snmp-mibs-downloader";
version = "1.6";
src = fetchFromGitLab {
domain = "salsa.debian.org";
owner = "debian";
repo = "${pname}";
rev = "debian/${version}";
hash = "sha256-W2VW3EJWmHwlqMoL12dFcfkYmAADLOtUWCydcL5qUKc=";
};
# installPhase = ''
# install -Dm755 download-mibs $out/bin
# install -Dm644 *.conf *list $out/etc/snmp-mips-downloader
# cp mibrfcs/* $out/share/snmp/mibs-downloader/mibrfcs
# cp mibiana/* $out/share/snmp/mibs-downloader/mibiana
# gzip -9 $out/share/snmp/mibs-downloader/*/*
# '';
postPatch = ''
substituteInPlace download-mibs \
--replace-fail SMISTRIP=/usr/bin/smistrip "" \
--replace-fail CONFDIR=/etc/snmp-mibs-downloader "BASEDIR=/var/lib/mibs; AUTOLOAD='rfc ianarfc iana'" \
--replace-fail '. $CONFDIR/snmp-mibs-downloader.conf' ""
'';
preInstall = ''
mkdir -p $out/usr/bin $out/etc/snmp-mibs-downloader $out/usr/share/snmp/mibs-downloader/mib{rfcs,iana} $out/usr/share/snmp/mibs
'';
installFlags = [
"INSTALL=install"
"DESTDIR=$(out)"
];
postInstall = ''
mv $out/usr/* $out
rmdir $out/usr
substituteInPlace $out/etc/snmp-mibs-downloader/* \
--replace-quiet 'DIR=/usr/share/snmp/mibs-downloader' 'DIR='$out'/share/snmp/mibs-downloader'
mv $out/bin/download-mibs $out/bin/.download-mibs-unwrapped
cat <<EOF > $out/bin/download-mibs
#!${bash}/bin/bash
PATH=${
lib.escapeShellArg (
lib.concatStringsSep ":" (
lib.flip map [
coreutils
gzip
gnutar
unzip
wget
gnupatch
] (p: "${p}/bin")
)
)
}
SMISTRIP=${libsmi}/bin/smistrip
CONFDIR=$out/etc/snmp-mibs-downloader
source $out/bin/.download-mibs-unwrapped
EOF
chmod u+x $out/bin/download-mibs
'';
env.NIX_DEBUG = "7";
# solutions.default = {
# scripts = [ "bin/download-mibs" ];
# interpreter = "${bash}/bin/bash";
# inputs = [ coreutils gzip gnutar unzip wget gnupatch ];
# keep = {
# "$archive_fetcher" = true;
# source = [ "$CONFDIR/$i.conf" ];
# "${wget}/bin/wget" = true;
# };
# fix = { "$SMISTRIP" = [ "${libsmi}/bin/smistrip" ]; };
# };
meta = {
mainProgram = "download-mibs";
};
}
)

133
packages/snmpb/package.nix Normal file
View File

@@ -0,0 +1,133 @@
{
fetchgit,
lib,
libsmi,
libtomcrypt,
qmake,
qtbase,
qwt,
stdenv,
wrapQtAppsHook,
breakpointHook,
}@args:
stdenv.mkDerivation (
finalAttrs:
let
# ./configure --disable-shared --disable-yang --with-pathseparator=';' --with-dirseparator='/' --with-smipath=${INSTALL_PREFIX}'/${SHARE}/snmpb/mibs;'${INSTALL_PREFIX}'/${SHARE}/snmpb/pibs'
libsmi = finalAttrs.passthru.libsmi;
# $(INSTALL) -m 444 ${ROOT_OWNER} libsmi/mibs/iana/* ${INSTALL_PREFIX}/${SHARE}/snmpb/mibs
# $(INSTALL) -m 444 ${ROOT_OWNER} libsmi/mibs/ietf/* ${INSTALL_PREFIX}/${SHARE}/snmpb/mibs
# $(INSTALL) -m 444 ${ROOT_OWNER} libsmi/mibs/tubs/* ${INSTALL_PREFIX}/${SHARE}/snmpb/mibs
# $(INSTALL) -m 444 ${ROOT_OWNER} libsmi/pibs/ietf/* ${INSTALL_PREFIX}/${SHARE}/snmpb/pibs
# $(INSTALL) -m 444 ${ROOT_OWNER} libsmi/pibs/tubs/* ${INSTALL_PREFIX}/${SHARE}/snmpb/pibs
in
{
pname = "snmpb";
version = "0.9pre1";
# __structuredAttrs = true;
passthru = {
proFile = "${finalAttrs.pname}.pro";
makeFile = "makefile.${finalAttrs.pname}";
smipath = "${finalAttrs.passthru.libsmi-data}/share/snmpb/mibs;${finalAttrs.passthru.libsmi-data}/share/snmpb/pibs";
libsmi = args.libsmi.overrideAttrs (
final: prev: {
#preConfigure = (prev.preConfigure or "") + "\n" + ''
# appendToVar configureFlags --prefix=$out/ --disable-yang --with-pathseparator=';' --with-dirseparator='/'
#'';
configureFlags = (prev.configureFlags or [ ]) ++ [
"--with-pathseparator=;"
"--with-smipath=${finalAttrs.passthru.smipath}"
];
env.NIX_DEBUG = "2";
pname = prev.pname + "-for-snmpb";
}
);
libsmi-data = stdenv.mkDerivation {
name = "libsmi-snmpb-data";
phases = "unpackPhase installPhase";
src = libsmi.src;
installPhase = ''
mkdir -p $out/share/snmpb/{mibs,pibs}
shopt -s globstar
for foo in mibs pibs; do
for node in $foo/**/*; do
[[ -f $node ]] && install -m444 $node $out/share/snmpb/$foo/
done
done
rm $out/share/snmpb/*/Makefile*
'';
};
};
src = fetchgit {
url = "https://git.code.sf.net/p/snmpb/code";
rev = "a092855bfd201778f87be578b91aeb062726e329";
hash = "sha256-nlS1pqv2ERZGkk0SJ8ByXqBHHho1GTSq/oxrXL2tytM=";
};
patches = [ ./unvendor.patch ];
buildInputs = [
qwt
qtbase
libtomcrypt
libsmi
];
nativeBuildInputs = [
wrapQtAppsHook
qmake
breakpointHook
];
#setSourceRoot = "sourceRoot=$(echo */app)";
#NIX_DEBUG="7";
#installFlags = "INSTALL_PREFIX=$(out) NO_ROOT=1";
installPhase = ''
popd
install -Dm 555 -s app/snmpb $out/bin/snmpb
#mkdir -p $out/share/snmpb/{mibs,pibs}
#for foo in mibs pibs; do
# for file in ${libsmi}/share/$foo/*; do
# ln -s $file $out/share/snmpb/$foo/
# done
#done
install -Dm 444 app/snmpb.desktop $out/share/applications
install -Dm 444 app/snmpb.xml $out/share/mime/packages
install -Dm 444 app/images/snmpb.png $out/share/icons/hicolor/128x128/apps
install -Dm 444 app/images/snmpb.png $out/share/pixmaps
install -Dm 444 app/images/snmpb.svg $out/share/icons/hicolor/scalable/apps
'';
postPatch = ''
rm -rf libsmi libtomcrypt qwt #ensures un-vendoring worked correctly
#smipath_parts=(${libsmi}/share/{mibs,pibs}/*)
#smipath=$(IFS=";" ; echo "''${smipath_parts[*]}")
substituteInPlace app/preferences.cpp --subst-var smipath
substituteInPlace app/*.pro \
--subst-var libs \
--subst-var include
pushd app
'';
env = {
include = "${qwt.dev}/include ${libsmi}/include ${libtomcrypt}/include";
libs = "${qwt}/lib/libqwt.so ${libsmi}/lib/libsmi.so ${libtomcrypt}/lib/libtomcrypt.so -lqwt -lsmi -ltomcrypt";
inherit (finalAttrs.passthru) smipath;
};
preConfigure = ''
qmakeFlags+=( "${finalAttrs.passthru.proFile}" "-o" "${finalAttrs.passthru.makeFile}" )
'';
makefile = finalAttrs.passthru.makeFile;
meta = {
description = "GUI SNMP browser and MIB editor wrtten with Qt";
};
}
)

View File

@@ -0,0 +1,61 @@
diff --git a/app/preferences.cpp b/app/preferences.cpp
index 29fa8c8..98e842f 100644
--- a/app/preferences.cpp
+++ b/app/preferences.cpp
@@ -22,13 +22,6 @@
#include <qfileinfo.h>
#include <qtextstream.h>
-// For DEFAULT_SMIPATH
-#ifdef WIN32
-#include "../libsmi/win/config.h"
-#else
-#include "../libsmi/config.h"
-#endif
-
#include "mibmodule.h"
#include "preferences.h"
@@ -288,7 +281,7 @@ void Preferences::MibPathRefresh()
void Preferences::MibPathReset()
{
// "Reset to default" for MIB paths
- QStringList defaultpaths = QString(DEFAULT_SMIPATH).split(SMI_PATH_SEPARATOR);
+ QStringList defaultpaths = QString("@smipath@").split(SMI_PATH_SEPARATOR);
QSettings settings;
settings.beginWriteArray("mibpaths");
diff --git a/app/snmpb.h b/app/snmpb.h
index 63f0d6e..c1da1b8 100644
--- a/app/snmpb.h
+++ b/app/snmpb.h
@@ -20,6 +20,7 @@
#ifndef SNMPB_H
#define SNMPB_H
+#include <qwt_text.h>
#include "ui_mainw.h"
#define SNMPB_VERSION_STRING "1.0"
diff --git a/app/snmpb.pro b/app/snmpb.pro
index b6ee631..a5ff14a 100644
--- a/app/snmpb.pro
+++ b/app/snmpb.pro
@@ -83,14 +83,9 @@ FORMS += \
INCLUDEPATH += \
../snmp++/include \
../snmp++/ \
- ../libtomcrypt/src/headers \
- ../libsmi/lib \
- ../qwt/src
-LIBS += \
- -L../libtomcrypt \
- -L../libsmi/lib/.libs \
- -L../qwt/lib \
- -lsmi -ltomcrypt -lqwt
+ @include@
+
+LIBS += @libs@
RESOURCES = snmpb.qrc

View File

@@ -1,6 +1,7 @@
dovecot-passwd: ENC[AES256_GCM,data:8tu5q45q9FGhTjALtXtcklbRUnJQ9GvmVVKqsNdMNaFtsz/g/REY312K3nNc2nmDTlehIzopc86fW9z/HXfpeT433Yyi5s/4ulbN/lIpsQJK8WNNslzHOnSlUrPBETQKxuLIA1nsr8DKFOfvFIqTtD7ohpvKNp+rySGnyBYze6EIkwnTTnik59ESUnI6IBi3gxYN7vuw9ZraHZsCdp7PY4EJav077gLOSimgCMF2CYnVJ6D7ibKUC4SJ6mCq/DkqUtJwi7BlQMyvn3FpKSHhUAFwTJ2/ryvqX9zKVycVCRUqsaGUo360bWRs+TCLsvvz3Kih6O2RVqsSqjKq3U3kcb9w4Tt+jvpKGSVfW8Ig/BnOctfO0qDikwz5eqq+8qYCasWTP6hmyrM2+ydPRR6kqA0q77XxTRX1CrOSSP7GDd200LVY36NXVE/6wWv1aOMRbSi1XI7rcX2g8EmQNSNTS9hZRJvnjizgsLFX4U1/06hCLGfGoU+xkMuUtOrZ2MxL9sFUjPy/xq2XcpOZatfsKiaJzV8P1w==,iv:6Fv8DJPZsci4B0BqQTVjGt3KxR0mRThS025iR997nyE=,tag:k2tCEssV5NLswWFNiRz7Cw==,type:str]
dovecot-passwd: ENC[AES256_GCM,data:pcj7T1AKqZfMBGiHiihW0WxVKzAiy6xsGGlOhOV4IeHPEn+SXNoQjTQQVhZoNxYsENptH54SgWwlMETCcQrQzq6prrktlT3iZCnwlwvzaNRXrMe1mk/WT+OiTpaQ0PWGfrhVkQXj4bxWKCRc2i3NJxm1AtYfE0nNL/1dUk9rzwYTH6zjiQFYmZHbwzjtxiE3YbZCwYnpNR3Ql08S4kNf5TtsecFtTY1VOPFRycjEfIIIUbVLUM06DZ5savKVNRdgaVMUuXyPoOxy65YbkwZ9vkoBleRShY0v6FOgG1YLmQmr7f8QtiHlFbA0NJ0vUkg8bgSTsw27jC/JQU0qTSNVrMHgzfApw6GUQgGTYZK24tFCVNBJ3sxvTbuVOcShy01yJA==,iv:5gTo8ySgq//ZaY88F7AcAa2CEe2hXR415EqqSsYIbF8=,tag:DOf4yEXW5kzYAL89KQOAdQ==,type:str]
dkim_key: ENC[AES256_GCM,data:CZC/1U1cJUIyNhXAWp+YFJd0pZZKvZClJxOh3uZ3YyfEQBiK9nEQryAJHirpFXAmZTcGhsuotkAuJvVQtoh/pM9YGkrncCKlw+P96hiafHGoSOnqd77DazcVERwGEGYBPK7fIZfhpAaYiIvjwq6FbMzkkZ4vLcYRNRj+LCtrXu4K5cy5ZJaRFkLCiaIVHhrOfjyhDFCkFBd3pZ/oCGH57teisjFl+LWFqGOQFyGs3Vkv0bY1fUTUtFvpYcTdrRe6A7yI3OGveX3Q9JnDKD+PBqHhd/a/OjBF0Xme6BeipRnv6/Md2F5LNDfUWugOtDy0xigtWAp/mbVel8GYgTXEQYv+sxVu0kFM7bX8fa/A/BHNx98HFoScwLCt8VmCc26asfGvGFfADrJMBIk2IbmqjQ2NV7/ejB6Zym7tjLLpYI24LBAyZDH/Rtw7CqGPmpHXCQ9xILFxLMdqMSmgPPJtF/75qFICCQH2p3CHj7b/TmTpu8RLIVu2pxG48u4VnUgJE1zPBeaY5EY1uS7L5sF37CI+vMy1mY/3m5ZsWeOu9YigZouYy/Y6OrdtOzaEVaipQ2cYirD00MOYqO57izmjuUdw47OJ5zK7XInR4MHoLX0PfdJiw5Oq8OVir6KJf9UWPSXBbSZlj6PMkqbvQ+7VWJmDT0jKTbRg2M1eZCbcRrJAnE/YenMqYFXiVY1dOGjcrrxUn0zcnJ51UJmfDU2+UQc7urBVtqm7jfegudQ+Em735ynclMfYRWvRXQGQUm2YCUFXTwd6RhY4hHb32j6x00hi6iLjt1gjlMx8pHAcVbqcOdHFoLvNe1DlBsl/7jmL7otyY5m1VF3+H0tksDTSYfil5oudMEECTPypsZfp8iLU4xgjuh/+fXjZf4hQJMiA6OaGMw7R2cwvfiuSaHL/iz57ZtlHFW6TMWK77UBU2xZACVfylnqEaaIgzhYX0/wAsVQI+gqt03EsUx/AqlCFOCrOSwjov06k2bTDzSDcITayLkf9UjwOo/lmRz+7fCfvCaw26wZCEsEtRBfLrZc+Ibwq9uvNDsrV1hthi0qh1ngZonQOA1Y2NURDom3VMKkfu++nFIV+CGrAI5n0CVlVLkJn4RbPCDcmNGd9Kr8pYv7rU4MnMmD2n2M1OzAJbScrbb+f4Z8hEOIUk0dMVxOr/clrg+7F3vqceZC8VTzBbBAH4QuBAf67VwmZTpDB5bobFv/UwEC8pJ4HWmKcBN+s1QihtD7x+WYz+8pSNucr+oN56fiY8xAyvFFyTE7/zNWlXVi94E0is30q3/ZB/Gog5eOQT21tOI4Ak0N4y+ElfNIXSqtEUGhck2DIjfegygpvwiuu8ktEZwje9Q4SAYK8/0THT8ANyzDunwSocMdztL1zF6/ZhDub8hmOuaRJWotXzmL/zCXSGR0nEPXVSmyXKwHt/4MMGkasXOXetrENKIwDqYdm1eZBMCl8EGnyAbAo21LAfVTI0GLrNoFWNTPkpBIo3dKoBofmdRei/jHtQmBtvaILUv6UsIAyjJ+x2cpARW+yMIrv/0g8MnDMj4cCiIFk+AIXI279BvMrkVP1cOA7ESJkLe1hsL6+b7lmrhAWK1cpDnIWTXJG+v9aKlc0jz9D47gr7kD/ePC8sMaI95aQBbA93ftzYhKzsU9hINsU/IKGmT0rXS4j/BPZ0o8uC1HRaMjdE5Z0KHsebS9tn8lXfHFgX5wTDMaES9h+usUJrjc6F1lj2zYP5oTOjM8YmN6YQedo3wmi/PnA/8YMXz0tRFAZvg8VAYYtsfdV/2GLtjfD2YRK3iHsg5+GSEwqFafmWGgr+uhsl4JmKiASWJvx0Ron8RwdEzK2MC6WD1JERLU4UojOfx2xy5v15eveNnEufb7o1MJSAbjuRbVYiABqNFjIwe9hquIyTYVsiqiXi6fLeIV4fsTtiI5LLKx/6dOw31nFg/WfFWzvzLiLJ6b0NZowECP+Rsvzl3U0Qo/LbePyY/o8UYOo7u1zLpzxIOPyTqdKh64WqGYnqXmWy1ga57vnyl9mWhzr9ZlEuhM+0U8bVelIXmLTZp1Nredrs8E5ERdVnKmThbrLr8GvJAl4B7g5BIrGhSBB841wMm9h/SheKdq8SN9gUDRNgW0QNFkflBhX5ZsAHlPiJxddePbbAxfChv+ClG0oDuFDoSwSElCRR9GRayLRiws6CCDhviU8ub5JApSPTI9p/UjSJePSj+GqyqljTge0J/wgxRL2pAHk1HDQyOnv4kFZ5UhMFjU6GvbuPl2W2lqICJOcK9UuKdvivGsYkSSrOfke3mZMh52/f+03ciZ4xlwjDGV91kGONq5GME8dFEPD093xg0KbScfWanRWSoV3fOxitPWpcJ+xuNnDDOHjzLOYgt07u1QQs62rg/6BII+1XKBowLwG9Z5aWexZ3yCzrOR70pLRWPbOJNCAggEIaTkIa0ukOlaPbGzSZ6LuIyup7ex0Uabd2cOuvmAdMqGwnIB7fhtkdR7G4iDbnUqu7hbFurJn/3IZalJvbyZUuvC5X4oGU/CTWzDtdSgv5jQQ9qnr9ehCNCWjdg9T05v65XsW/OwHnRUN8A+1vxBIZ884lvFoOhJYeKXMufdAg4bCzUE/kdctRPwAVt3OjLnykXYcJV/3Ch+YIwv2vNA4pXqsMw8wgxX7DCvrCrVpkZAC1JIE32aKCXrN4tRUMrc0mnqUXa9M1rc6HCGa/vFCMj5ZW8xP9mOG+HEJFiJaV6ydxvhI7NMyXW2YDSxVh5RMMjXHUBq/bKMHPrLN57qmzvtcKUNcmS+VTvjS64wZlUsA1PEVwaJ/EQVAaY6ZeZi0CJ2A3YpklXYJpNqYhv8ICtFK2Uf6STfNYGaLTW2bgfZpWhic1y/V4wAWKa5A/XALXec+ioFr0foQR2ADiUycQYhMLZPSKPnWhcmwUPY+KPrjP11raVSM4ehtKdDlrbL3vmw6SlwowveyC3aqiceYzISWAw9o+ccvLs/bedEBeC2af2V53/vIuN4XYWjtZArRyqpzeeqlnTOb7vhpI84plXJdGHlmw0bml0yV3r3ucgB50wbAMRvQtJQ6ePPfOLOYLpDYFLPZJci8Vc3vRInskPOF39m9tSTT1noUSRZ3IxGi4LiUT76nAgI8BeTp3bqNuA6Of6I4yYS4Jmmby5C5eel0Ozl3gkMk1xuM5UTwcE7EDkr9rnzxs6rbx3CpQB3y6QB3tAe00zPpMm5YKJq1AKqvSzPco58g1vVu06e3l+tcGyt85t5wQTco3OX2kgBBxsiA629yAWcSIqKFZ+o7nTpA+zZmQrjVganWflbOhVNkvRSkLpThkYVlnkqBU9ixzQa79xVOF3WmNYBhdWfnO9VxFwE4MqgpOyL7sz0PsV5/ZsOy8m7DadM3GCS2mFtWZiM1RnGCayZvyY2KFNj3I8qM1HGMMfeF+3KXjyCBSyBkD25in85M0QaPlMzBxFZupSoleJLLwqd4BfsLk+POiZjLQQseSDVSqrjqWyE6d+baiy+m6d+z6sx4ojRf+q9wlMjZ2oRa+wsLnhbCrdHsZi6Q9eZawU6Vlsy3/KjarJABnapJsMbHYTlwPHlPYU6Du9T3lO2aJuTewOzA42Aoqm2Tlm4xh0GRV6Rx7najkMjc3cex1DAu0PNaFzWVBD7yPuv9FS+DzdEneEj9Tx81v245I9U8Oc6yacu72Ry2CG03ONld70oEU2BHrIgswoyMNg72hnhot9jfDutjJrB10b65pP5WZOAUGtwDh2a2KrdnYG/TGId+ehnkkwS2Sd87/CM4aaSYlsVneId6bXYpUcxSLroXUAHsigA3rjMpNpvR8XRiQZUfLWRQ+d8gyL5PVLp1H7R6LEDO4sZP8IuDJfxDzlP0Rh6GOQgu+dlkcxWGVHQxcexBThMURJYVMhTDoYopEfUqo3j+q7Fla4Q3HdypKg17VyVfEA/J7Nie+eDZvTEuvX0jWQmGAFdC9GbkVuT7hlzYx4kZ6/B81kVyQi8e3L3ZBAYHQXbHeK4GhSWQDwHG6ZBU16KrD6dhjIvn4HlXaGYaPMvv0Rp+yjeiur/n0NOWyvx0R1RrksbsyeaLIEDhOS19wXP4kiDrTR2qJN4LHcWu3m/hYuB4Fj72qyr2K7osXvbC/up2bSpY0IOcei8Nc/hIhqoe7uM4Jg3cpXt0hTpcDZ74HNIsd/6f592BqpoXIy5Cr1ZOxmnpkHdgZIyJ3KqwZEhYa7pSkOIIEAY9EnTPm3ViBHQdqjUpghYNzntO8EomNNw0sXUFFrwlGAY+ntLYUty0kREWt4l8Iot+XblCc8FX1gKYSqhnJOGjHHjOHO22Cr6NPJdcHfgkIBCknwwFWWMRPwZOomE=,iv:7LF3l52m6YRKGd/8rxDady3AbSEcXuVRsIaLlgNfKOs=,tag:UCjMRgFZFHQyXY5NfbZRcg==,type:str]
dkim_pub: ENC[AES256_GCM,data:XLYRTAviK+r6DnRU4+lc58elI3FJ+FPsB1A5sQOk+pb+fNu7zFCiZdz/MwTVkE9izDP1Onv+VhV8sRgmxacTv4nW5GcukCrm3FmCp2jm6QF1/40/WRv6Lkbek0tV1bMOQPy9Zj8wdO9M05XCXUVXk4x17rj+lw8ApwJS2pJMoultMFx34tx2pNEnmO3MFtuBOxzeU2yP+NhF2sJNA62to78AiH5EblkoF0a6sUYk553U+sv3Ob0lo1nSv6c8zwl7y1WSNQnLK+/3WxSVGfePHVsVM8Zze1KFTVLQQggIzWTdcr7AgcTGbk3kaYCeucfQ60pVlqOyPnkJoUJ8HR1RSajFk6Ylzw0xBpY85qAXNT2YIRiq0HTUc1s5lD0luXLQEP+g+XUwZfzFRZgt1nWBlPmpbj2Ylj1FfrA7EXsIK9nyo+rf0qRn/4HusJATr9ddYmZdxwazl1FXkOKLHPyu1NlzwoTNSQQgMHlzxzUvrrv7+mI2nQvXRx82TSRytqrMvoBTF1NFX+pRjhNg9fcq0oPJ2ORqOVQsxzhLhB+tw7Cg+UHGWlnKnkqaKH1JDmOFyJDB96aPUnSQT2J8qkyb+hMBXz9mme8rZopkHrA4WyDXv3zpEi0P5Sj0DDwdRxKMdDdZ4hw79YQIrd63cIorN8XG6Icevb25LfekLEq/C2FS8+kADagyOM0uzCw2p/qacNz37ZNGqPK6gYkjnyoAfSm14zbgoLX/5dnf7eCuMatevTm4AcE53RawQfzz0YNJuEv5uqD/WUy+UIKHIwxPYY9FWBBPmH+8eaPC1mMPh54I444b39FwpnPU8GwxEPsjRg8TSnohawNmmhEWEpmlawEKw+C+BE6A2DmVJzyeBvVRwe/W6CPgyYxgSGWUuvfZFm1GrzwZDjCOEMRn7qMwMBxh1nr2BOAiNxA38UtsymaZO5ZOknClWlKIkIFl8NJdVITNNsI48KMuSY20o1puzkxMaAUH3OrGEhtoHrEOeIq+KCFzH2gZo6L5hbv9CHM7QgCYsbtVIMwL+cRZZaSNubS3K48OmWJnHNuqkcrSI4lqfjLhz1DbnQ==,iv:/cNMmlpq9LSOk0MwVq8NaWvp47q68lKWTx4s5nkwF5c=,tag:ZNX+yZsSxdhFsavDpX380g==,type:str]
relay_creds: ENC[AES256_GCM,data:yWG53NaiA2s5aUudZWecDS1+fOURTHd0D0rNxZ9Tud9TsTO2F/6+5i3vRz/4qP4FoBexEVoW5Xhkqo8o8OaGOpZHh/Nla7TJTnaSCgJw9QPfFoRNiE9f46LytXYThiCGBdy3Z3gtNmSX5BQk1zNI1TiHBFG4IYfauq7e6jJ4Bp/9z3LRknDITdlLjzAPjIO5kUG95IrQQCl3SeAjS+LwxPFRuV1+zWNdOXJLmSeWv1JcAcyhkwutMhQYRGMaS09bbXp29N8DX3lsAK9pYZLr5F3gXwOrZN7nG4+K0KOqfMI4UcLpIOlCPdj9XjgAYcWC+LL5bA0W53e7je3IDVebevDheKPowKK/A6le2TfqXKfhOVi4qXaEsjOBIJzLylOqXoAb1ZCM3nTHCC3M/r3/il+6RnFgISOCHezTiEYM,iv:0kAJzoV/HEIRuEAxzWAaQqwlzWlBSwklipWquF9WeoY=,tag:SCQOQCXm6kmLSYhkT6dubQ==,type:str]
sops:
kms: []
gcp_kms: []
@@ -115,8 +116,8 @@ sops:
TjhQY0VoNU91Zi96VzZGaitsWHptT0UKZ3Vx/iqilkHrFkAbaSeJZNmSOzXvMDX6
HhcXrrq+sVjnq0XhOqWVY72h8Hp3d0JWA9VOxNQRyM9hdVENXur8YA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-06-28T22:46:43Z"
mac: ENC[AES256_GCM,data:2W8TPIx7sowGBhSP63SHCiA+zvY1tKM6Ki5wBrbg5O8cYqf1UzaK7BOfU63aPq+ev+7n68B09A+MccCuRSRFIWNO/3H+I/jHrgQL2bYe5xwwqFQ8KYp3qeuxTgV5GlgVRNbBnXsxqbC5Cb+FnaisQc8bwm4wCED1+AtB2gm+XMo=,iv:XhchcixL9EwkjQJELC2IfvtGEEzUV4nK9v/Dbckh3SA=,tag:jaGdZaTVx0eq3CljcHuc4A==,type:str]
lastmodified: "2024-07-10T20:44:49Z"
mac: ENC[AES256_GCM,data:tSTKCP7HUUCSCrbeiLutPghjfbL9TsxuCmbARUqwQBH8pyeOsyFHyPCqmqjCDSu2ha0QTldNGM9baiIQa/05DV5KNmFfVuoWy6dd4/3L5yNd3FPkzR2SvBua1g09YZpC1G2IaGrOcqBEOY9baILeBGgXfxRtcpMVAR2C3bOqJyQ=,iv:4phBdZ/4u5DAbUn4Z7pdrJym+iG9oxZSsIPZqoDEqco=,tag:RJn0416yl+0FV9bTu5tA5w==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View File

@@ -1,75 +1,210 @@
{ pkgs, nodes, ... }: {
{
pkgs,
nodes,
lib,
...
}:
let
certs = import ../deterministic-certs.nix { nixpkgs = pkgs; };
relayDomain = "relay.test.example.com";
rootCA = certs.selfSigned "liam-test" {
ca = true;
cert_signing_key = true;
cn = "Liam test CA";
};
relayCert = certs.caSigned "liam-relay" rootCA {
ca = false;
signing_key = true;
encryption_key = true;
data_encipherment = true;
tls_www_client = true;
tls_www_server = true;
cn = relayDomain;
dns_name = relayDomain;
};
relayUser = "foobar@shelvacu.com";
relayPass = "asdfghjkl";
relayPassFile = pkgs.writeText "relay-password-file" "${relayUser}:${relayPass}";
testAgeSecret = "AGE-SECRET-KEY-1QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQPQQ94XCHF";
testAgeSecretFile = pkgs.writeText "test-age-key" testAgeSecret;
sopsTestSecrets = {
"dovecot-passwd" =
(lib.concatStringsSep "\n" (
map (name: "${name}:{plain}${name}::::::") [
"shelvacu"
"julie"
]
))
+ "\nbackup:::::::";
dkim_key = ''
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANn62hMdcFw4znAB
CKth6N4JD8XrNezCYbvyrUcVpGkkMX3TC9sEyZgGV6Y2Cs/J2Q6jKakC47nXebzV
Edk/kWsApj4J7PQl4t/G3vf1rdfICQx1pIspsmqQKsYugUG18EugEZzelai3+n4U
wqsed4551aRtwaws8dJQePOEEq1BAgMBAAECgYEAummKgXpVkqiJ8sMPlPEgYnHB
aXLjJNx/FGpOwVHCzp/DK2WG6ADKHhaecmgZCuYFmDz07bKo6U9arqBQqUdxpUor
JT2SS9RFP5MTsTB6R+eRqX8oMRQhcXB/+MczoSV/087vIZsL3L//6XoGyvjuHKW/
bvUR/F8PhB84uPU6RLkCQQDzXXj80iRhY6jHDwqoGf3BXd4O4cIAzPbBXN0W41fV
L5ZBm0K0KAgLnyjVygbsSn6lXsZXzAa/wAbSstMeCn7PAkEA5Uv88nfZSLU99XvF
WB9GD7lKXsAnWlf09F8hH4a1TH/zfGUCxrDdYNmdBdG6t0XuIVjay3TZcpW68Z2Q
lLeW7wJACj7KJCKYo3z1kwPAGBmYBDb2bTv11eDLFpLZP+hsPy5UrghiQ4FX7V1S
88Ugi3wLXtzhjrqpIhNsdhxPJPmeIwJAVpx8YE4a+hbT340v/thZS4ku6Vllw/9j
XIcuaM0mYE4Yd81j3g9in7mzUUZmY+H7UAdTJfTuShT6t1dQDIzIawJBAIJ+azsj
H5M2KsE3Nuxe3RODM/D4I5M5dngTkgNZQvUAywAyj9U39ZeFPEyXJyGkKNoR2CXB
hCvgabgr0wsi1y0=
-----END PRIVATE KEY-----
'';
relay_creds = "[${relayDomain}]:587 ${relayUser}:${relayPass}";
};
sopsTestSecretsYaml = pkgs.writeText "test-secrets-plain.json.yaml" (
builtins.toJSON sopsTestSecrets
);
sopsTestSecretsFolder = pkgs.runCommand "test-secrets-encrypted" { } ''
mkdir -p $out/liam
SOPS_AGE_KEY="${testAgeSecret}" ${pkgs.sops}/bin/sops --verbose -e --age "$(echo "${testAgeSecret}" | ${pkgs.age}/bin/age-keygen -y)" ${sopsTestSecretsYaml} --output-type yaml > $out/liam/main.yaml
'';
in
{
name = "liam-receives-mail";
nodes.ns = { lib, nodes, ... }: let
liam_config = nodes.liam;
in {
networking.firewall.allowedUDPPorts = [ 53 ];
services.bind.enable = true;
services.bind.extraOptions = "empty-zones-enable no;";
services.bind.zones = [{
name = ".";
master = true;
file = pkgs.writeText "root.zone" ''
$TTL 3600
. IN SOA ns. ns. ( 1 8 2 4 1 )
. IN NS ns.
${lib.concatMapStringsSep "\n"
(node: "${node.networking.hostName}. IN A ${node.networking.primaryIPAddress}")
(builtins.attrValues nodes)
nodes.ns =
{ lib, nodes, ... }:
let
liam_config = nodes.liam;
in
{
networking.firewall.allowedUDPPorts = [ 53 ];
services.bind.enable = true;
services.bind.extraOptions = "empty-zones-enable no;";
services.bind.zones = [
{
name = ".";
master = true;
file = pkgs.writeText "root.zone" ''
$TTL 3600
. IN SOA ns. fake-hostmaster.example.com. ( 1 1 1 1 1 )
. IN NS ns.
${relayDomain}. IN A ${nodes.relay.networking.primaryIPAddress}
${lib.concatMapStringsSep "\n" (
node: "${node.networking.hostName}. IN A ${node.networking.primaryIPAddress}"
) (builtins.attrValues nodes)}
${lib.concatMapStringsSep "\n" (d: ''
${d}. IN A ${nodes.liam.networking.primaryIPAddress}
${d}. IN MX 0 ${d}.
${d}. IN TXT ( "v=spf1 mx -all" ) ;
${liam_config.services.opendkim.selector}._domainkey.${d}. IN TXT ( "v=DKIM1; k=rsa; "
"p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZ+toTHXBcOM5wAQirYejeCQ/F6zXswmG78q1HFaRpJDF90wvbBMmYBlemNgrPydkOoympAuO513m81RHZP5FrAKY+Cez0JeLfxt739a3XyAkMdaSLKbJqkCrGLoFBtfBLoBGc3pWot/p+FMKrHneOedWkbcGsLPHSUHjzhBKtQQIDAQAB" )
'') liam_config.vacu.liam.domains}
'';
}
${lib.concatMapStringsSep "\n"
(d: ''
${d}. IN A ${nodes.liam.networking.primaryIPAddress}
${d}. IN MX ${nodes.liam.networking.primaryIPAddress} 0
${d}. IN TXT ( "v=spf1 mx -all" ) ;
${liam_config.services.opendkim.selector}._domainkey.${d}. IN TXT ( "v=DKIM1; k=rsa; "
"p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZ+toTHXBcOM5wAQirYejeCQ/F6zXswmG78q1HFaRpJDF90wvbBMmYBlemNgrPydkOoympAuO513m81RHZP5FrAKY+Cez
0JeLfxt739a3XyAkMdaSLKbJqkCrGLoFBtfBLoBGc3pWot/p+FMKrHneOedWkbcGsLPHSUHjzhBKtQQIDAQAB" ) '')
liam_config.vacu.liam.domains
}
'';
}];
};
nodes.liam = { lib, ... }: {
imports = [ ../liam ];
systemd.services."acme-liam.dis8.net".enable = lib.mkForce false;
systemd.timers."acme-liam.dis8.net".enable = lib.mkForce false;
systemd.services."acme-selfsigned-liam.dis8.net".wantedBy = [ "postfix.service" "dovecot2.service" ];
systemd.services."acme-selfsigned-liam.dis8.net".before = [ "postfix.service" "dovecot2.service" ];
# sops = lib.mkForce {};
vacu.secretsFolder = ./test_secrets;
sops.age.sshKeyPaths = [ ./test_key ];
services.do-agent.enable = false;
virtualisation.digitalOcean = {
seedEntropy = false;
setSshKeys = false;
rebuildFromUserData = false;
setRootPassword = false;
];
};
# uncomment to significantly speed up the test
services.dovecot2.enableDHE = lib.mkForce false;
security.acme.defaults.email = lib.mkForce "me@example.org";
security.acme.defaults.server = lib.mkForce "https://example.com"; # self-signed only
networking.nameservers = lib.mkForce (lib.singleton nodes.ns.networking.primaryIPAddress);
};
nodes.checker = { pkgs, lib, ... }: {
environment.systemPackages = [
pkgs.wget
pkgs.python311Packages.imap-tools
pkgs.python311
(pkgs.writeScriptBin "mailtest" ''
#!${pkgs.python311}/bin/python
import sys
sys.argv.insert(1, "${nodes.liam.networking.primaryIPAddress}")
sys.path.append("${pkgs.python311Packages.imap-tools}/lib/python3.11/site-packages")
${builtins.readFile ./mailtest.py}
'')
];
networking.nameservers = lib.mkForce (lib.singleton nodes.ns.networking.primaryIPAddress);
};
nodes.relay =
{
lib,
pkgs,
config,
...
}:
let
mailpit = pkgs.mailpit;
dir = "/var/lib/mailpit";
in
{
networking.firewall.enable = false;
users.groups.mailpit = { };
users.users.mailpit = {
isSystemUser = true;
home = dir;
createHome = true;
group = config.users.groups.mailpit.name;
};
systemd.services.mailpit = {
environment = {
MP_DATABASE = "${dir}/mailpit.db";
MP_SMTP_TLS_CERT = relayCert.certificatePath;
MP_SMTP_TLS_KEY = relayCert.privateKeyPath;
MP_SMTP_REQUIRE_STARTTLS = "true";
MP_SMTP_BIND_ADDR = "0.0.0.0:587";
MP_SMTP_AUTH_FILE = "${relayPassFile}";
MP_UI_BIND_ADDR = "0.0.0.0:8025";
};
serviceConfig.ExecStart = "${mailpit}/bin/mailpit";
# serviceConfig.Restart = "always";
serviceConfig.User = config.users.users.mailpit.name;
serviceConfig.Group = config.users.groups.mailpit.name;
serviceConfig.AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
wantedBy = [ "multi-user.target" ];
};
};
nodes.liam =
{ lib, ... }:
{
imports = [ ../liam ];
vacu.underTest = true;
#systemd.tmpfiles.settings."69-whatever"."/run/secretKey".L.argument = "${testAgeSecretFile}";
systemd.services."acme-liam.dis8.net".enable = lib.mkForce false;
systemd.timers."acme-liam.dis8.net".enable = lib.mkForce false;
systemd.services."acme-selfsigned-liam.dis8.net".wantedBy = [
"postfix.service"
"dovecot2.service"
];
systemd.services."acme-selfsigned-liam.dis8.net".before = [
"postfix.service"
"dovecot2.service"
];
vacu.secretsFolder = "${sopsTestSecretsFolder}";
vacu.liam.relayhost = "[badhost.blarg]:587 [${relayDomain}]:587";
system.activationScripts.sopsHack.text = "ln -s ${testAgeSecretFile} /run/secretKey";
system.activationScripts.setupSecrets.deps = [ "sopsHack" ];
sops.age.keyFile = "/run/secretKey";
services.do-agent.enable = false;
virtualisation.digitalOcean = {
seedEntropy = false;
setSshKeys = false;
rebuildFromUserData = false;
setRootPassword = false;
};
# uncomment to significantly speed up the test
services.dovecot2.enableDHE = lib.mkForce false;
security.acme.defaults.email = lib.mkForce "me@example.org";
security.acme.defaults.server = lib.mkForce "https://example.com"; # self-signed only
networking.nameservers = lib.mkForce [ nodes.ns.networking.primaryIPAddress ];
security.pki.certificateFiles = [ rootCA.certificatePath ];
};
nodes.checker =
{ pkgs, lib, ... }:
{
environment.systemPackages = [
pkgs.wget
pkgs.python311Packages.imap-tools
pkgs.python311
(pkgs.writers.writePython3Bin "mailtest"
{
libraries = with pkgs.python3Packages; [
imap-tools
requests
];
}
''
# flake8: noqa
# #!${pkgs.python311}/bin/python
import sys
sys.argv.insert(1, "${nodes.liam.networking.primaryIPAddress}")
#sys.path.append("${pkgs.python311Packages.imap-tools}/lib/python3.11/site-packages")
#sys.path.append("${pkgs.python311Packages.urllib3}/lib/python3.11/site-packages")
#sys.path.append("${pkgs.python311Packages.requests}/lib/python3.11/site-packages")
${builtins.readFile ./mailtest.py}
''
)
];
networking.nameservers = lib.mkForce (lib.singleton nodes.ns.networking.primaryIPAddress);
};
testScript = ''
start_all()
@@ -78,20 +213,28 @@
liam.wait_for_unit("nginx.service")
liam.wait_for_open_port(80)
liam.copy_from_host("${pkgs.writeText "acme-test" "test"}", "${nodes.liam.security.acme.defaults.webroot + "/.well-known/acme-challenge/test"}")
liam.copy_from_host("${pkgs.writeText "acme-test" "test"}", "${
nodes.liam.security.acme.defaults.webroot + "/.well-known/acme-challenge/test"
}")
checker.succeed("wget http://liam.dis8.net/.well-known/acme-challenge/test")
liam.wait_for_unit("postfix.service")
liam.wait_for_unit("dovecot2.service")
relay.wait_for_unit("mailpit.service")
checks = """
--submission --mailfrom me@shelvacu.com --rcptto foo@example.com --username shelvacu --expect-mailpit-received --mailpit-url http://${nodes.relay.networking.primaryIPAddress}:8025
--submission --mailfrom me@dis8.net --rcptto foo@example.com --username shelvacu --expect-mailpit-not-received --mailpit-url http://${nodes.relay.networking.primaryIPAddress}:8025
# julie's emails should NOT get sieve'd like mine
--rcptto julie@shelvacu.com --username julie --imap-dir INBOX
--rcptto julie+stuff@shelvacu.com --username julie --imap-dir INBOX
# test the sieve script is working
--mailfrom whoever@example.com --rcptto sievetest@shelvacu.com --username shelvacu --imap-dir com.shelvacu
--rcptto shelvacu@shelvacu.com --username shelvacu --smtp-starttls
--rcptto mar@shelvacu.com --username mar
--rcptto mar+stuff@shelvacu.com --username mar
--rcptto shelvacu@shelvacu.com --username shelvacu
--rcptto julie@shelvacu.com --username julie
--rcptto foobar@shelvacu.com --username shelvacu
@@ -108,10 +251,6 @@
--submission --expect-recipient-refused --mailfrom julie@shelvacu.com --username shelvacu
--submission --expect-recipient-refused --mailfrom fubar@theviolincase.com --username shelvacu
--submission --expect-recipient-refused --mailfrom fubar@vacu.store --username julie
--submission --expect-recipient-refused --mailfrom shelvacu@shelvacu.com --username mar
--submission --expect-recipient-refused --mailfrom me@shelvacu.com --username mar
--submission --expect-recipient-refused --mailfrom shelvacu+foo@shelvacu.com --username mar
--submission --expect-recipient-refused --mailfrom me+foo@shelvacu.com --username mar
--submission --mailfrom shelvacu@shelvacu.com --rcptto foo@example.com --username shelvacu --password shelvacu --expect-sent
--submission --mailfrom shelvacu@shelvacu.com --rcptto foo@example.com --username shelvacu@shelvacu.com --password shelvacu --expect-sent
@@ -119,8 +258,7 @@
--submission --mailfrom foo@vacu.store --rcptto foo@example.com --username shelvacu@shelvacu.com --password shelvacu --expect-sent
--submission --mailfrom foo@violingifts.com --rcptto foo@example.com --username julie --password julie --expect-sent
--submission --mailfrom foo@violingifts.com --rcptto foo@example.com --username julie@shelvacu.com --password julie --expect-sent
--submission --mailfrom mar@shelvacu.com --rcptto foo@example.com --username mar --password mar --expect-sent
--submission --mailfrom mar+stuff@shelvacu.com --rcptto foo@example.com --username mar --password mar --expect-sent
"""
for check in checks.split("\n"):
check = check.strip()

View File

@@ -5,6 +5,7 @@ import time
import ssl
import argparse
import uuid
import requests
parser = argparse.ArgumentParser()
parser.add_argument('host', type = str)
@@ -24,6 +25,9 @@ parser.add_argument('--expect-recipient-refused',
)
parser.add_argument('--expect-sent', dest = 'expect', action = 'store_const', const = 'sent')
parser.add_argument('--expect-imap-error', dest = 'expect', action = 'store_const', const = 'imap_error')
parser.add_argument('--expect-mailpit-received', dest = 'expect', action = 'store_const', const = 'mailpit_received')
parser.add_argument('--expect-mailpit-not-received', dest = 'expect', action = 'store_const', const = 'mailpit_not_received')
parser.add_argument('--mailpit-url')
args = parser.parse_args()
@@ -41,6 +45,9 @@ if password is None:
if (username is None or password is None) and (args.submission or args.expect == 'received'):
assert False, "Bad args"
if args.expect.startswith("mailpit_") and args.mailpit_url is None:
assert False, "Bad args"
msg_magic = str(uuid.uuid4())
def mk_ctx():
@@ -68,6 +75,19 @@ except smtplib.SMTPRecipientsRefused:
else:
assert (not args.expect == 'recipient_refused'), "Server was supposed to reject this message, but it didn't"
if args.mailpit_url is not None:
time.sleep(3)
mails = requests.get(args.mailpit_url + "/api/v1/messages").json()
found_message = False
for message_data in mails["messages"]:
if msg_magic in message_data["Snippet"]:
found_message = True
break
if args.expect == 'mailpit_received':
assert found_message, "Message not received by mailpit server"
else:
assert not found_message, "Message was received by the mailpit server when it wasn't supposed to be"
if args.expect == 'received' or args.expect == 'imap_error':
time.sleep(3)
try:
@@ -93,4 +113,4 @@ if args.expect == 'received' or args.expect == 'imap_error':
except imaplib.IMAP4.error as e:
assert args.expect == 'imap_error', f"IMAP error: {e}"
else:
assert not args.expect == 'imap_error', "Expected an IMAP error, but didn't get one"
assert not args.expect == 'imap_error', "Expected an IMAP error, but didn't get one"

View File

@@ -1,41 +1,53 @@
{ pkgs, nodes, ... }: {
{ pkgs, nodes, ... }:
{
name = "trip-megatest";
nodes.triple-dezert = { lib, config, ... }: let
domains = builtins.attrNames config.security.acme.certs;
disableAcmes = builtins.listToAttrs (
map (d: {
name = "acme-${d}";
value = { enable = lib.mkForce false; };
}) domains
);
reEnableSelfsigned = builtins.listToAttrs (
map (d: {
name = "acme-selfsigned-${d}";
value = { wantedBy = [ "container@frontproxy.service" ]; before = [ "container@frontproxy.service" ]; };
}) domains
);
unitsToDisable = [
"container@vacustore.service"
"container@nix-cache-nginx.service"
"openvpn-awootrip.service"
];
disableUnits = builtins.listToAttrs (
map (u: {
name = u;
value = { enable = lib.mkForce false; };
}) unitsToDisable
);
in {
imports = [ ../triple-dezert ];
systemd.services = disableAcmes // reEnableSelfsigned;
systemd.units = disableUnits;
#vacu.secretsFolder = ./test_secrets;
#sops.age.sshKeyPaths = [ ./test_key ];
boot.zfs.extraPools = lib.mkForce [];
security.acme.defaults.email = lib.mkForce "me@example.org";
security.acme.defaults.server = lib.mkForce "https://example.com"; # self-signed only
};
nodes.triple-dezert =
{ lib, config, ... }:
let
domains = builtins.attrNames config.security.acme.certs;
disableAcmes = builtins.listToAttrs (
map (d: {
name = "acme-${d}";
value = {
enable = lib.mkForce false;
};
}) domains
);
reEnableSelfsigned = builtins.listToAttrs (
map (d: {
name = "acme-selfsigned-${d}";
value = {
wantedBy = [ "container@frontproxy.service" ];
before = [ "container@frontproxy.service" ];
};
}) domains
);
unitsToDisable = [
"container@vacustore.service"
"container@nix-cache-nginx.service"
"openvpn-awootrip.service"
];
disableUnits = builtins.listToAttrs (
map (u: {
name = u;
value = {
enable = lib.mkForce false;
};
}) unitsToDisable
);
in
{
imports = [ ../triple-dezert ];
vacu.underTest = true;
systemd.services = disableAcmes // reEnableSelfsigned;
systemd.units = disableUnits;
#vacu.secretsFolder = ./test_secrets;
#sops.age.sshKeyPaths = [ ./test_key ];
boot.zfs.extraPools = lib.mkForce [ ];
security.acme.defaults.email = lib.mkForce "me@example.org";
security.acme.defaults.server = lib.mkForce "https://example.com"; # self-signed only
};
# nodes.checker = { pkgs, lib, ... }: {
# environment.systemPackages = [
@@ -93,4 +105,4 @@
triple_dezert.wait_for_open_port(80)
triple_dezert.succeed("curl -vv http://shelvacu.com/ --resolve shelvacu.com:80:127.0.0.1")
'';
}
}

View File

@@ -1,13 +1,23 @@
{ config, pkgs, inputs, lib, ... }:
{
config,
pkgs,
inputs,
lib,
...
}:
let
prefix = "10.16.237.";
tripAddr = prefix + "2";
awooAddr = prefix + "1";
devName = "at4"; # It was my fourth attempt before it worked...
tunnelName = "awootrip";
in {
in
{
systemd.network.netdevs.${devName} = {
netdevConfig = { Kind = "tun"; Name = devName; };
netdevConfig = {
Kind = "tun";
Name = devName;
};
enable = true;
};

View File

@@ -1,47 +1,62 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
with lib;
let
let
cfg = config.vacu;
databases = attrValues cfg.databases;
authText = flip (concatMapStringsSep "\n") databases
(d:
if d.authByIp != null then
# host database user address auth-method [auth-options]
''host "${d.name}" "${d.user}" ${d.authByIp}/32 trust''
else
# local database user auth-method [auth-options]
''local "${d.name}" "${d.user}" peer'')
;
authText = flip (concatMapStringsSep "\n") databases (
d:
if d.authByIp != null then
# host database user address auth-method [auth-options]
''host "${d.name}" "${d.user}" ${d.authByIp}/32 trust''
else
# local database user auth-method [auth-options]
''local "${d.name}" "${d.user}" peer''
);
in
{
options.vacu.databases = mkOption {
default = {};
default = { };
description = "Databases that should be created and how they should be accessed";
type = types.attrsOf (types.submodule ({ name, config, options, ... }: {
options = {
name = mkOption {
type = types.str;
default = name;
description = "name of the database to create";
};
user = mkOption {
type = types.str;
default = name;
description = "username of the user created to access/own the database";
};
authByIp = mkOption {
type = types.nullOr types.str;
default = null;
description = "If set, user is authenticated based on connecting from the given ip address";
};
authByUser = mkOption {
type = types.bool;
default = false;
description = "If true, user is authenticated based on connecting to the unix socket from a process running as the user";
};
};
}));
type = types.attrsOf (
types.submodule (
{
name,
config,
options,
...
}:
{
options = {
name = mkOption {
type = types.str;
default = name;
description = "name of the database to create";
};
user = mkOption {
type = types.str;
default = name;
description = "username of the user created to access/own the database";
};
authByIp = mkOption {
type = types.nullOr types.str;
default = null;
description = "If set, user is authenticated based on connecting from the given ip address";
};
authByUser = mkOption {
type = types.bool;
default = false;
description = "If true, user is authenticated based on connecting to the unix socket from a process running as the user";
};
};
}
)
);
};
config = {
@@ -53,11 +68,9 @@ in
services.postgresql = rec {
enable = true;
package = pkgs.postgresql_16;
dataDir = "/trip/pg/data/${package.psqlSchema}";
dataDir = "/var/postgres/data/${package.psqlSchema}";
enableJIT = true;
initdbArgs = [
"--waldir=/trip/pg/wal/${package.psqlSchema}"
];
initdbArgs = [ "--waldir=/var/postgres/wal/${package.psqlSchema}" ];
ensureUsers = [
{
name = "root";
@@ -74,6 +87,11 @@ in
'';
};
systemd.services.postgresql.postStart = "\n#START stuff from database.nix\n" + (concatMapStringsSep "\n" (d: ''$PSQL -tAc 'ALTER DATABASE "${d.name}" OWNER TO "${d.user}";' '') databases) + "\n#END stuff from database.nix\n";
systemd.services.postgresql.postStart =
"\n#START stuff from database.nix\n"
+ (concatMapStringsSep "\n" (
d: ''$PSQL -tAc 'ALTER DATABASE "${d.name}" OWNER TO "${d.user}";' ''
) databases)
+ "\n#END stuff from database.nix\n";
};
}
}

View File

@@ -1,26 +1,28 @@
{ config, pkgs, inputs, lib, ... }: {
imports =
[
../common-nixos-config.nix
./hardware-configuration.nix
./awootrip.nix
./frontproxy.nix
# ./kanidm.nix
# ./keycloak.nix
./database.nix
./vacustore.nix
./nix-cache-nginx.nix
./jl-stats.nix
./static-stuff.nix
#./vms.nix
./networking.nix
./devver-host.nix
];
system.nixos.tags = [ "host-${config.networking.hostName}" ];
{ config, pkgs, ... }:
{
imports = [
../common/nixos.nix
./hardware-configuration.nix
./awootrip.nix
./frontproxy.nix
# ./kanidm.nix
# ./keycloak.nix
./database.nix
./vacustore.nix
./nix-cache-nginx.nix
./jl-stats.nix
./static-stuff.nix
#./vms.nix
./networking.nix
#./devver-host.nix
./emily.nix
./jellyfin.nix
];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
#todo: increase boot partition size
boot.loader.systemd-boot.configurationLimit = 10;
# The first thing to complain was redis in the vacustore container:
#
# WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
@@ -30,17 +32,35 @@
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
networking.hostName = "triple-dezert";
vacu.hostName = "triple-dezert";
vacu.shortHostName = "trip";
vacu.shell.color = "yellow";
vacu.verifySystem.expectedMac = "b8:ca:3a:68:15:c8";
services.xserver.enable = false;
environment.systemPackages = with pkgs; [
zfs
smartmontools
openvpn
nvme-cli
tshark
postgresql_16
vacu.packages =
(with pkgs; [
zfs
smartmontools
openvpn
nvme-cli
tshark
])
++ [
config.services.postgresql.package
(pkgs.writeScriptBin "into-nix-cache" ''
if [[ $UID -ne 0 ]]; then exec sudo $0 "$@";fi
${pkgs.nix}/bin/nix copy \
--no-update-lock-file \
--no-write-lock-file \
--to 'file:///trip/nix-binary-cache?parallel-compression=true&secret-key=/root/cache-priv-key.pem&want-mass-query=true&write-nar-listing=true' \
"$@"
'')
];
hardware.opengl.extraPackages = [
pkgs.intel-compute-runtime
pkgs.ocl-icd
];
services.openssh = {
@@ -49,14 +69,6 @@
ports = [ 6922 ];
};
system.copySystemConfiguration = false;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "22.05"; # Did you read the comment?
boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
@@ -68,4 +80,3 @@
networking.hostId = "c871875e";
hardware.enableAllFirmware = true;
}

View File

@@ -1,4 +1,11 @@
{ pkgs, lib, config, inputs, ... }: let
{
pkgs,
lib,
config,
inputs,
...
}:
let
qemu-pkg = pkgs.qemu_kvm;
#rootPath = "/trip/devver-vm/root";
bootPath = "/trip/devver-vm/boot";
@@ -10,55 +17,83 @@
tapdev-int = "qemu-devver-int";
commonArgs = [
"${qemu-pkg}/bin/qemu-kvm"
"-name" "devver"
"-name"
"devver"
# https://www.qemu.org/docs/master/system/i386/microvm.html
# "microvm" is basically no-batteries-included, and should allow including only the things we need
"-machine" "microvm,accel=kvm,dump-guest-core=off,mem-merge=off,acpi=on,pcie=on,pic=off,pit=off,usb=off"
"-m" "8G"
"-smp" "12"
"-machine"
"microvm,accel=kvm,dump-guest-core=off,mem-merge=off,acpi=on,pcie=on,pic=off,pit=off,usb=off"
"-m"
"8G"
"-smp"
"12"
"-nodefaults"
"-no-user-config"
"-chardev" "stdio,id=stdio,signal=off"
"-serial" "chardev:stdio"
"-monitor" "none"
"-device" "virtio-rng-pci"
"-chardev"
"stdio,id=stdio,signal=off"
"-serial"
"chardev:stdio"
"-monitor"
"none"
"-device"
"virtio-rng-pci"
"-enable-kvm"
"-cpu" "host,-sgx"
"-cpu"
"host,-sgx"
"-usb"
"-device" "usb-kbd"
"-device"
"usb-kbd"
"-nographic"
# do I need/want QMP here?
"-device" "virtio-balloon"
"-object" "memory-backend-memfd,id=mem,size=8G,share=off"
"-numa" "node,memdev=mem"
"-device"
"virtio-balloon"
"-object"
"memory-backend-memfd,id=mem,size=8G,share=off"
"-numa"
"node,memdev=mem"
# I don't understand, the docs for "-drive" says it's a shortcut for -blockdev and -device, but all the real-world code has -drive and -device
#"-drive" "file=/trip/devver-vm/disk-image/root.img,discard=unmap,if=none,format=raw,cache=none,id=root-disk"
"-blockdev" "driver=raw,node-name=root-disk,file.driver=file,file.filename=/trip/devver-vm/disk-image/root.img,discard=unmap,cache.direct=on"
"-device" "virtio-blk-device,drive=root-disk,write-cache=off"
"-fsdev" "local,id=fs0,path=${bootPath},security_model=mapped-xattr,fmode=0600,dmode=0700"
"-device" "virtio-9p-pci,fsdev=fs0,mount_tag=boot"
"-blockdev"
"driver=raw,node-name=root-disk,file.driver=file,file.filename=/trip/devver-vm/disk-image/root.img,discard=unmap,cache.direct=on"
"-device"
"virtio-blk-device,drive=root-disk,write-cache=off"
"-netdev" "tap,id=vm-devver,ifname=${tapdev},script=no,downscript=no"
"-fsdev"
"local,id=fs0,path=${bootPath},security_model=mapped-xattr,fmode=0600,dmode=0700"
"-device"
"virtio-9p-pci,fsdev=fs0,mount_tag=boot"
"-netdev"
"tap,id=vm-devver,ifname=${tapdev},script=no,downscript=no"
#Why 34? No idea! Best hint I could find is in the mailing list about the serial driver: https://lists.nongnu.org/archive/html/qemu-devel/2013-01/msg05952.html
"-device" "virtio-net-pci,netdev=vm-devver,mac=02:19:07:A2:15:72,romfile=,mq=on,vectors=34"
"-netdev" "tap,id=vm-devver2,ifname=${tapdev-int},script=no,downscript=no"
"-device" "virtio-net-pci,netdev=vm-devver2,romfile=,mq=on,vectors=34"
"-device"
"virtio-net-pci,netdev=vm-devver,mac=02:19:07:A2:15:72,romfile=,mq=on,vectors=34"
"-netdev"
"tap,id=vm-devver2,ifname=${tapdev-int},script=no,downscript=no"
"-device"
"virtio-net-pci,netdev=vm-devver2,romfile=,mq=on,vectors=34"
];
installerArgs = [
# "-boot" "once=d"
# "-cdrom" "${installerIsoPath}"
"-drive" "if=virtio,media=cdrom,driver=raw,node-name=disk,file.driver=file,file.filename=${installerIsoPath},file.locking=off,read-only=on"
"-kernel" "${installer.config.system.build.kernel}/${installer.config.system.boot.loader.kernelFile}"
"-initrd" "${installer.config.system.build.initialRamdisk}/${installer.config.system.boot.loader.initrdFile}"
"-append" "${lib.concatStringsSep " " installer.config.boot.kernelParams} init=${installer.config.system.build.toplevel}/init earlyprintk=ttyS0 console=ttyS0 debug"
"-drive"
"if=virtio,media=cdrom,driver=raw,node-name=disk,file.driver=file,file.filename=${installerIsoPath},file.locking=off,read-only=on"
"-kernel"
"${installer.config.system.build.kernel}/${installer.config.system.boot.loader.kernelFile}"
"-initrd"
"${installer.config.system.build.initialRamdisk}/${installer.config.system.boot.loader.initrdFile}"
"-append"
"${lib.concatStringsSep " " installer.config.boot.kernelParams} init=${installer.config.system.build.toplevel}/init earlyprintk=ttyS0 console=ttyS0 debug"
];
mainArgs = [
"-kernel" "${bootPath}/kernel"
"-initrd" "${bootPath}/initrd"
"-append" "earlyprintk=ttyS0 console=ttyS0"
"-kernel"
"${bootPath}/kernel"
"-initrd"
"${bootPath}/initrd"
"-append"
"earlyprintk=ttyS0 console=ttyS0"
];
runScript = ''
@@ -73,13 +108,17 @@
cd $d
"''${args[@]}"
'';
in {
users.groups.devver = {};
in
{
users.groups.devver = { };
users.users.devver = {
isSystemUser = true;
group = config.users.groups.devver.name;
};
environment.systemPackages = [(pkgs.writeScriptBin "run-devver" runScript) qemu-pkg];
environment.systemPackages = [
(pkgs.writeScriptBin "run-devver" runScript)
qemu-pkg
];
systemd.network.netdevs.${tapdev} = {
netdevConfig = {
Kind = "tap";

49
triple-dezert/emily.nix Normal file
View File

@@ -0,0 +1,49 @@
{ config, ... }:
let
sshPort = 32767;
container = config.containers.emily;
in
{
networking.firewall.allowedTCPPorts = [ sshPort ];
networking.nat.forwardPorts = [
{
destination = container.localAddress;
proto = "tcp";
sourcePort = sshPort;
}
];
containers.emily = {
privateNetwork = true;
hostAddress = "192.168.100.20";
localAddress = "192.168.100.21";
autoStart = true;
ephemeral = false;
bindMounts."/emdata" = {
hostPath = "/trip/ncdata/data/melamona/files";
isReadOnly = false;
};
config =
{ config, ... }:
{
system.stateVersion = "24.05";
services.openssh.enable = true;
services.openssh.ports = [ sshPort ];
services.openssh.openFirewall = true;
users.groups.emily.gid = 999;
users.users.emily = {
isNormalUser = true;
isSystemUser = false;
hashedPassword = "$y$j9T$gP2phgJ9iSH.tWROn/T2C1$dwifP4R4SY4Fyd6W4vZ7tMDFhZB7Cfji9QvporeKUXB";
group = "emily";
};
users.mutableUsers = false;
users.allowNoPasswordLogin = true;
};
};
}

View File

@@ -1,4 +1,10 @@
{ config, pkgs, inputs, lib, ... }:
{
config,
pkgs,
inputs,
lib,
...
}:
let
# How to register a new domain in acme-dns before deploying the nix config:
# From trip:
@@ -10,8 +16,10 @@ let
"vacu.store"
"jean-luc.org"
"pwrhs.win"
"jf.finaltask.xyz"
];
in {
in
{
security.acme.acceptTerms = true;
security.acme.defaults = {
email = "nix-acme@shelvacu.com";
@@ -23,7 +31,14 @@ in {
postRun = "${pkgs.nixos-container}/bin/nixos-container run frontproxy -- systemctl reload haproxy";
};
security.acme.certs = builtins.listToAttrs (map (d: { name = d; value = { extraDomainNames = ["*.${d}"]; }; }) domains);
security.acme.certs = builtins.listToAttrs (
map (d: {
name = d;
value = {
extraDomainNames = [ "*.${d}" ];
};
}) domains
);
users.groups.acme.gid = 993;
@@ -32,46 +47,61 @@ in {
after = [ "network-online.target" ];
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
networking.firewall.allowedTCPPorts = [
80
443
];
networking.firewall.allowedUDPPorts = [ 443 ]; # quic!
containers.frontproxy = let outer_config = config; in {
autoStart = true;
restartIfChanged = true;
ephemeral = true;
bindMounts = builtins.listToAttrs (map (d: { name = "/certs/${d}"; value = {
hostPath = outer_config.security.acme.certs.${d}.directory;
isReadOnly = true;
}; }) domains);
config = { config, pkgs, ... }:
let
haproxySrc = pkgs.runCommand "extract-haproxy" {} ''
cd `mktemp -d`
tar -xf ${config.services.haproxy.package.src}
mv * $out
'';
in {
system.stateVersion = "23.11";
users.groups.acme.gid = outer_config.users.groups.acme.gid;
users.users.haproxy.extraGroups = [ config.users.groups.acme.name ];
services.haproxy.enable = true;
services.haproxy.config = ''
# # ssl keylogging
# global
# tune.ssl.keylog on
# lua-load ${ pkgs.writeText "sslkeylog.lua" (builtins.readFile ./sslkeylog.lua) }
# haproxy-config.cfg
${builtins.readFile ./haproxy-config.cfg}
'';
networking.hosts = {
"${outer_config.containers.vacustore.localAddress}" = [ "vacustore" ];
"127.4.20.165" = [ "kani" ];
# "${outer_config.containers.keycloak.localAddress}" = [ "keycloak" ];
"${outer_config.containers.nix-cache-nginx.localAddress}" = [ "nix-cache" ];
"${outer_config.containers.jl-stats.localAddress}" = [ "jl_stats" ];
"${outer_config.containers.static-stuff.localAddress}" = [ "static_stuff" ];
};
containers.frontproxy =
let
outer_config = config;
in
{
autoStart = true;
restartIfChanged = true;
ephemeral = true;
bindMounts = builtins.listToAttrs (
map (d: {
name = "/certs/${d}";
value = {
hostPath = outer_config.security.acme.certs.${d}.directory;
isReadOnly = true;
};
}) domains
);
config =
{ config, pkgs, ... }:
let
haproxySrc = pkgs.runCommand "extract-haproxy" { } ''
cd `mktemp -d`
tar -xf ${config.services.haproxy.package.src}
mv * $out
'';
in
{
system.stateVersion = "23.11";
users.groups.acme.gid = outer_config.users.groups.acme.gid;
users.users.haproxy.extraGroups = [ config.users.groups.acme.name ];
services.haproxy.enable = true;
services.haproxy.config = ''
# # ssl keylogging
# global
# tune.ssl.keylog on
# lua-load ${pkgs.writeText "sslkeylog.lua" (builtins.readFile ./sslkeylog.lua)}
# haproxy-config.cfg
${builtins.readFile ./haproxy-config.cfg}
'';
networking.hosts = {
"${outer_config.containers.vacustore.localAddress}" = [ "vacustore" ];
"127.4.20.165" = [ "kani" ];
# "${outer_config.containers.keycloak.localAddress}" = [ "keycloak" ];
"${outer_config.containers.nix-cache-nginx.localAddress}" = [ "nix-cache" ];
"${outer_config.containers.jl-stats.localAddress}" = [ "jl_stats" ];
"${outer_config.containers.static-stuff.localAddress}" = [ "static_stuff" ];
"${outer_config.containers.jellyfin.localAddress}" = [ "jellyfin" ];
};
};
};
};
}

View File

@@ -13,8 +13,8 @@ global
defaults
# https://world.hey.com/goekesmi/haproxy-chrome-tcp-preconnect-and-error-408-a-post-preserved-from-the-past-2497d1f7
timeout server 302s
timeout client 302s
timeout server 3s
timeout client 3s
timeout connect 10s
option http-ignore-probes
@@ -25,7 +25,7 @@ defaults
frontend main
bind :80
bind :443 ssl crt /certs/shelvacu.com/full.pem crt /certs/vacu.store/full.pem crt /certs/jean-luc.org/full.pem crt /certs/pwrhs.win/full.pem
bind :443 ssl crt /certs/shelvacu.com/full.pem crt /certs/vacu.store/full.pem crt /certs/jean-luc.org/full.pem crt /certs/pwrhs.win/full.pem crt /certs/jf.finaltask.xyz/full.pem
mode http
@@ -36,12 +36,13 @@ frontend main
# Check whether the client is attempting domain fronting.
acl ssl_sni_http_host_match ssl_fc_sni,strcmp(req.host) eq 0
acl host_vacustore var(req.host) -m str "vacu.store"
# acl host_auth var(req.host) -m str "auth.shelvacu.com"
acl host_cache var(req.host) -m str "nixcache.shelvacu.com"
acl host_stats_jl var(req.host) -m str "stats.jean-luc.org"
acl host_tulpaudcast_jl var(req.host) -m str "tulpaudcast.jean-luc.org"
acl host_habitat_pwrhs var(req.host) -m str "habitat.pwrhs.win"
acl host_vacustore var(req.host) -m str "vacu.store"
acl host_cache var(req.host) -m str "nixcache.shelvacu.com"
acl host_stats_jl var(req.host) -m str "stats.jean-luc.org"
acl host_tulpaudcast_jl var(req.host) -m str "tulpaudcast.jean-luc.org"
acl host_habitat_pwrhs var(req.host) -m str "habitat.pwrhs.win"
acl host_jellyfin var(req.host) -m str "jf.finaltask.xyz"
http-after-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" if { ssl_fc }
@@ -64,6 +65,7 @@ frontend main
http-request allow if host_stats_jl
http-request allow if host_tulpaudcast_jl
http-request allow if host_habitat_pwrhs
http-request allow if host_jellyfin
http-request return status 404 string "not found" content-type text/plain
use_backend vacustore if host_vacustore
@@ -72,6 +74,7 @@ frontend main
use_backend jl_stats if host_stats_jl
use_backend static_stuff if host_tulpaudcast_jl
use_backend habitat if host_habitat_pwrhs
use_backend jellyfin if host_jellyfin
backend vacustore
mode http
@@ -83,6 +86,11 @@ backend kani
option forwardfor
server main kani:8443 check maxconn 500 ssl verify none ssl-reuse
backend jellyfin
mode http
option forwardfor
server main jellyfin:8096 check maxconn 100 proto h1
# backend keycloak
# mode http
# option forwardfor

View File

@@ -1,24 +1,36 @@
{ config, lib, pkgs, modulesPath, ... }:
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot.initrd.availableKernelModules = [ "ehci_pci" "ahci" "mpt3sas" "nvme" "usb_storage" "usbhid" "sd_mod" ];
boot.initrd.availableKernelModules = [
"ehci_pci"
"ahci"
"mpt3sas"
"nvme"
"usb_storage"
"usbhid"
"sd_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/a4d6a30b-a8b1-460c-9f90-554e61b112fe";
fsType = "f2fs";
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/a4d6a30b-a8b1-460c-9f90-554e61b112fe";
fsType = "f2fs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/4F4C-7557";
fsType = "vfat";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/4F4C-7557";
fsType = "vfat";
};
swapDevices = [ ];
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;

View File

@@ -0,0 +1,46 @@
{ config, pkgs, ... }:
let
name = "jellyfin";
contain = config.containers.${name};
in
{
systemd.tmpfiles.settings.${name}."/trip/${name}".d = {
mode = "0755";
};
containers.${name} = {
privateNetwork = true;
hostAddress = "192.168.100.22";
localAddress = "192.168.100.23";
autoStart = true;
ephemeral = true;
restartIfChanged = true;
bindMounts."/${name}" = {
hostPath = "/trip/${name}";
isReadOnly = false;
};
config =
{ pkgs, ... }:
{
system.stateVersion = "24.05";
networking.useHostResolvConf = false;
networking.nameservers = [ "10.78.79.1" ];
networking.firewall.enable = false;
services.jellyfin = {
enable = true;
dataDir = "/${name}";
};
environment.systemPackages = with pkgs; [
jellyfin
jellyfin-web
jellyfin-ffmpeg
];
};
};
}

View File

@@ -1,31 +1,19 @@
{ config, pkgs, inputs, lib, ... }:
{
config,
pkgs,
inputs,
lib,
...
}:
let
name = "jl-stats";
contain = config.containers.${name};
most-winningest = pkgs.callPackage ({
rustPlatform,
fetchFromGitHub,
pkg-config,
openssl,
postgresql,
}: rustPlatform.buildRustPackage rec {
pname = "most-winningest";
version = "69.420";
nativeBuildInputs = [ pkg-config ];
buildInputs = [ openssl postgresql ];
src = fetchFromGitHub {
owner = "captain-jean-luc";
repo = pname;
rev = "d203ae1b8dd450b281bc1b4bb2ae7518a5665352";
hash = "sha256-RDVIu4zU4BvsJ1Ek7SwlpvA7H48TlPTzTCvUk+9hZ74=";
name = "jl-stats";
contain = config.containers.${name};
pg = config.services.postgresql.package;
most-winningest = inputs.most-winningest.packages."${config.nixpkgs.system}".default.override {
postgresql = pg;
};
cargoHash = "sha256-5Wbx/RBqtDmJUKdLXttryMuJfpkUJwRGTFYP3UFEPT0=";
}) {};
in {
in
{
vacu.databases.${name}.authByIp = contain.localAddress;
networking.firewall.extraCommands = ''
@@ -52,40 +40,51 @@ in {
isReadOnly = false;
};
config = { pkgs, ... }: {
system.stateVersion = "23.11";
config =
{ pkgs, ... }:
{
system.stateVersion = "23.11";
networking.useHostResolvConf = false;
networking.nameservers = [ "10.78.79.1" ];
networking.firewall.enable = false;
networking.useHostResolvConf = false;
networking.nameservers = [ "10.78.79.1" ];
networking.firewall.enable = false;
systemd.tmpfiles.settings.${name}."/${name}/generated".d = {
mode = "0755";
};
services.nginx.enable = true;
services.nginx.virtualHosts."stats.jean-luc.org" = {
default = true;
root = "/${name}/generated";
};
systemd.services.most-winningest = {
environment = {
DATABASE_URL = "postgres://${name}@${contain.hostAddress}/${name}";
systemd.tmpfiles.settings.${name}."/${name}/generated".d = {
mode = "0755";
};
script = ''
cd ${most-winningest.src}
${pkgs.diesel-cli.override { sqliteSupport = false; mysqlSupport = false; }}/bin/diesel migration run --locked-schema
cd /${name}
${most-winningest}/bin/${most-winningest.pname}
'';
};
systemd.timers.most-winningest = {
wantedBy = [ "multi-user.target" ];
timerConfig.OnBootSec = "5m";
timerConfig.OnUnitInactiveSec = "1h";
services.nginx.enable = true;
services.nginx.virtualHosts."stats.jean-luc.org" = {
default = true;
root = "/${name}/generated";
};
systemd.services.most-winningest = {
environment = {
DATABASE_URL = "postgres://${name}@${contain.hostAddress}/${name}";
};
script = ''
cd ${most-winningest.src}
${
pkgs.diesel-cli.override {
sqliteSupport = false;
mysqlSupport = false;
}
}/bin/diesel migration run --locked-schema
cd /${name}
${most-winningest}/bin/${most-winningest.pname}
'';
};
systemd.timers.most-winningest = {
wantedBy = [ "multi-user.target" ];
timerConfig.OnBootSec = "5m";
timerConfig.OnUnitInactiveSec = "1h";
};
environment.systemPackages = [
pg # provides psql binary, helpful for debugging
];
};
};
};
}
}

View File

@@ -1,51 +1,60 @@
{ config, pkgs, inputs, lib, ... }: {
networking.firewall.allowedTCPPorts = [ 636 ];
services.postgresql = {
ensureUsers = [
{
name = "kanidm";
ensureDBOwnership = true;
}
];
ensureDatabases = [
"kanidm"
];
};
environment.systemPackages = [ config.services.kanidm.package ]; # adds the binary to the PATH
systemd.mounts = [
{
what = "/trip/sqlites/kani";
where = builtins.dirOf config.services.kanidm.serverSettings.db_path;
type = "none";
options = "bind";
}
];
users.users.kanidm.extraGroups = [ "acme" ];
services.kanidm = let tls_dir = config.security.acme.certs."shelvacu.com".directory; in rec {
package = inputs.nixpkgs-unstable.legacyPackages.x86_64-linux.kanidm;
enableServer = true;
serverSettings = {
domain = "id.shelvacu.com";
origin = "https://id.shelvacu.com";
# db_path = "/trip/sqlites/kani/kani.sqlite";
db_fs_type = "zfs";
bindaddress = "127.4.20.165:8443";
ldapbindaddress = "[::]:636";
trust_x_forward_for = true;
tls_chain = tls_dir + "/fullchain.pem";
tls_key = tls_dir + "/key.pem";
};
enableClient = true;
clientSettings = {
uri = serverSettings.origin;
verify_ca = true;
verify_hostnames = true;
};
};
}
{
config,
pkgs,
inputs,
lib,
...
}:
{
networking.firewall.allowedTCPPorts = [ 636 ];
services.postgresql = {
ensureUsers = [
{
name = "kanidm";
ensureDBOwnership = true;
}
];
ensureDatabases = [ "kanidm" ];
};
environment.systemPackages = [ config.services.kanidm.package ]; # adds the binary to the PATH
systemd.mounts = [
{
what = "/trip/sqlites/kani";
where = builtins.dirOf config.services.kanidm.serverSettings.db_path;
type = "none";
options = "bind";
}
];
users.users.kanidm.extraGroups = [ "acme" ];
services.kanidm =
let
tls_dir = config.security.acme.certs."shelvacu.com".directory;
in
rec {
package = inputs.nixpkgs-unstable.legacyPackages.x86_64-linux.kanidm;
enableServer = true;
serverSettings = {
domain = "id.shelvacu.com";
origin = "https://id.shelvacu.com";
# db_path = "/trip/sqlites/kani/kani.sqlite";
db_fs_type = "zfs";
bindaddress = "127.4.20.165:8443";
ldapbindaddress = "[::]:636";
trust_x_forward_for = true;
tls_chain = tls_dir + "/fullchain.pem";
tls_key = tls_dir + "/key.pem";
};
enableClient = true;
clientSettings = {
uri = serverSettings.origin;
verify_ca = true;
verify_hostnames = true;
};
};
}

View File

@@ -1,5 +1,13 @@
{ config, pkgs, inputs, lib, ... }:
let contain = config.containers.keycloak; in
{
config,
pkgs,
inputs,
lib,
...
}:
let
contain = config.containers.keycloak;
in
{
vacu.databases.keycloak.authByIp = contain.localAddress;
@@ -19,33 +27,43 @@ let contain = config.containers.keycloak; in
ephemeral = false;
restartIfChanged = true;
config = let outer_config = config; in { config, pkgs, lib, ... }: {
system.stateVersion = "23.11";
networking.firewall.enable = false;
config =
let
outer_config = config;
in
{
config,
pkgs,
lib,
...
}:
{
system.stateVersion = "23.11";
networking.firewall.enable = false;
#debugging
environment.systemPackages = [ pkgs.inetutils ];
#debugging
environment.systemPackages = [ pkgs.inetutils ];
services.keycloak = {
enable = true;
database.type = "postgresql";
services.keycloak = {
enable = true;
database.type = "postgresql";
# most people would call this setting "bind address", keycloak is just dumb
settings.http-host = contain.localAddress;
settings.http-port = 80;
settings.proxy = "edge";
#todo: investigate any plugins i might want
settings.hostname-strict-backchannel = false;
settings.hostname = "auth.shelvacu.com";
database.username = "keycloak";
database.passwordFile = "/dev/null";
database.name = "keycloak";
database.host = contain.hostAddress;
database.useSSL = false;
database.createLocally = false;
# database.createLocally = true;
# most people would call this setting "bind address", keycloak is just dumb
settings.http-host = contain.localAddress;
settings.http-port = 80;
settings.proxy = "edge";
#todo: investigate any plugins i might want
settings.hostname-strict-backchannel = false;
settings.hostname = "auth.shelvacu.com";
database.username = "keycloak";
database.passwordFile = "/dev/null";
database.name = "keycloak";
database.host = contain.hostAddress;
database.useSSL = false;
database.createLocally = false;
# database.createLocally = true;
};
};
};
};
}

View File

@@ -1,8 +1,10 @@
# Partially based on https://astro.github.io/microvm.nix/simple-network.html
{ config, lib, ... }: let
{ config, lib, ... }:
let
bridge = config.vacu.network.lan_bridge;
lan_port = "eno1";
in {
in
{
options = {
vacu.network.lan_bridge = lib.mkOption {
type = lib.types.str;
@@ -52,9 +54,9 @@ in {
networking.nat = {
enable = true;
internalInterfaces = ["ve-+"];
internalInterfaces = [ "ve-+" ];
externalInterface = bridge;
enableIPv6 = false;
};
};
}
}

View File

@@ -2,7 +2,8 @@
#
# to build&copy to binary cache:
# nix copy --to 'file:///trip/nix-binary-cache?parallel-compression=true&secret-key=/root/cache-priv-key.pem&want-mass-query=true&write-nar-listing=true' .#nixosConfigurations."compute-deck".config.system.build.toplevel
{ config, ... }: {
{ config, lib, ... }:
{
containers.nix-cache-nginx = {
privateNetwork = true;
hostAddress = "192.168.100.12";
@@ -15,16 +16,27 @@
hostPath = "/trip/nix-binary-cache";
isReadOnly = true;
};
config = let outer_config = config; in { config, pkgs, lib, ... }: {
system.stateVersion = "23.11";
networking.firewall.enable = false;
services.nginx.enable = true;
services.nginx.virtualHosts.binary-cache = {
root = "/www/";
listenAddresses = [ outer_config.containers.nix-cache-nginx.localAddress ];
default = true;
config =
let
outer_config = config;
in
{
config,
pkgs,
lib,
...
}:
{
system.stateVersion = "23.11";
networking.firewall.enable = false;
services.nginx.enable = true;
services.nginx.virtualHosts.binary-cache = {
root = "/www/";
listenAddresses = [ outer_config.containers.nix-cache-nginx.localAddress ];
default = true;
};
};
};
};
}
vacu.nix.caches.nixcache-shelvacu.url = lib.mkForce "file:///trip/nix-binary-cache";
}

View File

@@ -1,7 +1,14 @@
{ config, pkgs, inputs, lib, ... }:
{
config,
pkgs,
inputs,
lib,
...
}:
let
contain = config.containers.keycloak;
in {
contain = config.containers.keycloak;
in
{
systemd.tmpfiles.settings.asdf."/trip/static-stuff".d = {
mode = "0744";
};
@@ -19,12 +26,14 @@ in {
isReadOnly = true;
};
config = { pkgs, ... }: {
system.stateVersion = "23.11";
networking.firewall.enable = false;
config =
{ pkgs, ... }:
{
system.stateVersion = "23.11";
networking.firewall.enable = false;
services.nginx.enable = true;
services.nginx.virtualHosts."tulpaudcast.jean-luc.org".root = "/static-stuff/tulpaudcast.jean-luc.org";
};
services.nginx.enable = true;
services.nginx.virtualHosts."tulpaudcast.jean-luc.org".root = "/static-stuff/tulpaudcast.jean-luc.org";
};
};
}
}

View File

@@ -1,4 +1,5 @@
{ config, ... }: {
{ config, ... }:
{
vacu.databases.nextcloud = {
user = "ncadmin";
authByIp = config.containers.vacustore.localAddress;
@@ -24,100 +25,113 @@
isReadOnly = false;
};
config = let outer_config = config; in { config, pkgs, lib, ... }: {
system.stateVersion = "22.05";
config =
let
outer_config = config;
in
{
config,
pkgs,
lib,
...
}:
{
system.stateVersion = "22.05";
networking.firewall.enable = false;
networking.useHostResolvConf = lib.mkForce false;
services.resolved.enable = true;
networking.firewall.enable = false;
networking.useHostResolvConf = lib.mkForce false;
services.resolved.enable = true;
systemd.services.nextcloud-setup.after = [ "network-online.target" ];
services.nginx.virtualHosts."vacu.store".extraConfig = ''
client_body_timeout 5m;
'';
services.nginx.virtualHosts."vacu.store".extraConfig = ''
client_body_timeout 5m;
'';
environment.systemPackages = [ config.services.nextcloud.package ]; # make occ command available without having to dig for it
environment.systemPackages = [ config.services.nextcloud.package ]; # make occ command available without having to dig for it
services.nextcloud = {
enable = true;
package = pkgs.nextcloud29;
configureRedis = true;
hostName = "vacu.store";
datadir = "/ncdata";
https = true;
maxUploadSize = "1000G";
database.createLocally = false;
services.nextcloud = {
enable = true;
package = pkgs.nextcloud28;
configureRedis = true;
hostName = "vacu.store";
datadir = "/ncdata";
logLevel = 1;
https = true;
maxUploadSize = "1000G";
database.createLocally = false;
extraApps = {
inherit (config.services.nextcloud.package.packages.apps) calendar notes tasks contacts;
appointments = pkgs.fetchNextcloudApp {
appName = "appointments";
url = "https://github.com/SergeyMosin/Appointments/raw/v2.1.4/build/artifacts/appstore/appointments.tar.gz";
sha256 = "sha256-LKxTF6yF7n6t34KzRRRqsf1doqS7DaKPmqscmNmtzAg=";
appVersion = "2.1.4";
license = "agpl3";
};
gpoddersync = pkgs.fetchNextcloudApp {
appName = "gpoddersync";
url = "https://github.com/thrillfall/nextcloud-gpodder/releases/download/3.8.2/gpoddersync.tar.gz";
sha256 = "sha256-eeBvRZUDVIaym0ngfPD2d7aY3SI/7lPWkrYPnqSh5Kw=";
appVersion = "3.8.2";
license = "agpl3";
extraApps = {
inherit (config.services.nextcloud.package.packages.apps)
calendar
notes
tasks
contacts
;
# appointments = pkgs.fetchNextcloudApp {
# appName = "appointments";
# url = "https://github.com/SergeyMosin/Appointments/raw/v2.1.4/build/artifacts/appstore/appointments.tar.gz";
# sha256 = "sha256-LKxTF6yF7n6t34KzRRRqsf1doqS7DaKPmqscmNmtzAg=";
# appVersion = "2.1.4";
# license = "gpl3";
# };
gpoddersync = pkgs.fetchNextcloudApp {
appName = "gpoddersync";
url = "https://github.com/thrillfall/nextcloud-gpodder/releases/download/3.9.0/gpoddersync.tar.gz";
sha256 = "sha256-wLiM8kv+HinOoAebarQ9MwuxqUpVeF0zS2RVYpAoYMI=";
appVersion = "3.9.0";
license = "gpl3";
};
webapppassword = pkgs.fetchNextcloudApp {
appName = "webapppassword";
url = "https://github.com/digital-blueprint/webapppassword/releases/download/v24.6.0/webapppassword.tar.gz";
sha256 = "sha256-x9uARo/VtkFLabif2/GZhs4cG6qmhAJs93dzhFFmhB0=";
appVersion = "24.6.0";
license = "gpl3";
};
# oidc_login = pkgs.fetchNextcloudApp {
# appName = "oidc_login";
# url = "https://github.com/pulsejet/nextcloud-oidc-login/releases/download/v3.0.2/oidc_login.tar.gz";
# sha256 = "sha256-cN5azlThKPKRVip14yfUNR85of5z+N6NVI7sg6pSGQI=";
# appVersion = "3.0.2";
# license = "gpl3";
# };
# sociallogin = pkgs.fetchNextcloudApp {
# appName = "sociallogin";
# url = "https://github.com/zorn-v/nextcloud-social-login/releases/download/v5.6.3/release.tar.gz";
# sha256 = "sha256-XHHD87InU9P5uq9zCJnFliHhWh5tpSpSnMMOfNgJKRw=";
# appVersion = "5.6.3";
# license = "gpl3";
# };
};
webapppassword = pkgs.fetchNextcloudApp {
appName = "webapppassword";
url = "https://github.com/digital-blueprint/webapppassword/releases/download/v23.12.0/webapppassword.tar.gz";
sha256 = "sha256-nQUHEm+cvTmRS2ECZK4lk7YAd+2gUYTFcu44A967kY4=";
appVersion = "23.12.0";
license = "agpl3";
phpOptions."opcache.interned_strings_buffer" = "32";
config = {
adminpassFile = "/etc/admin_password";
dbtype = "pgsql";
dbuser = "ncadmin";
dbhost = outer_config.containers.vacustore.hostAddress;
dbname = "nextcloud";
dbtableprefix = "oc_";
};
# oidc_login = pkgs.fetchNextcloudApp {
# appName = "oidc_login";
# url = "https://github.com/pulsejet/nextcloud-oidc-login/releases/download/v3.0.2/oidc_login.tar.gz";
# sha256 = "sha256-cN5azlThKPKRVip14yfUNR85of5z+N6NVI7sg6pSGQI=";
# appVersion = "3.0.2";
# license = "agpl3";
# };
sociallogin = pkgs.fetchNextcloudApp {
appName = "sociallogin";
url = "https://github.com/zorn-v/nextcloud-social-login/releases/download/v5.6.3/release.tar.gz";
sha256 = "sha256-XHHD87InU9P5uq9zCJnFliHhWh5tpSpSnMMOfNgJKRw=";
appVersion = "5.6.3";
license = "agpl3";
settings = {
loglevel = 1;
default_phone_region = "US";
overwriteprotocol = "https";
trusted_proxies = [ outer_config.containers.vacustore.hostAddress ];
allow_user_to_change_display_name = false;
lost_password_link = "disabled";
oidc_login_provider_url = "https://id.shelvacu.com/oauth2/openid/vacustore/";
oidc_login_client_id = "vacustore";
# client_secret can't go here...
# oidc_login_auto_redirect = true;
oidc_login_button_text = "Yo Do Da Login Thangg";
oidc_login_scope = "email profile";
oidc_login_disable_registration = false;
oidc_login_code_challenge_method = "S256";
};
};
phpOptions."opcache.interned_strings_buffer" = "32";
config = {
trustedProxies = [ outer_config.containers.vacustore.hostAddress ];
adminpassFile = "/etc/admin_password";
dbtype = "pgsql";
dbuser = "ncadmin";
dbhost = outer_config.containers.vacustore.hostAddress;
dbname = "nextcloud";
dbtableprefix = "oc_";
overwriteProtocol = "https";
defaultPhoneRegion = "US";
secretFile = "/etc/nc-secrets.json";
};
extraOptions = {
allow_user_to_change_display_name = false;
lost_password_link = "disabled";
oidc_login_provider_url = "https://id.shelvacu.com/oauth2/openid/vacustore/";
oidc_login_client_id = "vacustore";
# client_secret can't go here...
# oidc_login_auto_redirect = true;
oidc_login_button_text = "Yo Do Da Login Thangg";
oidc_login_scope = "email profile";
oidc_login_disable_registration = false;
oidc_login_code_challenge_method = "S256";
};
secretFile = "/etc/nc-secrets.json";
};
};
};
}

View File

@@ -1,17 +1,24 @@
# https://astro.github.io/microvm.nix/host.html
{ pkgs, inputs, config, self, ... }: {
imports = [
inputs.microvm.nixosModules.host
];
{
pkgs,
inputs,
config,
self,
...
}:
{
imports = [ inputs.microvm.nixosModules.host ];
microvm.host.enable = true;
# https://gitlab.com/virtio-fs/virtiofsd/-/issues/121
microvm.virtiofsd.inodeFileHandles = "mandatory";
assertions = [{
assertion = config.networking.useNetworkd;
message = "microvm setup requires networkd";
}];
assertions = [
{
assertion = config.networking.useNetworkd;
message = "microvm setup requires networkd";
}
];
microvm.vms.devver2 = {
autostart = true;
@@ -23,4 +30,4 @@
# matchConfig.name = "vm-devver";
# networkConfig.Bridge = config.vacu.network.lan_bridge;
# };
}
}