diff options
Diffstat (limited to 'nixos')
50 files changed, 2194 insertions, 1545 deletions
diff --git a/nixos/configurations/adm-mpd.nix b/nixos/configurations/adm-mpd.nix deleted file mode 100644 index ac3b4de..0000000 --- a/nixos/configurations/adm-mpd.nix +++ /dev/null @@ -1,56 +0,0 @@ -{ - config, - lib, - ... -}: let - inherit (lib) filterAttrs; -in { - nixpkgs.hostPlatform.system = "aarch64-linux"; - - fileSystems = { - "/" = { - device = "/dev/mmcblk0p2"; - options = ["compress=lzo" "subvol=@nix"]; - }; - "/home" = { - device = "/dev/mmcblk0p2"; - options = ["compress=lzo" "subvol=@home"]; - }; - "/boot" = { - device = "/dev/mmcblk0p1"; - }; - }; - - networking.wireless = { - enable = true; - networks = filterAttrs (n: _: n == "Nela") config.secrets.wifiNetworks; - environmentFile = "/run/secrets/wifi.env"; - userControlled.enable = true; - }; - - #services.pipewire = { - #enable = true; - #alsa.enable = true; - #pulse.enable = true; - #}; - hardware.pulseaudio = { - enable = true; - systemWide = true; - zeroconf.publish.enable = true; - }; - - services.spotifyd = { - enable = true; - settings.global = { - device_name = "Adámkovi"; - device = "sysdefault"; - mixer = "Master"; - bitrate = 320; - cache_path = "/var/cahe/spotify"; - no_audio_cache = true; - volume_normalisation = true; - normalisation_pregain = -10; - initial_volume = 60; - }; - }; -} diff --git a/nixos/configurations/adm-omnia.nix b/nixos/configurations/adm-omnia.nix index 672788a..6df1098 100644 --- a/nixos/configurations/adm-omnia.nix +++ b/nixos/configurations/adm-omnia.nix @@ -1,60 +1,95 @@ -{config, ...}: { +{config, ...}: let + hosts = config.cynerd.hosts.adm; +in { + system.stateVersion = "24.05"; + turris.board = "omnia"; + deploy = { + enable = true; + ssh.host = "adm.cynerd.cz"; + configurationLimit = 16; + }; cynerd = { router = { enable = true; wan = "pppoe-wan"; - lanIP = config.cynerd.hosts.adm.omnia; + lanIP = hosts.omnia; + staticLeases = { + "4c:d5:77:0d:85:d9" = hosts.binky; + "f4:a9:97:a4:bd:59" = hosts.printer; + }; }; wifiAP.adm = { enable = true; - ar9287.interface = "wlp3s0"; - qca988x.interface = "wlp2s0"; + ar9287 = { + interface = "wlp2s0"; + bssids = config.secrets.wifiMacs.adm-omnia.ar9287; + channel = 7; + }; + qca988x = { + interface = "wlp1s0"; + bssids = config.secrets.wifiMacs.adm-omnia.qca988x; + channel = 44; + }; }; + wireguard = true; monitoring.speedtest = true; }; + services = { + journald.settings.Journal = { + SystemMaxUse = "8G"; + }; + + btrfs.autoScrub = { + enable = true; + fileSystems = ["/"]; + }; + + fail2ban = { + enable = true; + ignoreIP = ["10.8.0.0/24" "10.8.1.0/24"]; + }; + }; + + # Warning: This Omnia has broker WAN port thus LAN4 is used for WAN!!!!!!!! networking.useDHCP = false; systemd.network = { networks = { - "end2" = { - matchConfig.Name = "end2"; - #networkConfig = { - # DHCP = "ipv6"; - # IPv6AcceptRA = "yes"; - # DHCPPrefixDelegation = "yes"; - #}; - #dhcpPrefixDelegationConfig = { - # UplinkInterface = ":self"; - # SubnetId = 0; - # Announce = "no"; - #}; + "lan4" = { + matchConfig.Name = "lan4"; # Ensure that it is managed by systemd-networkd + networkConfig.IPv6AcceptRA = false; + }; + "pppoe-wan" = { + matchConfig.Name = "pppoe-wan"; + networkConfig = { + BindCarrier = "lan4"; + DHCP = "ipv6"; + IPv6AcceptRA = "no"; + DHCPPrefixDelegation = "yes"; + DNS = "1.1.1.1"; + }; + dhcpV6Config = { + PrefixDelegationHint = "::/56"; + UseDNS = "no"; + }; + dhcpPrefixDelegationConfig = { + UplinkInterface = ":self"; + SubnetId = 0; + Announce = "no"; + }; linkConfig.RequiredForOnline = "routable"; }; "lan-brlan" = { - matchConfig.Name = "lan[1-4]"; - networkConfig.Bridge = "brlan"; - bridgeVLANs = [ - { - bridgeVLANConfig = { - EgressUntagged = 1; - PVID = 1; - }; - } - {bridgeVLANConfig.VLAN = 2;} - ]; - }; - "lan0-guest" = { - matchConfig.Name = "lan0"; + matchConfig.Name = "lan0 lan1 lan2 lan3"; networkConfig.Bridge = "brlan"; bridgeVLANs = [ { - bridgeVLANConfig = { - EgressUntagged = 2; - PVID = 2; - }; + EgressUntagged = 1; + PVID = 1; } + {VLAN = 2;} ]; }; }; @@ -63,19 +98,34 @@ services.pppd = { enable = true; peers."wan".config = '' - plugin pppoe.so end2 + plugin pppoe.so lan4 ifname pppoe-wan lcp-echo-interval 1 lcp-echo-failure 5 lcp-echo-adaptive - +ipv6 defaultroute defaultroute6 - usepeerdns + #usepeerdns maxfail 1 user O2 password 02 ''; }; - systemd.services."pppd-wan".after = ["sys-subsystem-net-devices-end2.device"]; + systemd.services = { + "pppd-wan" = { + after = ["sys-subsystem-net-devices-lan4.device"]; + partOf = ["systemd-networkd.service"]; + serviceConfig = { + Restart = "always"; + StartLimitBurst = 0; + }; + }; + "systemd-networkd".environment.SYSTEMD_LOG_LEVEL = "debug"; + }; + # TODO limit NSS clamping to just pppoe-wan + networking.firewall.extraForwardRules = '' + tcp flags syn tcp option maxseg size set rt mtu comment "Needed for PPPoE to fix IPv4" + iifname "wg" oifname "home" accept + iifname "home" oifname "guest" accept comment "Allow home to access guest devices" + ''; } diff --git a/nixos/configurations/adm-omnia2.nix b/nixos/configurations/adm-omnia2.nix index 19ee446..317ee62 100644 --- a/nixos/configurations/adm-omnia2.nix +++ b/nixos/configurations/adm-omnia2.nix @@ -1,8 +1,11 @@ {config, ...}: { + system.stateVersion = "24.05"; + turris.board = "omnia"; deploy = { enable = true; ssh.host = "omnia2.adm"; + configurationLimit = 16; }; cynerd = { @@ -14,25 +17,27 @@ wifiAP.adm = { enable = true; ar9287 = { - interface = "wlp1s0"; - bssids = ["12:f0:21:23:2b:00" "12:f0:21:23:2b:01" "12:f0:21:23:2b:02"]; + interface = "wlp2s0"; + bssids = config.secrets.wifiMacs.adm-omnia2.ar9287; channel = 11; }; qca988x = { - interface = "wlp2s0"; - bssids = ["12:f0:21:23:2b:03" "12:f0:21:23:2b:04" "12:f0:21:23:2b:05"]; + interface = "wlp1s0"; + bssids = config.secrets.wifiMacs.adm-omnia2.qca988x; channel = 36; }; }; }; - services.journald.extraConfig = '' - SystemMaxUse=8G - ''; + services = { + journald.settings.Journal = { + SystemMaxUse = "8G"; + }; - services.btrfs.autoScrub = { - enable = true; - fileSystems = ["/"]; + btrfs.autoScrub = { + enable = true; + fileSystems = ["/"]; + }; }; networking = { @@ -45,12 +50,10 @@ networkConfig.Bridge = "brlan"; bridgeVLANs = [ { - bridgeVLANConfig = { - EgressUntagged = 1; - PVID = 1; - }; + EgressUntagged = 1; + PVID = 1; } - {bridgeVLANConfig.VLAN = 2;} + {VLAN = 2;} ]; }; }; diff --git a/nixos/configurations/albert.nix b/nixos/configurations/albert.nix deleted file mode 100644 index a6a4ee1..0000000 --- a/nixos/configurations/albert.nix +++ /dev/null @@ -1,41 +0,0 @@ -{ - nixpkgs.hostPlatform.system = "x86_64-linux"; - - cynerd = { - desktop = { - enable = true; - laptop = true; - }; - wifiClient = true; - openvpn = { - oldpersonal = true; - }; - }; - - boot.initrd.availableKernelModules = ["xhci_pci" "usb_storage" "sd_mod"]; - - hardware.cpu.intel.updateMicrocode = true; - - fileSystems = { - "/" = { - device = "/dev/disk/by-uuid/1c9bafac-fcf8-41c4-b394-bca5917ca82d"; - fsType = "btrfs"; - options = ["compress=lzo" "subvol=@nix"]; - }; - "/home" = { - device = "/dev/disk/by-uuid/1c9bafac-fcf8-41c4-b394-bca5917ca82d"; - fsType = "btrfs"; - options = ["compress=lzo" "subvol=@home"]; - }; - "/boot" = { - device = "/dev/disk/by-uuid/E403-124B"; - fsType = "vfat"; - }; - - "/home2" = { - device = "/dev/disk/by-uuid/55e177a1-215e-475b-ba9c-771b5fa3f8f0"; - fsType = "btrfs"; - options = ["compress=lzo" "subvol=@home"]; - }; - }; -} diff --git a/nixos/configurations/binky.nix b/nixos/configurations/binky.nix index 6dfb6a5..f4f82fb 100644 --- a/nixos/configurations/binky.nix +++ b/nixos/configurations/binky.nix @@ -1,11 +1,10 @@ -{lib, ...}: let - inherit (lib) mkDefault; -in { +{lib, ...}: { + system.stateVersion = "24.05"; nixpkgs.hostPlatform.system = "x86_64-linux"; deploy = { enable = true; default = false; - ssh.host = "binky.spt"; + ssh.host = "binky"; }; cynerd = { @@ -15,6 +14,7 @@ in { }; wifiClient = true; develop = true; + gaming = true; wireguard = true; openvpn.elektroline = true; }; @@ -75,7 +75,7 @@ in { DHCP = "yes"; IPv6AcceptRA = "yes"; }; - routes = [{routeConfig.Metric = 1088;}]; + routes = [{Metric = 1088;}]; linkConfig.RequiredForOnline = "routable"; }; }; @@ -84,14 +84,8 @@ in { services.syncthing = { enable = true; - user = mkDefault "cynerd"; - group = mkDefault "cynerd"; - openDefaultPorts = true; - - overrideDevices = false; - overrideFolders = false; - dataDir = "/home/cynerd"; - configDir = "/home/cynerd/.config/syncthing"; }; + + programs.steam.enable = lib.mkForce false; } diff --git a/nixos/configurations/dean.nix b/nixos/configurations/dean.nix index 187e148..85615dd 100644 --- a/nixos/configurations/dean.nix +++ b/nixos/configurations/dean.nix @@ -1,8 +1,17 @@ -{pkgs, ...}: { +{ + lib, + pkgs, + ... +}: { + system.stateVersion = "24.05"; turris.board = "mox"; - deploy.enable = true; + deploy = { + enable = true; + configurationLimit = 8; + }; cynerd = { + devmin = true; wireguard = true; monitoring = { speedtest = true; @@ -10,6 +19,20 @@ }; }; + boot.initrd.availableKernelModules = ["dm-mod"]; + + hardware.enableAllFirmware = false; # No wifi so we do not need firmwares + services = { + journald.settings.Journal = { + SystemMaxUse = "512M"; + }; + + btrfs.autoScrub = { + enable = false; # TODO https://github.com/NixOS/nixpkgs/pull/564119 + fileSystems = ["/"]; + }; + }; + networking = { useNetworkd = true; useDHCP = false; @@ -39,5 +62,29 @@ environment.systemPackages = with pkgs; [ #openocd tio + gnupg + ]; + + programs = { + fuse = { + enable = true; + userAllowOther = true; + }; + nix-ld.enable = true; + }; + boot.binfmt = { + emulatedSystems = ["x86_64-linux"]; + }; + environment.sessionVariables = { + NIX_LD_x86_64_linux = "${pkgs.buildPackages.glibc}/lib/ld-linux-x86-64.so.2"; + NIX_LD_LIBRARY_PATH_x86_64_linux = lib.makeLibraryPath (with pkgs.buildPackages; [ + stdenv.cc.cc + glibc + zlib + ]); + }; + systemd.tmpfiles.rules = [ + "d /lib64 0755 root root -" + "L+ /lib64/ld-linux-x86-64.so.2 - - - - ${pkgs.buildPackages.nix-ld}/libexec/nix-ld" ]; } diff --git a/nixos/configurations/dribbler.nix b/nixos/configurations/dribbler.nix new file mode 100644 index 0000000..038f455 --- /dev/null +++ b/nixos/configurations/dribbler.nix @@ -0,0 +1,112 @@ +{pkgs, ...}: { + system.stateVersion = "25.11"; + nixpkgs.hostPlatform.system = "x86_64-linux"; + deploy = { + enable = true; + default = false; + ssh.host = "dribbler"; + }; + + cynerd = { + wifiClient = true; + }; + + boot = { + initrd.availableKernelModules = ["nvme" "xhci_pci" "usb_storage" "sd_mod"]; + kernelModules = ["kvm-intel"]; + kernelParams = ["video=eDP-1:d"]; # Disable internal display for kodi to use HDMI + }; + + hardware.cpu.intel.updateMicrocode = true; + + cynerd.autounlock = { + "encroot" = "/dev/disk/by-uuid/f791f524-0552-487b-9bf9-5c20ca78651b"; + }; + fileSystems = { + "/" = { + device = "/dev/mapper/encroot"; + fsType = "btrfs"; + options = ["compress=lzo"]; + }; + "/boot" = { + device = "/dev/disk/by-uuid/7143-1EE7"; + fsType = "vfat"; + }; + }; + services.btrfs.autoScrub = { + enable = true; + fileSystems = ["/"]; + }; + + networking = { + useNetworkd = true; + useDHCP = false; + }; + systemd.network = { + networks = { + "dhcp" = { + matchConfig.Name = "enp1s0"; + networkConfig = { + DHCP = "yes"; + IPv6AcceptRA = "yes"; + }; + linkConfig.RequiredForOnline = "routable"; + }; + "dhcp-wlan" = { + matchConfig.Name = "wlp2s0"; + networkConfig = { + DHCP = "yes"; + IPv6AcceptRA = "yes"; + }; + routes = [{Metric = 1088;}]; + linkConfig.RequiredForOnline = "routable"; + }; + }; + wait-online.enable = false; + }; + + # Kodi + environment.systemPackages = with pkgs; [ + kodi-gbm + ]; + hardware = { + graphics = { + enable = true; + enable32Bit = true; + extraPackages = with pkgs; [ + intel-media-driver + libvdpau-va-gl + ]; + }; + bluetooth.enable = true; + }; + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + }; + security.rtkit.enable = true; + #nixpkgs.config.kodi.enableAdvancedLauncher = true; + users.extraUsers.kodi = { + isNormalUser = true; + extraGroups = ["audio" "video" "input"]; + }; + systemd.services.kodi = { + description = "Kodi standalone (GBM)"; + wantedBy = ["multi-user.target"]; + conflicts = ["getty@tty1.service"]; + serviceConfig = { + User = "kodi"; + TTYPath = "/dev/tty1"; + ExecStart = "${pkgs.kodi-gbm}/bin/kodi-standalone"; + Restart = "on-abort"; + StandardInput = "tty"; + StandardOutput = "journal"; + }; + }; + networking.firewall = { + allowedTCPPorts = [8080]; + allowedUDPPorts = [8080]; + }; +} diff --git a/nixos/configurations/errol.nix b/nixos/configurations/errol.nix index fd348e8..e45fae5 100644 --- a/nixos/configurations/errol.nix +++ b/nixos/configurations/errol.nix @@ -1,31 +1,24 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) mkDefault; -in { +{pkgs, ...}: { + system.stateVersion = "24.05"; nixpkgs.hostPlatform.system = "x86_64-linux"; deploy.enable = true; - cynerd = { - desktop.enable = true; - develop = true; - gaming = true; - openvpn.elektroline = true; - }; - boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "usb_storage"]; boot.kernelModules = ["kvm-amd"]; hardware.cpu.amd.updateMicrocode = true; services.hardware.openrgb.motherboard = "amd"; + zramSwap = { + enable = true; + memoryPercent = 50; + }; + cynerd.autounlock = { "encroot" = "/dev/disk/by-uuid/7c412ae6-6016-45af-8c2a-8fcc394dbbe6"; "enchdd1" = "/dev/disk/by-uuid/87f16080-5ff6-43dd-89f3-307455a46fbe"; "enchdd2" = "/dev/disk/by-uuid/be4a33fa-8bc6-431d-a3ac-787668f223ed"; + #"encback" = "/dev/disk/by-uuid/1bd8c637-f71e-4fb0-96de-b660c4f1afaf"; }; fileSystems = { "/" = { @@ -53,6 +46,11 @@ in { fsType = "btrfs"; options = ["compress=lzo" "subvol=@home"]; }; + #"/back" = { + # device = "/dev/mapper/encback"; + # fsType = "btrfs"; + # options = ["compress=lzo"]; + #}; }; services.btrfs.autoScrub = { enable = true; @@ -83,75 +81,11 @@ in { pkgs.nvtopPackages.amd ]; - services.syncthing = { - enable = true; - user = mkDefault "cynerd"; - group = mkDefault "cynerd"; - openDefaultPorts = true; - - overrideDevices = false; - overrideFolders = false; - - dataDir = "/home/cynerd"; - configDir = "/home/cynerd/.config/syncthing"; - }; - - nixpkgs.config.permittedInsecurePackages = ["openssl-1.1.1w"]; # TODO - services.home-assistant = { - enable = true; - 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 ../modules/home-assistant/sensors.nix; - light = import ../modules/home-assistant/light.nix; - }; - default_config = {}; - automation = "!include automations.yaml"; - }; - extraComponents = ["met"]; - package = pkgs.home-assistant.override { - extraPackages = pkgs: - with pkgs; [ - securetar - pyipp - ]; - }; - }; - - services.zigbee2mqtt = { - enable = true; - settings = { - serial.port = "/dev/serial/by-id/usb-ITEAD_SONOFF_Zigbee_3.0_USB_Dongle_Plus_V2_20220812153849-if00"; - mqtt = { - server = "mqtt://${config.cynerd.hosts.spt.mox}:1883"; - user = "zigbee2mqtt"; - password = "!secret.yaml mqtt_password"; - }; - advanced = { - network_key = "!secret.yaml network_key"; - homeassistant_legacy_entity_attributes = false; - legacy_api = false; - legacy_availability_payload = false; - last_seen = "epoch"; - }; - frontend = true; - availability = true; - homeassistant = { - legacy_triggers = false; - }; - device_options.legacy = false; - permit_join = false; - devices = config.secrets.zigbee2mqttDevices; + ############################################################################## + services = { + syncthing = { + enable = true; + dataDir = "/home/cynerd"; }; }; } diff --git a/nixos/configurations/gaspode.nix b/nixos/configurations/gaspode.nix deleted file mode 100644 index 78d8277..0000000 --- a/nixos/configurations/gaspode.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ - nixpkgs.hostPlatform.system = "armv7l-linux"; - - fileSystems = { - "/" = { - device = "/dev/mmcblk0p2"; - options = ["compress=lzo" "subvol=@nix"]; - }; - "/home" = { - device = "/dev/mmcblk0p2"; - options = ["compress=lzo" "subvol=@home"]; - }; - "/boot" = { - device = "/dev/mmcblk0p1"; - }; - }; -} diff --git a/nixos/configurations/lipwig.nix b/nixos/configurations/lipwig.nix index e6ec96a..dd029e1 100644 --- a/nixos/configurations/lipwig.nix +++ b/nixos/configurations/lipwig.nix @@ -2,11 +2,13 @@ config, pkgs, inputModules, + lib, ... }: { imports = [inputModules.vpsadminos]; config = { + system.stateVersion = "24.05"; nixpkgs.hostPlatform.system = "x86_64-linux"; deploy = { @@ -19,12 +21,15 @@ hw = false; drives = false; }; - syncthing = { - enable = false; - baseDir = "/nas"; - }; wireguard = true; - openvpn.oldpersonal = true; + borgjobs = { + # TODO backup influx + postgresql.dumpCommand = pkgs.writeScript "postgreqsl-backup.sh" '' + /run/wrappers/bin/sudo -u postgres /run/current-system/sw/bin/pg_dumpall + ''; + nextcloud_data.paths = "/nas/nextcloud/data"; + sync_data.paths = "/sync"; + }; }; boot.loader.systemd-boot.enable = false; @@ -33,27 +38,16 @@ "/nas" = { device = "172.16.128.63:/nas/2682"; fsType = "nfs"; + options = [ + "_netdev" + "x-systemd.automount" + ]; }; "/nas/nextcloud-sync" = { - device = "/nas/sync"; + device = "/sync"; fsType = "fuse.bindfs"; options = ["map=syncthing/nextcloud:@syncthing/@nextcloud"]; }; - "/nas/spt" = { - device = "nas@omnia.spt:/data/nas"; - fsType = "fuse.sshfs"; - options = [ - "noauto" - "x-systemd.automount" - "_netdev" - "reconnect" - "identityfile=/run/secrets/nas.ssh.priv" - "allow_other" - "idmap=user" - "uid=nextcloud" - "gid=nextcloud" - ]; - }; }; networking = { @@ -81,62 +75,74 @@ ]; # Web ###################################################################### - services.nginx = { - enable = true; - virtualHosts = { - "cynerd.cz" = { - forceSSL = true; - enableACME = true; - locations = { - "/".root = ../../web; - "/radicale/" = { - proxyPass = "http://127.0.0.1:5232/"; - extraConfig = '' - proxy_set_header X-Script-Name /radicale; - proxy_pass_header Authorization; - ''; + services = { + nginx = { + enable = true; + virtualHosts = { + "cynerd.cz" = { + forceSSL = true; + enableACME = true; + locations = { + "/".root = ../../web; + "/radicale/" = { + proxyPass = "http://127.0.0.1:5232/"; + extraConfig = '' + proxy_set_header X-Script-Name /radicale; + proxy_pass_header Authorization; + ''; + }; }; }; - }; - "git.cynerd.cz" = { - forceSSL = true; - useACMEHost = "cynerd.cz"; - root = "${pkgs.cgit}/cgit"; - locations."/".tryFiles = "$uri @cgit"; - locations."@cgit".extraConfig = '' - fastcgi_param SCRIPT_FILENAME ${pkgs.cgit}/cgit/cgit.cgi; - fastcgi_pass unix:${config.services.fcgiwrap.socketAddress}; - fastcgi_param PATH_INFO $uri; - fastcgi_param QUERY_STRING $args; - fastcgi_param HTTP_HOST $server_name; - ''; - }; - "cloud.cynerd.cz" = { - forceSSL = true; - useACMEHost = "cynerd.cz"; - }; - "grafana.cynerd.cz" = { - forceSSL = true; - useACMEHost = "cynerd.cz"; - locations."/" = { - proxyPass = "http://127.0.0.1:${toString config.services.grafana.settings.server.http_port}/"; - extraConfig = "proxy_set_header Host $host;"; - proxyWebsockets = true; + "git.cynerd.cz" = { + forceSSL = true; + useACMEHost = "cynerd.cz"; + root = "${pkgs.cgit}/cgit"; + locations."/".tryFiles = "$uri @cgit"; + locations."@cgit".extraConfig = '' + fastcgi_pass unix:${config.services.fcgiwrap.instances.cgit.socket.address}; + fastcgi_param SCRIPT_FILENAME ${pkgs.cgit}/cgit/cgit.cgi; + fastcgi_param PATH_INFO $uri; + fastcgi_param QUERY_STRING $args; + fastcgi_param HTTP_HOST $server_name; + ''; + }; + "cloud.cynerd.cz" = { + forceSSL = true; + useACMEHost = "cynerd.cz"; + }; + "grafana.cynerd.cz" = { + forceSSL = true; + useACMEHost = "cynerd.cz"; + locations."/" = { + proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}"; + proxyWebsockets = true; + recommendedProxySettings = true; + }; + }; + "searx.cynerd.cz" = { + forceSSL = true; + useACMEHost = "cynerd.cz"; + locations."/".extraConfig = '' + uwsgi_pass "unix://${config.services.searx.uwsgiConfig.socket}"; + include ${config.services.nginx.package}/conf/uwsgi_params; + ''; }; }; }; - }; - services.fcgiwrap = { - enable = true; - inherit (config.services.nginx) group; + fcgiwrap.instances.cgit = { + process.user = "git"; + socket = {inherit (config.services.nginx) user group;}; + }; }; security.acme = { acceptTerms = true; defaults.email = "cynerd+acme@email.cz"; certs."cynerd.cz".extraDomainNames = [ - "git.cynerd.cz" "cloud.cynerd.cz" + "office.cynerd.cz" + "git.cynerd.cz" "grafana.cynerd.cz" + "searx.cynerd.cz" ]; }; @@ -193,7 +199,7 @@ # Nextcloud ################################################################ services.nextcloud = { enable = true; - package = pkgs.nextcloud28; + package = pkgs.nextcloud34; https = true; hostName = "cloud.cynerd.cz"; datadir = "/nas/nextcloud"; @@ -202,11 +208,25 @@ adminpassFile = "/run/secrets/nextcloud.admin.pass"; dbtype = "pgsql"; dbhost = "/run/postgresql"; - dbtableprefix = "oc_"; }; settings = { - #log_type = "systemd"; + log_type = "systemd"; + default_locale = "CZ"; default_phone_region = "CZ"; + default_timezone = "Europe/Prague"; + enabledPreviewProviders = [ + "OC\\Preview\\BMP" + "OC\\Preview\\GIF" + "OC\\Preview\\JPEG" + "OC\\Preview\\Krita" + "OC\\Preview\\MarkDown" + "OC\\Preview\\MP3" + "OC\\Preview\\OpenDocument" + "OC\\Preview\\PNG" + "OC\\Preview\\TXT" + "OC\\Preview\\XBitmap" + "OC\\Preview\\HEIC" + ]; }; phpExtraExtensions = php: [php.pgsql php.pdo_pgsql]; phpOptions = { @@ -214,69 +234,144 @@ }; maxUploadSize = "1G"; appstoreEnable = false; - extraApps = { - inherit - (config.services.nextcloud.package.packages.apps) - bookmarks - calendar - contacts - cookbook - deck - forms - groupfolders - impersonate - maps - memories - notes - phonetrack - previewgenerator - spreed - tasks - twofactor_nextcloud_notification - twofactor_webauthn - ; - # Additional modules can be fetched with: - # NEXTCLOUD_VERSIONS=28 nix run nixpkgs#nc4nix -- -apps "passwords,integration_homeassistant,integration_github,integration_gitlab" - passwords = pkgs.fetchNextcloudApp { - url = "https://git.mdns.eu/api/v4/projects/45/packages/generic/passwords/2024.2.0/passwords.tar.gz"; - sha256 = "0s5z6pxkcwmhlbzy9s2g0s05n1iqjmxr2jqxz7ayklin9kcgr3h7"; - license = "gpl3"; - }; - integration_github = pkgs.fetchNextcloudApp { - url = "https://github.com/nextcloud-releases/integration_github/releases/download/v2.0.6/integration_github-v2.0.6.tar.gz"; - sha256 = "0rjdlsalayb21nmh3j5bl42dcbavxka2r5g9csagz7vc9dl0qrw6"; - license = "gpl3"; - }; - integration_gitlab = pkgs.fetchNextcloudApp { - url = "https://github.com/nextcloud-releases/integration_gitlab/releases/download/v1.0.18/integration_gitlab-v1.0.18.tar.gz"; - sha256 = "13vlbr7sigqrh480a9zp7zl9nbzb4pk8m1zzlqv9lkzj3zywp7mi"; - license = "gpl3"; - }; - }; + extraApps = + { + inherit + (config.services.nextcloud.package.packages.apps) + bookmarks + calendar + contacts + cookbook + deck + forms + groupfolders + impersonate + maps + memories + notes + phonetrack + previewgenerator + spreed + tasks + twofactor_webauthn + ; + } + // (lib.mapAttrs (_: v: + pkgs.fetchNextcloudApp { + inherit (v) url hash; + license = "agpl3Plus"; + }) + # Additional modules can be fetched with: + # NEXTCLOUD_VERSIONS=34 nix run .#nc4nix -- -apps "passwords,integration_github,integration_gitlab,money,fileslibreofficeedit" + (lib.importJSON ../nextcloud-extra-apps.json)); }; # Postgresql ############################################################### services.postgresql = { enable = true; + enableTCPIP = true; ensureUsers = [ { + name = "cynerd"; + ensureClauses = { + login = true; + createdb = true; + createrole = true; + bypassrls = true; + replication = true; + }; + } + { name = "nextcloud"; ensureDBOwnership = true; } ]; - ensureDatabases = ["nextcloud"]; + ensureDatabases = ["nextcloud" "monitoring"]; + #extensions = ps: [ps.timescaledb]; }; - # Old Syncthing ############################################################ - services.syncthing = { + # SearX #################################################################### + services.searx = { enable = true; - openDefaultPorts = true; - - overrideDevices = false; - overrideFolders = false; + environmentFile = "/run/secrets/searx.env"; + settings = { + server.secret_key = "@SEARX_SECRET_KEY@"; + search = { + autocomplete = "google"; + autocomplete_min = 2; + }; + ui = { + query_in_title = true; + infinite_scroll = true; + center_alignment = true; + hotkeys = "vim"; + }; + engines = [ + { + name = "seznam"; + disabled = false; + } + { + name = "material icons"; + disabled = false; + } + { + name = "svgrepo"; + disabled = false; + } + { + name = "peertube"; + disabled = false; + } + { + name = "lib.rs"; + disabled = false; + } + { + name = "gitlab"; + disabled = false; + } + { + name = "sourcehut"; + disabled = false; + } + { + name = "free software directory"; + disabled = false; + } + { + name = "cppreference"; + disabled = false; + } + { + name = "searchcode code"; + disabled = false; + } + { + name = "imdb"; + disabled = false; + } + { + name = "tmdb"; + disabled = false; + } + ]; + }; + configureUwsgi = true; + uwsgiConfig = { + socket = "/run/searx/searx.sock"; + chmod-socket = "660"; + }; + redisCreateLocally = true; + }; + users.groups.searx.members = ["nginx"]; - dataDir = "/nas/sync"; - configDir = "/nas/sync/.syncthing"; + # Syncthing ################################################################ + services.syncthing = { + enable = true; + user = "syncthing"; + group = "syncthing"; + dataDir = "/sync"; }; }; } diff --git a/nixos/configurations/ridcully.nix b/nixos/configurations/ridcully.nix index 66daf1b..e454b2c 100644 --- a/nixos/configurations/ridcully.nix +++ b/nixos/configurations/ridcully.nix @@ -1,10 +1,5 @@ -{ - lib, - pkgs, - ... -}: let - inherit (lib) mkDefault; -in { +{pkgs, ...}: { + system.stateVersion = "24.05"; nixpkgs.hostPlatform.system = "x86_64-linux"; deploy.enable = true; @@ -15,17 +10,26 @@ in { openvpn = { elektroline = true; }; + borgjobs = { + hetzner-s3.paths = "/back/hetzner-s3-sync"; + }; }; - boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "usb_storage"]; + boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod"]; boot.kernelModules = ["kvm-amd"]; hardware.cpu.amd.updateMicrocode = true; services.hardware.openrgb.motherboard = "amd"; + zramSwap = { + enable = true; + memoryPercent = 50; + }; + cynerd.autounlock = { "encroot" = "/dev/disk/by-uuid/bc7d2ba4-6e04-4c49-b40c-3aecd1a86c71"; "enchdd" = "/dev/disk/by-uuid/7fee3cda-efa0-47cd-8832-fdead9a7e6db"; + "encback" = "/dev/disk/by-uuid/b426cbe7-fba2-473b-90f9-9ebe3e34b76e"; }; fileSystems = { "/" = { @@ -48,34 +52,72 @@ in { fsType = "btrfs"; options = ["compress=lzo" "subvol=@home"]; }; + "/back" = { + device = "/dev/mapper/encback"; + fsType = "btrfs"; + options = ["compress=lzo"]; + }; }; services.btrfs.autoScrub = { enable = true; fileSystems = ["/" "/home2"]; }; - #networking.vlans."enp6s0.adm" = { - #id = 2; - #interface = "enp6s0"; - #}; + networking = { + useNetworkd = true; + useDHCP = true; + }; + systemd.network = { + wait-online.enable = false; + }; environment.systemPackages = [ pkgs.nvtopPackages.amd + #sbctl ]; - services.syncthing = { - enable = true; - user = mkDefault "cynerd"; - group = mkDefault "cynerd"; - openDefaultPorts = true; + # Force nix to use less jobs + nix.settings.max-jobs = 4; + + ############################################################################## + services = { + syncthing = { + enable = true; + dataDir = "/home/cynerd"; + }; - overrideDevices = false; - overrideFolders = false; + #octoprint = { + # enable = true; + # openFirewall = true; + #}; - dataDir = "/home/cynerd"; - configDir = "/home/cynerd/.config/syncthing"; + #mjpg-streamer = { + # enable = true; + # inputPlugin = "input_uvc.so -d /dev/video2 -r 1920x1080 -f 30"; + # outputPlugin = "output_http.so -p 5001 -w @www@"; + #}; }; + networking.firewall.allowedTCPPorts = [5001]; - # Force nix to use less jobs - nix.settings.max-jobs = 8; + # Service to synchronize local copy of Hetzner S3 + systemd = { + services."hetzner-sync" = { + script = '' + /run/current-system/sw/bin/rclone --config /run/secrets/rclone-hetzner.conf \ + sync hetzner: /back/hetzner-s3-sync + ''; + serviceConfig = { + Type = "oneshot"; + User = "root"; + }; + }; + timers."hetzner-sync" = { + wantedBy = ["timers.target"]; + timerConfig.Unit = "hetzner-sync.service"; + timerConfig = { + OnCalendar = "daily"; + Persistent = false; + }; + }; + }; } diff --git a/nixos/configurations/spt-mox.nix b/nixos/configurations/spt-mox.nix index 4e29bca..d1e9208 100644 --- a/nixos/configurations/spt-mox.nix +++ b/nixos/configurations/spt-mox.nix @@ -1,12 +1,17 @@ -{config, ...}: { +{ + config, + pkgs, + ... +}: { + system.stateVersion = "24.05"; turris.board = "mox"; deploy = { enable = true; ssh.host = "mox.spt"; + configurationLimit = 8; }; cynerd = { - home-assistant = true; monitoring.drives = false; switch = { enable = true; @@ -17,19 +22,23 @@ enable = true; qca988x = { interface = "wlp1s0"; - bssids = ["04:f0:21:24:24:d2" "08:f0:21:24:24:d2"]; + bssids = config.secrets.wifiMacs.spt-mox.qca988x; channel = 7; }; }; }; - services.journald.extraConfig = '' - SystemMaxUse=512M - ''; + boot.initrd.availableKernelModules = ["dm-mod"]; - services.btrfs.autoScrub = { - enable = true; - fileSystems = ["/"]; + services = { + journald.settings.Journal = { + SystemMaxUse = "512M"; + }; + + btrfs.autoScrub = { + enable = true; + fileSystems = ["/"]; + }; }; networking = { @@ -42,13 +51,111 @@ networkConfig.Bridge = "brlan"; bridgeVLANs = [ { - bridgeVLANConfig = { - EgressUntagged = 1; - PVID = 1; + EgressUntagged = 1; + PVID = 1; + } + {VLAN = 2;} + ]; + }; + }; + + ############################################################################## + networking.firewall.allowedTCPPorts = [ + 1883 # Mosquitto + ]; + 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"; + }; + bigclown = { + acl = ["readwrite bigclown/#"]; + passwordFile = "/run/secrets/mosquitto.bigclown.pass"; + }; }; } - {bridgeVLANConfig.VLAN = 2;} ]; }; + + 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"]; + } + ]; + }; + + bcg = { + enable = true; + device = "/dev/ttyUSB0"; + baseTopicPrefix = "bigclown/"; + environmentFiles = ["/run/secrets/bigclown.env"]; + mqtt = { + username = "bigclown"; + password = "\${MQTT_PASSWORD}"; + }; + }; + }; + + systemd.services = { + telegraf.wants = ["mosquitto.service"]; + + 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"; + }; }; } diff --git a/nixos/configurations/spt-mox2.nix b/nixos/configurations/spt-mox2.nix index 9ffde96..1ddf23a 100644 --- a/nixos/configurations/spt-mox2.nix +++ b/nixos/configurations/spt-mox2.nix @@ -1,8 +1,10 @@ {config, ...}: { + system.stateVersion = "24.05"; turris.board = "mox"; deploy = { enable = true; ssh.host = "mox2.spt"; + configurationLimit = 8; }; cynerd = { @@ -16,19 +18,23 @@ enable = true; qca988x = { interface = "wlp1s0"; - bssids = ["04:f0:21:45:d3:47" "08:f0:21:45:d3:47"]; + bssids = config.secrets.wifiMacs.spt-mox2.qca988x; channel = 1; }; }; }; - services.journald.extraConfig = '' - SystemMaxUse=512M - ''; + boot.initrd.availableKernelModules = ["dm-mod"]; - services.btrfs.autoScrub = { - enable = true; - fileSystems = ["/"]; + services = { + journald.settings.Journal = { + SystemMaxUse = "512M"; + }; + + btrfs.autoScrub = { + enable = true; + fileSystems = ["/"]; + }; }; networking = { @@ -41,12 +47,10 @@ networkConfig.Bridge = "brlan"; bridgeVLANs = [ { - bridgeVLANConfig = { - EgressUntagged = 1; - PVID = 1; - }; + EgressUntagged = 1; + PVID = 1; } - {bridgeVLANConfig.VLAN = 2;} + {VLAN = 2;} ]; }; }; diff --git a/nixos/configurations/spt-mpd.nix b/nixos/configurations/spt-mpd.nix deleted file mode 100644 index b212932..0000000 --- a/nixos/configurations/spt-mpd.nix +++ /dev/null @@ -1,15 +0,0 @@ -{inputModules, ...}: { - imports = [inputModules.nixos-hardware.raspberry-pi-2]; - - config = { - nixpkgs.hostPlatform.system = "armv7l-linux"; - - fileSystems = { - "/" = { - device = "/dev/mmcblk0p1"; - fsType = "btrfs"; - options = ["compress=lzo"]; - }; - }; - }; -} diff --git a/nixos/configurations/spt-omnia.nix b/nixos/configurations/spt-omnia.nix index e97f29f..a593189 100644 --- a/nixos/configurations/spt-omnia.nix +++ b/nixos/configurations/spt-omnia.nix @@ -1,14 +1,12 @@ -{ - config, - pkgs, - ... -}: let +{config, ...}: let hosts = config.cynerd.hosts.spt; in { + system.stateVersion = "24.05"; turris.board = "omnia"; deploy = { enable = true; - ssh.host = "omnia.spt"; + ssh.host = "spt.cynerd.cz"; + configurationLimit = 16; }; cynerd = { @@ -21,19 +19,18 @@ in { "7c:b0:c2:bb:9c:ca" = hosts.albert; "4c:d5:77:0d:85:d9" = hosts.binky; "b8:27:eb:57:a2:31" = hosts.mpd; - "74:bf:c0:42:82:19" = hosts.printer; }; }; wifiAP.spt = { enable = true; ar9287 = { interface = "wlp1s0"; - bssids = ["04:f0:21:24:21:93" "08:f0:21:24:21:93"]; + bssids = config.secrets.wifiMacs.spt-omnia.ar9287; channel = 11; }; qca988x = { - interface = "wlp3s0"; - bssids = ["04:f0:21:23:16:64" "08:f0:21:23:16:64"]; + interface = "wlp2s0"; + bssids = config.secrets.wifiMacs.spt-omnia.qca988x; channel = 36; }; }; @@ -41,75 +38,21 @@ in { monitoring.speedtest = true; }; - services.journald.extraConfig = '' - SystemMaxUse=8G - ''; - - environment = { - etc.crypttab.text = '' - nas UUID=3472bef9-cbae-48bd-873e-fd4858a0b72f /run/secrets/luks-spt-omnia-nas.key luks - nassec UUID=016e9e75-bbc8-4b24-8bb7-c800c8f6a500 /run/secrets/luks-spt-omnia-nas.key luks - ''; - systemPackages = with pkgs; [ - cryptsetup - ]; - }; - fileSystems = { - "/data" = { - device = "/dev/mapper/nas"; - fsType = "btrfs"; - options = ["compress=lzo" "subvol=@data" "nofail"]; + services = { + journald.settings.Journal = { + SystemMaxUse = "8G"; }; - "/srv" = { - device = "/dev/mapper/nas"; - fsType = "btrfs"; - options = ["compress=lzo" "subvol=@srv" "nofail"]; - depends = ["/data"]; + + btrfs.autoScrub = { + enable = false; # TODO https://github.com/NixOS/nixpkgs/pull/564119 + fileSystems = ["/"]; }; - }; - services.btrfs.autoScrub = { - enable = true; - fileSystems = ["/" "/data"]; - }; - services.udev.packages = [ - (pkgs.writeTextFile rec { - name = "queue_depth_sata.rules"; - destination = "/etc/udev/rules.d/50-${name}"; - text = '' - SUBSYSTEMS=="pci", DRIVER=="ahci", ATTR{device}!="0x0612", GOTO="turris_pci_end" - ACTION=="add|change", SUBSYSTEM=="scsi", ATTR{vendor}=="ATA", ATTR{queue_depth}="1" - LABEL="turris_pci_end" - ''; - }) - ]; - users = { - groups.nas = {}; - users = { - nas = { - group = "nas"; - openssh.authorizedKeys.keyFiles = [ - (config.personal-secrets + "/unencrypted/nas.pub") - (config.personal-secrets + "/unencrypted/nas-spt.pub") - ]; - isNormalUser = true; - home = "/data/nas"; - homeMode = "770"; - }; - cynerd.extraGroups = ["nas"]; + fail2ban = { + enable = true; + ignoreIP = ["10.8.1.0/24" "10.8.2.0/24"]; }; }; - services.openssh = { - settings.Macs = ["hmac-sha2-256"]; # Allow sha2-256 for Nexcloud access - extraConfig = '' - Match User nas - X11Forwarding no - AllowTcpForwarding no - AllowAgentForwarding no - ForceCommand internal-sftp -d /data/nas - ''; - }; - services.fail2ban.enable = true; networking.useDHCP = false; systemd.network = { @@ -156,12 +99,10 @@ in { networkConfig.Bridge = "brlan"; bridgeVLANs = [ { - bridgeVLANConfig = { - EgressUntagged = 1; - PVID = 1; - }; + EgressUntagged = 1; + PVID = 1; } - {bridgeVLANConfig.VLAN = 2;} + {VLAN = 2;} ]; }; }; @@ -179,24 +120,32 @@ in { defaultroute6 #usepeerdns maxfail 1 + #holdoff 5 + #persist user metronet password metronet ''; }; - systemd.services."pppd-wan".after = ["sys-subsystem-net-devices-end2.848.device"]; + systemd.services."pppd-wan" = { + after = ["sys-subsystem-net-devices-end2.848.device"]; + partOf = ["systemd-networkd.service"]; + serviceConfig = { + Restart = "always"; + StartLimitBurst = 0; + }; + }; # TODO limit NSS clamping to just pppoe-wan networking.firewall.extraForwardRules = '' tcp flags syn tcp option maxseg size set rt mtu comment "Needed for PPPoE to fix IPv4" - iifname {"home", "personalvpn", "wg"} oifname {"home", "personalvpn", "wg"} accept + iifname {"home", "wg"} oifname {"home", "wg"} accept ''; - services.syncthing = { - enable = false; - openDefaultPorts = true; - - overrideDevices = false; - overrideFolders = false; - - dataDir = "/data"; # TODO this can't be the location + ############################################################################## + cynerd.ha = { + enable = true; + domain = "spt.cynerd.cz"; + extraOptions = [ + "--device=/dev/serial/by-id/usb-ITEAD_SONOFF_Zigbee_3.0_USB_Dongle_Plus_V2_20220812153849-if00:/dev/ttyACM0" + ]; }; } diff --git a/nixos/configurations/zd-mox.nix b/nixos/configurations/zd-mox.nix new file mode 100644 index 0000000..01f5a8b --- /dev/null +++ b/nixos/configurations/zd-mox.nix @@ -0,0 +1,164 @@ +{ + config, + pkgs, + ... +}: let + hosts = config.cynerd.hosts.zd; +in { + system.stateVersion = "25.05"; + turris.board = "mox"; + deploy = { + enable = true; + ssh.host = "zd.cynerd.cz"; + configurationLimit = 8; + }; + + cynerd = { + router = { + enable = true; + wan = "pppoe-wan"; + lanIP = hosts.mox; + staticLeases = { + "4c:d5:77:0d:85:d9" = hosts.binky; + "70:85:c2:4a:59:f2" = hosts.ridcully; + "74:bf:c0:42:82:19" = hosts.printer; + "f8:dc:7a:79:00:e6" = hosts.tc; + "34:94:54:33:6b:48" = hosts.vb; + }; + }; + wireguard = true; + monitoring.speedtest = true; + }; + + boot.initrd.availableKernelModules = ["dm-mod"]; + + services = { + journald.settings.Journal = { + SystemMaxUse = "512M"; + }; + + btrfs.autoScrub = { + enable = false; # TODO https://github.com/NixOS/nixpkgs/pull/564119 + fileSystems = ["/"]; + }; + + fail2ban = { + enable = true; + ignoreIP = ["10.8.0.0/24" "10.8.1.0/24" "10.8.2.0/24"]; + }; + }; + + networking.useDHCP = false; + systemd.network = { + netdevs = { + "end0.848" = { + netdevConfig = { + Kind = "vlan"; + Name = "end0.848"; + }; + vlanConfig.Id = 848; + }; + }; + networks = { + "end0" = { + matchConfig.Name = "end0"; + networkConfig.VLAN = ["end0.848"]; + }; + "end0.848" = { + matchConfig.Name = "end0.848"; + networkConfig.BindCarrier = "end0"; + }; + "pppoe-wan" = { + matchConfig.Name = "pppoe-wan"; + networkConfig = { + BindCarrier = "end0.848"; + DHCP = "ipv6"; + IPv6AcceptRA = "no"; + DHCPPrefixDelegation = "yes"; + #DNS = ["84.19.64.3" "84.19.64.4" "1.1.1.1"]; + DNS = "1.1.1.1"; + }; + dhcpV6Config = { + PrefixDelegationHint = "::/56"; + UseDNS = "no"; + }; + dhcpPrefixDelegationConfig = { + UplinkInterface = ":self"; + SubnetId = 0; + Announce = "no"; + }; + linkConfig.RequiredForOnline = "routable"; + }; + "lan-brlan" = { + matchConfig.Name = "lan*"; + networkConfig.Bridge = "brlan"; + bridgeVLANs = [ + { + EgressUntagged = 1; + PVID = 1; + } + {VLAN = 2;} + ]; + }; + }; + }; + + services.pppd = { + enable = true; + peers."wan".config = '' + plugin pppoe.so end0.848 + ifname pppoe-wan + lcp-echo-interval 1 + lcp-echo-failure 5 + lcp-echo-adaptive + defaultroute + defaultroute6 + maxfail 1 + #holdoff 5 + #persist + # user and password added in secrets + ''; + }; + systemd.services = { + "pppd-wan" = { + requires = ["sys-subsystem-net-devices-end0.848.device"]; + partOf = ["systemd-networkd.service"]; + serviceConfig = { + Restart = "always"; + StartLimitBurst = 0; + }; + }; + "systemd-networkd".environment.SYSTEMD_LOG_LEVEL = "debug"; + }; + # TODO limit NSS clamping to just pppoe-wan + networking.firewall.extraForwardRules = '' + tcp flags syn tcp option maxseg size set rt mtu comment "Needed for PPPoE to fix IPv4" + iifname {"home", "wg"} oifname {"home", "wg"} accept + ''; + + services.nginx = { + enable = true; + virtualHosts = { + "zd.cynerd.cz" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://${hosts.one0}:8123"; + proxyWebsockets = true; + recommendedProxySettings = true; + }; + }; + }; + }; + security.acme = { + acceptTerms = true; + defaults.email = "cynerd+acme@email.cz"; + certs."zd.cynerd.cz" = {}; + }; + networking.firewall.allowedTCPPorts = [80 443]; + + environment.systemPackages = with pkgs; [ + nmap + tcpdump + ]; +} diff --git a/nixos/configurations/zd-one0.nix b/nixos/configurations/zd-one0.nix new file mode 100644 index 0000000..52f673b --- /dev/null +++ b/nixos/configurations/zd-one0.nix @@ -0,0 +1,65 @@ +{config, ...}: { + system.stateVersion = "25.11"; + deploy = { + enable = true; + #ssh.host = "zd-one0"; + ssh.host = "one0nix"; + }; + + cynerd = { + openwrtone = true; + switch = { + enable = true; + lanAddress = "${config.cynerd.hosts.zd.one0nix}/24"; + lanGateway = config.cynerd.hosts.zd.mox; + }; + wifiAP.zd = { + enable = false; + wlan0 = { + bssids = [ + "20:05:b7:00:4c:02" + "20:05:b7:04:4c:02" + "20:05:b7:08:4c:02" + ]; + channel = 7; + }; + }; + }; + + boot.initrd.availableKernelModules = ["dm-mod"]; + boot.consoleLogLevel = 7; + + services = { + journald.settings.Journal = { + SystemMaxUse = "32G"; + }; + + btrfs.autoScrub = { + enable = false; # TODO https://github.com/NixOS/nixpkgs/pull/564119 + fileSystems = ["/"]; + }; + + fail2ban = { + enable = true; + ignoreIP = ["10.8.0.0/24" "10.8.1.0/24" "10.8.2.0/24"]; + }; + }; + + networking = { + useNetworkd = true; + useDHCP = false; + }; + systemd.network.networks = { + "lan-brlan" = { + matchConfig.Name = "end*"; + networkConfig.Bridge = "brlan"; + bridgeVLANs = [ + { + EgressUntagged = 1; + PVID = 1; + } + {VLAN = 2;} + ]; + }; + }; +} diff --git a/nixos/modules/autounlock.nix b/nixos/modules/autounlock.nix index d7d6a7c..912f55f 100644 --- a/nixos/modules/autounlock.nix +++ b/nixos/modules/autounlock.nix @@ -18,6 +18,7 @@ in { config = mkIf (cnf != {}) { environment.systemPackages = [pkgs.luks-hw-password]; boot.initrd = { + systemd.enable = false; extraFiles."/luks-hw-password".source = pkgs.luks-hw-password; luks.devices = mapAttrs (name: value: { 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 3146c15..0000000 --- a/nixos/modules/bcg.nix +++ /dev/null @@ -1,167 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -with lib; let - cfg = config.services.bcg; - configFile = (pkgs.formats.yaml {}).generate "bcg.conf.yaml" ( - filterAttrsRecursive (_: 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/compile.nix b/nixos/modules/compile.nix index 3c90345..332a095 100644 --- a/nixos/modules/compile.nix +++ b/nixos/modules/compile.nix @@ -20,7 +20,10 @@ in { cores = 0; }; - boot.binfmt.emulatedSystems = ["armv7l-linux" "aarch64-linux" "riscv32-linux"]; + boot.binfmt = { + emulatedSystems = ["armv7l-linux" "aarch64-linux" "riscv32-linux"]; + preferStaticEmulators = true; + }; environment.systemPackages = with pkgs; [ # Tools @@ -28,9 +31,6 @@ in { bash #uroot qemu - - # Python - python3Packages.pip ]; }; } diff --git a/nixos/modules/default.nix b/nixos/modules/default.nix index 6bc0d70..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 0c8f287..007f1df 100644 --- a/nixos/modules/desktop.nix +++ b/nixos/modules/desktop.nix @@ -24,9 +24,9 @@ in { config = mkIf cnf.enable { hardware = { - opengl = { - driSupport = true; - driSupport32Bit = true; + graphics = { + enable = true; + enable32Bit = true; }; bluetooth.enable = mkIf cnf.laptop true; }; @@ -37,7 +37,9 @@ in { wrapperFeatures.gtk = true; extraPackages = with pkgs; [ - gnome.dconf-editor + appimage-run + + dconf-editor glib gsettings-desktop-schemas sysstat @@ -47,17 +49,19 @@ in { waybar swaybackground myswaylock + brightnessctl alacritty - gnome.nautilus + nautilus kanshi + shikane wdisplays wayvnc wl-mirror slurp grim - wf-recorder + #wf-recorder wl-clipboard wl-color-picker swayidle @@ -67,30 +71,34 @@ in { resources isync + davmail 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 + ranger chromium + tangram ferdium signal-desktop - libreoffice mupdf zathura pdfgrep + libreoffice-qt + hunspell + hunspellDicts.en_US-large + hunspellDicts.en_GB-large + hunspellDicts.cs_CZ + xdg-utils xdg-launch mesa-demos @@ -98,23 +106,22 @@ in { pulsemixer mpd - mpc-cli - ncmpcpp + mpc + #ncmpcpp feh shotwell 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]) @@ -124,8 +131,8 @@ in { tigervnc freerdp - plasma5Packages.kdeconnect-kde + gnome-firmware hdparm ethtool multipath-tools @@ -143,32 +150,31 @@ in { gimp inkscape blender - kdenlive + tenacity + kdePackages.kdenlive + qrrs # 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 # Writing typst - typst-fmt - typst-live - typst-lsp + typstyle + tinymist vale - # Gnome utils - gnome-firmware - #gaphor - # CAD - freecad + #freecad kicad sweethome3d.application qelectrotech + super-slicer ] ++ (optionals cnf.laptop [ # Power management @@ -183,11 +189,9 @@ in { nativeMessagingHosts.packages = with pkgs; [browserpass]; }; - light.enable = mkIf cnf.laptop true; - - nix-ld = { + fuse = { enable = true; - libraries = with pkgs; [xorg.libXpm]; + userAllowOther = true; }; usbkey = { @@ -202,7 +206,16 @@ in { enable = true; enableSSHSupport = true; enableBrowserSocket = true; + pinentryPackage = pkgs.writeShellScriptBin "pinentry-auto" '' + if [ -n "$WAYLAND_DISPLAY" ] || [ -n "$DISPLAY" ]; then + exec ${pkgs.pinentry-gnome3}/bin/pinentry-gnome3 "$@" + else + exec ${pkgs.pinentry-gnome3}/bin/pinentry-curses "$@" + fi + ''; }; + + kdeconnect.enable = true; }; xdg = { @@ -241,17 +254,24 @@ in { xserver.xkb.options = "grp:alt_shift_toggle,caps:escape"; # Gnome crypto services (GnuPG) - dbus.packages = [pkgs.gcr]; + dbus.packages = [pkgs.gcr_4]; pipewire = { enable = true; alsa.enable = true; alsa.support32Bit = true; pulse.enable = true; - extraConfig.pipewire."10-zeroconf" = { - "context.modules" = [{name = "libpipewire-module-zeroconf-discover";}]; - }; + configPackages = [ + (pkgs.writeTextDir "share/pipewire/pipewire.conf.d/10-zeroconf-discover.conf" '' + context.modules = [ + { name = libpipewire-module-zeroconf-discover + args = { } + } + ] + '') + ]; }; + playerctld.enable = true; upower.enable = true; hardware.openrgb = { @@ -267,14 +287,46 @@ in { cnijfilter2 ]; }; + saned.enable = true; avahi.enable = true; + samba = { + enable = false; + openFirewall = true; + settings = { + global = { + "workgroup" = "WORKGROUP"; + "server string" = "smbnix"; + "netbios name" = "smbnix"; + "security" = "user"; + "hosts allow" = "0.0.0.0/0"; + "guest account" = "nobody"; + "map to guest" = "bad user"; + }; + public = { + "path" = "/mnt/public"; + "browseable" = "yes"; + "read only" = "no"; + "guest ok" = "yes"; + "create mask" = "0644"; + "directory mask" = "0755"; + "force user" = "cynerd"; + "force group" = "cynerd"; + }; + }; + }; samba-wsdd = { - enable = true; + enable = false; discovery = true; }; - davfs2.enable = true; + #davfs2.enable = true; TODO!!! locate.enable = true; + + gnome = { + at-spi2-core.enable = true; + gnome-keyring.enable = true; + gnome-online-accounts.enable = true; + }; }; # Beneficial for Pipewire @@ -286,22 +338,30 @@ in { allowedUDPPorts = [3702]; }; - fonts.packages = with pkgs; [ - (nerdfonts.override {fonts = ["Hack"];}) - arkpandora_ttf - corefonts - dejavu_fonts - font-awesome - freefont_ttf - hack-font - liberation_ttf - libertine - noto-fonts - noto-fonts-emoji - terminus_font_ttf - ubuntu_font_family - unifont - ]; + fonts = { + enableDefaultPackages = true; + packages = with pkgs; [ + arkpandora_ttf + corefonts + dejavu_fonts + fira-code + fira-code-symbols + fira-math + fira-mono + fira-sans + font-awesome + freefont_ttf + hack-font + liberation_ttf + libertine + nerd-fonts.hack + noto-fonts + noto-fonts-color-emoji + terminus_font_ttf + ubuntu-classic + unifont + ]; + }; documentation = { enable = true; @@ -334,13 +394,13 @@ in { }; # Support running app images - boot.binfmt.registrations.appimage = { - wrapInterpreterInShell = false; - interpreter = "${pkgs.appimage-run}/bin/appimage-run"; - recognitionType = "magic"; - offset = 0; - mask = ''\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff''; - magicOrExtension = ''\x7fELF....AI\x02''; - }; + #boot.binfmt.registrations.appimage = { + # wrapInterpreterInShell = false; + # interpreter = "${pkgs.appimage-run}/bin/appimage-run"; + # recognitionType = "magic"; + # offset = 0; + # mask = ''\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff''; + # magicOrExtension = ''\x7fELF....AI\x02''; + #}; }; } diff --git a/nixos/modules/develop.nix b/nixos/modules/develop.nix index a18c7ac..7c00f1b 100644 --- a/nixos/modules/develop.nix +++ b/nixos/modules/develop.nix @@ -15,12 +15,16 @@ in { }; config = mkIf config.cynerd.develop { - cynerd.compile = true; - environment.enableDebugInfo = true; + cynerd = { + devmin = true; + compile = true; + }; environment.systemPackages = with pkgs; [ # Tools + git-lfs gitlint tig + gitg gource glab github-cli @@ -29,8 +33,10 @@ in { openssl tio vim-vint - nodePackages.vim-language-server + vim-language-server vale + can-utils + unixtools.xxd # Required for neovim plugins editorconfig-checker @@ -41,30 +47,35 @@ in { dev cachix nurl - nix-universal-prefetch nil + nixfmt alejandra statix deadnix agenix nix-tree + nix-output-monitor # Shell dash # Posix shell bats shellcheck shfmt - nodePackages.bash-language-server + bash-language-server jq yq fq # C clang-tools + bear + #massif-visualizer + elf-size-analyze # Python (python3.withPackages (pypkgs: with pypkgs; [ + pip ipython python-lsp-server @@ -75,15 +86,17 @@ in { mypy scipy + statsmodels sympy pygraphviz matplotlib + seaborn plotly pygal python-gitlab - PyGithub + pygithub schema jinja2 @@ -102,8 +115,14 @@ in { pyserial pylibftdi + pyusb + usbtmc + pylxd selenium + + pyvisa + pyvisa-py ])) ruff geckodriver @@ -120,19 +139,21 @@ in { # Julia julia + # XML + libxml2 + # Qemmu qemu virt-manager cdrtools + # Docker + docker-credential-helpers + # U-Boot ubootTools tftp-hpa - # Network - iperf3 - inetutils - # Gtk cambalache @@ -148,13 +169,56 @@ in { linux-manual stdmanpages - # SHV - shvcli + # Writing documentation + docstrfmt # Images imagemagick + + # S3 + rclone ]; - programs.wireshark.package = pkgs.wireshark; + #programs.wireshark = { + # enable = true; + # package = pkgs.wireshark; + #}; + + programs.nix-ld = { + enable = true; + libraries = with pkgs; [ + alsa-lib + at-spi2-atk + cairo + cups + dbus + expat + gdk-pixbuf + glib + gtk3 + libGL + libXpm + libdrm + libgbm + libgcrypt + libsoup_3 + libudev0-shim + libusb1 + libx11 + libxcb + libxcomposite + libxdamage + libxext + libxfixes + libxkbcommon + libxrandr + nspr + nss + openssl + pango + udev + webkitgtk_4_1 + ]; + }; documentation = { nixos = { @@ -165,12 +229,18 @@ in { doc.enable = true; }; - services.udev.extraRules = '' - SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", MODE:="0660", GROUP="develop", SYMLINK+="stlinkv2_%n" - 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" - ''; + services.guix.enable = true; + #environment.etc."guix/machines.scm".text = '' + # (list (build-machine + # (name "czellembsrv.elektroline.cz") + # (systems (list "x86_64-linux" "i686-linux")) + # (host-key "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQZIwdzBo5CvMjS0M9tKYG2ikqPmSgSKRa/UPAoyhBC root@embsrv") + # (user "kkoci") + # (private-key "/home/cynerd/.ssh/elektroline-emb") + # (parallel-builds 16) + # (speed 2.0) + # )) + #''; virtualisation = { containers.enable = true; @@ -179,20 +249,21 @@ in { autoPrune.enable = true; storageDriver = "btrfs"; }; - lxd = { + lxc.enable = true; + libvirtd = { enable = true; - recommendedSysctlSettings = true; + qemu = { + swtpm.enable = true; + vhostUserPackages = with pkgs; [virtiofsd]; + }; }; - lxc.enable = true; - libvirtd.enable = true; spiceUSBRedirection.enable = true; }; + networking.firewall.trustedInterfaces = ["virbr0"]; - users.groups.develop = {}; users.users.cynerd.extraGroups = [ "docker" "lxd" - "develop" "libvirtd" ]; }; diff --git a/nixos/modules/devmin.nix b/nixos/modules/devmin.nix new file mode 100644 index 0000000..e317af1 --- /dev/null +++ b/nixos/modules/devmin.nix @@ -0,0 +1,48 @@ +{ + config, + lib, + pkgs, + ... +}: let + inherit (lib) mkOption mkIf types; +in { + options = { + cynerd.devmin = mkOption { + type = types.bool; + default = false; + description = "If machine is about to be used for remote development."; + }; + }; + + config = mkIf config.cynerd.devmin { + environment = { + enableDebugInfo = true; + systemPackages = with pkgs; [ + # Network + iperf3 + inetutils + + # SHV + (shvcli.withPlugins [python3Packages.shvcli-ell]) + ]; + }; + + users.groups.develop = {}; + users.users.cynerd.extraGroups = [ + "develop" + ]; + + services.udev.extraRules = '' + SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", MODE:="0660", GROUP="develop", SYMLINK+="stlinkv2_%n" + 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}=="0451", ATTRS{idProduct}=="bef3", MODE:="0660", GROUP="develop", SYMLINK+="xds110_%n" + SUBSYSTEMS=="usb", ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00ff", MODE:="0660", GROUP="develop", SYMLINK+="xds110_update_%n" + SUBSYSTEMS=="usb", ATTRS{idVendor}=="0451", ATTRS{idProduct}=="16a2", MODE:="0660", GROUP="develop", SYMLINK+="ccdebugger_%n" + SUBSYSTEMS=="usb", ATTRS{idVendor}=="1ab1", ATTRS{idProduct}=="0e11", MODE:="0660", GROUP="develop" + SUBSYSTEMS=="usb", ATTRS{idVendor}=="303a", ATTRS{idProduct}=="1001", MODE:="0660", GROUP="develop", TAG+="uaccess" + SUBSYSTEMS=="usb", ATTRS{idVendor}=="303a", ATTRS{idProduct}=="1002", MODE:="0660", GROUP="develop", TAG+="uaccess" + ''; + }; +} diff --git a/nixos/modules/gaming.nix b/nixos/modules/gaming.nix index 64af068..e939bf2 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; @@ -30,9 +37,29 @@ in { extraPkgs = pkgs: with pkgs; [ ncurses - xorg.libXpm - flac1_3 + libxpm + flac134 + libopus + ]; + }; + heroic = pkgs.heroic.override { + extraPkgs = pkgs: + with pkgs; [ + ncurses + libxpm + flac134 # For Nebuchadnezzar libopus + SDL + SDL2_image + SDL2_mixer + SDL2_ttf + SDL_image + SDL_mixer + SDL_ttf + glew_1_10 + libdrm + libidn + tbb ]; }; }; diff --git a/nixos/modules/generic.nix b/nixos/modules/generic.nix index 02afd17..3e8abaf 100644 --- a/nixos/modules/generic.nix +++ b/nixos/modules/generic.nix @@ -6,20 +6,10 @@ 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 = [ - "https://thefloweringash-armv7.cachix.org" - "https://arm.cachix.org" - ]; - trusted-public-keys = [ - "thefloweringash-armv7.cachix.org-1:v+5yzBD2odFKeXbmC+OPWVqx4WVoIVO6UXgnSAWFtso=" - "arm.cachix.org-1:K3XjAeWPgWkFtSS9ge5LJSLw3xgnNqyOaG7MDecmTQ8=" - ]; trusted-users = ["@wheel"]; }; registry = { @@ -31,13 +21,16 @@ 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"]; }; - hardware.enableAllFirmware = true; - services.fwupd.enable = mkDefault (pkgs.system == "x86_64-linux"); + hardware.enableAllFirmware = mkDefault true; + services.fwupd.enable = mkDefault (pkgs.stdenv.hostPlatform.system == "x86_64-linux"); systemd.oomd.enable = false; networking = { @@ -59,11 +52,6 @@ in { }) ]; - system.extraSystemBuilderCmds = '' - substituteAll ${./nixos-system.sh} $out/bin/nixos-system - chmod +x $out/bin/nixos-system - ''; - 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/homeassistant.nix b/nixos/modules/homeassistant.nix new file mode 100644 index 0000000..f7ebe9c --- /dev/null +++ b/nixos/modules/homeassistant.nix @@ -0,0 +1,57 @@ +{ + config, + lib, + ... +}: let + inherit (lib) mkOption mkEnableOption types mkIf; + cnf = config.cynerd.ha; +in { + options.cynerd.ha = { + enable = mkEnableOption "Home assistant setup on the primary router."; + domain = mkOption { + type = with types; str; + description = "The domain name of the system."; + }; + extraOptions = mkOption { + type = with types; listOf str; + default = []; + description = "Extra options passed to the container."; + }; + }; + + config = mkIf cnf.enable { + virtualisation.oci-containers = { + backend = "podman"; + containers.homeassistant = { + volumes = ["home-assistant:/config" "/run/dbus:/run/dbus:ro"]; + environment.TZ = "Europe/Prague"; + image = "ghcr.io/home-assistant/armv7-homeassistant:latest"; + extraOptions = + ["--privileged" "--network=host"] + ++ cnf.extraOptions; + }; + }; + + services.nginx = { + enable = true; + virtualHosts = { + "${cnf.domain}" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://localhost:8123"; + proxyWebsockets = true; + recommendedProxySettings = true; + }; + }; + }; + }; + security.acme = { + acceptTerms = true; + defaults.email = "cynerd+acme@email.cz"; + certs."${cnf.domain}" = {}; + }; + + networking.firewall.allowedTCPPorts = [80 443]; + }; +} diff --git a/nixos/modules/hosts.nix b/nixos/modules/hosts.nix index e7ad76b..0aafb12 100644 --- a/nixos/modules/hosts.nix +++ b/nixos/modules/hosts.nix @@ -19,7 +19,7 @@ in { default = true; description = "Use my personal static hosts"; }; - vpn = staticZoneOption; + zd = staticZoneOption; wg = staticZoneOption; spt = staticZoneOption; adm = staticZoneOption; @@ -28,9 +28,21 @@ in { config = { cynerd.hosts = { - vpn = { - "lipwig" = "10.8.0.1"; - "adm-omnia" = "10.8.0.51"; + zd = { + # Network + "mox" = "10.8.0.1"; + "one0" = "10.8.0.2"; + "one0nix" = "10.8.0.3"; + "camera1" = "10.8.0.21"; + "camera2" = "10.8.0.22"; + # Local + "ridcully" = "10.8.0.59"; + "dribbler" = "10.8.0.60"; + "tc" = "10.8.0.99"; + "vb" = "10.8.0.98"; + "printer" = "10.8.0.90"; + # Portable + "binky" = "10.8.0.63"; }; wg = { "lipwig" = "10.8.1.1"; @@ -40,6 +52,7 @@ in { # Endpoints "spt-omnia" = "10.8.1.50"; "adm-omnia" = "10.8.1.51"; + "zd-mox" = "10.8.1.52"; # Endpoints without routing "dean" = "10.8.1.59"; }; @@ -51,7 +64,6 @@ in { # Local "mpd" = "10.8.2.51"; "errol" = "10.8.2.60"; - "printer" = "10.8.2.90"; # Portable "albert" = "10.8.2.61"; "binky" = "10.8.2.63"; @@ -61,25 +73,27 @@ in { "omnia" = "10.8.3.1"; "omnia2" = "10.8.3.3"; # Local - "ridcully" = "10.8.3.60"; "3dprint" = "10.8.3.80"; - "mpd" = "10.8.3.51"; + "printer" = "10.8.3.20"; # Portable - "albert" = "10.8.3.61"; "binky" = "10.8.3.63"; }; }; networking.hosts = mkIf cnf.enable { - # VPN - "${cnf.vpn.lipwig}" = ["lipwig.vpn"]; - "${cnf.vpn.adm-omnia}" = ["adm.vpn"]; + # Zd + "${cnf.zd.mox}" = ["mox.zd"]; + "${cnf.zd.one0}" = ["one0.zd"]; + "${cnf.zd.ridcully}" = ["ridcully"]; + "${cnf.zd.tc}" = ["tc.zd"]; + "${cnf.zd.binky}" = ["binky.zd"]; # Wireguard "${cnf.wg.lipwig}" = ["lipwig.wg"]; "${cnf.wg.binky}" = ["binky.wg"]; "${cnf.wg.android}" = ["android.wg"]; "${cnf.wg.spt-omnia}" = ["spt.wg"]; "${cnf.wg.adm-omnia}" = ["adm.wg"]; + "${cnf.wg.zd-mox}" = ["zd.wg"]; "${cnf.wg.dean}" = ["dean" "dean.wg"]; # Spt "${cnf.spt.omnia}" = ["omnia.spt"]; @@ -87,18 +101,15 @@ in { "${cnf.spt.mox2}" = ["mox2.spt"]; "10.8.2.4" = ["mi3g.spt"]; "${cnf.spt.mpd}" = ["mpd.spt"]; - "${cnf.spt.errol}" = ["errol" "desktop.spt"]; + "${cnf.spt.errol}" = ["errol"]; "${cnf.spt.albert}" = ["albert.spt"]; "${cnf.spt.binky}" = ["binky.spt"]; # Adm "${cnf.adm.omnia}" = ["omnia.adm"]; "10.8.3.2" = ["redmi.adm"]; "${cnf.adm.omnia2}" = ["omnia2.adm"]; - "${cnf.adm.ridcully}" = ["ridcully" "desktop.adm"]; - "${cnf.adm.albert}" = ["albert.adm"]; "${cnf.adm.binky}" = ["binky.adm"]; - "${cnf.adm."3dprint"}" = ["3dprint"]; - "${cnf.adm.mpd}" = ["mpd.adm"]; + "${cnf.adm.printer}" = ["printer.adm"]; }; }; } diff --git a/nixos/modules/monitoring.nix b/nixos/modules/monitoring.nix index 394915a..96761b9 100644 --- a/nixos/modules/monitoring.nix +++ b/nixos/modules/monitoring.nix @@ -32,6 +32,12 @@ in { config = mkMerge [ (mkIf cnf.enable { + # Glances + services.glances = { + enable = true; + openFirewall = true; + }; + # Telegraf configuration services.telegraf = { enable = true; @@ -78,7 +84,7 @@ in { nstat = [{}]; system = [{}]; processes = [{}]; - systemd_units = [{}]; + systemd_units = [{details = true;}]; wireguard = [{}]; } // (optionalAttrs cnf.drives { @@ -136,8 +142,8 @@ in { }) (mkIf (config.networking.hostName == "lipwig") { - # InfluxDB services = { + # InfluxDB influxdb2.enable = true; telegraf.extraConfig.inputs.prometheus = { urls = ["http://localhost:8086/metrics"]; @@ -150,8 +156,11 @@ in { security = { admin_user = "cynerd"; admin_password = "$__file{/run/secrets/grafana.admin.pass}"; + secret_key = "SW2YcwTIb9zpOOhoPsMm"; }; 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..8837904 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 = '' @@ -48,6 +40,10 @@ in { ${pkgs.systemd}/bin/resolvectl domain "$dev" "~$domain" ''; }; + ellshv = mkIf cnf.elektroline { + config = "config /run/secrets/ellshv.ovpn"; + autoStart = false; + }; }; }; } diff --git a/nixos/modules/openwrtone.nix b/nixos/modules/openwrtone.nix new file mode 100644 index 0000000..b4ffe06 --- /dev/null +++ b/nixos/modules/openwrtone.nix @@ -0,0 +1,119 @@ +{ + config, + lib, + pkgs, + modulesPath, + extendModules, + ... +}: let + inherit (lib) mkEnableOption mkIf mkDefault; + variant = extendModules { + modules = [ + { + boot.postBootCommands = '' + # On the first boot do some maintenance tasks + if [ -f /nix-path-registration ]; then + set -euo pipefail + + # Register the contents of the initial Nix store + ${config.nix.package.out}/bin/nix-store --load-db < /nix-path-registration + + # nixos-rebuild also requires a "system" profile and an /etc/NIXOS tag. + touch /etc/NIXOS + ${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system + + # Prevents this from running on later boots. + rm -f /nix-path-registration + fi + ''; + # We do not have generations in the initial image + boot.loader.generic-extlinux-compatible.configurationLimit = 0; + } + ]; + }; + inherit (variant.config.system.build) toplevel; +in { + options.cynerd.openwrtone = mkEnableOption "Configuration for OpenWrt One"; + + config = mkIf config.cynerd.openwrtone { + nixpkgs = { + hostPlatform = { + config = "aarch64-unknown-linux-gnu"; + system = "aarch64-linux"; + }; + buildPlatform = { + config = "x86_64-unknown-linux-gnu"; + system = "x86_64-linux"; + }; + }; + + # We do not need Grub as U-Boot supports boot using extlinux like file + boot = { + loader = { + grub.enable = mkDefault false; + systemd-boot.enable = mkDefault false; + generic-extlinux-compatible.enable = mkDefault true; + }; + + # Use OpenWrt One specific kernel. It fixes SError with patch. + kernelPackages = mkDefault (pkgs.linuxPackagesFor pkgs.linux_7_2); + kernelParams = [ + "fw_devlink=permissive" + "clk_ignore_unused" + ]; + + initrd = { + kernelModules = ["pcie-mediatek-gen3" "nvme"]; + # This includes modules to support common PC manufacturers but is not + # something required on embedded device. + includeDefaultModules = false; + supportedFilesystems = ["btrfs"]; + }; + supportedFilesystems = ["btrfs"]; + }; + hardware.deviceTree.name = mkDefault "mediatek/mt7981b-openwrt-one.dtb"; + + # Cover nix memory consumption peaks by compressing the RAM + zramSwap = mkDefault { + enable = true; + memoryPercent = 80; + }; + + fileSystems = { + "/boot" = mkDefault { + device = "/dev/nvme0n1p1"; + fsType = "vfat"; + }; + "/" = mkDefault { + device = "/dev/nvme0n1p2"; + fsType = "btrfs"; + }; + }; + + environment.systemPackages = with pkgs; [ + iw + ]; + + # No need for installer tools in standard system + system.disableInstallerTools = true; + # No need for NixOS documentation in headless system + documentation.nixos.enable = mkDefault false; + + system.build.tarball = pkgs.callPackage "${modulesPath}/../lib/make-system-tarball.nix" { + extraCommands = pkgs.buildPackages.writeShellScript "tarball-extra-commands" '' + ${variant.config.boot.loader.generic-extlinux-compatible.populateCmd} \ + -c ${toplevel} -d ./boot + ''; + contents = []; + + storeContents = + map (x: { + object = x; + symlink = "none"; + }) [ + toplevel + pkgs.stdenv + ]; + }; + }; +} diff --git a/nixos/modules/packages.nix b/nixos/modules/packages.nix index d321901..a85f14a 100644 --- a/nixos/modules/packages.nix +++ b/nixos/modules/packages.nix @@ -1,11 +1,11 @@ { - config, lib, pkgs, ... }: let inherit (lib) optionals; - isNative = config.nixpkgs.hostPlatform == config.nixpkgs.buildPlatform; + inherit (pkgs.stdenv.hostPlatform) isx86_64; + isNative = pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform; in { nixpkgs = { config.allowUnfree = true; @@ -41,14 +41,12 @@ in { btop iotop mc - screen - tmux - pv # ls tools tree lsof strace + ripgrep sourceHighlight # Colors for less unrar @@ -65,13 +63,16 @@ in { wakeonlan speedtest-cli librespeed-cli - termshark + #termshark + w3m lm_sensors ] - ++ optionals (system == "x86_64-linux") [ + ++ optionals isx86_64 [ nmap ltrace + pv + screen ] ++ optionals (!isNative) [ ncdu_1 diff --git a/nixos/modules/router.nix b/nixos/modules/router.nix index c8b1283..b01c94a 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; @@ -162,12 +178,11 @@ in { services.resolved = { enable = true; - dnssec = "true"; - fallbackDns = ["1.1.1.1" "8.8.8.8"]; - extraConfig = '' - DNSStubListenerExtra=${cnf.lanIP} - DNSStubListenerExtra=192.168.1.1 - ''; + settings.Resolve = { + FallbackDNS = ["1.1.1.1" "8.8.8.8"]; + DNSStubListenerExtra = [cnf.lanIP "192.168.1.1"]; + # TODO possibly enforce DNSSEC again + }; }; }; } 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..08a2e91 --- /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.settings.Journal = { + 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 91736ca..eab61c7 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" ]; + + inherit (config.networking) hostName; + baseDir = config.services.syncthing.dataDir; filterDevice = filterAttrs (_: 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 { + 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}/images" = { + label = "Images"; + 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 index d098ec7..24eedb5 100644 --- a/nixos/modules/users.nix +++ b/nixos/modules/users.nix @@ -3,8 +3,8 @@ config, ... }: let - isNative = config.nixpkgs.hostPlatform == config.nixpkgs.buildPlatform; - isArm = config.nixpkgs.hostPlatform.isAarch; + isNative = pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform; + isArm = pkgs.stdenv.hostPlatform.isAarch; in { users = { mutableUsers = false; @@ -43,12 +43,25 @@ in { }; }; - security.sudo.extraRules = [ - { - groups = ["wheel"]; - commands = ["ALL"]; - } - ]; + security = { + doas = { + enable = true; + extraRules = [ + { + groups = ["wheel"]; + keepEnv = true; + persist = true; + } + ]; + }; + + sudo.extraRules = [ + { + groups = ["wheel"]; + commands = ["ALL"]; + } + ]; + }; services.openssh = { enable = true; @@ -64,14 +77,17 @@ in { syntaxHighlighting.enable = isNative; }; shellrc = true; - vim.defaultEditor = isArm; + vim = { + enable = isArm; + defaultEditor = isArm; + }; neovim = { enable = !isArm; - defaultEditor = true; + defaultEditor = !isArm; withNodeJs = true; + withPython3 = true; + withRuby = true; }; - - wireshark.enable = true; }; programs.fuse.userAllowOther = true; diff --git a/nixos/modules/wifi-adm.nix b/nixos/modules/wifi-adm.nix index 40210e7..e69afd1 100644 --- a/nixos/modules/wifi-adm.nix +++ b/nixos/modules/wifi-adm.nix @@ -3,9 +3,55 @@ 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}.milan" = { + bssid = elemAt cnf."${name}".bssids 1; + 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}.milan" = { + matchConfig.Name = "${cnf."${name}".interface}.milan"; + networkConfig.Bridge = "brlan"; + bridgeVLANs = [ + { + EgressUntagged = 1; + PVID = 1; + } + ]; + }; + }; + wOptions = card: channelDefault: { interface = mkOption { type = with types; nullOr str; @@ -43,32 +89,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 +103,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..07eb686 100644 --- a/nixos/modules/wifi-client.nix +++ b/nixos/modules/wifi-client.nix @@ -21,8 +21,9 @@ in { networking.wireless = { enable = true; networks = config.secrets.wifiNetworks; - environmentFile = "/run/secrets/wifi.env"; - userControlled.enable = true; + secretsFile = "/run/secrets/wifi.secrets"; + userControlled = true; }; + users.users.cynerd.extraGroups = ["wpa_supplicant"]; }; } diff --git a/nixos/modules/wifi-spt.nix b/nixos/modules/wifi-spt.nix index 669439d..dc1de09 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 = mkForce 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/wifi-zd.nix b/nixos/modules/wifi-zd.nix new file mode 100644 index 0000000..c275fc3 --- /dev/null +++ b/nixos/modules/wifi-zd.nix @@ -0,0 +1,112 @@ +{ + config, + lib, + ... +}: let + inherit (lib) mkOption mkEnableOption types mkIf mkForce elemAt; + cnf = config.cynerd.wifiAP.zd; + + wOptions = { + bssids = mkOption { + type = with types; listOf str; + default = []; + description = "BSSIDs for networks."; + }; + channel = mkOption { + type = types.ints.positive; + description = "Channel to be used"; + }; + }; +in { + options = { + cynerd.wifiAP.zd = { + enable = mkEnableOption "Enable Wi-Fi Access Point support (OpenWrt One)"; + wlan0 = wOptions; + wlan1 = wOptions; + }; + }; + + config = mkIf cnf.enable { + # TODO regdom doesn't work for some reason + boot.extraModprobeConfig = '' + options cfg80211 ieee80211_regdom="CZ" + ''; + services.hostapd = { + enable = true; + radios = { + "wlan0" = { + inherit (cnf.wlan0) channel; + countryCode = "CZ"; + wifi4 = { + enable = true; + capabilities = [ + "HT40" + "SHORT-GI-20" + "SHORT-GI-40" + "TX-STBC" + "RX-STBC1" + "MAX-AMSDU-7935" + ]; + }; + networks = { + "wlan0" = { + bssid = elemAt cnf.wlan0.bssids 0; + ssid = "UNas"; + authentication = { + mode = "wpa2-sha256"; + wpaPasswordFile = "/run/secrets/hostapd-UNas.pass"; + }; + }; + "wlan0.guest" = { + bssid = elemAt cnf.wlan0.bssids 1; + ssid = "Koci"; + authentication = { + mode = "wpa2-sha256"; + wpaPasswordFile = "/run/secrets/hostapd-Koci.pass"; + }; + }; + "wlan0.iotd" = { + bssid = elemAt cnf.wlan0.bssids 2; + ssid = "IOTD"; + authentication = { + mode = "wpa2-sha256"; + wpaPasswordFile = "/run/secrets/hostapd-IOTD.pass"; + }; + settings = { + ieee80211w = mkForce 0; + wpa_key_mgmt = mkForce "WPA-PSK"; # force use without sha256 + }; + }; + }; + }; + #"wlan1" = { + #}; + }; + }; + systemd.network.networks = { + "lan-wlan0" = { + matchConfig = { + Name = "wlan0 wlan0.iotd"; + WLANInterfaceType = "ap"; + }; + networkConfig.Bridge = "brlan"; + bridgeVLANs = [ + { + EgressUntagged = 1; + PVID = 1; + } + ]; + }; + "lan-wlan0-guest" = { + matchConfig.Name = "wlan0.guest"; + networkConfig.Bridge = "brlan"; + bridgeVLANs = [ + { + EgressUntagged = 2; + PVID = 2; + } + ]; + }; + }; + }; +} 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..4fd942c --- /dev/null +++ b/nixos/modules/wireguard.nix @@ -0,0 +1,100 @@ +{ + 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" "zd-mox"]; + 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;})) + ({ + Endpoint = "zd.cynerd.cz:51820"; + AllowedIPs = [ + "${config.cynerd.hosts.wg.zd-mox}/32" + "10.8.0.0/24" + ]; + PublicKey = config.secrets.wireguardPubs.zd-mox; + } + // (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; + }) + ++ (optional (hostName != "zd-mox") { + # ZD network + Gateway = config.cynerd.hosts.wg.zd-mox; + Destination = "10.8.0.0/24"; + Metric = 2048; + }); + }; + }; + networking.firewall.allowedUDPPorts = [51820]; + }; +} diff --git a/nixos/nextcloud-extra-apps.json b/nixos/nextcloud-extra-apps.json new file mode 100644 index 0000000..cbe982b --- /dev/null +++ b/nixos/nextcloud-extra-apps.json @@ -0,0 +1,52 @@ +{ + "fileslibreofficeedit": { + "hash": "sha256-Xqx5snQWintYJG3Q1Crw22TkNw18DdADXkurMQqt3X8=", + "url": "https://github.com/allotropia/nextcloud_files_libreoffice_edit/releases/download/v2.0.1/fileslibreofficeedit.tar.gz", + "version": "2.0.1", + "description": "This adds a new context menu item to the Files dropdown menu \"Edit with LibreOffice\".\nClicking that item will open the file in LibreOffice via WebDAV (the file can then be edited and saved back directly in LibreOffice).\n\nThis greatly improves the user experience when working with Office files in the browser. No need to download, edit, reupload. Instead use the \"Edit with LibreOffice\" item.\n\nThis app requires at least LibreOffice 7.2 on Linux and macOS. On Windows it also works with older LibreOffice versions (since LibreOffice 5.3).", + "homepage": "https://github.com/allotropia/nextcloud_files_libreoffice_edit", + "licenses": [ + "agpl" + ] + }, + "integration_github": { + "hash": "sha256-u/Y/6j5PUwpRBj/GTv3FTB8+SuWdQlCgwTIfZNcUiSA=", + "url": "https://github.com/nextcloud-releases/integration_github/releases/download/v3.2.7/integration_github-v3.2.7.tar.gz", + "version": "3.2.7", + "description": "GitHub integration provides a dashboard widget displaying your most important notifications\n and a unified search provider for repositories, issues and pull requests. It also provides a link reference provider\n to render links to issues, pull requests and comments in Talk and Text.", + "homepage": "https://github.com/nextcloud/integration_github", + "licenses": [ + "agpl" + ] + }, + "integration_gitlab": { + "hash": "sha256-f0D9UrlX8bsf4BSTCzb9bN1gYKDlSY9JxmgO6el7HZw=", + "url": "https://github.com/nextcloud-releases/integration_gitlab/releases/download/v5.0.0/integration_gitlab-v5.0.0.tar.gz", + "version": "5.0.0", + "description": "GitLab integration provides a dashboard widget displaying your most important notifications\n and a unified search provider for repositories, issues and merge requests.", + "homepage": "https://github.com/nextcloud/integration_gitlab", + "licenses": [ + "agpl" + ] + }, + "money": { + "hash": "sha256-bEcKzgItP/Bs336qXAI72cGFXkPVNSfzMjrYQ5212K8=", + "url": "https://github.com/powerpaul17/nc_money/releases/download/v0.32.0/money.tar.gz", + "version": "0.32.0", + "description": "Finance manager for Nextcloud.", + "homepage": "https://github.com/powerpaul17/nc_money", + "licenses": [ + "agpl" + ] + }, + "passwords": { + "hash": "sha256-jD27qTp0EoPkTiwagKMXGLvTgwIHFaf8pMMW32/MsjE=", + "url": "https://git.mdns.eu/api/v4/projects/45/packages/generic/passwords/2026.9.0/passwords.tar.gz", + "version": "2026.9.20", + "description": "Passwords is the most advanced password manager for Nextcloud and allows you to manage and store your passwords safely in your own cloud.\nThe intuitive and modern web interface of the app makes it easy to update and add new passwords from anywhere.\nIncluded security checks help you to keep your online accounts safe and up-to-date.\nYou can also share passwords with other Nextcloud users.\n\n**Features**\n * Intuitive and modern user interface\n * Password security monitor\n * Secure encryption\n * Folders & tags\n * Sharing\n * Dashboard Widget\n * API for apps\n * Extensive handbook\n * Import & Export\n * Browser extensions & Apps\n * ... and many more to come\n\n**Support**\n * [Official Chat](https://matrix.to/#/#nextcloud-passwords:chat.passwordsapp.org)\n * [Official Forum](https://help.nextcloud.com/tag/passwords-app)\n * [User Handbook](https://git.mdns.eu/nextcloud/passwords/-/wikis/Users/Index)\n * [Administrator Handbook](https://git.mdns.eu/nextcloud/passwords/-/wikis/Administrators/Index)\n\n**Apps & Extensions**\n * [Official Firefox Add-On](https://addons.mozilla.org/de/firefox/addon/nextcloud-passwords?utm_source=app&utm_medium=nc-apps)\n * [Official Chrome Extension](https://chrome.google.com/webstore/detail/nextcloud-passwords/mhajlicjhgoofheldnmollgbgjheenbi)\n * [Official Microsoft Edge Extension](https://microsoftedge.microsoft.com/addons/detail/cjmlcljdpphgdfpkngjcmeepdpcgpffk)\n * [Android App](https://play.google.com/store/apps/details?id=de.jbservices.nc_passwords_app) by [joleaf](https://gitlab.com/joleaf/nc-passwords-app)\n * [Android App](https://play.google.com/store/apps/details?id=com.hegocre.nextcloudpasswords) by [hegocre](https://github.com/hegocre/NextcloudPasswords)\n * [Windows App (WIP)](https://www.microsoft.com/store/apps/9NXVZ0ZP6D5Z) by [j0chn](https://gitlab.com/j0chn/nextcloud_password_client)\n * [Linux App (WIP)](https://gitlab.com/j0chn/nextcloud_password_client/-/tree/main#linux) by [j0chn](https://gitlab.com/j0chn/nextcloud_password_client)\n * [macOS App (WIP)](https://gitlab.com/j0chn/nextcloud_password_client/-/tree/main#mac-os) by [j0chn](https://gitlab.com/j0chn/nextcloud_password_client)\n * [iOS App](https://apps.apple.com/app/id1546212226) by [Johannes Schliephake](https://github.com/johannes-schliephake/nextcloud-passwords-ios)", + "homepage": "https://passwordsapp.org/", + "licenses": [ + "agpl" + ] + } +} |
