Compare commits

..

No commits in common. "50c182d827446e54a6bbad20ac00675c2ba02ceb" and "d67d75eda33f720de6bb8491a9c9f9cf034d0daa" have entirely different histories.

74 changed files with 1302 additions and 1584 deletions

View file

@ -6,8 +6,7 @@ end_of_line = lf
insert_final_newline = true insert_final_newline = true
trim_trailing_whitespace = true trim_trailing_whitespace = true
charset = utf-8 charset = utf-8
indent_style = space indent_style = tab
indent_size = 2
# Ignore diffs/patches # Ignore diffs/patches
[*.{diff,patch}] [*.{diff,patch}]
@ -20,8 +19,8 @@ indent_style = unset
indent_size = unset indent_size = unset
[{.*,secrets}/**] [{.*,secrets}/**]
end_of_line = false end_of_line = unset
insert_final_newline = false insert_final_newline = unset
trim_trailing_whitespace = unset trim_trailing_whitespace = unset
charset = unset charset = unset
indent_style = unset indent_style = unset

View file

@ -48,8 +48,8 @@
invoiceplane-template.inputs.nixpkgs.follows = "nixpkgs"; invoiceplane-template.inputs.nixpkgs.follows = "nixpkgs";
}; };
outputs = inputs @ {self, ...}: outputs = inputs@{ self, ... }:
inputs.flake-parts.lib.mkFlake {inherit inputs;} { inputs.flake-parts.lib.mkFlake { inherit inputs; } {
systems = [ systems = [
"x86_64-linux" "x86_64-linux"
"aarch64-linux" "aarch64-linux"
@ -65,13 +65,7 @@
./overlays ./overlays
]; ];
perSystem = args @ { perSystem = args@{ system, pkgs, lib, config, ... }: {
system,
pkgs,
lib,
config,
...
}: {
_module.args = { _module.args = {
inherit inputs; inherit inputs;
pkgs = import inputs.nixpkgs { pkgs = import inputs.nixpkgs {
@ -109,6 +103,7 @@
terraform-backend-git terraform-backend-git
deno deno
denols
]; ];
shellHook = '' shellHook = ''

View file

@ -1,4 +1,4 @@
{...}: { { ... }: {
imports = [ imports = [
./configuration.nix ./configuration.nix
./hardware-configuration.nix ./hardware-configuration.nix

View file

@ -39,6 +39,6 @@ in {
]; ];
}; };
networking.firewall.allowedUDPPorts = [34197]; networking.firewall.allowedUDPPorts = [ 34197 ];
networking.firewall.allowedTCPPorts = [34197]; networking.firewall.allowedTCPPorts = [ 34197 ];
} }

View file

@ -1,9 +1,5 @@
{ withSystem, self, inputs, ...}:
{ {
withSystem,
self,
inputs,
...
}: {
flake = { flake = {
nixosConfigurations = { nixosConfigurations = {
stroopwafel = self.nixos-flake.lib.mkLinuxSystem { stroopwafel = self.nixos-flake.lib.mkLinuxSystem {
@ -141,7 +137,7 @@
self.nixosModules.graphical self.nixosModules.graphical
self.nixosModules.audio self.nixosModules.audio
self.nixosModules.bluetooth self.nixosModules.bluetooth
({...}: {pub-solar.graphical.wayland.software-renderer.enable = true;}) ({ ... }: { pub-solar.graphical.wayland.software-renderer.enable = true; })
]; ];
}; };
}; };

View file

@ -23,7 +23,7 @@ in {
# Hack so that network is considered up by boot.initrd.network and postCommands gets executed. # Hack so that network is considered up by boot.initrd.network and postCommands gets executed.
"ip=127.0.0.1:::::lo:none" "ip=127.0.0.1:::::lo:none"
]; ];
boot.initrd.availableKernelModules = ["tg3"]; boot.initrd.availableKernelModules = [ "tg3" ];
boot.initrd.network = { boot.initrd.network = {
enable = true; enable = true;
ssh = { ssh = {

View file

@ -1,21 +1,17 @@
# Do not modify this file! It was generated by nixos-generate-config # Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes # and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead. # to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{ {
config, imports =
lib, [ (modulesPath + "/installer/scan/not-detected.nix")
pkgs,
modulesPath,
...
}: {
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
]; ];
boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "ehci_pci" "usbhid" "usb_storage" "uas" "sd_mod"]; boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "ehci_pci" "usbhid" "usb_storage" "uas" "sd_mod" ];
boot.initrd.kernelModules = ["dm-snapshot" "amdgpu"]; boot.initrd.kernelModules = [ "dm-snapshot" "amdgpu" ];
boot.kernelModules = ["kvm-amd"]; boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = []; boot.extraModulePackages = [ ];
boot.initrd.luks.devices = { boot.initrd.luks.devices = {
"cryptroot" = { "cryptroot" = {
@ -25,41 +21,41 @@
"cryptdata".device = "/dev/sda1"; "cryptdata".device = "/dev/sda1";
}; };
fileSystems."/" = { fileSystems."/" =
device = "none"; { device = "none";
fsType = "tmpfs"; fsType = "tmpfs";
}; };
fileSystems."/nix" = { fileSystems."/nix" =
device = "/dev/disk/by-uuid/837cc93f-6d9a-4bfd-b089-29ac6d68127c"; { device = "/dev/disk/by-uuid/837cc93f-6d9a-4bfd-b089-29ac6d68127c";
fsType = "ext4"; fsType = "ext4";
neededForBoot = true; neededForBoot = true;
}; };
fileSystems."/persist" = { fileSystems."/persist" =
device = "/dev/disk/by-uuid/a7711118-51b0-4d84-8f18-ef2e06084e05"; { device = "/dev/disk/by-uuid/a7711118-51b0-4d84-8f18-ef2e06084e05";
fsType = "ext4"; fsType = "ext4";
neededForBoot = true; neededForBoot = true;
}; };
fileSystems."/home" = { fileSystems."/home" =
device = "/dev/disk/by-uuid/0965d496-ffad-4a8d-9de7-28af903baf16"; { device = "/dev/disk/by-uuid/0965d496-ffad-4a8d-9de7-28af903baf16";
fsType = "ext4"; fsType = "ext4";
}; };
fileSystems."/boot" = { fileSystems."/boot" =
device = "/dev/disk/by-uuid/991E-79C1"; { device = "/dev/disk/by-uuid/991E-79C1";
fsType = "vfat"; fsType = "vfat";
neededForBoot = true; neededForBoot = true;
}; };
fileSystems."/data" = { fileSystems."/data" =
device = "/dev/disk/by-uuid/5fc34ef4-207b-45fb-b846-dbb01080d9fe"; { device = "/dev/disk/by-uuid/5fc34ef4-207b-45fb-b846-dbb01080d9fe";
fsType = "ext4"; fsType = "ext4";
}; };
swapDevices = [ swapDevices =
{device = "/dev/disk/by-uuid/0ef8dbbd-2832-4fb2-8a52-86682822f769";} [ { device = "/dev/disk/by-uuid/0ef8dbbd-2832-4fb2-8a52-86682822f769"; }
]; ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";

View file

@ -17,7 +17,7 @@
}; };
# from https://jellyfin.org/docs/general/networking/index.html # from https://jellyfin.org/docs/general/networking/index.html
networking.firewall.allowedUDPPorts = [1900 7359]; networking.firewall.allowedUDPPorts = [ 1900 7359 ];
security.acme.certs = { security.acme.certs = {
"media.b12f.io" = {}; "media.b12f.io" = {};

View file

@ -10,12 +10,7 @@
networking.interfaces.enp2s0f1.useDHCP = true; networking.interfaces.enp2s0f1.useDHCP = true;
networking.interfaces.enp2s0f0 = { networking.interfaces.enp2s0f0 = {
ipv6.addresses = [ ipv6.addresses = [ { address = "2a02:908:5b1:e3c0:3::"; prefixLength = 64; } ];
{
address = "2a02:908:5b1:e3c0:3::";
prefixLength = 64;
}
];
}; };
# Allow pub.solar restic backups # Allow pub.solar restic backups

View file

@ -9,6 +9,7 @@ with lib; let
psCfg = config.pub-solar; psCfg = config.pub-solar;
xdg = config.home-manager.users."${psCfg.user.name}".xdg; xdg = config.home-manager.users."${psCfg.user.name}".xdg;
in { in {
# Use the systemd-boot EFI boot loader. # Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true; boot.loader.efi.canTouchEfiVariables = true;
@ -19,13 +20,13 @@ in {
"ip=127.0.0.1:::::lo:none" "ip=127.0.0.1:::::lo:none"
]; ];
boot.initrd.availableKernelModules = ["virtio_pci" "virtio_net"]; boot.initrd.availableKernelModules = [ "virtio_pci" "virtio_net" ];
boot.initrd.network = { boot.initrd.network = {
enable = true; enable = true;
ssh = { ssh = {
enable = true; enable = true;
port = 2222; port = 2222;
hostKeys = [/boot/initrd-ssh-key]; hostKeys = [ /boot/initrd-ssh-key ];
authorizedKeys = flake.self.publicKeys; authorizedKeys = flake.self.publicKeys;
shell = "/bin/cryptsetup-askpass"; shell = "/bin/cryptsetup-askpass";
}; };
@ -43,7 +44,7 @@ in {
''; '';
}; };
boot.supportedFilesystems = ["zfs"]; boot.supportedFilesystems = [ "zfs" ];
# Copy the NixOS configuration file and link it from the resulting system # Copy the NixOS configuration file and link it from the resulting system
# (/run/current-system/configuration.nix). This is useful in case you # (/run/current-system/configuration.nix). This is useful in case you

View file

@ -5,7 +5,7 @@
lib, lib,
... ...
}: let }: let
hzDomain = lib.concatStrings ["hw" "dz" "z." "net"]; hzDomain = lib.concatStrings [ "hw" "dz" "z." "net" ];
dkimDNSb12fio = '' dkimDNSb12fio = ''
default._domainkey IN TXT ( "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyla9hW3TvoXvZQxwzaJ4SZ9ict1HU3E6+FWlwNIgE6tIpTCyRJtiSIUDqB8TLTIBoxIs+QQBXZi+QUi3Agu6OSY2RiV0EwO8+oOOqOD9pERftc/aqe51cXuv4kPqwvpXEBwrXFWVM+VxivEubUJ7eKkFyXJpelv0LslXv/MmYbUyed6dF+reOGZCsvnbiRv74qdxbAL/25j62E8WrnxzJwhUtx/JhdBOjsHBvuw9hy6rZsVJL9eXayWyGRV6qmsLRzsRSBs+mDrgmKk4dugADd11+A03ics3i8hplRoWDkqnNKz1qy4f5TsV6v9283IANrAzRfHwX8EvNiFsBz+ZCQIDAQAB" ) ; default._domainkey IN TXT ( "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyla9hW3TvoXvZQxwzaJ4SZ9ict1HU3E6+FWlwNIgE6tIpTCyRJtiSIUDqB8TLTIBoxIs+QQBXZi+QUi3Agu6OSY2RiV0EwO8+oOOqOD9pERftc/aqe51cXuv4kPqwvpXEBwrXFWVM+VxivEubUJ7eKkFyXJpelv0LslXv/MmYbUyed6dF+reOGZCsvnbiRv74qdxbAL/25j62E8WrnxzJwhUtx/JhdBOjsHBvuw9hy6rZsVJL9eXayWyGRV6qmsLRzsRSBs+mDrgmKk4dugADd11+A03ics3i8hplRoWDkqnNKz1qy4f5TsV6v9283IANrAzRfHwX8EvNiFsBz+ZCQIDAQAB" ) ;
''; '';
@ -55,23 +55,21 @@ in {
owner = "maddy"; owner = "maddy";
}; };
users.users.maddy.extraGroups = ["nginx"]; users.users.maddy.extraGroups = [ "nginx" ];
security.acme.certs = { security.acme.certs = {
"mail.b12f.io".reloadServices = ["maddy"]; "mail.b12f.io".reloadServices = [ "maddy" ];
"b12f.io".reloadServices = ["maddy"]; "b12f.io".reloadServices = [ "maddy" ];
"mta-sts.b12f.io" = {}; "mta-sts.b12f.io" = {};
"mail.mezza.biz".reloadServices = ["maddy"]; "mail.mezza.biz".reloadServices = [ "maddy" ];
"mezza.biz".reloadServices = ["maddy"]; "mezza.biz".reloadServices = [ "maddy" ];
"mta-sts.mezza.biz" = {}; "mta-sts.mezza.biz" = {};
"mail.${hzDomain}".reloadServices = ["maddy"]; "mail.${hzDomain}".reloadServices = [ "maddy" ];
"${hzDomain}".reloadServices = ["maddy"]; "${hzDomain}".reloadServices = [ "maddy" ];
"mta-sts.${hzDomain}" = {}; "mta-sts.${hzDomain}" = {};
}; };
services.nginx.virtualHosts = builtins.foldl' (hosts: hostName: services.nginx.virtualHosts = builtins.foldl' (hosts: hostName: hosts // {
hosts
// {
"mta-sts.${hostName}" = { "mta-sts.${hostName}" = {
forceSSL = true; forceSSL = true;
useACMEHost = "mta-sts.${hostName}"; useACMEHost = "mta-sts.${hostName}";
@ -88,13 +86,13 @@ in {
tryFiles = "$uri $uri/ =404"; tryFiles = "$uri $uri/ =404";
}; };
}; };
}) {} ["b12f.io" "mezza.biz" hzDomain]; }) {} [ "b12f.io" "mezza.biz" hzDomain ];
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
"d '/run/maddy' 0750 maddy maddy - -" "d '/run/maddy' 0750 maddy maddy - -"
]; ];
system.activationScripts.makeMaddyDKIMDNS = lib.stringAfter ["var"] '' system.activationScripts.makeMaddyDKIMDNS = lib.stringAfter [ "var" ] ''
mkdir -p /var/lib/maddy/dkim_keys mkdir -p /var/lib/maddy/dkim_keys
echo '${dkimDNSb12fio}' >> /var/lib/maddy/dkim_keys/b12f.io_default.dns echo '${dkimDNSb12fio}' >> /var/lib/maddy/dkim_keys/b12f.io_default.dns
@ -103,8 +101,8 @@ in {
chown -R maddy:maddy /var/lib/maddy chown -R maddy:maddy /var/lib/maddy
''; '';
networking.firewall.allowedTCPPorts = [25]; networking.firewall.allowedTCPPorts = [ 25 ];
networking.firewall.interfaces.wg-private.allowedTCPPorts = [465 587 993]; networking.firewall.interfaces.wg-private.allowedTCPPorts = [ 465 587 993 ];
services.maddy = { services.maddy = {
enable = true; enable = true;
@ -313,7 +311,7 @@ in {
''; '';
}; };
systemd.services.rspamd.serviceConfig.SupplementaryGroups = ["maddy"]; systemd.services.rspamd.serviceConfig.SupplementaryGroups = [ "maddy" ];
age.secrets."rclone-pubsolar.conf" = { age.secrets."rclone-pubsolar.conf" = {
file = "${flake.self}/secrets/rclone-pubsolar.conf.age"; file = "${flake.self}/secrets/rclone-pubsolar.conf.age";
@ -327,7 +325,7 @@ in {
services.restic.backups = { services.restic.backups = {
maddy = { maddy = {
paths = ["/var/lib/maddy"]; paths = [ "/var/lib/maddy" ];
initialize = true; initialize = true;
passwordFile = config.age.secrets."restic-password".path; passwordFile = config.age.secrets."restic-password".path;
# See https://www.hosting.de/blog/verschluesselte-backups-mit-rclone-und-restic-in-nextcloud/ # See https://www.hosting.de/blog/verschluesselte-backups-mit-rclone-und-restic-in-nextcloud/

View file

@ -1,21 +1,16 @@
# Do not modify this file! It was generated by nixos-generate-config # Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes # and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead. # to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{ {
config,
lib,
pkgs,
modulesPath,
...
}: {
imports = [ imports = [
(modulesPath + "/profiles/qemu-guest.nix") (modulesPath + "/profiles/qemu-guest.nix")
]; ];
boot.initrd.availableKernelModules = ["ahci" "xhci_pci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod"]; boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = []; boot.initrd.kernelModules = [ ];
boot.kernelModules = []; boot.kernelModules = [ ];
boot.extraModulePackages = []; boot.extraModulePackages = [ ];
boot.initrd.luks.devices = { boot.initrd.luks.devices = {
cryptroot = { cryptroot = {
@ -24,18 +19,18 @@
}; };
}; };
fileSystems."/" = { fileSystems."/" =
device = "zroot/root"; { device = "zroot/root";
fsType = "zfs"; fsType = "zfs";
}; };
fileSystems."/boot" = { fileSystems."/boot" =
device = "/dev/disk/by-uuid/684A-5884"; { device = "/dev/disk/by-uuid/684A-5884";
fsType = "vfat"; fsType = "vfat";
}; };
swapDevices = [ swapDevices =
{device = "/dev/disk/by-uuid/a7d1cbb8-7c9e-4c3d-841a-add867f47389";} [ { device = "/dev/disk/by-uuid/a7d1cbb8-7c9e-4c3d-841a-add867f47389"; }
]; ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";

View file

@ -17,18 +17,8 @@
# Network configuration (Hetzner uses static IP assignments, and we don't use DHCP here) # Network configuration (Hetzner uses static IP assignments, and we don't use DHCP here)
networking.useDHCP = false; networking.useDHCP = false;
networking.interfaces.enp1s0 = { networking.interfaces.enp1s0 = {
ipv4.addresses = [ ipv4.addresses = [{ address = "128.140.109.213"; prefixLength = 32; }];
{ ipv6.addresses = [{ address = "2a01:4f8:c2c:b60::"; prefixLength = 64; }];
address = "128.140.109.213";
prefixLength = 32;
}
];
ipv6.addresses = [
{
address = "2a01:4f8:c2c:b60::";
prefixLength = 64;
}
];
}; };
networking.defaultGateway = { networking.defaultGateway = {
address = "172.31.1.1"; address = "172.31.1.1";
@ -39,5 +29,5 @@
interface = "enp1s0"; interface = "enp1s0";
}; };
networking.firewall.allowedTCPPorts = [80 443]; networking.firewall.allowedTCPPorts = [ 80 443 ];
} }

View file

@ -29,8 +29,8 @@
owner = "unbound"; owner = "unbound";
}; };
networking.firewall.interfaces.wg-private.allowedUDPPorts = [53]; networking.firewall.interfaces.wg-private.allowedUDPPorts = [ 53 ];
networking.firewall.interfaces.wg-private.allowedTCPPorts = [53]; networking.firewall.interfaces.wg-private.allowedTCPPorts = [ 53 ];
services.resolved.enable = false; services.resolved.enable = false;
services.unbound = { services.unbound = {
@ -102,10 +102,10 @@
"\"mail.mezza.biz. 10800 IN A 10.13.12.7\"" "\"mail.mezza.biz. 10800 IN A 10.13.12.7\""
"\"mail.mezza.biz. 10800 IN AAAA fd00:b12f:acab:1312:acab:7::\"" "\"mail.mezza.biz. 10800 IN AAAA fd00:b12f:acab:1312:acab:7::\""
"\"h${"w" + "dz" + "z.n"}et. 10800 IN A 10.13.12.7\"" "\"h${"w"+"dz"+"z.n"}et. 10800 IN A 10.13.12.7\""
"\"h${"w" + "dz" + "z.n"}et. 10800 IN AAAA fd00:b12f:acab:1312:acab:7::\"" "\"h${"w"+"dz"+"z.n"}et. 10800 IN AAAA fd00:b12f:acab:1312:acab:7::\""
"\"mail.h${"w" + "dz" + "z.n"}et. 10800 IN A 10.13.12.7\"" "\"mail.h${"w"+"dz"+"z.n"}et. 10800 IN A 10.13.12.7\""
"\"mail.h${"w" + "dz" + "z.n"}et. 10800 IN AAAA fd00:b12f:acab:1312:acab:7::\"" "\"mail.h${"w"+"dz"+"z.n"}et. 10800 IN AAAA fd00:b12f:acab:1312:acab:7::\""
]; ];
tls-cert-bundle = "/etc/ssl/certs/ca-certificates.crt"; tls-cert-bundle = "/etc/ssl/certs/ca-certificates.crt";
@ -133,4 +133,5 @@
}; };
}; };
}; };
} }

View file

@ -4,8 +4,7 @@
pkgs, pkgs,
lib, lib,
... ...
}: }: with lib; {
with lib; {
boot.kernel.sysctl = { boot.kernel.sysctl = {
"net.ipv4.ip_forward" = 1; "net.ipv4.ip_forward" = 1;
"net.ipv6.conf.wg-private.forwarding" = 1; "net.ipv6.conf.wg-private.forwarding" = 1;
@ -17,10 +16,10 @@ with lib; {
enable = true; enable = true;
enableIPv6 = true; enableIPv6 = true;
externalInterface = "enp1s0"; externalInterface = "enp1s0";
internalInterfaces = ["wg-private"]; internalInterfaces = [ "wg-private" ];
}; };
networking.firewall.allowedUDPPorts = [51899]; networking.firewall.allowedUDPPorts = [ 51899 ];
networking.firewall.extraForwardRules = [ networking.firewall.extraForwardRules = [
"iifname { != wg-private } reject" "iifname { != wg-private } reject"
@ -58,8 +57,7 @@ with lib; {
]; ];
privateKeyFile = config.age.secrets.wg-private-key.path; privateKeyFile = config.age.secrets.wg-private-key.path;
peers = [ peers = [
{ { # pie
# pie
publicKey = "hPTXEqQ2GYEywdPNdZBacwB9KKcoFZ/heClxnqmizyw="; publicKey = "hPTXEqQ2GYEywdPNdZBacwB9KKcoFZ/heClxnqmizyw=";
allowedIPs = [ allowedIPs = [
"10.13.12.2/32" "10.13.12.2/32"
@ -68,8 +66,7 @@ with lib; {
persistentKeepalive = 30; persistentKeepalive = 30;
dynamicEndpointRefreshSeconds = 30; dynamicEndpointRefreshSeconds = 30;
} }
{ { # droppie
# droppie
publicKey = "qsnBMoj9Z16D8PJ5ummRtIfT5AiMpoF3SoOCo4sbyiw="; publicKey = "qsnBMoj9Z16D8PJ5ummRtIfT5AiMpoF3SoOCo4sbyiw=";
allowedIPs = [ allowedIPs = [
"10.13.12.3/32" "10.13.12.3/32"
@ -78,8 +75,7 @@ with lib; {
persistentKeepalive = 30; persistentKeepalive = 30;
dynamicEndpointRefreshSeconds = 30; dynamicEndpointRefreshSeconds = 30;
} }
{ { # chocolatebar
# chocolatebar
publicKey = "nk8EtGE/QsnSEm1lhLS3/w83nOBD2OGYhODIf92G91A="; publicKey = "nk8EtGE/QsnSEm1lhLS3/w83nOBD2OGYhODIf92G91A=";
allowedIPs = [ allowedIPs = [
"10.13.12.5/32" "10.13.12.5/32"
@ -88,8 +84,7 @@ with lib; {
persistentKeepalive = 30; persistentKeepalive = 30;
dynamicEndpointRefreshSeconds = 30; dynamicEndpointRefreshSeconds = 30;
} }
{ { # biolimo
# biolimo
publicKey = "4ymN7wwBuhF+h+5fFN0TqXmVyOe1AsWiTqRL0jJ3CDc="; publicKey = "4ymN7wwBuhF+h+5fFN0TqXmVyOe1AsWiTqRL0jJ3CDc=";
allowedIPs = [ allowedIPs = [
"10.13.12.6/32" "10.13.12.6/32"
@ -98,8 +93,7 @@ with lib; {
persistentKeepalive = 30; persistentKeepalive = 30;
dynamicEndpointRefreshSeconds = 30; dynamicEndpointRefreshSeconds = 30;
} }
{ { # stroopwafel
# stroopwafel
publicKey = "5iNRg13utOJ30pX2Z8SjwPNUFwfH2zonlbeYW2mKFkU="; publicKey = "5iNRg13utOJ30pX2Z8SjwPNUFwfH2zonlbeYW2mKFkU=";
allowedIPs = [ allowedIPs = [
"10.13.12.8/32" "10.13.12.8/32"
@ -108,8 +102,7 @@ with lib; {
persistentKeepalive = 30; persistentKeepalive = 30;
dynamicEndpointRefreshSeconds = 30; dynamicEndpointRefreshSeconds = 30;
} }
{ { # fp3
# fp3
publicKey = "wQJXFibxhWkyUbRPrPt5y/YfDnH3gDQ5a/PWoyxDfDI="; publicKey = "wQJXFibxhWkyUbRPrPt5y/YfDnH3gDQ5a/PWoyxDfDI=";
allowedIPs = [ allowedIPs = [
"10.13.12.9/32" "10.13.12.9/32"

View file

@ -4,7 +4,7 @@
... ...
}: { }: {
isoImage.squashfsCompression = "gzip -Xcompression-level 1"; isoImage.squashfsCompression = "gzip -Xcompression-level 1";
systemd.services.sshd.wantedBy = lib.mkForce ["multi-user.target"]; systemd.services.sshd.wantedBy = lib.mkForce [ "multi-user.target" ];
networking.networkmanager.enable = false; networking.networkmanager.enable = false;
services.openssh.openFirewall = lib.mkForce true; services.openssh.openFirewall = lib.mkForce true;
} }

View file

@ -1,12 +1,8 @@
{ { flake, pkgs, ... }: {
flake,
pkgs,
...
}: {
imports = [ imports = [
./configuration.nix ./configuration.nix
./hardware-configuration.nix ./hardware-configuration.nix
((import "${flake.inputs.mobile-nixos}/lib/configuration.nix") {device = "pine64-pinephone";}) ((import "${flake.inputs.mobile-nixos}/lib/configuration.nix") { device = "pine64-pinephone"; })
"${flake.inputs.mobile-nixos}/examples/phosh/phosh.nix" "${flake.inputs.mobile-nixos}/examples/phosh/phosh.nix"
]; ];
} }

View file

@ -1,10 +1,6 @@
# NOTE: this file was generated by the Mobile NixOS installer. # NOTE: this file was generated by the Mobile NixOS installer.
{ config, lib, pkgs, ... }:
{ {
config,
lib,
pkgs,
...
}: {
fileSystems = { fileSystems = {
"/" = { "/" = {
device = "/dev/disk/by-uuid/51a668b8-fa2e-4d3e-ac3f-73ca002d0004"; device = "/dev/disk/by-uuid/51a668b8-fa2e-4d3e-ac3f-73ca002d0004";

View file

@ -81,7 +81,7 @@ in {
}; };
authentication_backend = { authentication_backend = {
refresh_interval = "disable"; refresh_interval = "disable";
password_reset = {disable = true;}; password_reset = { disable = true; };
file = { file = {
path = config.age.secrets."authelia-users-file".path; path = config.age.secrets."authelia-users-file".path;
watch = false; watch = false;
@ -93,10 +93,7 @@ in {
storage.local.path = "/var/lib/authelia-b12f/db.sqlite3"; storage.local.path = "/var/lib/authelia-b12f/db.sqlite3";
access_control.default_policy = "two_factor"; access_control.default_policy = "two_factor";
session.cookies = [ session.cookies = [
{ { domain = "b12f.io"; authelia_url = "https://auth.b12f.io"; }
domain = "b12f.io";
authelia_url = "https://auth.b12f.io";
}
]; ];
notifier.smtp = { notifier.smtp = {
host = "mail.b12f.io"; host = "mail.b12f.io";
@ -113,7 +110,7 @@ in {
services.restic.backups = { services.restic.backups = {
authelia = { authelia = {
paths = ["/var/lib/authelia-b12f"]; paths = [ "/var/lib/authelia-b12f" ];
initialize = true; initialize = true;
passwordFile = config.age.secrets."restic-password".path; passwordFile = config.age.secrets."restic-password".path;
# See https://www.hosting.de/blog/verschluesselte-backups-mit-rclone-und-restic-in-nextcloud/ # See https://www.hosting.de/blog/verschluesselte-backups-mit-rclone-und-restic-in-nextcloud/

View file

@ -20,7 +20,7 @@ in {
boot.loader.systemd-boot.enable = false; boot.loader.systemd-boot.enable = false;
boot.loader.generic-extlinux-compatible.enable = false; boot.loader.generic-extlinux-compatible.enable = false;
boot.supportedFilesystems = ["zfs"]; boot.supportedFilesystems = [ "zfs" ];
boot.kernelParams = [ boot.kernelParams = [
"boot.shell_on_fail=1" "boot.shell_on_fail=1"
@ -28,7 +28,7 @@ in {
"ip=127.0.0.1:::::lo:none" "ip=127.0.0.1:::::lo:none"
]; ];
# See https://discourse.nixos.org/t/ssh-and-network-in-initrd-on-raspberry-pi-4/6289/3 # See https://discourse.nixos.org/t/ssh-and-network-in-initrd-on-raspberry-pi-4/6289/3
boot.initrd.availableKernelModules = ["genet"]; boot.initrd.availableKernelModules = [ "genet" ];
boot.initrd.network = { boot.initrd.network = {
enable = true; enable = true;
ssh = { ssh = {

View file

@ -1,9 +1,6 @@
{ pkgs, adblock-unbound, ... }:
{ {
pkgs, networking.firewall.allowedUDPPorts = [ 67 547 ];
adblock-unbound,
...
}: {
networking.firewall.allowedUDPPorts = [67 547];
networking.firewall.extraInputRules = '' networking.firewall.extraInputRules = ''
ip6 daddr ff02::1:2/128 udp dport 547 accept comment "DHCPv6 server" ip6 daddr ff02::1:2/128 udp dport 547 accept comment "DHCPv6 server"
''; '';
@ -33,7 +30,7 @@
{ {
subnet = "192.168.178.0/24"; subnet = "192.168.178.0/24";
pools = [ pools = [
{pool = "192.168.178.2 - 192.168.178.255";} { pool = "192.168.178.2 - 192.168.178.255"; }
]; ];
option-data = [ option-data = [
@ -103,7 +100,7 @@
subnet = "2a02:908:5b1:e3c0::/64"; subnet = "2a02:908:5b1:e3c0::/64";
pools = [ pools = [
{pool = "2a02:908:5b1:e3c0::/72";} { pool = "2a02:908:5b1:e3c0::/72"; }
]; ];
ddns-qualifying-suffix = "local."; ddns-qualifying-suffix = "local.";

View file

@ -80,14 +80,14 @@ in {
volumes = [ volumes = [
"/var/lib/firefly/upload:/var/www/html/storage/upload" "/var/lib/firefly/upload:/var/www/html/storage/upload"
]; ];
extraOptions = ["--network=firefly"]; extraOptions = [ "--network=firefly" ];
environmentFiles = [ environmentFiles = [
./.env.firefly ./.env.firefly
config.age.secrets."firefly-secrets.env".path config.age.secrets."firefly-secrets.env".path
config.age.secrets."firefly-cron-secrets.env".path config.age.secrets."firefly-cron-secrets.env".path
]; ];
ports = ["127.0.0.1:8080:8080"]; ports = [ "127.0.0.1:8080:8080" ];
dependsOn = ["firefly-db"]; dependsOn = [ "firefly-db" ];
}; };
containers."firefly-db" = { containers."firefly-db" = {
@ -96,7 +96,7 @@ in {
volumes = [ volumes = [
"/var/lib/firefly/db:/var/lib/postgresql/data" "/var/lib/firefly/db:/var/lib/postgresql/data"
]; ];
extraOptions = ["--network=firefly"]; extraOptions = [ "--network=firefly" ];
environmentFiles = [ environmentFiles = [
config.age.secrets."firefly-db-secrets.env".path config.age.secrets."firefly-db-secrets.env".path
]; ];
@ -105,8 +105,8 @@ in {
containers."firefly-importer" = { containers."firefly-importer" = {
image = "fireflyiii/data-importer:latest"; image = "fireflyiii/data-importer:latest";
autoStart = true; autoStart = true;
extraOptions = ["--network=firefly"]; extraOptions = [ "--network=firefly" ];
ports = ["127.0.0.1:8081:8080"]; ports = [ "127.0.0.1:8081:8080" ];
environment = { environment = {
FIREFLY_III_URL = "https://firefly.b12f.io"; FIREFLY_III_URL = "https://firefly.b12f.io";
}; };
@ -114,7 +114,7 @@ in {
./.env.firefly-importer ./.env.firefly-importer
config.age.secrets."firefly-importer-secrets.env".path config.age.secrets."firefly-importer-secrets.env".path
]; ];
dependsOn = ["firefly"]; dependsOn = [ "firefly" ];
}; };
containers."firefly-cron" = { containers."firefly-cron" = {
@ -128,7 +128,7 @@ in {
environmentFiles = [ environmentFiles = [
config.age.secrets."firefly-cron-secrets.env".path config.age.secrets."firefly-cron-secrets.env".path
]; ];
extraOptions = ["--network=firefly"]; extraOptions = [ "--network=firefly" ];
}; };
}; };
}; };

View file

@ -1,22 +1,18 @@
# Do not modify this file! It was generated by nixos-generate-config # Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes # and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead. # to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{ {
config,
lib,
pkgs,
modulesPath,
...
}: {
imports = [ imports = [
(modulesPath + "/installer/scan/not-detected.nix") (modulesPath + "/installer/scan/not-detected.nix")
]; ];
boot.initrd.availableKernelModules = ["xhci_pci" "usbhid" "uas" "usb_storage"]; boot.initrd.availableKernelModules = [ "xhci_pci" "usbhid" "uas" "usb_storage" ];
boot.initrd.kernelModules = []; boot.initrd.kernelModules = [ ];
boot.kernelModules = []; boot.kernelModules = [ ];
boot.extraModulePackages = []; boot.extraModulePackages = [ ];
boot.supportedFilesystems = ["zfs"]; boot.supportedFilesystems = [ "zfs" ];
boot.initrd.luks.devices = { boot.initrd.luks.devices = {
cryptroot = { cryptroot = {
@ -25,20 +21,21 @@
}; };
}; };
fileSystems."/" = { fileSystems."/" =
device = "zroot/root"; { device = "zroot/root";
fsType = "zfs"; fsType = "zfs";
}; };
fileSystems."/boot" = { fileSystems."/boot" =
device = "/dev/disk/by-uuid/0D5D-B809"; { device = "/dev/disk/by-uuid/0D5D-B809";
fsType = "vfat"; fsType = "vfat";
}; };
swapDevices = [ swapDevices =
{device = "/dev/disk/by-uuid/af71e930-42ce-4174-a098-4ea5753b1ea9";} [ { device = "/dev/disk/by-uuid/af71e930-42ce-4174-a098-4ea5753b1ea9"; }
]; ];
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux"; nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand"; powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
} }

View file

@ -44,7 +44,7 @@ in {
createLocally = false; createLocally = false;
}; };
invoiceTemplates = [pkgs.invoiceplane-template]; invoiceTemplates = [ pkgs.invoiceplane-template ];
extraConfig = '' extraConfig = ''
SETUP_COMPLETED=true SETUP_COMPLETED=true
@ -72,7 +72,7 @@ in {
containers."invoiceplane-db" = { containers."invoiceplane-db" = {
image = "mariadb:11"; image = "mariadb:11";
autoStart = true; autoStart = true;
ports = ["127.0.0.1:3306:3306"]; ports = [ "127.0.0.1:3306:3306" ];
volumes = [ volumes = [
"/var/lib/invoiceplane/db:/var/lib/mysql" "/var/lib/invoiceplane/db:/var/lib/mysql"
]; ];

View file

@ -15,25 +15,16 @@
networking.interfaces.enabcm6e4ei0 = { networking.interfaces.enabcm6e4ei0 = {
ipv4.addresses = [ ipv4.addresses = [
{ { address = "192.168.178.2"; prefixLength = 32; }
address = "192.168.178.2";
prefixLength = 32;
}
]; ];
ipv6.addresses = [ ipv6.addresses = [
{ { address = "2a02:908:5b1:e3c0:2::"; prefixLength = 128; }
address = "2a02:908:5b1:e3c0:2::"; { address = "fe80:b12f:acab:1312:acab:2::"; prefixLength = 128; }
prefixLength = 128;
}
{
address = "fe80:b12f:acab:1312:acab:2::";
prefixLength = 128;
}
]; ];
}; };
networking.hosts = { networking.hosts = {
"192.168.178.3" = ["droppie-initrd.b12f.io"]; "192.168.178.3" = [ "droppie-initrd.b12f.io" ];
}; };
services.openssh.allowSFTP = true; services.openssh.allowSFTP = true;

View file

@ -13,8 +13,7 @@ with lib; let
backupDir = "/var/lib/PaperlessBackup"; backupDir = "/var/lib/PaperlessBackup";
consumptionDir = "/var/lib/scandir"; consumptionDir = "/var/lib/scandir";
scan2paperless = with pkgs; scan2paperless = with pkgs; writeShellScriptBin "scan2paperless" ''
writeShellScriptBin "scan2paperless" ''
DEVICE=$1 DEVICE=$1
NUM_PAGES=$2 NUM_PAGES=$2
NAME=$3 NAME=$3
@ -83,7 +82,7 @@ in {
}; };
}; };
systemd.services.paperless-web.serviceConfig.EnvironmentFile = [config.age.secrets."paperless.env".path]; systemd.services.paperless-web.serviceConfig.EnvironmentFile = [ config.age.secrets."paperless.env".path ];
################################# #################################
# Scanning # Scanning
@ -148,7 +147,7 @@ in {
services.restic.backups = { services.restic.backups = {
paperless = { paperless = {
paths = [backupDir]; paths = [ backupDir ];
initialize = true; initialize = true;
passwordFile = config.age.secrets."restic-password".path; passwordFile = config.age.secrets."restic-password".path;
# See https://www.hosting.de/blog/verschluesselte-backups-mit-rclone-und-restic-in-nextcloud/ # See https://www.hosting.de/blog/verschluesselte-backups-mit-rclone-und-restic-in-nextcloud/

View file

@ -29,8 +29,8 @@
owner = "unbound"; owner = "unbound";
}; };
networking.firewall.allowedUDPPorts = [53]; networking.firewall.allowedUDPPorts = [ 53 ];
networking.firewall.allowedTCPPorts = [53]; networking.firewall.allowedTCPPorts = [ 53 ];
services.resolved.enable = false; services.resolved.enable = false;
services.unbound = { services.unbound = {
@ -94,4 +94,5 @@
}; };
}; };
}; };
} }

View file

@ -1,4 +1,5 @@
{pkgs, ...}: { { pkgs, ... }:
{
services.cron = { services.cron = {
enable = true; enable = true;
systemCronJobs = [ systemCronJobs = [

View file

@ -17,9 +17,9 @@ in {
boot.initrd.preLVMCommands = "udevadm trigger --settle"; boot.initrd.preLVMCommands = "udevadm trigger --settle";
boot.swraid.enable = true; boot.swraid.enable = true;
boot.swraid.mdadmConf = '' boot.swraid.mdadmConf = ''
DEVICE /dev/nvme0n1p2 /dev/nvme1n1p2 DEVICE /dev/nvme0n1p2 /dev/nvme1n1p2
ARRAY /dev/md/nixos:root metadata=1.2 name=nixos:root UUID=67d1aa81:1b348887:c17a75e8:f2edf2bd ARRAY /dev/md/nixos:root metadata=1.2 name=nixos:root UUID=67d1aa81:1b348887:c17a75e8:f2edf2bd
MAILADDR ${psCfg.user.email} MAILADDR ${psCfg.user.email}
''; '';
pub-solar.core.hibernation.enable = true; pub-solar.core.hibernation.enable = true;

View file

@ -1,4 +1,4 @@
{...}: { { ... }: {
imports = [ imports = [
./configuration.nix ./configuration.nix
./hardware-configuration.nix ./hardware-configuration.nix

View file

@ -1,58 +1,54 @@
# Do not modify this file! It was generated by nixos-generate-config # Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes # and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead. # to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{ {
config, imports =
lib, [ (modulesPath + "/installer/scan/not-detected.nix")
pkgs,
modulesPath,
...
}: {
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
]; ];
boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "usbhid" "usb_storage" "sd_mod"]; boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "usbhid" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = ["dm-snapshot"]; boot.initrd.kernelModules = [ "dm-snapshot" ];
boot.kernelModules = ["kvm-amd"]; boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = []; boot.extraModulePackages = [ ];
boot.initrd.luks.devices."cryptroot" = { boot.initrd.luks.devices."cryptroot" = {
device = "/dev/disk/by-id/md-name-nixos:root"; device = "/dev/disk/by-id/md-name-nixos:root";
allowDiscards = true; allowDiscards = true;
}; };
fileSystems."/" = { fileSystems."/" =
device = "none"; { device = "none";
fsType = "tmpfs"; fsType = "tmpfs";
}; };
fileSystems."/boot" = { fileSystems."/boot" =
device = "/dev/disk/by-uuid/EC82-67F4"; { device = "/dev/disk/by-uuid/EC82-67F4";
fsType = "vfat"; fsType = "vfat";
}; };
fileSystems."/home" = { fileSystems."/home" =
device = "/dev/disk/by-uuid/0cc568f0-402d-4535-980a-ed3a1dc697b9"; { device = "/dev/disk/by-uuid/0cc568f0-402d-4535-980a-ed3a1dc697b9";
fsType = "ext4"; fsType = "ext4";
# https://github.com/ryantm/agenix/issues/45#issuecomment-957865406 # https://github.com/ryantm/agenix/issues/45#issuecomment-957865406
neededForBoot = true; neededForBoot = true;
}; };
fileSystems."/nix" = { fileSystems."/nix" =
device = "/dev/disk/by-uuid/e203d629-4d34-4147-bee6-919f0bfa25de"; { device = "/dev/disk/by-uuid/e203d629-4d34-4147-bee6-919f0bfa25de";
fsType = "ext4"; fsType = "ext4";
}; };
fileSystems."/persist" = { fileSystems."/persist" =
device = "/dev/disk/by-uuid/a0855aaa-76bf-445e-b0d1-ab1552e5496f"; { device = "/dev/disk/by-uuid/a0855aaa-76bf-445e-b0d1-ab1552e5496f";
fsType = "ext4"; fsType = "ext4";
# https://github.com/ryantm/agenix/issues/45#issuecomment-957865406 # https://github.com/ryantm/agenix/issues/45#issuecomment-957865406
neededForBoot = true; neededForBoot = true;
}; };
swapDevices = [ swapDevices =
{device = "/dev/disk/by-uuid/761507ab-479d-414b-ac3e-2149564ca470";} [ { device = "/dev/disk/by-uuid/761507ab-479d-414b-ac3e-2149564ca470"; }
]; ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking # Enables DHCP on each ethernet and wireless interface. In case of scripted networking

View file

@ -1,4 +1,5 @@
{lib}: hostnames: { { lib }:
hostnames: {
"127.0.0.1" = hostnames; "127.0.0.1" = hostnames;
"::1" = hostnames; "::1" = hostnames;
} }

View file

@ -1,8 +1,4 @@
{ { lib, inputs, ... }: {
lib,
inputs,
...
}: {
# Configuration common to all Linux systems # Configuration common to all Linux systems
flake = { flake = {
lib = let lib = let
@ -14,7 +10,7 @@
#foo = callLibs ./foo.nix; #foo = callLibs ./foo.nix;
## In configs, they can be used under "lib.our" ## In configs, they can be used under "lib.our"
deploy = import ./deploy.nix {inherit inputs lib;}; deploy = import ./deploy.nix { inherit inputs lib; };
addLocalHostname = callLibs ./add-local-hostname.nix; addLocalHostname = callLibs ./add-local-hostname.nix;
recursiveMerge = callLibs ./recursive-merge.nix; recursiveMerge = callLibs ./recursive-merge.nix;
mkEmailAddress = account: domain: account + "@" + domain; mkEmailAddress = account: domain: account + "@" + domain;

View file

@ -1,13 +1,11 @@
/* /*
* The contents of this file are adapted from digga * The contents of this file are adapted from digga
* https://github.com/divnix/digga * https://github.com/divnix/digga
* *
* Licensed under the MIT license * Licensed under the MIT license
*/ */
{
lib, { lib, inputs }: let
inputs,
}: let
getFqdn = c: let getFqdn = c: let
net = c.config.networking; net = c.config.networking;
fqdn = fqdn =
@ -54,18 +52,13 @@ in {
_: c: let _: c: let
system = c.pkgs.stdenv.hostPlatform.system; system = c.pkgs.stdenv.hostPlatform.system;
# Unmodified nixpkgs # Unmodified nixpkgs
pkgs = import inputs.nixpkgs {inherit system;}; pkgs = import inputs.nixpkgs { inherit system; };
# nixpkgs with deploy-rs overlay but force the nixpkgs package # nixpkgs with deploy-rs overlay but force the nixpkgs package
deployPkgs = import inputs.nixpkgs { deployPkgs = import inputs.nixpkgs {
inherit system; inherit system;
overlays = [ overlays = [
inputs.deploy-rs.overlay # or deploy-rs.overlays.default inputs.deploy-rs.overlay # or deploy-rs.overlays.default
(self: super: { (self: super: { deploy-rs = { inherit (pkgs) deploy-rs; lib = super.deploy-rs.lib; }; })
deploy-rs = {
inherit (pkgs) deploy-rs;
lib = super.deploy-rs.lib;
};
})
]; ];
}; };
in { in {

View file

@ -1,4 +1,6 @@
{lib}: attrList: let { lib }:
attrList:
let
f = attrPath: f = attrPath:
zipAttrsWith ( zipAttrsWith (
n: values: n: values:
@ -11,4 +13,4 @@
else last values else last values
); );
in in
f [] attrList f [] attrList;

View file

@ -10,8 +10,8 @@
systemd.services.systemd-networkd-wait-online.enable = lib.mkDefault false; systemd.services.systemd-networkd-wait-online.enable = lib.mkDefault false;
networking.hosts = { networking.hosts = {
"128.140.109.213" = ["vpn.b12f.io"]; "128.140.109.213" = [ "vpn.b12f.io" ];
"2a01:4f8:c2c:b60::" = ["vpn.b12f.io"]; "2a01:4f8:c2c:b60::" = [ "vpn.b12f.io" ];
}; };
networking.networkmanager = { networking.networkmanager = {
@ -38,7 +38,7 @@
}; };
# Don't expose SSH via public interfaces # Don't expose SSH via public interfaces
networking.firewall.interfaces.wg-private.allowedTCPPorts = [22]; networking.firewall.interfaces.wg-private.allowedTCPPorts = [ 22 ];
# For rage encryption, all hosts need a ssh key pair # For rage encryption, all hosts need a ssh key pair
services.openssh = { services.openssh = {

View file

@ -2,12 +2,11 @@
pkgs, pkgs,
psCfg, psCfg,
... ...
}: }: with pkgs;
with pkgs; ''
''
# Set shut down, restart and locking features # Set shut down, restart and locking features
'' ''
+ ( + (
if psCfg.core.hibernation.enable if psCfg.core.hibernation.enable
then '' then ''
set $mode_system (e)xit, (l)ock, (h)ibernate, (r)eboot, (Shift+s)hutdown set $mode_system (e)xit, (l)ock, (h)ibernate, (r)eboot, (Shift+s)hutdown
@ -15,27 +14,27 @@ with pkgs;
else '' else ''
set $mode_system (e)xit, (l)ock, (r)eboot, (Shift+s)hutdown set $mode_system (e)xit, (l)ock, (r)eboot, (Shift+s)hutdown
'' ''
) )
+ '' + ''
bindsym $mod+0 mode "$mode_system" bindsym $mod+0 mode "$mode_system"
mode "$mode_system" { mode "$mode_system" {
bindsym e exec ${sway}/bin/swaymsg exit, mode "default" bindsym e exec ${sway}/bin/swaymsg exit, mode "default"
bindsym l exec ${swaylock-bg}/bin/swaylock-bg, mode "default" bindsym l exec ${swaylock-bg}/bin/swaylock-bg, mode "default"
'' ''
+ ( + (
if psCfg.core.hibernation.enable if psCfg.core.hibernation.enable
then '' then ''
bindsym h exec ${systemd}/bin/systemctl hibernate, mode "default" bindsym h exec ${systemd}/bin/systemctl hibernate, mode "default"
'' ''
else "" else ""
) )
+ '' + ''
bindsym r exec ${systemd}/bin/systemctl reboot, mode "default" bindsym r exec ${systemd}/bin/systemctl reboot, mode "default"
bindsym Shift+s exec ${systemd}/bin/systemctl poweroff, mode "default" bindsym Shift+s exec ${systemd}/bin/systemctl poweroff, mode "default"
# exit system mode: "Enter" or "Escape" # exit system mode: "Enter" or "Escape"
bindsym Return mode "default" bindsym Return mode "default"
bindsym Escape mode "default" bindsym Escape mode "default"
} }
'' ''

View file

@ -1,17 +1,14 @@
{ { config, pkgs, lib, ... }:
config,
pkgs, with lib;
lib,
... let
}:
with lib; let
cfg = config.services.invoiceplane; cfg = config.services.invoiceplane;
eachSite = cfg.sites; eachSite = cfg.sites;
user = "invoiceplane"; user = "invoiceplane";
webserver = config.services.${cfg.webserver}; webserver = config.services.${cfg.webserver};
invoiceplane-config = hostName: cfg: invoiceplane-config = hostName: cfg: pkgs.writeText "ipconfig.php" ''
pkgs.writeText "ipconfig.php" ''
IP_URL=http://${hostName} IP_URL=http://${hostName}
ENABLE_DEBUG=false ENABLE_DEBUG=false
DISABLE_SETUP=false DISABLE_SETUP=false
@ -19,11 +16,7 @@ with lib; let
DB_HOSTNAME=${cfg.database.host} DB_HOSTNAME=${cfg.database.host}
DB_USERNAME=${cfg.database.user} DB_USERNAME=${cfg.database.user}
# NOTE: file_get_contents adds newline at the end of returned string # NOTE: file_get_contents adds newline at the end of returned string
DB_PASSWORD=${ DB_PASSWORD=${if cfg.database.passwordFile == null then "" else "trim(file_get_contents('${cfg.database.passwordFile}'),\"\\r\\n\")"}
if cfg.database.passwordFile == null
then ""
else "trim(file_get_contents('${cfg.database.passwordFile}'),\"\\r\\n\")"
}
DB_DATABASE=${cfg.database.name} DB_DATABASE=${cfg.database.name}
DB_PORT=${toString cfg.database.port} DB_PORT=${toString cfg.database.port}
SESS_EXPIRATION=864000 SESS_EXPIRATION=864000
@ -35,13 +28,11 @@ with lib; let
REMOVE_INDEXPHP=true REMOVE_INDEXPHP=true
''; '';
extraConfig = hostName: cfg: extraConfig = hostName: cfg: pkgs.writeText "extraConfig.php" ''
pkgs.writeText "extraConfig.php" ''
${toString cfg.extraConfig} ${toString cfg.extraConfig}
''; '';
pkg = hostName: cfg: pkg = hostName: cfg: pkgs.stdenv.mkDerivation rec {
pkgs.stdenv.mkDerivation rec {
pname = "invoiceplane-${hostName}"; pname = "invoiceplane-${hostName}";
version = src.version; version = src.version;
src = pkgs.invoiceplane; src = pkgs.invoiceplane;
@ -73,12 +64,10 @@ with lib; let
''; '';
}; };
siteOpts = { siteOpts = { lib, name, ... }:
lib, {
name,
...
}: {
options = { options = {
enable = mkEnableOption (lib.mdDoc "InvoicePlane web application"); enable = mkEnableOption (lib.mdDoc "InvoicePlane web application");
stateDir = mkOption { stateDir = mkOption {
@ -166,7 +155,7 @@ with lib; let
}; };
poolConfig = mkOption { poolConfig = mkOption {
type = with types; attrsOf (oneOf [str int bool]); type = with types; attrsOf (oneOf [ str int bool ]);
default = { default = {
"pm" = "dynamic"; "pm" = "dynamic";
"pm.max_children" = 32; "pm.max_children" = 32;
@ -197,6 +186,7 @@ with lib; let
}; };
cron = { cron = {
enable = mkOption { enable = mkOption {
type = types.bool; type = types.bool;
default = false; default = false;
@ -212,10 +202,14 @@ with lib; let
type = types.str; type = types.str;
description = lib.mdDoc "Cron key taken from the administration page."; description = lib.mdDoc "Cron key taken from the administration page.";
}; };
}; };
}; };
}; };
in { in
{
disabledModules = [ disabledModules = [
"services/web-apps/invoiceplane.nix" "services/web-apps/invoiceplane.nix"
]; ];
@ -224,6 +218,7 @@ in {
options = { options = {
services.invoiceplane = mkOption { services.invoiceplane = mkOption {
type = types.submodule { type = types.submodule {
options.sites = mkOption { options.sites = mkOption {
type = types.attrsOf (types.submodule siteOpts); type = types.attrsOf (types.submodule siteOpts);
default = {}; default = {};
@ -231,7 +226,7 @@ in {
}; };
options.webserver = mkOption { options.webserver = mkOption {
type = types.enum ["caddy" "nginx"]; type = types.enum [ "caddy" "nginx" ];
default = "caddy"; default = "caddy";
description = lib.mdDoc '' description = lib.mdDoc ''
Which webserver to use for virtual host management. Currently only Which webserver to use for virtual host management. Currently only
@ -242,61 +237,53 @@ in {
default = {}; default = {};
description = lib.mdDoc "InvoicePlane configuration."; description = lib.mdDoc "InvoicePlane configuration.";
}; };
}; };
# implementation # implementation
config = mkIf (eachSite != {}) (mkMerge [ config = mkIf (eachSite != {}) (mkMerge [{
{
assertions = flatten (mapAttrsToList (hostName: cfg: [ assertions = flatten (mapAttrsToList (hostName: cfg:
{ [{ assertion = cfg.database.createLocally -> cfg.database.user == user;
assertion = cfg.database.createLocally -> cfg.database.user == user;
message = ''services.invoiceplane.sites."${hostName}".database.user must be ${user} if the database is to be automatically provisioned''; message = ''services.invoiceplane.sites."${hostName}".database.user must be ${user} if the database is to be automatically provisioned'';
} }
{ { assertion = cfg.database.createLocally -> cfg.database.passwordFile == null;
assertion = cfg.database.createLocally -> cfg.database.passwordFile == null;
message = ''services.invoiceplane.sites."${hostName}".database.passwordFile cannot be specified if services.invoiceplane.sites."${hostName}".database.createLocally is set to true.''; message = ''services.invoiceplane.sites."${hostName}".database.passwordFile cannot be specified if services.invoiceplane.sites."${hostName}".database.createLocally is set to true.'';
} }
{ { assertion = cfg.cron.enable -> cfg.cron.key != null;
assertion = cfg.cron.enable -> cfg.cron.key != null;
message = ''services.invoiceplane.sites."${hostName}".cron.key must be set in order to use cron service.''; message = ''services.invoiceplane.sites."${hostName}".cron.key must be set in order to use cron service.'';
} }
]) ]) eachSite);
eachSite);
services.mysql = mkIf (any (v: v.database.createLocally) (attrValues eachSite)) { services.mysql = mkIf (any (v: v.database.createLocally) (attrValues eachSite)) {
enable = true; enable = true;
package = mkDefault pkgs.mariadb; package = mkDefault pkgs.mariadb;
ensureDatabases = mapAttrsToList (hostName: cfg: cfg.database.name) eachSite; ensureDatabases = mapAttrsToList (hostName: cfg: cfg.database.name) eachSite;
ensureUsers = ensureUsers = mapAttrsToList (hostName: cfg:
mapAttrsToList ( { name = cfg.database.user;
hostName: cfg: { ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; };
name = cfg.database.user;
ensurePermissions = {"${cfg.database.name}.*" = "ALL PRIVILEGES";};
} }
) ) eachSite;
eachSite;
}; };
services.phpfpm = { services.phpfpm = {
phpPackage = pkgs.php81; phpPackage = pkgs.php81;
pools = pools = mapAttrs' (hostName: cfg: (
mapAttrs' (hostName: cfg: (
nameValuePair "invoiceplane-${hostName}" { nameValuePair "invoiceplane-${hostName}" {
inherit user; inherit user;
group = webserver.group; group = webserver.group;
settings = settings = {
{
"listen.owner" = webserver.user; "listen.owner" = webserver.user;
"listen.group" = webserver.group; "listen.group" = webserver.group;
} // cfg.poolConfig;
} }
// cfg.poolConfig; )) eachSite;
}
))
eachSite;
}; };
} }
{ {
systemd.tmpfiles.rules = flatten (mapAttrsToList (hostName: cfg: [ systemd.tmpfiles.rules = flatten (mapAttrsToList (hostName: cfg: [
"d ${cfg.stateDir} 0750 ${user} ${webserver.group} - -" "d ${cfg.stateDir} 0750 ${user} ${webserver.group} - -"
"f ${cfg.stateDir}/ipconfig.php 0750 ${user} ${webserver.group} - -" "f ${cfg.stateDir}/ipconfig.php 0750 ${user} ${webserver.group} - -"
@ -307,42 +294,41 @@ in {
"d ${cfg.stateDir}/uploads/temp 0750 ${user} ${webserver.group} - -" "d ${cfg.stateDir}/uploads/temp 0750 ${user} ${webserver.group} - -"
"d ${cfg.stateDir}/uploads/temp/mpdf 0750 ${user} ${webserver.group} - -" "d ${cfg.stateDir}/uploads/temp/mpdf 0750 ${user} ${webserver.group} - -"
"d ${cfg.stateDir}/tmp 0750 ${user} ${webserver.group} - -" "d ${cfg.stateDir}/tmp 0750 ${user} ${webserver.group} - -"
]) ]) eachSite);
eachSite);
systemd.services.invoiceplane-config = { systemd.services.invoiceplane-config = {
serviceConfig.Type = "oneshot"; serviceConfig.Type = "oneshot";
script = concatStrings (mapAttrsToList (hostName: cfg: '' script = concatStrings (mapAttrsToList (hostName: cfg:
''
mkdir -p ${cfg.stateDir}/logs \ mkdir -p ${cfg.stateDir}/logs \
${cfg.stateDir}/uploads ${cfg.stateDir}/uploads
if ! grep -q IP_URL "${cfg.stateDir}/ipconfig.php"; then if ! grep -q IP_URL "${cfg.stateDir}/ipconfig.php"; then
cp "${invoiceplane-config hostName cfg}" "${cfg.stateDir}/ipconfig.php" cp "${invoiceplane-config hostName cfg}" "${cfg.stateDir}/ipconfig.php"
fi fi
'') '') eachSite);
eachSite); wantedBy = [ "multi-user.target" ];
wantedBy = ["multi-user.target"];
}; };
users.users.${user} = { users.users.${user} = {
group = webserver.group; group = webserver.group;
isSystemUser = true; isSystemUser = true;
}; };
} }
{ {
# Cron service implementation # Cron service implementation
systemd.timers = systemd.timers = mapAttrs' (hostName: cfg: (
mapAttrs' (hostName: cfg: (
nameValuePair "invoiceplane-cron-${hostName}" (mkIf cfg.cron.enable { nameValuePair "invoiceplane-cron-${hostName}" (mkIf cfg.cron.enable {
wantedBy = ["timers.target"]; wantedBy = [ "timers.target" ];
timerConfig = { timerConfig = {
OnBootSec = "5m"; OnBootSec = "5m";
OnUnitActiveSec = "5m"; OnUnitActiveSec = "5m";
Unit = "invoiceplane-cron-${hostName}.service"; Unit = "invoiceplane-cron-${hostName}.service";
}; };
}) })
)) )) eachSite;
eachSite;
systemd.services = systemd.services =
mapAttrs' (hostName: cfg: ( mapAttrs' (hostName: cfg: (
@ -353,15 +339,14 @@ in {
ExecStart = "${pkgs.curl}/bin/curl --header 'Host: ${hostName}' http://localhost/invoices/cron/recur/${cfg.cron.key}"; ExecStart = "${pkgs.curl}/bin/curl --header 'Host: ${hostName}' http://localhost/invoices/cron/recur/${cfg.cron.key}";
}; };
}) })
)) )) eachSite;
eachSite;
} }
(mkIf (cfg.webserver == "caddy") { (mkIf (cfg.webserver == "caddy") {
services.caddy = { services.caddy = {
enable = true; enable = true;
virtualHosts = virtualHosts = mapAttrs' (hostName: cfg: (
mapAttrs' (hostName: cfg: (
nameValuePair "http://${hostName}" { nameValuePair "http://${hostName}" {
extraConfig = '' extraConfig = ''
root * ${pkg hostName cfg} root * ${pkg hostName cfg}
@ -369,16 +354,14 @@ in {
php_fastcgi unix/${config.services.phpfpm.pools."invoiceplane-${hostName}".socket} php_fastcgi unix/${config.services.phpfpm.pools."invoiceplane-${hostName}".socket}
''; '';
} }
)) )) eachSite;
eachSite;
}; };
}) })
(mkIf (cfg.webserver == "nginx") { (mkIf (cfg.webserver == "nginx") {
services.nginx = { services.nginx = {
enable = true; enable = true;
virtualHosts = virtualHosts = mapAttrs' (hostName: cfg: (
mapAttrs' (hostName: cfg: (
nameValuePair "${hostName}" { nameValuePair "${hostName}" {
root = "${pkg hostName cfg}"; root = "${pkg hostName cfg}";
extraConfig = '' extraConfig = ''
@ -405,9 +388,9 @@ in {
}; };
}; };
} }
)) )) eachSite;
eachSite;
}; };
}) })
]); ]);
} }

View file

@ -5,8 +5,7 @@
flake, flake,
... ...
}: { }: {
nixpkgs.config.allowUnfreePredicate = pkg: nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
builtins.elem (lib.getName pkg) [
"steam" "steam"
"steam-original" "steam-original"
"steam-run" "steam-run"

View file

@ -1,8 +1,5 @@
{ lib, config, ... }:
{ {
lib,
config,
...
}: {
environment.persistence."/persist" = { environment.persistence."/persist" = {
hideMounts = true; hideMounts = true;
directories = [ directories = [
@ -20,7 +17,7 @@
fileSystems."/etc/nixos" = { fileSystems."/etc/nixos" = {
device = "/home/${config.pub-solar.user.name}/Workspace/os"; device = "/home/${config.pub-solar.user.name}/Workspace/os";
options = ["bind"]; options = [ "bind" ];
}; };
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [

View file

@ -1,4 +1,5 @@
{pkgs, ...}: { { pkgs, ... }:
{
services.cron = { services.cron = {
enable = true; enable = true;
systemCronJobs = [ systemCronJobs = [

View file

@ -16,15 +16,11 @@
services.printing.listenAddresses = ["localhost:631"]; services.printing.listenAddresses = ["localhost:631"];
services.printing.defaultShared = lib.mkDefault false; services.printing.defaultShared = lib.mkDefault false;
services.printing.drivers = services.printing.drivers = [
[
pkgs.gutenprint pkgs.gutenprint
] ] ++ (if (pkgs.system == "x86_64-linux")
++ ( then [ pkgs.cups-brother-hl3140cw ]
if (pkgs.system == "x86_64-linux") else []);
then [pkgs.cups-brother-hl3140cw]
else []
);
# environment.persistence."/persist" = { # environment.persistence."/persist" = {
# directories = [ # directories = [

View file

@ -5,7 +5,7 @@
lib, lib,
... ...
}: { }: {
networking.firewall.allowedTCPPorts = [80 443]; networking.firewall.allowedTCPPorts = [ 80 443 ];
services.nginx = { services.nginx = {
enable = true; enable = true;

View file

@ -6,27 +6,27 @@
user = config.pub-solar.user; user = config.pub-solar.user;
xdg = config.home-manager.users."${user.name}".xdg; xdg = config.home-manager.users."${user.name}".xdg;
in '' in ''
# What happened? # What happened?
# #
# fix feat build chore ci docs style refactor perf test # fix feat build chore ci docs style refactor perf test
# #
# type!(optional scope): <summary> --------------# # type!(optional scope): <summary> --------------#
# #
# ^\n # ^\n
# What exactly was done and why? --------------------------------------# # What exactly was done and why? --------------------------------------#
# #
# ^\n # ^\n
# #
# Any issue numbers or links? # Any issue numbers or links?
# #
# Ref: #123 # Ref: #123
# ^\n # ^\n
# #
# Co-authored-by: Example Name <email@example.com> # Co-authored-by: Example Name <email@example.com>
'' ''

View file

@ -21,8 +21,7 @@ in {
config = { config = {
programs.command-not-found.enable = false; programs.command-not-found.enable = false;
users.users."${psCfg.user.name}".packages = with pkgs; users.users."${psCfg.user.name}".packages = with pkgs; [
[
asciinema asciinema
bat bat
blesh blesh
@ -41,10 +40,7 @@ in {
screen screen
watson watson
jump jump
] ] ++ (if cfg.full then [
++ (
if cfg.full
then [
# Nix specific utilities # Nix specific utilities
alejandra alejandra
manix manix
@ -52,9 +48,7 @@ in {
nix-tree nix-tree
nix-inspect nix-inspect
nvd nvd
] ] else []);
else []
);
home-manager.users."${psCfg.user.name}" = { home-manager.users."${psCfg.user.name}" = {
xdg.dataFile."scripts/base16.sh".source = .local/share/scripts/base16.sh; xdg.dataFile."scripts/base16.sh".source = .local/share/scripts/base16.sh;

View file

@ -1,4 +1,5 @@
{...}: { { ... }:
{
enable = true; enable = true;
nix-direnv = { nix-direnv = {
enable = true; enable = true;

View file

@ -1,4 +1,5 @@
{...}: { { ... }:
{
enable = true; enable = true;
extraConfig = { extraConfig = {

View file

@ -46,8 +46,7 @@ in {
# python3Full # python3Full
]; ];
plugins = with pkgs.vimPlugins; plugins = with pkgs.vimPlugins; [
[
# The status bar in the bottom of the screen with the mode indication and file location # The status bar in the bottom of the screen with the mode indication and file location
vim-airline vim-airline
@ -97,10 +96,7 @@ in {
# Work with tags files # Work with tags files
vim-gutentags vim-gutentags
] ] ++ (if cfg.full then [
++ (
if cfg.full
then [
nvim-treesitter.withAllGrammars nvim-treesitter.withAllGrammars
# Dependencies for nvim-lspconfig # Dependencies for nvim-lspconfig
@ -118,9 +114,7 @@ in {
# JSON schemas # JSON schemas
SchemaStore-nvim SchemaStore-nvim
] ] else []);
else []
);
extraConfig = builtins.concatStringsSep "\n" ([ extraConfig = builtins.concatStringsSep "\n" ([
'' ''
@ -136,13 +130,8 @@ in {
(builtins.readFile ./clipboard.vim) (builtins.readFile ./clipboard.vim)
(builtins.readFile ./ui.vim) (builtins.readFile ./ui.vim)
(builtins.readFile ./filetypes.vim) (builtins.readFile ./filetypes.vim)
] ] ++ (if cfg.full then [
++ (
if cfg.full
then [
(builtins.readFile ./lsp.vim) (builtins.readFile ./lsp.vim)
(builtins.readFile ./cmp.vim) (builtins.readFile ./cmp.vim)
] ] else []));
else []
));
} }

View file

@ -62,18 +62,13 @@ telescope.setup{
}, },
}, },
}, },
pickers = {
find_files = {
-- `hidden = true` will still show the inside of `.git/` as it's not `.gitignore`d.
find_command = { "rg", "--files", "--hidden", "--glob", "!**/.git/*" },
},
},
extensions = { extensions = {
fzf = { fzf = {
fuzzy = true, -- false will only do exact matching fuzzy = true, -- false will only do exact matching
override_generic_sorter = true, -- override the generic sorter override_generic_sorter = true, -- override the generic sorter
override_file_sorter = true, -- override the file sorter override_file_sorter = true, -- override the file sorter
case_mode = "smart_case", -- or "ignore_case" or "respect_case" case_mode = "smart_case", -- or "ignore_case" or "respect_case"
-- the default case_mode is "smart_case"
} }
} }
} }
@ -85,7 +80,6 @@ vim.keymap.set('n', '<leader>ff', builtin.find_files, {})
vim.keymap.set('n', '<leader>f/', builtin.live_grep, {}) vim.keymap.set('n', '<leader>f/', builtin.live_grep, {})
vim.keymap.set('n', '<leader>f?', builtin.builtin, {}) vim.keymap.set('n', '<leader>f?', builtin.builtin, {})
vim.keymap.set('n', '<leader>fb', builtin.buffers, {}) vim.keymap.set('n', '<leader>fb', builtin.buffers, {})
vim.keymap.set('n', '<leader>fr', builtin.command_history, {})
vim.keymap.set('n', '<leader>fc', builtin.commands, {}) vim.keymap.set('n', '<leader>fc', builtin.commands, {})
vim.keymap.set('n', '<leader>ft', builtin.treesitter, {}) vim.keymap.set('n', '<leader>ft', builtin.treesitter, {})
EOF EOF

View file

@ -7,7 +7,7 @@
}: let }: let
psCfg = config.pub-solar; psCfg = config.pub-solar;
in in
with lib; { with lib; {
imports = [ imports = [
./home.nix ./home.nix
]; ];
@ -82,12 +82,10 @@ in
then psCfg.user.password then psCfg.user.password
else ""; else "";
openssh.authorizedKeys.keys = openssh.authorizedKeys.keys =
flake.self.publicKeys flake.self.publicKeys ++
++ ( (if psCfg.user.publicKeys != null
if psCfg.user.publicKeys != null
then psCfg.user.publicKeys then psCfg.user.publicKeys
else [] else []);
);
}; };
}; };
@ -103,4 +101,4 @@ in
} }
]; ];
}; };
} }

View file

@ -1,4 +1,4 @@
{...}: { { ... }: {
imports = [ imports = [
./private.nix ./private.nix
./tunnel.nix ./tunnel.nix

View file

@ -2,7 +2,8 @@
lib, lib,
config, config,
... ...
}: let }:
let
cfg = config.pub-solar.wireguard.ehex; cfg = config.pub-solar.wireguard.ehex;
in { in {
options.pub-solar.wireguard.ehex = { options.pub-solar.wireguard.ehex = {
@ -18,10 +19,10 @@ in {
}; };
}; };
config = lib.mkIf (lib.length cfg.ownIPs != 0) { config = lib.mkIf (lib.length cfg.ownIPs != 0){
networking.firewall.allowedUDPPorts = [51822]; networking.firewall.allowedUDPPorts = [51822];
systemd.network.wait-online.ignoredInterfaces = ["wg-ehex"]; systemd.network.wait-online.ignoredInterfaces = [ "wg-ehex" ];
systemd.services.wireguard-wg-ehex = import ./service-override.nix lib; systemd.services.wireguard-wg-ehex = import ./service-override.nix lib;
@ -42,7 +43,7 @@ in {
endpoint = "vpn-gateway.ehex.de:4242"; endpoint = "vpn-gateway.ehex.de:4242";
publicKey = "Fsg4KEyDEvQEt/1cVWU9xa/k9x/3UhONDj61aXZ7tys="; publicKey = "Fsg4KEyDEvQEt/1cVWU9xa/k9x/3UhONDj61aXZ7tys=";
presharedKey = "tQy7B5R3wOgWwIKFDcEr4WZIqCrwG+9UgPRIQx/5xso="; presharedKey = "tQy7B5R3wOgWwIKFDcEr4WZIqCrwG+9UgPRIQx/5xso=";
allowedIPs = ["10.42.0.0/22" "10.0.66.0/24"]; allowedIPs = [ "10.42.0.0/22" "10.0.66.0/24" ];
persistentKeepalive = 15; persistentKeepalive = 15;
dynamicEndpointRefreshSeconds = 30; dynamicEndpointRefreshSeconds = 30;
} }

View file

@ -3,7 +3,8 @@
config, config,
pkgs, pkgs,
... ...
}: let }:
let
cfg = config.pub-solar.wireguard.private; cfg = config.pub-solar.wireguard.private;
in { in {
options.pub-solar.wireguard.private = { options.pub-solar.wireguard.private = {
@ -42,7 +43,7 @@ in {
config = lib.mkIf (builtins.length cfg.ownIPs != 0) { config = lib.mkIf (builtins.length cfg.ownIPs != 0) {
networking.firewall.allowedUDPPorts = [51899]; networking.firewall.allowedUDPPorts = [51899];
systemd.network.wait-online.ignoredInterfaces = ["wg-private"]; systemd.network.wait-online.ignoredInterfaces = [ "wg-private" ];
systemd.services.wireguard-wg-private = import ./service-override.nix lib; systemd.services.wireguard-wg-private = import ./service-override.nix lib;
@ -52,18 +53,11 @@ in {
mtu = 1300; mtu = 1300;
ips = cfg.ownIPs; ips = cfg.ownIPs;
privateKeyFile = cfg.privateKeyFile; privateKeyFile = cfg.privateKeyFile;
postSetup = postSetup = ""
"" + (if cfg.useDNS then ''
+ (
if cfg.useDNS
then ''
printf "nameserver 10.13.12.7\nnameserver fd00:b12f:acab:1312:acab:7::" | resolvconf -a wg-private -m 0 -x printf "nameserver 10.13.12.7\nnameserver fd00:b12f:acab:1312:acab:7::" | resolvconf -a wg-private -m 0 -x
'' '' else "")
else "" + (if cfg.fullTunnel then ''
)
+ (
if cfg.fullTunnel
then ''
defaultRoute=$(${pkgs.iproute2}/bin/ip r | ${pkgs.gnugrep}/bin/grep "default via" | head -n 1 | ${pkgs.gawk}/bin/awk '{ print $3 " " $4 " " $5 }') defaultRoute=$(${pkgs.iproute2}/bin/ip r | ${pkgs.gnugrep}/bin/grep "default via" | head -n 1 | ${pkgs.gawk}/bin/awk '{ print $3 " " $4 " " $5 }')
ipv4=$(${pkgs.dnsutils}/bin/dig +short A vpn.b12f.io) ipv4=$(${pkgs.dnsutils}/bin/dig +short A vpn.b12f.io)
${pkgs.iproute2}/bin/ip route add $ipv4 metric 256 via $defaultRoute ${pkgs.iproute2}/bin/ip route add $ipv4 metric 256 via $defaultRoute
@ -73,9 +67,7 @@ in {
ip -4 route replace default dev wg-private metric 512 ip -4 route replace default dev wg-private metric 512
ip -6 route delete default dev wg-private || true ip -6 route delete default dev wg-private || true
ip -6 route replace default dev wg-private metric 512 ip -6 route replace default dev wg-private metric 512
'' '' else "");
else ""
);
postShutdown = lib.mkIf cfg.useDNS '' postShutdown = lib.mkIf cfg.useDNS ''
resolvconf -d wg-private -f resolvconf -d wg-private -f
''; '';
@ -83,19 +75,13 @@ in {
{ {
# frikandel # frikandel
publicKey = "p6YKNYBlySKfhTN+wbSsKdoNjzko/XSAiTAlCJzP1jA="; publicKey = "p6YKNYBlySKfhTN+wbSsKdoNjzko/XSAiTAlCJzP1jA=";
allowedIPs = allowedIPs = [
[
"10.13.12.0/24" "10.13.12.0/24"
"fd00:b12f:acab:1312::/64" "fd00:b12f:acab:1312::/64"
] ] ++ (if cfg.fullTunnel then [
++ (
if cfg.fullTunnel
then [
"0.0.0.0/0" "0.0.0.0/0"
"::/0" "::/0"
] ] else []);
else []
);
endpoint = "vpn.b12f.io:51899"; endpoint = "vpn.b12f.io:51899";
dynamicEndpointRefreshSeconds = 30; dynamicEndpointRefreshSeconds = 30;
} }

View file

@ -2,7 +2,8 @@
lib, lib,
config, config,
... ...
}: let }:
let
cfg = config.pub-solar.wireguard.pub-solar; cfg = config.pub-solar.wireguard.pub-solar;
in { in {
options.pub-solar.wireguard.pub-solar = { options.pub-solar.wireguard.pub-solar = {
@ -18,10 +19,10 @@ in {
}; };
}; };
config = lib.mkIf (lib.length cfg.ownIPs != 0) { config = lib.mkIf (lib.length cfg.ownIPs != 0){
networking.firewall.allowedUDPPorts = [51821]; networking.firewall.allowedUDPPorts = [51821];
systemd.network.wait-online.ignoredInterfaces = ["wg-pub-solar"]; systemd.network.wait-online.ignoredInterfaces = [ "wg-pub-solar" ];
systemd.services.wireguard-wg-pub-solar = import ./service-override.nix lib; systemd.services.wireguard-wg-pub-solar = import ./service-override.nix lib;
@ -35,14 +36,14 @@ in {
{ {
endpoint = "flora-6.pub.solar:51820"; endpoint = "flora-6.pub.solar:51820";
publicKey = "jtSR5G2P/nm9s8WrVc26Xc/SQLupRxyXE+5eIeqlsTU="; publicKey = "jtSR5G2P/nm9s8WrVc26Xc/SQLupRxyXE+5eIeqlsTU=";
allowedIPs = ["10.7.6.2/32" "fd00:fae:fae:fae:fae:2::/96"]; allowedIPs = [ "10.7.6.2/32" "fd00:fae:fae:fae:fae:2::/96" ];
persistentKeepalive = 15; persistentKeepalive = 15;
dynamicEndpointRefreshSeconds = 30; dynamicEndpointRefreshSeconds = 30;
} }
{ {
endpoint = "nachtigall.pub.solar:51820"; endpoint = "nachtigall.pub.solar:51820";
publicKey = "qzNywKY9RvqTnDO8eLik75/SHveaSk9OObilDzv+xkk="; publicKey = "qzNywKY9RvqTnDO8eLik75/SHveaSk9OObilDzv+xkk=";
allowedIPs = ["10.7.6.1/32" "fd00:fae:fae:fae:fae:1::/96"]; allowedIPs = [ "10.7.6.1/32" "fd00:fae:fae:fae:fae:1::/96" ];
persistentKeepalive = 15; persistentKeepalive = 15;
dynamicEndpointRefreshSeconds = 30; dynamicEndpointRefreshSeconds = 30;
} }

View file

@ -3,7 +3,8 @@
config, config,
pkgs, pkgs,
... ...
}: let }:
let
cfg = config.pub-solar.wireguard.tunnel; cfg = config.pub-solar.wireguard.tunnel;
in { in {
options.pub-solar.wireguard.tunnel = { options.pub-solar.wireguard.tunnel = {
@ -36,10 +37,10 @@ in {
}; };
}; };
config = lib.mkIf (lib.length cfg.ownIPs != 0) { config = lib.mkIf (lib.length cfg.ownIPs != 0){
networking.firewall.allowedUDPPorts = [51820]; networking.firewall.allowedUDPPorts = [51820];
systemd.network.wait-online.ignoredInterfaces = ["wg-tunnel"]; systemd.network.wait-online.ignoredInterfaces = [ "wg-tunnel" ];
systemd.targets.wireguard-wg-tunnel = { systemd.targets.wireguard-wg-tunnel = {
wantedBy = lib.mkForce []; wantedBy = lib.mkForce [];
@ -72,22 +73,11 @@ in {
}; };
networking.wireguard.interfaces = let networking.wireguard.interfaces = let
splitEndpoint = lib.strings.splitString ":" cfg.peer.endpoint; splitEndpoint = (lib.strings.splitString ":" cfg.peer.endpoint);
joinIPV6 = p: ip: joinIPV6 = p: ip: p + (if (lib.stringLength ip > 0) then ":" else "") + ip;
p
+ (
if (lib.stringLength ip > 0)
then ":"
else ""
)
+ ip;
isIPV4 = lib.length splitEndpoint < 3; isIPV4 = lib.length splitEndpoint < 3;
ipFlag = ipFlag = if isIPV4 then "-4" else "-6";
if isIPV4 endpointIP = (if isIPV4
then "-4"
else "-6";
endpointIP = (
if isIPV4
then lib.elemAt splitEndpoint 0 then lib.elemAt splitEndpoint 0
else lib.lists.fold joinIPV6 "" ((lib.lists.take ((lib.length splitEndpoint) - 1)) splitEndpoint) else lib.lists.fold joinIPV6 "" ((lib.lists.take ((lib.length splitEndpoint) - 1)) splitEndpoint)
); );
@ -97,36 +87,24 @@ in {
listenPort = 51820; listenPort = 51820;
ips = cfg.ownIPs; ips = cfg.ownIPs;
privateKeyFile = cfg.privateKeyFile; privateKeyFile = cfg.privateKeyFile;
postSetup = postSetup = ''
''
defaultRoute=$(${pkgs.iproute2}/bin/ip ${ipFlag} r | ${pkgs.gnugrep}/bin/grep "default via" | head -n 1 | ${pkgs.gawk}/bin/awk '{ print $3 " " $4 " " $5 }') defaultRoute=$(${pkgs.iproute2}/bin/ip ${ipFlag} r | ${pkgs.gnugrep}/bin/grep "default via" | head -n 1 | ${pkgs.gawk}/bin/awk '{ print $3 " " $4 " " $5 }')
${pkgs.iproute2}/bin/ip ${ipFlag} route add "${endpointIPStripped}${ ${pkgs.iproute2}/bin/ip ${ipFlag} route add "${endpointIPStripped}${if isIPV4 then "/32" else "/128"}" metric 256 via $defaultRoute
if isIPV4
then "/32"
else "/128"
}" metric 256 via $defaultRoute
ip -4 route delete default dev wg-tunnel || true ip -4 route delete default dev wg-tunnel || true
ip -4 route add default dev wg-tunnel metric 512 ip -4 route add default dev wg-tunnel metric 512
ip -6 route delete default dev wg-tunnel || true ip -6 route delete default dev wg-tunnel || true
ip -6 route add default dev wg-tunnel metric 512 ip -6 route add default dev wg-tunnel metric 512
'' '' + (if cfg.useDNS
+ (
if cfg.useDNS
then ''printf "nameserver 10.64.0.1" | resolvconf -a wg-tunnel -m 0 -x'' then ''printf "nameserver 10.64.0.1" | resolvconf -a wg-tunnel -m 0 -x''
else "" else "");
); postShutdown = ''
postShutdown =
''
addedRoute=$(${pkgs.iproute2}/bin/ip ${ipFlag} r | ${pkgs.gnugrep}/bin/grep "${endpointIPStripped}" | head -n 1 | ${pkgs.gawk}/bin/awk '{ print $1 " " $2 " " $3 " " $4 " " $5 }') addedRoute=$(${pkgs.iproute2}/bin/ip ${ipFlag} r | ${pkgs.gnugrep}/bin/grep "${endpointIPStripped}" | head -n 1 | ${pkgs.gawk}/bin/awk '{ print $1 " " $2 " " $3 " " $4 " " $5 }')
if [ -n "$addedRoute" ]; then if [ -n "$addedRoute" ]; then
${pkgs.iproute2}/bin/ip ${ipFlag} route delete $addedRoute ${pkgs.iproute2}/bin/ip ${ipFlag} route delete $addedRoute
fi fi
'' '' + (if cfg.useDNS
+ (
if cfg.useDNS
then ''resolvconf -d wg-tunnel -f'' then ''resolvconf -d wg-tunnel -f''
else "" else "");
);
peers = [ peers = [
{ {
publicKey = cfg.peer.publicKey; publicKey = cfg.peer.publicKey;

View file

@ -12,6 +12,6 @@ in {
users.users."${psCfg.user.name}" = { users.users."${psCfg.user.name}" = {
extraGroups = ["wireshark"]; extraGroups = ["wireshark"];
packages = [pkgs.wireshark]; packages = [ pkgs.wireshark ];
}; };
} }

View file

@ -5,16 +5,16 @@
}: { }: {
flake = { flake = {
nixosModules = rec { nixosModules = rec {
overlays = {...}: { overlays = ({ ... }: {
nixpkgs.overlays = [ nixpkgs.overlays = [
inputs.deno2nix.overlays.default inputs.deno2nix.overlays.default
inputs.nixd.overlays.default inputs.nixd.overlays.default
inputs.invoiceplane-template.overlays.default inputs.invoiceplane-template.overlays.default
(final: prev: let (final: prev: let
unstable = import inputs.nixpkgs-unstable {system = prev.system;}; unstable = import inputs.nixpkgs-unstable { system = prev.system; };
master = import inputs.nixpkgs-master {system = prev.system;}; master = import inputs.nixpkgs-master { system = prev.system; };
authelia-438 = import inputs.authelia-438 {system = prev.system;}; authelia-438 = import inputs.authelia-438 { system = prev.system; };
in { in {
factorio-headless = master.factorio-headless; factorio-headless = master.factorio-headless;
paperless-ngx = unstable.paperless-ngx; paperless-ngx = unstable.paperless-ngx;
@ -59,7 +59,7 @@
}; };
}) })
]; ];
}; });
}; };
}; };
} }

View file

@ -1,3 +1,3 @@
final: prev: { final: prev: {
element-desktop = prev.element-desktop.override {electron = prev.electron_28;}; element-desktop = prev.element-desktop.override { electron = prev.electron_28; };
} }

View file

@ -1,10 +1,6 @@
# This file was generated by nvfetcher, please do not modify it manually. # This file was generated by nvfetcher, please do not modify it manually.
{ fetchgit, fetchurl, fetchFromGitHub, dockerTools }:
{ {
fetchgit,
fetchurl,
fetchFromGitHub,
dockerTools,
}: {
b12f-io-nvfetcher = { b12f-io-nvfetcher = {
pname = "b12f-io-nvfetcher"; pname = "b12f-io-nvfetcher";
version = "38adb94ce69d8807ea2e36f57abe08091192b31c"; version = "38adb94ce69d8807ea2e36f57abe08091192b31c";

View file

@ -1,13 +1,13 @@
self: self:
with self; '' with self; ''
status=$(cat /sys/class/power_supply/BAT0/status) status=$(cat /sys/class/power_supply/BAT0/status)
if [ $status != "Discharging" ]; then if [ $status != "Discharging" ]; then
exit 0 exit 0
fi fi
capacity=$(cat /sys/class/power_supply/BAT0/capacity) capacity=$(cat /sys/class/power_supply/BAT0/capacity)
if [ $capacity -lt 20 ]; then if [ $capacity -lt 20 ]; then
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus
${libnotify}/bin/notify-send -u critical "Battery ''${capacity}%" ${libnotify}/bin/notify-send -u critical "Battery ''${capacity}%"
fi fi
'' ''

View file

@ -5,14 +5,8 @@ with prev; {
# then, call packages with `final.callPackage` # then, call packages with `final.callPackage`
check-battery = writeShellScriptBin "check-battery" (import ./check-battery.nix final); check-battery = writeShellScriptBin "check-battery" (import ./check-battery.nix final);
concourse = import ./concourse.nix final; concourse = import ./concourse.nix final;
element-b12f = writeShellScriptBin "element-b12f" (import ./element-desktop.nix { element-b12f = writeShellScriptBin "element-b12f" (import ./element-desktop.nix { inherit final; profile = "b12f"; });
inherit final; element-mezza = writeShellScriptBin "element-mezza" (import ./element-desktop.nix { inherit final; profile = "mezza"; });
profile = "b12f";
});
element-mezza = writeShellScriptBin "element-mezza" (import ./element-desktop.nix {
inherit final;
profile = "mezza";
});
fetch-hostingde-invoices = import ./fetch-hostingde-invoices final; fetch-hostingde-invoices = import ./fetch-hostingde-invoices final;
import-gtk-settings = writeShellScriptBin "import-gtk-settings" (import ./import-gtk-settings.nix final); import-gtk-settings = writeShellScriptBin "import-gtk-settings" (import ./import-gtk-settings.nix final);
lgcl = writeShellScriptBin "lgcl" (import ./lgcl.nix final); lgcl = writeShellScriptBin "lgcl" (import ./lgcl.nix final);

View file

@ -1,7 +1,4 @@
{ { final, profile }:
final,
profile,
}:
with final; '' with final; ''
${element-desktop}/bin/element-desktop --profile=${profile} ${element-desktop}/bin/element-desktop --profile=${profile}
'' ''

View file

@ -1,5 +1,4 @@
self: self: self.deno2nix.mkExecutable {
self.deno2nix.mkExecutable {
pname = "fetch-hostingde-invoices"; pname = "fetch-hostingde-invoices";
version = "0.1.0"; version = "0.1.0";

View file

@ -1,4 +1,5 @@
{lib, ...}: { { lib, ... }:
{
flake = { flake = {
publicKeys = [ publicKeys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCmXpOU6vzQiVSSYCoxHYv7wDxC63Qg3dxlAMR6AOzwIABCU5PFFNcO0NWYms/YR7MOViorl+19LCLRABar9JgHU1n+uqxKV6eGph3OPeMp5sN8LAh7C9N+TZj8iJzBxQ3ch+Z/LdmLRwYNJ7KSUI+gwGK6xRS3+z1022Y4P0G0sx7IeCBl4lealQEIIF10ZOfjUdBcLQar7XTc5AxyGKnHCerXHRtccCoadLQujk0AvPXbv3Ma4JwX9X++AnCWRWakqS5UInu2tGuZ/6Hrjd2a9AKWjTaBVDcbYqCvY4XVuMj2/A2bCceFBaoi41apybSk26FSFTU4qiEUNQ6lxeOwG4+1NCXyHe2bGI4VyoxinDYa8vLLzXIRfTRA0qoGfCweXNeWPf0jMqASkUKaSOH5Ot7O5ps34r0j9pWzavDid8QeKJPyhxKuF1a5G4iBEZ0O9vuti60dPSjJPci9oTxbune2/jb7Sa0yO06DtLFJ2ncr5f70s/BDxKk4XIwQLy+KsvzlQEGdY8yA6xv28bOGxL3sQ0HE2pDTsvIbAisVOKzdJeolStL9MM5W8Hg0r/KkGj2bg0TfoRp1xHV9hjKkvJrsQ6okaPvNFeZq0HXzPhWMOVQ+/46z80uaQ1ByRLr3FTwuWJ7F/73ndfxiq6bDE4z2Ji0vOjeWJm6HCxTdGw== id_bbcom" "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCmXpOU6vzQiVSSYCoxHYv7wDxC63Qg3dxlAMR6AOzwIABCU5PFFNcO0NWYms/YR7MOViorl+19LCLRABar9JgHU1n+uqxKV6eGph3OPeMp5sN8LAh7C9N+TZj8iJzBxQ3ch+Z/LdmLRwYNJ7KSUI+gwGK6xRS3+z1022Y4P0G0sx7IeCBl4lealQEIIF10ZOfjUdBcLQar7XTc5AxyGKnHCerXHRtccCoadLQujk0AvPXbv3Ma4JwX9X++AnCWRWakqS5UInu2tGuZ/6Hrjd2a9AKWjTaBVDcbYqCvY4XVuMj2/A2bCceFBaoi41apybSk26FSFTU4qiEUNQ6lxeOwG4+1NCXyHe2bGI4VyoxinDYa8vLLzXIRfTRA0qoGfCweXNeWPf0jMqASkUKaSOH5Ot7O5ps34r0j9pWzavDid8QeKJPyhxKuF1a5G4iBEZ0O9vuti60dPSjJPci9oTxbune2/jb7Sa0yO06DtLFJ2ncr5f70s/BDxKk4XIwQLy+KsvzlQEGdY8yA6xv28bOGxL3sQ0HE2pDTsvIbAisVOKzdJeolStL9MM5W8Hg0r/KkGj2bg0TfoRp1xHV9hjKkvJrsQ6okaPvNFeZq0HXzPhWMOVQ+/46z80uaQ1ByRLr3FTwuWJ7F/73ndfxiq6bDE4z2Ji0vOjeWJm6HCxTdGw== id_bbcom"

View file

@ -12,19 +12,12 @@ with lib; let
cacheHome = xdg.cacheHome; cacheHome = xdg.cacheHome;
maildirBasePath = "/home/${psCfg.user.name}/Mail"; maildirBasePath = "/home/${psCfg.user.name}/Mail";
generateMailAccount = args @ {address, ...}: generateMailAccount = args@{ address, ... }: rec {
rec {
inherit address; inherit address;
realName = realName = if (args ? "fullName") then args.fullName else psCfg.user.fullName;
if (args ? "fullName")
then args.fullName
else psCfg.user.fullName;
signature = { signature = {
showSignature = "append"; showSignature = "append";
text = text = if (args ? "emptysignature") then "" else builtins.readFile (./.config/neomutt + "/${builtins.replaceStrings ["@"] ["_"] address}.signature");
if (args ? "emptysignature")
then ""
else builtins.readFile (./.config/neomutt + "/${builtins.replaceStrings ["@"] ["_"] address}.signature");
}; };
folders = { folders = {
@ -51,7 +44,7 @@ with lib; let
offlineimap.enable = true; offlineimap.enable = true;
imapnotify = { imapnotify = {
enable = true; enable = true;
boxes = ["INBOX"]; boxes = [ "INBOX" ];
onNotify = "${pkgs.offlineimap}/bin/offlineimap -a ${address}"; onNotify = "${pkgs.offlineimap}/bin/offlineimap -a ${address}";
onNotifyPost = "${pkgs.libnotify}/bin/notify-send '${address} has new mail'"; onNotifyPost = "${pkgs.libnotify}/bin/notify-send '${address} has new mail'";
}; };
@ -71,12 +64,7 @@ with lib; let
+Trash +Trash
''; '';
}; };
} } // (if args ? "config" then args.config else {});
// (
if args ? "config"
then args.config
else {}
);
in { in {
users.users."${psCfg.user.name}".packages = with pkgs; [ users.users."${psCfg.user.name}".packages = with pkgs; [
w3m w3m
@ -98,8 +86,7 @@ in {
accounts.email = { accounts.email = {
inherit maildirBasePath; inherit maildirBasePath;
accounts = with flake.self.lib; accounts = with flake.self.lib; lib.lists.foldr (item: set: (set // { "${item.address}" = generateMailAccount item; })) {} [
lib.lists.foldr (item: set: (set // {"${item.address}" = generateMailAccount item;})) {} [
{ {
address = mkEmailAddress "hello" "benjaminbaedorf.eu"; address = mkEmailAddress "hello" "benjaminbaedorf.eu";
host = "mail.hosting.de"; host = "mail.hosting.de";
@ -152,7 +139,7 @@ in {
emptysignature = true; emptysignature = true;
} }
{ {
fullname = "hwd" + "zz"; fullname = "hwd"+ "zz";
address = mkEmailAddress "mail" "h" + "w" + "dz" + "z.net"; address = mkEmailAddress "mail" "h" + "w" + "dz" + "z.net";
host = "mail.h" + "w" + "dz" + "z.net"; host = "mail.h" + "w" + "dz" + "z.net";
emptysignature = true; emptysignature = true;
@ -167,133 +154,36 @@ in {
enable = true; enable = true;
binds = [ binds = [
# Moving around # Moving around
{ { map = ["generic"]; key = "g"; action = "noop"; }
map = ["generic"]; { map = ["generic"]; key = "gg"; action = "first-entry"; }
key = "g"; { map = ["generic" "index"]; key = "G"; action = "last-entry"; }
action = "noop"; { map = ["generic" "index"]; key = "i"; action = "previous-entry"; }
} { map = ["generic" "index"]; key = "k"; action = "next-entry"; }
{ { map = ["pager" "index"]; key = "d"; action = "noop"; }
map = ["generic"]; { map = ["pager" "index"]; key = "dd"; action = "delete-message"; }
key = "gg"; { map = ["pager"]; key = "i"; action = "previous-line"; }
action = "first-entry"; { map = ["pager"]; key = "k"; action = "next-line"; }
} { map = ["pager"]; key = "I"; action = "previous-entry"; }
{ { map = ["pager"]; key = "K"; action = "next-entry"; }
map = ["generic" "index"];
key = "G";
action = "last-entry";
}
{
map = ["generic" "index"];
key = "i";
action = "previous-entry";
}
{
map = ["generic" "index"];
key = "k";
action = "next-entry";
}
{
map = ["pager" "index"];
key = "d";
action = "noop";
}
{
map = ["pager" "index"];
key = "dd";
action = "delete-message";
}
{
map = ["pager"];
key = "i";
action = "previous-line";
}
{
map = ["pager"];
key = "k";
action = "next-line";
}
{
map = ["pager"];
key = "I";
action = "previous-entry";
}
{
map = ["pager"];
key = "K";
action = "next-entry";
}
{ { map = ["pager"]; key = "r"; action = "noop"; }
map = ["pager"]; { map = ["pager"]; key = "rr"; action = "reply"; }
key = "r"; { map = ["pager"]; key = "ra"; action = "group-reply"; }
action = "noop"; { map = ["pager"]; key = "rn"; action = "group-chat-reply"; }
} { map = ["pager"]; key = "rl"; action = "list-reply"; }
{
map = ["pager"];
key = "rr";
action = "reply";
}
{
map = ["pager"];
key = "ra";
action = "group-reply";
}
{
map = ["pager"];
key = "rn";
action = "group-chat-reply";
}
{
map = ["pager"];
key = "rl";
action = "list-reply";
}
# Threads # Threads
{ { map = ["browser" "pager" "index"]; key = "N"; action = "search-opposite"; }
map = ["browser" "pager" "index"]; { map = ["pager" "index"]; key = "dT"; action = "delete-thread"; }
key = "N"; { map = ["pager" "index"]; key = "dt"; action = "delete-subthread"; }
action = "search-opposite"; { map = ["pager" "index"]; key = "g"; action = "noop"; }
} { map = ["pager" "index"]; key = "gt"; action = "next-thread"; }
{ { map = ["pager" "index"]; key = "gT"; action = "previous-thread"; }
map = ["pager" "index"]; { map = ["index"]; key = "za"; action = "collapse-thread"; }
key = "dT"; { map = ["index"]; key = "zA"; action = "collapse-all"; }
action = "delete-thread";
}
{
map = ["pager" "index"];
key = "dt";
action = "delete-subthread";
}
{
map = ["pager" "index"];
key = "g";
action = "noop";
}
{
map = ["pager" "index"];
key = "gt";
action = "next-thread";
}
{
map = ["pager" "index"];
key = "gT";
action = "previous-thread";
}
{
map = ["index"];
key = "za";
action = "collapse-thread";
}
{
map = ["index"];
key = "zA";
action = "collapse-all";
}
]; ];
macros = macros = [
[
# Enable URL opening # Enable URL opening
{ {
map = ["index" "pager"]; map = ["index" "pager"];
@ -322,8 +212,7 @@ in {
key = "\\Ca"; key = "\\Ca";
action = ''<tag-pattern>~N<enter><tag-prefix><clear-flag>N<untag-pattern>.<enter>" "Mark all as read''; action = ''<tag-pattern>~N<enter><tag-prefix><clear-flag>N<untag-pattern>.<enter>" "Mark all as read'';
} }
] ] ++ lib.lists.imap1 (i: address: {
++ lib.lists.imap1 (i: address: {
map = ["index" "pager"]; map = ["index" "pager"];
key = "<F${builtins.toString i}>"; key = "<F${builtins.toString i}>";
action = ''<sync-mailbox><enter-command>source ${configHome}/neomutt/${address}<enter><change-folder>!<enter>''; action = ''<sync-mailbox><enter-command>source ${configHome}/neomutt/${address}<enter><change-folder>!<enter>'';
@ -362,7 +251,7 @@ in {
services.restic.backups = { services.restic.backups = {
email = { email = {
paths = [maildirBasePath]; paths = [ maildirBasePath ];
initialize = true; initialize = true;
passwordFile = config.age.secrets."restic-password".path; passwordFile = config.age.secrets."restic-password".path;
# See https://www.hosting.de/blog/verschluesselte-backups-mit-rclone-und-restic-in-nextcloud/ # See https://www.hosting.de/blog/verschluesselte-backups-mit-rclone-und-restic-in-nextcloud/

View file

@ -1,4 +1,5 @@
{self, ...}: { { self, ... }:
{
flake = { flake = {
nixosModules = rec { nixosModules = rec {
root = import ./root; root = import ./root;

View file

@ -1,3 +1,4 @@
{...}: { {...}:
{
users.users.root.hashedPassword = "$y$j9T$HihsChALx5fotahvDVhdC/$iQCGUr35quGDDEFg0SGjDBxWzU/kokgOVDX.weRvL80"; users.users.root.hashedPassword = "$y$j9T$HihsChALx5fotahvDVhdC/$iQCGUr35quGDDEFg0SGjDBxWzU/kokgOVDX.weRvL80";
} }