aboutsummaryrefslogtreecommitdiff
path: root/nixos/modules
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules')
-rw-r--r--nixos/modules/backup.nix63
-rw-r--r--nixos/modules/bcg.nix170
-rw-r--r--nixos/modules/default.nix1
-rw-r--r--nixos/modules/desktop.nix244
-rw-r--r--nixos/modules/develop.nix28
-rw-r--r--nixos/modules/gaming.nix31
-rw-r--r--nixos/modules/generic.nix165
-rw-r--r--nixos/modules/home-assistant.nix164
-rw-r--r--nixos/modules/home-assistant/light.nix13
-rw-r--r--nixos/modules/home-assistant/sensors.nix19
-rw-r--r--nixos/modules/hosts.nix1
-rw-r--r--nixos/modules/monitoring.nix64
-rw-r--r--nixos/modules/nixos-system.sh27
-rw-r--r--nixos/modules/openvpn.nix8
-rw-r--r--nixos/modules/packages.nix87
-rw-r--r--nixos/modules/router.nix32
-rw-r--r--nixos/modules/rpi.md25
-rw-r--r--nixos/modules/rpi.nix88
-rw-r--r--nixos/modules/switch.nix6
-rw-r--r--nixos/modules/syncthing.nix163
-rw-r--r--nixos/modules/users.nix79
-rw-r--r--nixos/modules/wifi-adm.nix198
-rw-r--r--nixos/modules/wifi-client.nix2
-rw-r--r--nixos/modules/wifi-spt.nix165
-rw-r--r--nixos/modules/wireguad.nix111
-rw-r--r--nixos/modules/wireguard.nix85
26 files changed, 885 insertions, 1154 deletions
diff --git a/nixos/modules/backup.nix b/nixos/modules/backup.nix
new file mode 100644
index 0000000..3f5042b
--- /dev/null
+++ b/nixos/modules/backup.nix
@@ -0,0 +1,63 @@
+{
+ config,
+ lib,
+ ...
+}: let
+ inherit (builtins) elem readFile readDir;
+ inherit (lib) mkOption types mkIf hasSuffix removeSuffix hasAttr filterAttrs mapAttrs mapAttrs' nameValuePair mergeAttrsList recursiveUpdate;
+
+ servers = ["ridcully"]; # TODO "errol"
+ clients =
+ mapAttrs' (fname: _:
+ nameValuePair (removeSuffix ".pub" fname)
+ (readFile (config.personal-secrets + "/unencrypted/backup/${fname}")))
+ (filterAttrs (n: v: v == "regular" && hasSuffix ".pub" n)
+ (readDir (config.personal-secrets + "/unencrypted/backup")));
+ edpersonal = readFile (config.personal-secrets + "/unencrypted/edpersonal.pub");
+in {
+ options.cynerd = {
+ borgjobs = mkOption {
+ type = with types; attrsOf anything;
+ description = "Job to be backed up for this ";
+ };
+ };
+
+ config = {
+ services.borgbackup = {
+ repos = mkIf (elem config.networking.hostName servers) (
+ mapAttrs (name: key: {
+ path = "/back/${name}";
+ authorizedKeys = [key edpersonal];
+ allowSubRepos = true;
+ })
+ clients
+ );
+
+ jobs = mkIf (hasAttr config.networking.hostName clients) (mergeAttrsList
+ (map (server: (mapAttrs' (n: v:
+ nameValuePair "${server}-${n}"
+ (recursiveUpdate
+ (recursiveUpdate {
+ encryption.mode = "none";
+ prune = {
+ keep = {
+ daily = 7;
+ weekly = 4;
+ monthly = -1;
+ };
+ prefix = n;
+ };
+ }
+ v)
+ {
+ repo = "borg@${server}:./${n}";
+ environment = {
+ BORG_RSH = "ssh -i /run/secrets/borgbackup.key";
+ };
+ archiveBaseName = null;
+ }))
+ config.cynerd.borgjobs))
+ servers));
+ };
+ };
+}
diff --git a/nixos/modules/bcg.nix b/nixos/modules/bcg.nix
deleted file mode 100644
index 626a67f..0000000
--- a/nixos/modules/bcg.nix
+++ /dev/null
@@ -1,170 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}:
-
-with lib;
-
-let
- cfg = config.services.bcg;
- configFile = (pkgs.formats.yaml {}).generate "bcg.conf.yaml" (
- filterAttrsRecursive (n: v: v != null) {
- inherit (cfg) device name mqtt;
- retain_node_messages = cfg.retainNodeMessages;
- qos_node_messages = cfg.qosNodeMessages;
- base_topic_prefix = cfg.baseTopicPrefix;
- automatic_remove_kit_from_names = cfg.automaticRemoveKitFromNames;
- automatic_rename_kit_nodes = cfg.automaticRenameKitNodes;
- automatic_rename_generic_nodes = cfg.automaticRenameGenericNodes;
- automatic_rename_nodes = cfg.automaticRenameNodes;
- }
- );
-in
-{
- options = {
- services.bcg = {
- enable = mkEnableOption "BigClown gateway";
- package = mkPackageOption pkgs [ "python3Packages" "bcg" ] { };
- environmentFiles = mkOption {
- type = types.listOf types.path;
- default = [];
- example = [ "/run/keys/bcg.env" ];
- description = ''
- File to load as environment file. Environment variables from this file
- will be interpolated into the config file using envsubst with this
- syntax: `$ENVIRONMENT` or `''${VARIABLE}`.
- This is useful to avoid putting secrets into the nix store.
- '';
- };
- verbose = mkOption {
- type = types.enum ["CRITICAL" "ERROR" "WARNING" "INFO" "DEBUG"];
- default = "WARNING";
- description = "Verbosity level.";
- };
- device = mkOption {
- type = types.str;
- description = "Device name to configure gateway to use.";
- };
- name = mkOption {
- type = with types; nullOr str;
- default = null;
- description = ''
- Name for the device.
-
- Supported variables:
- * `{ip}` IP address
- * `{id}` The ID of the connected usb-dongle or core-module
-
- `null` can be used for automatic detection from gateway firmware.
- '';
- };
- mqtt = {
- host = mkOption {
- type = types.str;
- default = "127.0.0.1";
- description = "Host where MQTT server is running.";
- };
- port = mkOption {
- type = types.port;
- default = 1883;
- description = "Port of MQTT server.";
- };
- username = mkOption {
- type = with types; nullOr str;
- default = null;
- description = "MQTT server access username.";
- };
- password = mkOption {
- type = with types; nullOr str;
- default = null;
- description = "MQTT server access password.";
- };
- cafile = mkOption {
- type = with types; nullOr str;
- default = null;
- description = "Certificate Authority file for MQTT server access.";
- };
- certfile = mkOption {
- type = with types; nullOr str;
- default = null;
- description = "Certificate file for MQTT server access.";
- };
- keyfile = mkOption {
- type = with types; nullOr str;
- default = null;
- description = "Key file for MQTT server access.";
- };
- };
- retainNodeMessages = mkOption {
- type = types.bool;
- default = false;
- description = "Specify that node messages should be retaied in MQTT broker.";
- };
- qosNodeMessages = mkOption {
- type = types.int;
- default = 1;
- description = "Set the guarantee of MQTT message delivery.";
- };
- baseTopicPrefix = mkOption {
- type = types.str;
- default = "";
- description = "Topic prefix added to all MQTT messages.";
- };
- automaticRemoveKitFromNames = mkOption {
- type = types.bool;
- default = true;
- description = "Automatically remove kits.";
- };
- automaticRenameKitNodes = mkOption {
- type = types.bool;
- default = true;
- description = "Automatically rename kit's nodes.";
- };
- automaticRenameGenericNodes = mkOption {
- type = types.bool;
- default = true;
- description = "Automatically rename generic nodes.";
- };
- automaticRenameNodes = mkOption {
- type = types.bool;
- default = true;
- description = "Automatically rename all nodes.";
- };
- rename = mkOption {
- type = with types; attrsOf str;
- default = {};
- description = "Rename nodes to different name.";
- };
- };
- };
-
- config = mkIf cfg.enable {
- environment.systemPackages = with pkgs; [
- python3Packages.bcg
- python3Packages.bch
- ];
-
- systemd.services.bcg = let
- envConfig = cfg.environmentFiles != [];
- finalConfig = if envConfig
- then "$RUNTIME_DIRECTORY/bcg.config.yaml"
- else configFile;
- in {
- description = "BigClown Gateway";
- wantedBy = [ "multi-user.target" ];
- wants = [ "network-online.target" ] ++ lib.optional config.services.mosquitto.enable "mosquitto.service";
- after = [ "network-online.target" ];
- preStart = ''
- umask 077
- ${pkgs.envsubst}/bin/envsubst -i "${configFile}" -o "${finalConfig}"
- '';
- serviceConfig = {
- EnvironmentFile = cfg.environmentFiles;
- ExecStart="${cfg.package}/bin/bcg -c ${finalConfig} -v ${cfg.verbose}";
- RuntimeDirectory = "bcg";
- };
- };
- };
-}
diff --git a/nixos/modules/default.nix b/nixos/modules/default.nix
index 90a4b58..d45cb0a 100644
--- a/nixos/modules/default.nix
+++ b/nixos/modules/default.nix
@@ -17,6 +17,5 @@ in
// {
default = {
imports = attrValues modules ++ default_modules;
- disabledModules = [ "services/misc/bcg.nix" ];
};
}
diff --git a/nixos/modules/desktop.nix b/nixos/modules/desktop.nix
index 2e67730..06c8215 100644
--- a/nixos/modules/desktop.nix
+++ b/nixos/modules/desktop.nix
@@ -4,7 +4,7 @@
pkgs,
...
}: let
- inherit (lib) mkOption mkIf mkDefault types optionals;
+ inherit (lib) mkOption mkIf types optionals;
cnf = config.cynerd.desktop;
in {
options = {
@@ -23,13 +23,21 @@ in {
};
config = mkIf cnf.enable {
+ hardware = {
+ graphics = {
+ enable = true;
+ enable32Bit = true;
+ };
+ bluetooth.enable = mkIf cnf.laptop true;
+ };
+
programs = {
sway = {
enable = true;
wrapperFeatures.gtk = true;
extraPackages = with pkgs;
[
- gnome.dconf-editor
+ dconf-editor
glib
gsettings-desktop-schemas
sysstat
@@ -41,7 +49,7 @@ in {
myswaylock
alacritty
- gnome.nautilus
+ nautilus
kanshi
wdisplays
@@ -62,18 +70,15 @@ in {
msmtp
notmuch
astroid
- taskwarrior
- vdirsyncer
- #khal
- #khard
+ dodo
+ taskwarrior3
gnupg
pinentry-gnome3
pinentry-curses
(pass.withExtensions (exts: [
exts.pass-otp
- #exts.pass-audit
+ exts.pass-audit
]))
- nextcloud-client
chromium
ferdium
@@ -97,16 +102,16 @@ in {
id3lib
vlc
mpv
- youtube-dl
+ yt-dlp
spotify
nordic
nordzy-cursor-theme
nordzy-icon-theme
- gnome.adwaita-icon-theme
+ adwaita-icon-theme
vanilla-dmz
sound-theme-freedesktop
- gnome.gnome-characters
+ gnome-characters
gucharmap
(sdcv.withDictionaries [stardict-en-cz stardict-de-cz stardict-cz])
@@ -116,8 +121,8 @@ in {
tigervnc
freerdp
- plasma5Packages.kdeconnect-kde
+ gnome-firmware
hdparm
ethtool
multipath-tools
@@ -135,27 +140,26 @@ in {
gimp
inkscape
blender
- kdenlive
+ tenacity
+ #kdePackages.kdenlive
# GStreamer
- gst_all_1.gst-libav
- gst_all_1.gst-plugins-bad
+ gst_all_1.gstreamer
gst_all_1.gst-plugins-base
gst_all_1.gst-plugins-good
+ gst_all_1.gst-plugins-bad
gst_all_1.gst-plugins-ugly
- gst_all_1.gst-plugins-viperfx
+ gst_all_1.gst-plugins-rs
+ gst_all_1.gst-libav
+ gst_all_1.gst-vaapi
# Writing
typst
- typst-fmt
+ typstfmt
typst-live
- typst-lsp
+ tinymist
vale
- # Gnome utils
- gnome-firmware
- #gaphor
-
# CAD
freecad
kicad
@@ -168,76 +172,132 @@ in {
acpi
]);
};
+
firefox = {
enable = true;
languagePacks = ["en-US" "cs"];
nativeMessagingHosts.packages = with pkgs; [browserpass];
};
+
light.enable = mkIf cnf.laptop true;
+
nix-ld = {
enable = true;
libraries = with pkgs; [xorg.libXpm];
};
- };
- xdg.portal = {
- enable = true;
- wlr.enable = true;
- extraPortals = with pkgs; [xdg-desktop-portal-gtk];
- };
- xdg.mime.defaultApplications = {
- "text/html" = ["firefox.desktop"];
- "application/pdf" = ["org.pwmt.zathura.desktop"];
- "image/jpeg" = ["feh.desktop"];
- "image/png" = ["feh.desktop"];
- "image/svg" = ["feh.desktop"];
- };
- programs.usbkey = {
- enable = true;
- devicesUUID = ["de269652-2070-46b2-84f8-409dc9dd50ee" "16a089d0-a663-4047-bd88-3885dd7fdee2"];
+ usbkey = {
+ enable = true;
+ devicesUUID = [
+ "de269652-2070-46b2-84f8-409dc9dd50ee"
+ "16a089d0-a663-4047-bd88-3885dd7fdee2"
+ ];
+ };
+
+ gnupg.agent = {
+ enable = true;
+ enableSSHSupport = true;
+ enableBrowserSocket = true;
+ };
+
+ kdeconnect.enable = true;
};
- programs.gnupg.agent = {
- enable = true;
- enableSSHSupport = true;
- enableBrowserSocket = true;
+ xdg = {
+ portal = {
+ enable = true;
+ wlr.enable = true;
+ extraPortals = with pkgs; [xdg-desktop-portal-gtk];
+ };
+ mime.defaultApplications = {
+ "text/html" = ["firefox.desktop"];
+ "application/pdf" = ["org.pwmt.zathura.desktop"];
+ "image/jpeg" = ["feh.desktop"];
+ "image/png" = ["feh.desktop"];
+ "image/svg" = ["feh.desktop"];
+ };
};
- services.dbus.packages = [pkgs.gcr];
- programs.kdeconnect.enable = true;
+ services = {
+ # Autologin on the first TTY
+ getty = {
+ extraArgs = ["--skip-login"];
+ loginProgram = "${pkgs.bash}/bin/sh";
+ loginOptions = toString (pkgs.writeText "login-program.sh" ''
+ if [[ "$(tty)" == '/dev/tty1' ]]; then
+ ${pkgs.shadow}/bin/login -f cynerd;
+ else
+ ${pkgs.shadow}/bin/login;
+ fi
+ '');
+ };
+
+ gpm.enable = true; # mouse in buffer
+ udev.extraRules = ''
+ ACTION=="add|change", KERNEL=="sd*[!0-9]", ATTR{queue/scheduler}="bfq"
+ '';
+ xserver.xkb.options = "grp:alt_shift_toggle,caps:escape";
- services.pipewire = {
- enable = true;
- alsa.enable = true;
- alsa.support32Bit = true;
- pulse.enable = true;
- extraConfig.pipewire."10-zeroconf" = {
- "context.modules" = [{name = "libpipewire-module-zeroconf-discover";}];
+ # Gnome crypto services (GnuPG)
+ dbus.packages = [pkgs.gcr];
+
+ pipewire = {
+ enable = true;
+ alsa.enable = true;
+ alsa.support32Bit = true;
+ pulse.enable = true;
+ configPackages = [
+ (pkgs.writeTextDir "share/pipewire/pipewire.conf.d/10-zeroconf-discover.conf" ''
+ context.modules = [
+ { name = libpipewire-module-zeroconf-discover
+ args = { }
+ }
+ ]
+ '')
+ ];
};
- };
- security.rtkit.enable = true;
- services.printing = {
- enable = true;
- drivers = with pkgs; [
- gutenprint
- gutenprintBin
- cnijfilter2
- ];
+ upower.enable = true;
+ hardware.openrgb = {
+ enable = true;
+ package = pkgs.openrgb-with-all-plugins;
+ };
+
+ printing = {
+ enable = true;
+ drivers = with pkgs; [
+ gutenprint
+ gutenprintBin
+ cnijfilter2
+ ];
+ };
+ avahi.enable = true;
+ samba-wsdd = {
+ enable = true;
+ discovery = true;
+ };
+ davfs2.enable = true;
+
+ locate.enable = true;
+
+ gnome = {
+ at-spi2-core.enable = true;
+ gnome-keyring.enable = true;
+ gnome-online-accounts.enable = true;
+ };
};
- services.upower.enable = mkDefault cnf.laptop;
+ # Beneficial for Pipewire
+ security.rtkit.enable = true;
- services.avahi.enable = true;
- services.samba-wsdd = {
- enable = true;
- discovery = true;
+ # Local share (avahi, samba)
+ networking.firewall = {
+ allowedTCPPorts = [5357];
+ allowedUDPPorts = [3702];
};
- networking.firewall.allowedTCPPorts = [5357];
- networking.firewall.allowedUDPPorts = [3702];
fonts.packages = with pkgs; [
- (nerdfonts.override {fonts = ["Hack"];})
+ nerd-fonts.hack
arkpandora_ttf
corefonts
dejavu_fonts
@@ -253,52 +313,12 @@ in {
unifont
];
- services.udev.extraRules = ''
- ACTION=="add|change", KERNEL=="sd*[!0-9]", ATTR{queue/scheduler}="bfq"
- '';
- hardware.opengl = {
- driSupport = true;
- driSupport32Bit = true;
- };
-
- hardware.bluetooth.enable = mkIf cnf.laptop true;
-
- services.hardware.openrgb = {
- enable = true;
- package = pkgs.openrgb-with-all-plugins;
- };
-
documentation = {
enable = true;
man.enable = true;
info.enable = true;
};
- services.snapper.configs = {
- home = {
- SUBVOLUME = "/home";
- ALLOW_GROUPS = ["users"];
- TIMELINE_CREATE = true;
- TIMELINE_CLEANUP = true;
- };
- };
-
- # Autologin on the first TTY
- services.getty = {
- extraArgs = ["--skip-login"];
- loginProgram = "${pkgs.bash}/bin/sh";
- loginOptions = toString (pkgs.writeText "login-program.sh" ''
- if [[ "$(tty)" == '/dev/tty1' ]]; then
- ${pkgs.shadow}/bin/login -f cynerd;
- else
- ${pkgs.shadow}/bin/login;
- fi
- '');
- };
-
- # Leds group is required for light
- users.users.cynerd.extraGroups = ["leds"];
-
# VTI settings
console = {
colors = [
@@ -322,12 +342,6 @@ in {
earlySetup = true;
useXkbConfig = true;
};
- services.xserver.xkb.options = "grp:alt_shift_toggle,caps:escape";
- services.gpm.enable = true;
-
- services.locate.enable = true;
-
- services.davfs2.enable = true;
# Support running app images
boot.binfmt.registrations.appimage = {
diff --git a/nixos/modules/develop.nix b/nixos/modules/develop.nix
index 25c40c3..6444473 100644
--- a/nixos/modules/develop.nix
+++ b/nixos/modules/develop.nix
@@ -21,9 +21,10 @@ in {
# Tools
gitlint
tig
+ gitg
gource
- hub
- github-cli # Git
+ glab
+ github-cli
wlc # Weblate
cloc
openssl
@@ -41,25 +42,28 @@ in {
dev
cachix
nurl
- nix-universal-prefetch
nil
+ nixfmt-rfc-style
alejandra
statix
deadnix
agenix
+ nix-tree
# Shell
dash # Posix shell
bats
shellcheck
shfmt
- nodePackages.bash-language-server
+ bash-language-server
jq
yq
fq
# C
clang-tools
+ massif-visualizer
+ qcachegrind
# Python
(python3.withPackages (pypkgs:
@@ -74,10 +78,12 @@ in {
mypy
scipy
+ statsmodels
sympy
pygraphviz
matplotlib
+ seaborn
plotly
pygal
@@ -101,6 +107,9 @@ in {
pyserial
pylibftdi
+ pyusb
+ usbtmc
+
pylxd
selenium
]))
@@ -119,6 +128,9 @@ in {
# Julia
julia
+ # XML
+ libxml2
+
# Qemmu
qemu
virt-manager
@@ -148,12 +160,15 @@ in {
stdmanpages
# SHV
- shvcli
+ (shvcli.withPlugins [python3Packages.shvcli-ell])
# Images
imagemagick
];
- programs.wireshark.package = pkgs.wireshark;
+ programs.wireshark = {
+ enable = true;
+ package = pkgs.wireshark;
+ };
documentation = {
nixos = {
@@ -169,6 +184,7 @@ in {
SUBSYSTEMS=="usb", ATTRS{idVendor}=="a600", ATTRS{idProduct}=="a003", MODE:="0660", GROUP="develop", SYMLINK+="aix_forte_%n"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0105", MODE:="0660", GROUP="develop", SYMLINK+="jlink_%n"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2111", MODE:="0660", GROUP="develop", SYMLINK+="cmsip_dap_%n"
+ SUBSYSTEMS=="usb", ATTRS{idVendor}=="1ab1", ATTRS{idProduct}=="0e11", MODE:="0660", GROUP="develop"
'';
virtualisation = {
diff --git a/nixos/modules/gaming.nix b/nixos/modules/gaming.nix
index 64af068..6e25320 100644
--- a/nixos/modules/gaming.nix
+++ b/nixos/modules/gaming.nix
@@ -18,7 +18,14 @@ in {
config = mkIf cnf {
cynerd.desktop.enable = true;
- environment.systemPackages = [pkgs.heroic];
+ environment.systemPackages = with pkgs; [
+ heroic
+ prismlauncher
+ ];
+
+ nixpkgs.config.permittedInsecurePackages = [
+ "SDL_ttf-2.0.11" # TODO
+ ];
programs.steam = {
enable = true;
@@ -31,8 +38,28 @@ in {
with pkgs; [
ncurses
xorg.libXpm
- flac1_3
+ #flac134
+ libopus
+ ];
+ };
+ heroic = pkgs.heroic.override {
+ extraPkgs = pkgs:
+ with pkgs; [
+ ncurses
+ xorg.libXpm
+ #flac134
libopus
+ SDL
+ SDL2_image
+ SDL2_mixer
+ SDL2_ttf
+ SDL_image
+ SDL_mixer
+ SDL_ttf
+ glew110
+ libdrm
+ libidn
+ tbb
];
};
};
diff --git a/nixos/modules/generic.nix b/nixos/modules/generic.nix
index 97391b8..e029058 100644
--- a/nixos/modules/generic.nix
+++ b/nixos/modules/generic.nix
@@ -1,18 +1,13 @@
{
- config,
lib,
pkgs,
...
}: let
- inherit (lib) mkOverride mkDefault optionals;
- isNative = config.nixpkgs.hostPlatform == config.nixpkgs.buildPlatform;
- isArm = config.nixpkgs.hostPlatform.isAarch;
+ inherit (lib) mkOverride mkDefault;
in {
config = {
- system.stateVersion = "24.05";
-
nix = {
- extraOptions = "experimental-features = nix-command flakes repl-flake";
+ extraOptions = "experimental-features = nix-command flakes";
settings = {
auto-optimise-store = true;
substituters = [
@@ -34,8 +29,11 @@ in {
};
boot = {
- loader.systemd-boot.enable = mkOverride 1100 true;
- loader.efi.canTouchEfiVariables = mkDefault true;
+ loader = {
+ systemd-boot.enable = mkOverride 1100 true;
+ efi.canTouchEfiVariables = mkDefault true;
+ grub.enable = mkOverride 1100 false;
+ };
kernelPackages = mkOverride 1100 pkgs.linuxPackages_latest;
kernelParams = ["boot.shell_on_fail"];
};
@@ -43,153 +41,11 @@ in {
services.fwupd.enable = mkDefault (pkgs.system == "x86_64-linux");
systemd.oomd.enable = false;
- nixpkgs = {
- config.allowUnfree = true;
- flake = {
- setNixPath = false;
- setFlakeRegistry = false;
- };
- };
- environment.systemPackages = with pkgs;
- [
- git # We need git for this repository to even work
- # Administration tools
- coreutils
- binutils
- psmisc
- progress
- lshw
- file
- vde2
- ldns
- wget
- gnumake
- exfat
- exfatprogs
- ntfs3g
- usbutils
- pciutils
- smartmontools
- parted
-
- # NCurses tools
- htop
- btop
- iotop
- mc
- screen
- tmux
- pv
-
- # ls tools
- tree
- lsof
- strace
-
- sourceHighlight # Colors for less
- unrar
- p7zip
- zip
- unzip
-
- # Network
- netcat
- traceroute
- iftop
- nethogs
- sshfs
- wakeonlan
- speedtest-cli
- librespeed-cli
- termshark
-
- lm_sensors
- ]
- ++ optionals (system == "x86_64-linux") [
- nmap
- ltrace
- ]
- ++ optionals (!isNative) [
- ncdu_1
- ]
- ++ optionals isNative [
- moreutils
- glances
- ncdu
- mlocate
- ];
-
- users = {
- mutableUsers = false;
- groups.cynerd.gid = 1000;
- users = {
- root = {
- hashedPasswordFile = "/run/secrets/root.pass";
- };
- cynerd = {
- group = "cynerd";
- extraGroups = ["users" "wheel" "dialout" "kvm" "uucp" "wireshark"];
- uid = 1000;
- subUidRanges = [
- {
- count = 65534;
- startUid = 10000;
- }
- ];
- subGidRanges = [
- {
- count = 65534;
- startGid = 10000;
- }
- ];
- isNormalUser = true;
- createHome = true;
- shell =
- if isNative
- then pkgs.zsh.out
- else pkgs.bash.out;
- hashedPasswordFile = "/run/secrets/cynerd.pass";
- openssh.authorizedKeys.keyFiles = [
- (config.personal-secrets + "/unencrypted/git-private.pub")
- ];
- };
- };
- };
- programs = {
- zsh = {
- enable = isNative;
- syntaxHighlighting.enable = isNative;
- };
- shellrc = true;
- vim.defaultEditor = isArm;
- neovim = {
- enable = !isArm;
- defaultEditor = true;
- withNodeJs = true;
- };
-
- wireshark.enable = true;
- };
-
- security.sudo.extraRules = [
- {
- groups = ["wheel"];
- commands = ["ALL"];
- }
- ];
networking = {
nftables.enable = true;
dhcpcd.extraConfig = "controlgroup wheel";
};
- services.openssh = {
- enable = true;
- settings = {
- PasswordAuthentication = false;
- PermitRootLogin = "no";
- };
- };
-
time.timeZone = "Europe/Prague";
i18n.defaultLocale = "en_US.UTF-8";
@@ -204,13 +60,6 @@ in {
})
];
- system.extraSystemBuilderCmds = ''
- substituteAll ${./nixos-system.sh} $out/bin/nixos-system
- chmod +x $out/bin/nixos-system
- '';
-
- programs.fuse.userAllowOther = true;
-
documentation = {
enable = mkDefault false;
doc.enable = mkDefault false;
diff --git a/nixos/modules/home-assistant.nix b/nixos/modules/home-assistant.nix
deleted file mode 100644
index ab16e8a..0000000
--- a/nixos/modules/home-assistant.nix
+++ /dev/null
@@ -1,164 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}: let
- inherit (lib) mkIf mkEnableOption;
-in {
- options = {
- cynerd.home-assistant = mkEnableOption "Enable Home Assistant and Bigclown";
- };
-
- config = mkIf config.cynerd.home-assistant {
- services.mosquitto = {
- enable = true;
- listeners = [
- {
- users = {
- cynerd = {
- acl = ["readwrite #"];
- passwordFile = "/run/secrets/mosquitto.cynerd.pass";
- };
- telegraf = {
- acl = ["read bigclown/node/#"];
- passwordFile = "/run/secrets/mosquitto.telegraf.pass";
- };
- homeassistant = {
- acl = [
- "readwrite homeassistant/#"
- "readwrite bigclown/#"
- "readwrite zigbee2mqtt/#"
- ];
- passwordFile = "/run/secrets/mosquitto.homeassistant.pass";
- };
- bigclown = {
- acl = ["readwrite bigclown/#"];
- passwordFile = "/run/secrets/mosquitto.bigclown.pass";
- };
- zigbee2mqtt = {
- acl = [
- "readwrite homeassistant/#"
- "readwrite zigbee2mqtt/#"
- ];
- passwordFile = "/run/secrets/mosquitto.zigbee2mqtt.pass";
- };
- };
- }
- ];
- };
- networking.firewall.allowedTCPPorts = [
- 1883 # Mosquitto
- ];
-
- services.bcg = {
- enable = true;
- device = "/dev/ttyUSB0";
- baseTopicPrefix = "bigclown/";
- environmentFiles = ["/run/secrets/bigclown.env"];
- mqtt = {
- username = "bigclown";
- password = "\${MQTT_PASSWORD}";
- };
- };
-
- systemd.services.bigclown-leds = {
- description = "Bigclown LEDs control";
- wantedBy = ["multi-user.target"];
- wants = ["mosquitto.service"];
- serviceConfig.ExecStart = "${pkgs.bigclown-leds}/bin/bigclown-leds /run/secrets/bigclown-leds.ini";
- };
-
- services.telegraf.extraConfig = {
- outputs.influxdb_v2 = [
- {
- urls = ["http://cynerd.cz:8086"];
- token = "$INFLUX_TOKEN";
- organization = "personal";
- bucket = "bigclown";
- tagpass.source = ["bigclown"];
- }
- ];
- inputs.mqtt_consumer = let
- consumer = data_type: topics: {
- tags = {source = "bigclown";};
- servers = ["tcp://localhost:1883"];
- inherit topics;
- username = "telegraf";
- password = "$MQTT_PASSWORD";
- data_format = "value";
- inherit data_type;
- topic_parsing = [
- {
- topic = "bigclown/node/+/+/+/+";
- measurement = "_/_/_/_/_/measurement";
- tags = "_/_/device/field/_/_";
- }
- ];
- };
- in [
- (consumer "float" [
- "bigclown/node/+/battery/+/voltage"
- "bigclown/node/+/thermometer/+/temperature"
- "bigclown/node/+/hygrometer/+/relative-humidity"
- "bigclown/node/+/lux-meter/+/illuminance"
- "bigclown/node/+/barometer/+/pressure"
- "bigclown/node/+/pir/+/event-count"
- "bigclown/node/+/push-button/+/event-count"
- ])
- (consumer "boolean" [
- "bigclown/node/+/flood-detector/+/alarm"
- ])
- ];
- processors.pivot = [
- {
- tag_key = "field";
- value_key = "value";
- tagpass.source = ["bigclown"];
- }
- ];
- };
- systemd.services.telegraf.wants = ["mosquitto.service"];
-
- #nixpkgs.config.permittedInsecurePackages = ["openssl-1.1.1w"]; # TODO
- services.home-assistant = {
- enable = false;
- openFirewall = true;
- configDir = "/var/lib/hass";
- config = {
- homeassistant = {
- name = "SPT";
- latitude = "!secret latitude";
- longitude = "!secret longitude";
- elevation = "!secret elevation";
- time_zone = "Europe/Prague";
- country = "CZ";
- };
- http.server_port = 8808;
- mqtt = {
- sensor = import ./home-assistant/sensors.nix;
- light = import ./home-assistant/light.nix;
- };
- default_config = {};
- automation = "!include automations.yaml";
- };
- extraComponents = ["met"];
- package = pkgs.home-assistant.override {
- extraPackages = pkgs:
- with pkgs; [
- securetar
- pyipp
- ];
- packageOverrides = _: super: {
- scapy = super.scapy.override {
- withPlottingSupport = false;
- };
- s3transfer = super.s3transfer.overridePythonAttrs {
- dontUsePytestCheck = true;
- dontUseSetuptoolsCheck = true;
- };
- };
- };
- };
- };
-}
diff --git a/nixos/modules/home-assistant/light.nix b/nixos/modules/home-assistant/light.nix
deleted file mode 100644
index a9d158b..0000000
--- a/nixos/modules/home-assistant/light.nix
+++ /dev/null
@@ -1,13 +0,0 @@
-[
- {
- name = "RGB Osvětlení";
- command_topic = "homeassistant/led-strip";
- brightness_scale = 100;
- brightness_command_topic = "bigclown/node/power-controller:0/led-strip/-/brightness/set";
- #brightness_state_topic = "bigclown/node/power-controller:0/led-strip/-/brightness/set";
- rgb_command_template = ''"#{{"%02x" % red}}{{"%02x" % green}}{{"%02x" % blue}}"'';
- rgb_command_topic = "bigclown/node/power-controller:0/led-strip/-/color/set";
- #rgb_value_template = ''{{int(value[2:4],16)}},{{int(value[5:7],16)}},{{int(value[8:10],16)}}'';
- #rgb_state_topic = "bigclown/node/power-controller:0/led-strip/-/color/set";
- }
-]
diff --git a/nixos/modules/home-assistant/sensors.nix b/nixos/modules/home-assistant/sensors.nix
deleted file mode 100644
index fadd4eb..0000000
--- a/nixos/modules/home-assistant/sensors.nix
+++ /dev/null
@@ -1,19 +0,0 @@
-[
- {
- name = "Teplota";
- state_class = "measurement";
- state_topic = "bigclown/node/climate-monitor:0/thermometer/0:0/temperature";
- unit_of_measurement = "°C";
- }
- {
- name = "Vlhkost";
- state_class = "measurement";
- state_topic = "bigclown/node/climate-monitor:0/hygrometer/0:4/relative-humidity";
- unit_of_measurement = "%";
- }
- {
- name = "Osvětlení";
- state_class = "measurement";
- state_topic = "bigclown/node/climate-monitor:0/lux-meter/0:0/illuminance";
- }
-]
diff --git a/nixos/modules/hosts.nix b/nixos/modules/hosts.nix
index e7ad76b..4b358b8 100644
--- a/nixos/modules/hosts.nix
+++ b/nixos/modules/hosts.nix
@@ -64,6 +64,7 @@ in {
"ridcully" = "10.8.3.60";
"3dprint" = "10.8.3.80";
"mpd" = "10.8.3.51";
+ "printer" = "192.168.1.20";
# Portable
"albert" = "10.8.3.61";
"binky" = "10.8.3.63";
diff --git a/nixos/modules/monitoring.nix b/nixos/modules/monitoring.nix
index 44d0cbb..e8ba2a9 100644
--- a/nixos/modules/monitoring.nix
+++ b/nixos/modules/monitoring.nix
@@ -18,6 +18,11 @@ in {
default = true;
description = "If hardware should be reported";
};
+ drives = mkOption {
+ type = types.bool;
+ default = true;
+ description = "If S.M.A.R.T. should be enabled";
+ };
speedtest = mkOption {
type = types.bool;
default = false;
@@ -30,6 +35,9 @@ in {
# Telegraf configuration
services.telegraf = {
enable = true;
+ package = pkgs.writeShellScriptBin "telegraf" ''
+ exec /run/wrappers/bin/telegraf "$@"
+ '';
environmentFiles = ["/run/secrets/telegraf.env"];
extraConfig = {
agent = {};
@@ -66,20 +74,23 @@ in {
}
];
diskio = [{}];
- net = [{}];
+ net = [{ignore_protocol_stats = false;}];
+ nstat = [{}];
system = [{}];
processes = [{}];
- systemd_units = [{}];
+ systemd_units = [{details = true;}];
wireguard = [{}];
}
- // (optionalAttrs cnf.hw {
- sensors = [{}];
+ // (optionalAttrs cnf.drives {
smart = [
{
path_smartctl = "${pkgs.smartmontools}/bin/smartctl";
use_sudo = true;
}
];
+ })
+ // (optionalAttrs cnf.hw {
+ sensors = [{}];
wireless = [{}];
})
// (optionalAttrs cnf.speedtest {
@@ -115,26 +126,37 @@ in {
];
}
];
+
+ security.wrappers.telegraf = {
+ owner = "root";
+ group = "root";
+ capabilities = "CAP_NET_ADMIN+epi";
+ source = "${pkgs.telegraf}/bin/telegraf";
+ };
})
(mkIf (config.networking.hostName == "lipwig") {
- # InfluxDB
- services.influxdb2.enable = true;
- services.telegraf.extraConfig.inputs.prometheus = {
- urls = ["http://localhost:8086/metrics"];
- };
- # Grafana
- services.grafana = {
- enable = true;
- settings = {
- users.allow_sign_up = false;
- security = {
- admin_user = "cynerd";
- admin_password = "$__file{/run/secrets/grafana.admin.pass}";
- };
- server = {
- http_addr = "";
- http_port = 3000;
+ services = {
+ # InfluxDB
+ influxdb2.enable = true;
+ telegraf.extraConfig.inputs.prometheus = {
+ urls = ["http://localhost:8086/metrics"];
+ };
+ # Grafana
+ grafana = {
+ enable = true;
+ settings = {
+ users.allow_sign_up = false;
+ security = {
+ admin_user = "cynerd";
+ admin_password = "$__file{/run/secrets/grafana.admin.pass}";
+ };
+ server = {
+ domain = "grafana.cynerd.cz";
+ root_url = "https://%(domain)s/";
+ http_addr = "";
+ http_port = 3000;
+ };
};
};
};
diff --git a/nixos/modules/nixos-system.sh b/nixos/modules/nixos-system.sh
deleted file mode 100644
index 7a220bb..0000000
--- a/nixos/modules/nixos-system.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!@shell@
-# Simple script handy to be used for activation
-
-while getopts "s" opt; do
- case "$opt" in
- s)
- if [ ! -v NIXOS_SYSTEM_GNU_SCREEN ]; then
- export NIXOS_SYSTEM_GNU_SCREEN=1
- exec @out@/sw/bin/screen "$0" "$@"
- fi
- ;;
- *)
- echo "Invalid argument: $1" >&2
- exit 1
- ;;
- esac
-done
-shift $((OPTIND - 1))
-
-
-@out@/sw/bin/nix-env --profile /nix/var/nix/profiles/system --set '@out@'
-
-@out@/bin/switch-to-configuration "$@" || {
- echo "Switch failed!" >&2
- read -r _
- exit 1
-}
diff --git a/nixos/modules/openvpn.nix b/nixos/modules/openvpn.nix
index 6a21721..da29dd7 100644
--- a/nixos/modules/openvpn.nix
+++ b/nixos/modules/openvpn.nix
@@ -9,11 +9,6 @@
in {
options = {
cynerd.openvpn = {
- oldpersonal = mkOption {
- type = types.bool;
- default = false;
- description = "My personal old OpenVPN";
- };
elektroline = mkOption {
type = types.bool;
default = false;
@@ -24,9 +19,6 @@ in {
config = {
services.openvpn.servers = {
- oldpersonal = mkIf cnf.oldpersonal {
- config = "config /run/secrets/old.ovpn";
- };
elektroline = mkIf cnf.elektroline {
config = "config /run/secrets/elektroline.ovpn";
up = ''
diff --git a/nixos/modules/packages.nix b/nixos/modules/packages.nix
new file mode 100644
index 0000000..155d8a5
--- /dev/null
+++ b/nixos/modules/packages.nix
@@ -0,0 +1,87 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: let
+ inherit (lib) optionals;
+ isNative = config.nixpkgs.hostPlatform == config.nixpkgs.buildPlatform;
+in {
+ nixpkgs = {
+ config.allowUnfree = true;
+ flake = {
+ setNixPath = false;
+ setFlakeRegistry = false;
+ };
+ };
+ environment.systemPackages = with pkgs;
+ [
+ git # We need git for this repository to even work
+ # Administration tools
+ coreutils
+ binutils
+ psmisc
+ progress
+ lshw
+ file
+ vde2
+ ldns
+ wget
+ gnumake
+ exfat
+ exfatprogs
+ ntfs3g
+ usbutils
+ pciutils
+ smartmontools
+ parted
+
+ # NCurses tools
+ htop
+ btop
+ iotop
+ mc
+ tmux
+
+ # ls tools
+ tree
+ lsof
+ strace
+
+ sourceHighlight # Colors for less
+ unrar
+ p7zip
+ zip
+ unzip
+
+ # Network
+ netcat
+ traceroute
+ iftop
+ nethogs
+ sshfs
+ wakeonlan
+ speedtest-cli
+ librespeed-cli
+ #termshark
+ w3m
+
+ lm_sensors
+ ]
+ ++ optionals (system != "armv7l-linux") [
+ ranger
+ ]
+ ++ optionals (system == "x86_64-linux") [
+ nmap
+ ltrace
+ pv
+ screen
+ ]
+ ++ optionals (!isNative) [
+ ncdu_1
+ ]
+ ++ optionals isNative [
+ ncdu
+ moreutils
+ ];
+}
diff --git a/nixos/modules/router.nix b/nixos/modules/router.nix
index c8b1283..224037b 100644
--- a/nixos/modules/router.nix
+++ b/nixos/modules/router.nix
@@ -44,10 +44,20 @@ in {
'';
description = "Mapping of MAC address to IP address";
};
+ guestStaticLeases = mkOption {
+ type = with types; attrsOf str;
+ default = {};
+ example = ''
+ {"xx:xx:xx:xx:xx:xx" = "10.8.1.30";}
+ '';
+ description = "Mapping of MAC address to IP address";
+ };
};
};
config = mkIf cnf.enable {
+ boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1;
+
networking = {
useNetworkd = true;
firewall = {
@@ -98,17 +108,18 @@ in {
matchConfig.Name = "brlan";
networkConfig.VLAN = ["home" "guest"];
bridgeVLANs = [
- {bridgeVLANConfig.VLAN = 1;}
- {bridgeVLANConfig.VLAN = 2;}
+ {VLAN = 1;}
+ {VLAN = 2;}
];
};
"home" = {
matchConfig.Name = "home";
networkConfig = {
Address = "${cnf.lanIP}/${toString cnf.lanPrefix}";
- IPForward = "yes";
+ IPv4Forwarding = "yes";
DHCPServer = "yes";
DHCPPrefixDelegation = "yes";
+ IPv6Forwarding = "yes";
IPv6SendRA = "yes";
IPv6AcceptRA = "no";
};
@@ -121,10 +132,8 @@ in {
};
dhcpServerStaticLeases =
mapAttrsToList (n: v: {
- dhcpServerStaticLeaseConfig = {
- MACAddress = n;
- Address = v;
- };
+ MACAddress = n;
+ Address = v;
})
cnf.staticLeases;
dhcpPrefixDelegationConfig = {
@@ -137,9 +146,10 @@ in {
matchConfig.Name = "guest";
networkConfig = {
Address = "192.168.1.1/24";
- IPForward = "yes";
+ IPv4Forwarding = "yes";
DHCPServer = "yes";
DHCPPrefixDelegation = "yes";
+ IPv6Forwarding = "yes";
IPv6SendRA = "yes";
IPv6AcceptRA = "no";
};
@@ -150,6 +160,12 @@ in {
EmitDNS = "yes";
DNS = "192.168.1.1";
};
+ dhcpServerStaticLeases =
+ mapAttrsToList (n: v: {
+ MACAddress = n;
+ Address = v;
+ })
+ cnf.guestStaticLeases;
dhcpPrefixDelegationConfig = {
UplinkInterface = cnf.wan;
SubnetId = 2;
diff --git a/nixos/modules/rpi.md b/nixos/modules/rpi.md
new file mode 100644
index 0000000..43b172f
--- /dev/null
+++ b/nixos/modules/rpi.md
@@ -0,0 +1,25 @@
+# Raspberry Pi SD card preparation steps
+
+```
+~# parted /dev/sdx
+(parted) mktable msdos
+(parted) mkpart primary fat16 0% 120M
+(parted) mkpart primary btrfs 120M 100%
+(parted) set 2 boot on
+(parted) quit
+~# mkfs.vfat -F16 /dev/sdx1
+~# mkfs.btrfs /dev/sdx2
+
+~# mount /dev/sdx1 /mnt
+~# nix build .#firmware-HOST
+~# cp -r result/* /mnt/
+~# umount mnt
+
+~# mount /dev/sdx2 /mnt
+~# nix copy --to /mnt .#toplevel-HOST
+~# nix build --print-out-paths .#toplevel-HOST
+~# nix eval .#nixosConfigurations.HOST.config.boot.loader.generic-extlinux-compatible.populateCmd
+"/nix/store/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-extlinux-conf-builder.sh -g 20 -t 5"
+~# /nix/store/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-extlinux-conf-builder.sh -c -d ./mnt/boot
+~# umount mnt
+```
diff --git a/nixos/modules/rpi.nix b/nixos/modules/rpi.nix
new file mode 100644
index 0000000..e4e10fe
--- /dev/null
+++ b/nixos/modules/rpi.nix
@@ -0,0 +1,88 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: let
+ inherit (lib) mkOption types mkMerge mkIf;
+
+ configTxt = pkgs.writeText "config.txt" ''
+ [pi3]
+ kernel=u-boot-rpi3.bin
+
+ # Boot in 64-bit mode.
+ arm_64bit=1
+
+ # Otherwise the serial output will be garbled.
+ core_freq=250
+ # Boot in 64-bit mode.
+ arm_64bit=1
+
+ [all]
+ # U-Boot needs this to work, regardless of whether UART is actually used or not.
+ # Look in arch/arm/mach-bcm283x/Kconfig in the U-Boot tree to see if this is still
+ # a requirement in the future.
+ enable_uart=1
+
+ # Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
+ # when attempting to show low-voltage or overtemperature warnings.
+ avoid_warnings=1
+ '';
+in {
+ options.cynerd.rpi = mkOption {
+ type = with types; nullOr (enum [2 3]);
+ default = null;
+ description = "If machine is RaspberryPi and which version";
+ };
+
+ config = mkMerge [
+ (mkIf (config.cynerd.rpi == 2) {
+ nixpkgs.hostPlatform.system = "armv7l-linux";
+ })
+ (mkIf (config.cynerd.rpi == 3) {
+ nixpkgs.hostPlatform.system = "aarch64-linux";
+ boot.kernelParams = ["console=ttyS1,115200n8"];
+ })
+ (mkIf (config.cynerd.rpi != null) {
+ boot.loader = {
+ systemd-boot.enable = false;
+ efi.canTouchEfiVariables = false;
+ generic-extlinux-compatible.enable = true;
+ };
+ boot.consoleLogLevel = 7;
+
+ fileSystems = {
+ "/" = {
+ device = "/dev/mmcblk0p2";
+ fsType = "ext4";
+ };
+ #"/" = {
+ # device = "/dev/mmcblk0p2";
+ # fsType = "btrfs";
+ # options = ["compress=lzo"];
+ #};
+ "/boot/firmware" = {
+ device = "/dev/mmcblk0p1";
+ fsType = "vfat";
+ options = ["nofail"];
+ };
+ };
+
+ services.journald.extraConfig = ''
+ SystemMaxUse=512M
+ '';
+
+ system.build.firmware = pkgs.callPackage ({stdenvNoCC}:
+ stdenvNoCC.mkDerivation {
+ name = "${config.system.name}-firmware";
+ buildCommand = ''
+ mkdir $out
+ cp -r ${pkgs.raspberrypifw}/share/raspberrypi/boot/* $out/
+ cp ${configTxt} $out/config.txt
+ # TODO support rpi2
+ cp ${pkgs.ubootRaspberryPi3_btrfs}/u-boot.bin $out/u-boot-rpi3.bin
+ '';
+ }) {};
+ })
+ ];
+}
diff --git a/nixos/modules/switch.nix b/nixos/modules/switch.nix
index 37ac687..e74102a 100644
--- a/nixos/modules/switch.nix
+++ b/nixos/modules/switch.nix
@@ -42,10 +42,8 @@ in {
matchConfig.Name = "brlan";
bridgeVLANs = [
{
- bridgeVLANConfig = {
- PVID = 1;
- EgressUntagged = 1;
- };
+ PVID = 1;
+ EgressUntagged = 1;
}
];
networkConfig = {
diff --git a/nixos/modules/syncthing.nix b/nixos/modules/syncthing.nix
index d6b65e6..1148da6 100644
--- a/nixos/modules/syncthing.nix
+++ b/nixos/modules/syncthing.nix
@@ -3,119 +3,96 @@
lib,
...
}: let
- inherit (lib) filterAttrs mkOption types mkIf any mkDefault recursiveUpdate genAttrs;
- cnf = config.cynerd.syncthing;
- inherit (config.networking) hostName;
+ inherit (lib) elem filterAttrs mkIf any mkDefault recursiveUpdate genAttrs;
+
allDevices = [
- "albert"
"binky"
"errol"
"lipwig"
"ridcully"
- "spt-omnia"
- ];
- mediaDevices = [
- "lipwig"
- "binky"
- "errol"
- "ridcully"
- "spt-omnia"
];
bigStorageDevices = [
"errol"
"ridcully"
- "spt-omnia"
];
- filterDevice = filterAttrs (n: v: any (d: d == hostName) v.devices);
-in {
- options = {
- cynerd.syncthing = {
- enable = mkOption {
- type = types.bool;
- default = false;
- description = "My personal Syncthing configuration";
- };
- baseDir = mkOption {
- type = types.str;
- default = "/home/cynerd";
- description = "Base directory for all folders being synced.";
- };
- };
- };
-
- config = mkIf cnf.enable {
+ inherit (config.networking) hostName;
+ baseDir = config.services.syncthing.dataDir;
+ filterDevice = filterAttrs (_: v: any (d: d == hostName) v.devices);
+in {
+ config = mkIf (config.services.syncthing.enable && elem hostName allDevices) {
services.syncthing = {
- enable = any (n: n == hostName) allDevices;
user = mkDefault "cynerd";
+ group = mkDefault "cynerd";
+
key = "/run/secrets/syncthing.key.pem";
cert = "/run/secrets/syncthing.cert.pem";
openDefaultPorts = true;
-
overrideFolders = true;
- folders = filterDevice {
- "${cnf.baseDir}/documents" = {
- label = "Documents";
- id = "documents";
- devices = allDevices;
- ignorePerms = false;
- };
- "${cnf.baseDir}/notes" = {
- label = "Notes";
- id = "notes";
- devices = allDevices;
- ignorePerms = false;
- };
- "${cnf.baseDir}/projects" = {
- label = "Projects";
- id = "projects";
- devices = allDevices;
- ignorePerms = false;
- };
- "${cnf.baseDir}/pictures" = {
- label = "Pictures";
- id = "pictures";
- devices = mediaDevices;
- ignorePerms = false;
- };
- # TODO phone-photos
- "${cnf.baseDir}/music/primary" = {
- label = "Music-primary";
- id = "music-primary";
- devices = mediaDevices;
- ignorePerms = false;
- };
- "${cnf.baseDir}/music/secondary" = {
- label = "Music-secondary";
- id = "music-secondary";
- devices = bigStorageDevices;
- ignorePerms = false;
- };
- "${cnf.baseDir}/music/flac" = {
- label = "Music-flac";
- id = "music-flac";
- devices = bigStorageDevices;
- ignorePerms = false;
- };
- "${cnf.baseDir}/video" = {
- label = "Video";
- id = "video";
- devices = bigStorageDevices;
- ignorePerms = false;
- };
- };
-
overrideDevices = true;
- devices =
- recursiveUpdate
- (genAttrs allDevices (name: {
- id = config.secrets.syncthingIDs."${name}";
- }))
- {
- lipwig.addresses = ["tcp://cynerd.cz"];
+
+ settings = {
+ folders = filterDevice {
+ "${baseDir}/documents" = {
+ label = "Documents";
+ id = "documents";
+ devices = allDevices;
+ ignorePerms = false;
+ };
+ "${baseDir}/notes" = {
+ label = "Notes";
+ id = "notes";
+ devices = allDevices;
+ ignorePerms = false;
+ };
+ "${baseDir}/projects" = {
+ label = "Projects";
+ id = "projects";
+ devices = allDevices;
+ ignorePerms = false;
+ };
+ "${baseDir}/elektroline" = {
+ label = "Elektroline";
+ id = "elektroline";
+ devices = allDevices;
+ ignorePerms = false;
+ };
+ "${baseDir}/pictures" = {
+ label = "Pictures";
+ id = "pictures";
+ devices = bigStorageDevices;
+ ignorePerms = false;
+ };
+ "${baseDir}/music" = {
+ label = "Music";
+ id = "music";
+ devices = bigStorageDevices;
+ ignorePerms = false;
+ };
+ "${baseDir}/video" = {
+ label = "Video";
+ id = "video";
+ devices = bigStorageDevices;
+ ignorePerms = false;
+ };
+ "${baseDir}/turris" = {
+ label = "Turris";
+ id = "turris";
+ devices = bigStorageDevices;
+ ignorePerms = false;
+ };
};
- # TODO phone
+
+ devices =
+ recursiveUpdate
+ (genAttrs allDevices (name: {
+ id = config.secrets.syncthingIDs."${name}";
+ }))
+ {
+ lipwig.addresses = ["tcp://cynerd.cz"];
+ };
+ };
};
};
}
diff --git a/nixos/modules/users.nix b/nixos/modules/users.nix
new file mode 100644
index 0000000..7d0dc77
--- /dev/null
+++ b/nixos/modules/users.nix
@@ -0,0 +1,79 @@
+{
+ pkgs,
+ config,
+ ...
+}: let
+ isNative = config.nixpkgs.hostPlatform == config.nixpkgs.buildPlatform;
+ isArm = pkgs.hostPlatform.isAarch;
+in {
+ users = {
+ mutableUsers = false;
+ groups.cynerd.gid = 1000;
+ users = {
+ root = {
+ hashedPasswordFile = "/run/secrets/root.pass";
+ };
+ cynerd = {
+ group = "cynerd";
+ extraGroups = ["users" "wheel" "video" "dialout" "kvm" "uucp" "wireshark" "leds"];
+ uid = 1000;
+ subUidRanges = [
+ {
+ count = 65534;
+ startUid = 10000;
+ }
+ ];
+ subGidRanges = [
+ {
+ count = 65534;
+ startGid = 10000;
+ }
+ ];
+ isNormalUser = true;
+ createHome = true;
+ shell =
+ if isNative
+ then pkgs.zsh.out
+ else pkgs.bash.out;
+ hashedPasswordFile = "/run/secrets/cynerd.pass";
+ openssh.authorizedKeys.keyFiles = [
+ (config.personal-secrets + "/unencrypted/git-private.pub")
+ ];
+ };
+ };
+ };
+
+ security.sudo.extraRules = [
+ {
+ groups = ["wheel"];
+ commands = ["ALL"];
+ }
+ ];
+
+ services.openssh = {
+ enable = true;
+ settings = {
+ PasswordAuthentication = false;
+ PermitRootLogin = "no";
+ };
+ };
+
+ programs = {
+ zsh = {
+ enable = isNative;
+ syntaxHighlighting.enable = isNative;
+ };
+ shellrc = true;
+ vim = {
+ enable = isArm;
+ defaultEditor = isArm;
+ };
+ neovim = {
+ enable = !isArm;
+ defaultEditor = !isArm;
+ withNodeJs = true;
+ };
+ };
+
+ programs.fuse.userAllowOther = true;
+}
diff --git a/nixos/modules/wifi-adm.nix b/nixos/modules/wifi-adm.nix
index 40210e7..56ca65a 100644
--- a/nixos/modules/wifi-adm.nix
+++ b/nixos/modules/wifi-adm.nix
@@ -3,9 +3,73 @@
lib,
...
}: let
- inherit (lib) mkOption mkEnableOption types mkIf hostapd elemAt;
+ inherit (lib) mkOption mkEnableOption types mkIf mkMerge hostapd elemAt;
cnf = config.cynerd.wifiAP.adm;
+ wifi-networks = name: {
+ "${cnf."${name}".interface}" = {
+ bssid = elemAt cnf."${name}".bssids 0;
+ ssid = "TurrisAdamkovi";
+ authentication = {
+ mode = "wpa3-sae-transition";
+ wpaPasswordFile = "/run/secrets/hostapd-TurrisAdamkovi.pass";
+ saePasswordsFile = "/run/secrets/hostapd-TurrisAdamkovi.pass";
+ };
+ };
+ "${cnf."${name}".interface}.nela" = {
+ bssid = elemAt cnf."${name}".bssids 1;
+ ssid = "Nela";
+ authentication = {
+ mode = "wpa2-sha256";
+ wpaPasswordFile = "/run/secrets/hostapd-Nela.pass";
+ };
+ };
+ "${cnf."${name}".interface}.milan" = {
+ bssid = elemAt cnf."${name}".bssids 2;
+ ssid = "MILAN-AC";
+ authentication = {
+ mode = "wpa2-sha1";
+ wpaPasswordFile = "/run/secrets/hostapd-MILAN-AC.pass";
+ };
+ };
+ };
+
+ net-networks = name: {
+ "lan-${cnf."${name}".interface}" = {
+ matchConfig = {
+ Name = cnf."${name}".interface;
+ WLANInterfaceType = "ap";
+ };
+ networkConfig.Bridge = "brlan";
+ bridgeVLANs = [
+ {
+ EgressUntagged = 1;
+ PVID = 1;
+ }
+ ];
+ };
+ "lan-${cnf."${name}".interface}.nela" = {
+ matchConfig.Name = "${cnf."${name}".interface}-nela";
+ networkConfig.Bridge = "brlan";
+ bridgeVLANs = [
+ {
+ EgressUntagged = 2;
+ PVID = 2;
+ }
+ ];
+ };
+ "lan-${cnf."${name}".interface}.milan" = {
+ matchConfig.Name = "${cnf."${name}".interface}.milan";
+ networkConfig.Bridge = "brlan";
+ bridgeVLANs = [
+ {
+ EgressUntagged = 2;
+ PVID = 2;
+ }
+ ];
+ };
+ };
+
wOptions = card: channelDefault: {
interface = mkOption {
type = with types; nullOr str;
@@ -43,32 +107,7 @@ in {
enable = true;
inherit (hostapd.qualcomAtherosAR9287.wifi4) capabilities;
};
- networks = {
- "${cnf.ar9287.interface}" = {
- bssid = elemAt cnf.ar9287.bssids 0;
- ssid = "TurrisAdamkovi";
- authentication = {
- mode = "wpa2-sha256";
- wpaPasswordFile = "/run/secrets/hostapd-TurrisAdamkovi.pass";
- };
- };
- "${cnf.ar9287.interface}-nela" = {
- bssid = elemAt cnf.ar9287.bssids 1;
- ssid = "Nela";
- authentication = {
- mode = "wpa2-sha256";
- wpaPasswordFile = "/run/secrets/hostapd-Nela.pass";
- };
- };
- "${cnf.ar9287.interface}.milan" = {
- bssid = elemAt cnf.ar9287.bssids 2;
- ssid = "MILAN-AC";
- authentication = {
- mode = "wpa2-sha256";
- wpaPasswordFile = "/run/secrets/hostapd-MILAN-AC.pass";
- };
- };
- };
+ networks = wifi-networks "ar9287";
};
"${cnf.qca988x.interface}" = mkIf (cnf.qca988x.interface != null) {
countryCode = "CZ";
@@ -82,108 +121,13 @@ in {
enable = true;
inherit (hostapd.qualcomAtherosQCA988x.wifi5) capabilities;
};
- networks = {
- "${cnf.qca988x.interface}" = {
- bssid = elemAt cnf.qca988x.bssids 0;
- ssid = "TurrisAdamkovi";
- authentication = {
- mode = "wpa2-sha256";
- wpaPasswordFile = "/run/secrets/hostapd-TurrisAdamkovi.pass";
- };
- };
- "${cnf.qca988x.interface}-nela" = {
- bssid = elemAt cnf.qca988x.bssids 1;
- ssid = "Nela";
- authentication = {
- mode = "wpa2-sha256";
- wpaPasswordFile = "/run/secrets/hostapd-Nela.pass";
- };
- };
- "${cnf.qca988x.interface}.milan" = {
- bssid = elemAt cnf.qca988x.bssids 2;
- ssid = "MILAN-AC";
- authentication = {
- mode = "wpa2-sha256";
- wpaPasswordFile = "/run/secrets/hostapd-MILAN-AC.pass";
- };
- };
- };
+ networks = wifi-networks "qca988x";
};
};
};
- systemd.network.networks = {
- "lan-${cnf.ar9287.interface}" = {
- matchConfig.Name = cnf.ar9287.interface;
- networkConfig.Bridge = "brlan";
- bridgeVLANs = [
- {
- bridgeVLANConfig = {
- EgressUntagged = 1;
- PVID = 1;
- };
- }
- ];
- };
- "lan-${cnf.ar9287.interface}-nela" = {
- matchConfig.Name = "${cnf.ar9287.interface}-nela";
- networkConfig.Bridge = "brlan";
- bridgeVLANs = [
- {
- bridgeVLANConfig = {
- EgressUntagged = 2;
- PVID = 2;
- };
- }
- ];
- };
- "lan-${cnf.ar9287.interface}.milan" = {
- matchConfig.Name = "${cnf.ar9287.interface}.milan";
- networkConfig.Bridge = "brlan";
- bridgeVLANs = [
- {
- bridgeVLANConfig = {
- EgressUntagged = 2;
- PVID = 2;
- };
- }
- ];
- };
- "lan-${cnf.qca988x.interface}" = {
- matchConfig.Name = cnf.qca988x.interface;
- networkConfig.Bridge = "brlan";
- bridgeVLANs = [
- {
- bridgeVLANConfig = {
- EgressUntagged = 1;
- PVID = 1;
- };
- }
- ];
- };
- "lan-${cnf.qca988x.interface}-nela" = {
- matchConfig.Name = "${cnf.qca988x.interface}-nela";
- networkConfig.Bridge = "brlan";
- bridgeVLANs = [
- {
- bridgeVLANConfig = {
- EgressUntagged = 2;
- PVID = 2;
- };
- }
- ];
- };
- "lan-${cnf.qca988x.interface}.milan" = {
- matchConfig.Name = "${cnf.qca988x.interface}.milan";
- networkConfig.Bridge = "brlan";
- bridgeVLANs = [
- {
- bridgeVLANConfig = {
- EgressUntagged = 2;
- PVID = 2;
- };
- }
- ];
- };
- };
+ systemd.network.networks = mkMerge [
+ (mkIf (cnf.ar9287.interface != null) (net-networks "ar9287"))
+ (mkIf (cnf.qca988x.interface != null) (net-networks "qca988x"))
+ ];
};
}
diff --git a/nixos/modules/wifi-client.nix b/nixos/modules/wifi-client.nix
index 8fc803d..b82633d 100644
--- a/nixos/modules/wifi-client.nix
+++ b/nixos/modules/wifi-client.nix
@@ -21,7 +21,7 @@ in {
networking.wireless = {
enable = true;
networks = config.secrets.wifiNetworks;
- environmentFile = "/run/secrets/wifi.env";
+ secretsFile = "/run/secrets/wifi.secrets";
userControlled.enable = true;
};
};
diff --git a/nixos/modules/wifi-spt.nix b/nixos/modules/wifi-spt.nix
index 669439d..bec093e 100644
--- a/nixos/modules/wifi-spt.nix
+++ b/nixos/modules/wifi-spt.nix
@@ -6,6 +6,61 @@
inherit (lib) mkOption mkEnableOption types mkIf mkForce mkMerge hostapd elemAt;
cnf = config.cynerd.wifiAP.spt;
+ wifi-networks = name: let
+ is2g = cnf."${name}".channel <= 14;
+ in {
+ "${cnf."${name}".interface}" = {
+ bssid = elemAt cnf."${name}".bssids 0;
+ ssid = "TurrisRules${
+ if is2g
+ then ""
+ else "5"
+ }";
+ authentication = {
+ mode = "wpa2-sha256";
+ wpaPasswordFile = "/run/secrets/hostapd-TurrisRules.pass";
+ };
+ settings = mkIf is2g {
+ ieee80211w = 0;
+ wpa_key_mgmt = mkForce "WPA-PSK"; # force use without sha256
+ };
+ };
+ "${cnf."${name}".interface}.guest" = {
+ bssid = elemAt cnf."${name}".bssids 1;
+ ssid = "Kocovi";
+ authentication = {
+ mode = "wpa2-sha256";
+ wpaPasswordFile = "/run/secrets/hostapd-Kocovi.pass";
+ };
+ };
+ };
+
+ net-networks = name: {
+ "lan-${cnf."${name}".interface}" = {
+ matchConfig = {
+ Name = cnf."${name}".interface;
+ WLANInterfaceType = "ap";
+ };
+ networkConfig.Bridge = "brlan";
+ bridgeVLANs = [
+ {
+ EgressUntagged = 1;
+ PVID = 1;
+ }
+ ];
+ };
+ "lan-${cnf."${name}".interface}-guest" = {
+ matchConfig.Name = "${cnf."${name}".interface}.guest";
+ networkConfig.Bridge = "brlan";
+ bridgeVLANs = [
+ {
+ EgressUntagged = 2;
+ PVID = 2;
+ }
+ ];
+ };
+ };
+
wOptions = card: channelDefault: {
interface = mkOption {
type = with types; nullOr str;
@@ -48,28 +103,7 @@ in {
enable = true;
inherit (hostapd.qualcomAtherosAR9287.wifi4) capabilities;
};
- networks = {
- "${cnf.ar9287.interface}" = {
- bssid = elemAt cnf.ar9287.bssids 0;
- ssid = "TurrisRules";
- authentication = {
- mode = "wpa2-sha256";
- wpaPasswordFile = "/run/secrets/hostapd-TurrisRules.pass";
- };
- settings = {
- ieee80211w = 0;
- wpa_key_mgmt = mkForce "WPA-PSK"; # force use without sha256
- };
- };
- #"${cnf.ar9287.interface}.guest" = {
- # bssid = elemAt cnf.ar9287.bssids 1;
- # ssid = "Kocovi";
- # authentication = {
- # mode = "wpa2-sha256";
- # wpaPasswordFile = "/run/secrets/hostapd-Kocovi.pass";
- # };
- #};
- };
+ networks = wifi-networks "ar9287";
};
})
(mkIf (cnf.qca988x.interface != null) {
@@ -90,95 +124,14 @@ in {
enable = !is2g;
inherit (hostapd.qualcomAtherosQCA988x.wifi5) capabilities;
};
- networks = {
- "${cnf.qca988x.interface}" = {
- bssid = elemAt cnf.qca988x.bssids 0;
- ssid = "TurrisRules${
- if is2g
- then ""
- else "5"
- }";
- authentication = {
- mode = "wpa2-sha256";
- wpaPasswordFile = "/run/secrets/hostapd-TurrisRules.pass";
- };
- settings = mkIf is2g {
- ieee80211w = 0;
- wpa_key_mgmt = mkForce "WPA-PSK"; # force use without sha256
- };
- };
- #"${cnf.qca988x.interface}.guest" = {
- # bssid = elemAt cnf.qca988x.bssids 1;
- # ssid = "Kocovi";
- # authentication = {
- # mode = "wpa2-sha256";
- # wpaPasswordFile = "/run/secrets/hostapd-Kocovi.pass";
- # };
- #};
- };
+ networks = wifi-networks "qca988x";
};
})
];
};
systemd.network.networks = mkMerge [
- (mkIf (cnf.ar9287.interface != null) {
- "lan-${cnf.ar9287.interface}" = {
- matchConfig = {
- Name = cnf.ar9287.interface;
- WLANInterfaceType = "ap";
- };
- networkConfig.Bridge = "brlan";
- bridgeVLANs = [
- {
- bridgeVLANConfig = {
- EgressUntagged = 1;
- PVID = 1;
- };
- }
- ];
- };
- #"lan-${cnf.ar9287.interface}-guest" = {
- # matchConfig.Name = "${cnf.ar9287.interface}.guest";
- # networkConfig.Bridge = "brlan";
- # bridgeVLANs = [
- # {
- # bridgeVLANConfig = {
- # EgressUntagged = 2;
- # PVID = 2;
- # };
- # }
- # ];
- #};
- })
- (mkIf (cnf.qca988x.interface != null) {
- "lan-${cnf.qca988x.interface}" = {
- matchConfig = {
- Name = cnf.qca988x.interface;
- WLANInterfaceType = "ap";
- };
- networkConfig.Bridge = "brlan";
- bridgeVLANs = [
- {
- bridgeVLANConfig = {
- EgressUntagged = 1;
- PVID = 1;
- };
- }
- ];
- };
- #"lan-${cnf.qca988x.interface}-guest" = {
- # matchConfig.Name = "${cnf.qca988x.interface}.guest";
- # networkConfig.Bridge = "brlan";
- # bridgeVLANs = [
- # {
- # bridgeVLANConfig = {
- # EgressUntagged = 2;
- # PVID = 2;
- # };
- # }
- # ];
- #};
- })
+ (mkIf (cnf.ar9287.interface != null) (net-networks "ar9287"))
+ (mkIf (cnf.qca988x.interface != null) (net-networks "qca988x"))
];
};
}
diff --git a/nixos/modules/wireguad.nix b/nixos/modules/wireguad.nix
deleted file mode 100644
index eb25a6e..0000000
--- a/nixos/modules/wireguad.nix
+++ /dev/null
@@ -1,111 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}: let
- inherit (lib) any all mkEnableOption mkIf mapAttrsToList optional optionals optionalAttrs filterAttrs;
- inherit (config.networking) hostName;
- endpoints = ["lipwig" "spt-omnia" "adm-omnia"];
- is_endpoint = any (v: v == hostName) endpoints;
-in {
- options = {
- cynerd.wireguard = mkEnableOption "Enable Wireguard";
- };
-
- config = mkIf config.cynerd.wireguard {
- environment.systemPackages = [pkgs.wireguard-tools];
- systemd.network = {
- netdevs."wg" = {
- netdevConfig = {
- Name = "wg";
- Kind = "wireguard";
- Description = "Personal Wireguard tunnel";
- MTUBytes = "1300";
- };
- wireguardConfig = {
- ListenPort = 51820;
- PrivateKeyFile = "/run/secrets/wg.key";
- };
- wireguardPeers =
- [
- {
- wireguardPeerConfig =
- {
- Endpoint = "cynerd.cz:51820";
- AllowedIPs = ["0.0.0.0/0"];
- PublicKey = config.secrets.wireguardPubs.lipwig;
- }
- // (optionalAttrs (!is_endpoint) {PersistentKeepalive = 25;});
- }
- {
- wireguardPeerConfig =
- {
- Endpoint = "spt.cynerd.cz:51820";
- AllowedIPs = [
- "${config.cynerd.hosts.wg.spt-omnia}/32"
- "10.8.2.0/24"
- ];
- PublicKey = config.secrets.wireguardPubs.spt-omnia;
- }
- // (optionalAttrs (!is_endpoint) {PersistentKeepalive = 25;});
- }
- #{
- # wireguardPeerConfig =
- # {
- # Endpoint = "adm.cynerd.cz:51820";
- # AllowedIPs = [
- # "${config.cynerd.hosts.wg.adm-omnia}/32"
- # "10.8.3.0/24"
- # ];
- # PublicKey = config.secrets.wireguardPubs.adm-omnia;
- # }
- # // (optionalAttrs (!is_endpoint) {PersistentKeepalive = 25;});
- #}
- ]
- ++ (optionals is_endpoint (mapAttrsToList (n: v: {
- wireguardPeerConfig = {
- AllowedIPs = "${config.cynerd.hosts.wg."${n}"}/32";
- PublicKey = v;
- };
- }) (filterAttrs (n: _: all (v: v != n) endpoints) config.secrets.wireguardPubs)));
- };
- networks."wg" = {
- matchConfig.Name = "wg";
- networkConfig = {
- Address = "${config.cynerd.hosts.wg."${hostName}"}/24";
- IPForward = is_endpoint;
- #DNS = mkIf (hostName != "dean") ["10.0.20.30" "10.0.20.31"];
- #DNSSEC = false;
- #Domains = mkIf (hostName != "dean") "~elektroline.cz";
- };
- routes =
- (optional (hostName != "lipwig") {
- # OpenVPN network
- routeConfig = {
- Gateway = config.cynerd.hosts.wg.lipwig;
- Destination = "10.8.0.0/24";
- Metric = 2048;
- };
- })
- ++ (optional (hostName != "spt-omnia") {
- # SPT network
- routeConfig = {
- Gateway = config.cynerd.hosts.wg.spt-omnia;
- Destination = "10.8.2.0/24";
- Metric = 2048;
- };
- })
- ++ (optional (hostName != "adm-omnia" && hostName != "lipwig") {
- # Adamkovi network
- routeConfig = {
- Gateway = config.cynerd.hosts.wg.adm-omnia;
- Destination = "10.8.3.0/24";
- Metric = 2048;
- };
- });
- };
- };
- networking.firewall.allowedUDPPorts = [51820];
- };
-}
diff --git a/nixos/modules/wireguard.nix b/nixos/modules/wireguard.nix
new file mode 100644
index 0000000..b49eaae
--- /dev/null
+++ b/nixos/modules/wireguard.nix
@@ -0,0 +1,85 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: let
+ inherit (lib) any all mkEnableOption mkIf mapAttrsToList optional optionals optionalAttrs filterAttrs;
+ inherit (config.networking) hostName;
+ endpoints = ["lipwig" "spt-omnia" "adm-omnia"];
+ is_endpoint = any (v: v == hostName) endpoints;
+in {
+ options = {
+ cynerd.wireguard = mkEnableOption "Enable Wireguard";
+ };
+
+ config = mkIf config.cynerd.wireguard {
+ environment.systemPackages = [pkgs.wireguard-tools];
+ systemd.network = {
+ netdevs."wg" = {
+ netdevConfig = {
+ Name = "wg";
+ Kind = "wireguard";
+ Description = "Personal Wireguard tunnel";
+ MTUBytes = "1300";
+ };
+ wireguardConfig = {
+ ListenPort = 51820;
+ PrivateKeyFile = "/run/secrets/wg.key";
+ };
+ wireguardPeers =
+ [
+ ({
+ Endpoint = "cynerd.cz:51820";
+ AllowedIPs = ["0.0.0.0/0"];
+ PublicKey = config.secrets.wireguardPubs.lipwig;
+ }
+ // (optionalAttrs (!is_endpoint) {PersistentKeepalive = 25;}))
+ ({
+ Endpoint = "spt.cynerd.cz:51820";
+ AllowedIPs = [
+ "${config.cynerd.hosts.wg.spt-omnia}/32"
+ "10.8.2.0/24"
+ ];
+ PublicKey = config.secrets.wireguardPubs.spt-omnia;
+ }
+ // (optionalAttrs (!is_endpoint) {PersistentKeepalive = 25;}))
+ ({
+ Endpoint = "adm.cynerd.cz:51820";
+ AllowedIPs = [
+ "${config.cynerd.hosts.wg.adm-omnia}/32"
+ "10.8.3.0/24"
+ ];
+ PublicKey = config.secrets.wireguardPubs.adm-omnia;
+ }
+ // (optionalAttrs (!is_endpoint) {PersistentKeepalive = 25;}))
+ ]
+ ++ (optionals is_endpoint (mapAttrsToList (n: v: {
+ AllowedIPs = "${config.cynerd.hosts.wg."${n}"}/32";
+ PublicKey = v;
+ }) (filterAttrs (n: _: all (v: v != n) endpoints) config.secrets.wireguardPubs)));
+ };
+ networks."wg" = {
+ matchConfig.Name = "wg";
+ networkConfig = {
+ Address = "${config.cynerd.hosts.wg."${hostName}"}/24";
+ IPv4Forwarding = "yes";
+ };
+ routes =
+ (optional (hostName != "spt-omnia") {
+ # SPT network
+ Gateway = config.cynerd.hosts.wg.spt-omnia;
+ Destination = "10.8.2.0/24";
+ Metric = 2048;
+ })
+ ++ (optional (hostName != "adm-omnia") {
+ # ADM network
+ Gateway = config.cynerd.hosts.wg.adm-omnia;
+ Destination = "10.8.3.0/24";
+ Metric = 2048;
+ });
+ };
+ };
+ networking.firewall.allowedUDPPorts = [51820];
+ };
+}