summaryrefslogtreecommitdiff
path: root/nixos/modules
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules')
-rw-r--r--nixos/modules/keyboard.nix24
-rw-r--r--nixos/modules/linode.nix38
-rw-r--r--nixos/modules/module-list.nix15
-rw-r--r--nixos/modules/overlays.nix22
-rw-r--r--nixos/modules/programs/dwm.nix22
-rw-r--r--nixos/modules/services/catbus-bridge-snapcast.nix93
-rw-r--r--nixos/modules/services/dlnatoad.nix49
-rw-r--r--nixos/modules/services/helix-player.nix54
-rw-r--r--nixos/modules/services/mosquitto.nix90
-rw-r--r--nixos/modules/services/snapclient.nix44
-rw-r--r--nixos/modules/services/ssh.nix29
-rw-r--r--nixos/modules/services/upmpdcli.nix82
-rw-r--r--nixos/modules/users.nix42
-rw-r--r--nixos/modules/yubikey.nix47
14 files changed, 651 insertions, 0 deletions
diff --git a/nixos/modules/keyboard.nix b/nixos/modules/keyboard.nix
new file mode 100644
index 0000000..69ab14a
--- /dev/null
+++ b/nixos/modules/keyboard.nix
@@ -0,0 +1,24 @@
+{ config, lib, pkgs, ... }:
+with lib;
+
+let
+ cfg = config.eth.keyboard;
+
+in {
+
+ options.eth.keyboard = {
+ enable = mkEnableOption "Eth's keyboard preferences";
+ };
+
+ config = mkIf cfg.enable {
+
+ console.useXkbConfig = true;
+
+ services.xserver = {
+ layout = "us";
+ xkbVariant = "colemak";
+ xkbOptions = "caps:escape";
+ };
+
+ };
+}
diff --git a/nixos/modules/linode.nix b/nixos/modules/linode.nix
new file mode 100644
index 0000000..d70c929
--- /dev/null
+++ b/nixos/modules/linode.nix
@@ -0,0 +1,38 @@
+{ config, pkgs, lib, ... }:
+with lib;
+
+# from https://www.linode.com/docs/tools-reference/custom-kernels-distros/install-nixos-on-linode/.
+
+let
+ cfg = config.eth.linode;
+
+in {
+
+ options.eth.linode = {
+ enable = mkEnableOption "good defaults for Linodes";
+ };
+
+ config = mkIf cfg.enable {
+
+ # Enable LISH serial console.
+ boot.kernelParams = [ "console=ttyS0,19200n8" ];
+ boot.loader.grub.extraConfig = ''
+ serial --speed=19200 --unit=0 --word=8 --parity=no --stop=1;
+ terminal_input serial;
+ terminal_output serial;
+ '';
+
+ # GRUB has issues with Linode,
+ # so this ignores the warnings.
+ boot.loader.grub.forceInstall = true;
+
+ # A long timeout to cope with LISH delays.
+ boot.loader.timeout = 10;
+
+ boot.loader.grub = {
+ enable = true;
+ version = 2;
+ device = "nodev"; # "nodev" for EFI.
+ };
+ };
+}
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
new file mode 100644
index 0000000..3985e25
--- /dev/null
+++ b/nixos/modules/module-list.nix
@@ -0,0 +1,15 @@
+[
+ ./keyboard.nix
+ ./linode.nix
+ ./overlays.nix
+ ./programs/dwm.nix
+ ./services/catbus-bridge-snapcast.nix
+ ./services/dlnatoad.nix
+ ./services/helix-player.nix
+ ./services/mosquitto.nix
+ ./services/snapclient.nix
+ ./services/ssh.nix
+ ./services/upmpdcli.nix
+ ./users.nix
+ ./yubikey.nix
+]
diff --git a/nixos/modules/overlays.nix b/nixos/modules/overlays.nix
new file mode 100644
index 0000000..7820e96
--- /dev/null
+++ b/nixos/modules/overlays.nix
@@ -0,0 +1,22 @@
+{ config, lib, pkgs, ... }:
+with lib;
+
+let
+ cfg = config.eth.overlays;
+
+ mozilla = import (builtins.fetchTarball
+ "https://github.com/mozilla/nixpkgs-mozilla/archive/master.tar.gz");
+
+ eth = import ../../pkgs;
+
+in {
+ options.eth.overlays = {
+ eth = mkEnableOption "Eth (yours truly)";
+ mozilla = mkEnableOption "Mozilla (Rust, Firefox, etc)";
+ };
+
+ config.nixpkgs.overlays = builtins.concatLists [
+ ( if cfg.eth then [ eth ] else [] )
+ ( if cfg.mozilla then [ mozilla ] else [] )
+ ];
+}
diff --git a/nixos/modules/programs/dwm.nix b/nixos/modules/programs/dwm.nix
new file mode 100644
index 0000000..c158a5e
--- /dev/null
+++ b/nixos/modules/programs/dwm.nix
@@ -0,0 +1,22 @@
+{ config, lib, pkgs, ... }:
+with lib;
+
+let
+ cfg = config.eth.programs.dwm;
+
+in {
+ options.eth.programs.dwm = {
+ enable = mkEnableOption "Whether to enable dwm";
+ };
+
+ config = mkIf cfg.enable {
+ environment.systemPackages = [ pkgs.eth.dwm ];
+ services.xserver.windowManager.session = singleton {
+ name = "dwm";
+ start = ''
+ ${pkgs.eth.dwm}/bin/dwm &
+ waitPID=$!
+ '';
+ };
+ };
+}
diff --git a/nixos/modules/services/catbus-bridge-snapcast.nix b/nixos/modules/services/catbus-bridge-snapcast.nix
new file mode 100644
index 0000000..6e7badf
--- /dev/null
+++ b/nixos/modules/services/catbus-bridge-snapcast.nix
@@ -0,0 +1,93 @@
+{ config, lib, pkgs, ... }:
+with lib;
+
+let
+
+ cfg = config.eth.services.catbus-bridge-snapcast;
+
+ configJSON = pkgs.writeText "config.json" ''
+ {
+ "broker_host": "${cfg.mqttBroker.host}",
+ "broker_port": ${toString cfg.mqttBroker.port},
+
+ "snapserver_host": "${cfg.snapserver.host}",
+ "snapserver_port": ${toString cfg.snapserver.port},
+
+ "topic_input": "${cfg.topics.input}",
+
+ "snapcast_group_id": "${cfg.snapcastGroupID}"
+ }
+ '';
+
+in {
+
+ options.eth.services.catbus-bridge-snapcast = {
+
+ enable = mkEnableOption "Whether to enable the Catbus Snapcast bridge";
+
+ mqttBroker = {
+ host = mkOption {
+ type = types.str;
+ description = "Host of the MQTT broker.";
+ example = "localhost";
+ };
+ port = mkOption {
+ type = types.int;
+ description = "Port of the MQTT broker.";
+ default = 1883;
+ };
+ };
+
+ snapserver = {
+ host = mkOption {
+ type = types.str;
+ description = "Host of the Snapserver.";
+ example = "localhost";
+ };
+ port = mkOption {
+ type = types.int;
+ description = "Port of the Snapserver.";
+ default = 1705;
+ };
+ };
+
+ topics = {
+ input = mkOption {
+ type = types.str;
+ description = "MQTT topic for controlling the Snapcast group input";
+ example = "home/house/speakers/input_enum";
+ };
+ };
+
+ snapcastGroupID = mkOption {
+ type = types.str;
+ description = "The ID of the Snapcast group to control";
+ example = "352aba34-0ba8-8a4e-9f46-cb634b1c800a";
+ };
+ };
+
+
+ config = mkIf cfg.enable {
+ systemd.services.catbus-bridge-snapcast = {
+ enable = true;
+ description = "Control Snapcast via Catbus";
+ wants = [ "network.target" ];
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ DynamicUser = true;
+
+ ExecStart = "${pkgs.eth.catbus-snapcast}/bin/catbus-bridge-snapcast --config-path ${configJSON}";
+
+ NoNewPrivileges = true;
+ ProtectKernelTunables = true;
+ ProtectControlGroups = true;
+ ProtectKernelModules = true;
+ RestrictAddressFamilies = "AF_INET AF_INET6";
+ RestrictNamespaces = true;
+ };
+ };
+ };
+
+}
+
diff --git a/nixos/modules/services/dlnatoad.nix b/nixos/modules/services/dlnatoad.nix
new file mode 100644
index 0000000..8f50c72
--- /dev/null
+++ b/nixos/modules/services/dlnatoad.nix
@@ -0,0 +1,49 @@
+{ config, lib, pkgs, ... }:
+with lib;
+
+let
+ cfg = config.eth.services.dlnatoad;
+
+ systemdDirectoryName = "dlnatoad";
+ cacheDirectory = "/var/cache/${systemdDirectoryName}";
+
+in {
+
+ options.eth.services.dlnatoad = {
+ enable = mkEnableOption "Whether to enable DLNAtoad";
+
+ directories = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ description = "A list of paths to index & serve.";
+ example = [ "/mnt/md0/media" ];
+ };
+ };
+
+
+ config = mkIf cfg.enable {
+ systemd.services.dlnatoad = {
+ enable = true;
+ description = "DLNAtoad UPnP ContentDirectory service";
+ wants = [ "network.target" ];
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ path = [ pkgs.ffmpeg ];
+ serviceConfig = {
+ DynamicUser = true;
+
+ CacheDirectory = systemdDirectoryName;
+
+ ExecStart = "${pkgs.eth.dlnatoad}/bin/dlnatoad ${concatStringsSep " " cfg.directories} --db ${cacheDirectory}/db --thumbs ${cacheDirectory} --verbose";
+
+ NoNewPrivileges = true;
+ ProtectHome = true;
+ ProtectKernelTunables = true;
+ ProtectControlGroups = true;
+ ProtectKernelModules = true;
+ };
+ };
+ };
+
+}
+
diff --git a/nixos/modules/services/helix-player.nix b/nixos/modules/services/helix-player.nix
new file mode 100644
index 0000000..977e263
--- /dev/null
+++ b/nixos/modules/services/helix-player.nix
@@ -0,0 +1,54 @@
+{ config, lib, pkgs, ... }:
+with lib;
+
+let
+
+ cfg = config.eth.services.helix-player;
+
+ systemdDirectoryName = "helix-player";
+ runtimeDirectory = "/run/${systemdDirectoryName}";
+ socket = "${runtimeDirectory}/listen.sock";
+
+in {
+
+ options.eth.services.helix-player = {
+
+ enable = mkEnableOption "Whether to enable helix-player";
+
+ socket = mkOption {
+ type = types.str;
+ readOnly = true;
+ description = "Path of the UNIX socket to listen on.";
+ example = socket;
+ };
+ };
+
+
+ config = mkIf cfg.enable {
+
+ eth.services.helix-player.socket = socket;
+
+ systemd.services.helix-player = {
+ enable = true;
+ description = "Helix UPnP player & controller";
+ wants = [ "network.target" ];
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ DynamicUser = true;
+ Group = config.services.nginx.group;
+
+ RuntimeDirectory = systemdDirectoryName;
+
+ ExecStart = "${pkgs.eth.helix}/bin/helix-player -socket ${socket}";
+
+ NoNewPrivileges = true;
+ ProtectHome = true;
+ ProtectKernelTunables = true;
+ ProtectControlGroups = true;
+ ProtectKernelModules = true;
+ };
+ };
+ };
+
+}
diff --git a/nixos/modules/services/mosquitto.nix b/nixos/modules/services/mosquitto.nix
new file mode 100644
index 0000000..fecf8a4
--- /dev/null
+++ b/nixos/modules/services/mosquitto.nix
@@ -0,0 +1,90 @@
+{ config, lib, pkgs, ... }:
+with lib;
+
+let
+
+ cfg = config.eth.services.mosquitto;
+
+ systemdDirectoryName = "mosquitto";
+ stateDirectory = "/var/lib/${systemdDirectoryName}";
+ runtimeDirectory = "/run/${systemdDirectoryName}";
+
+ mosquittoConf = pkgs.writeText "mosquitto.conf" ''
+ ${optionalString cfg.mqtt.enable ''
+ listener ${toString cfg.mqtt.port} ${optionalString (cfg.mqtt.host != "") cfg.mqtt.host}
+ ''}
+
+ ${optionalString cfg.websockets.enable ''
+ listener ${toString cfg.websockets.port} ${optionalString (cfg.websockets.host != "") cfg.websockets.host}
+ protocol websockets
+ ''}
+
+ ${optionalString cfg.persistence ''
+ persistence true
+ persistence_location ${stateDirectory}/
+ ''}
+ '';
+
+in {
+
+ options.eth.services.mosquitto = {
+
+ enable = mkEnableOption "Whether to enable mosquitto.";
+
+ persistence = mkOption {
+ type = types.bool;
+ default = true;
+ };
+
+ mqtt = {
+ enable = mkEnableOption "Whether to listen on unencrypted MQTT.";
+ host = mkOption {
+ type = types.str;
+ default = "";
+ example = "10.11.12.14";
+ };
+ port = mkOption {
+ type = types.int;
+ default = 1883;
+ };
+ };
+
+ websockets = {
+ enable = mkEnableOption "Whether to listen on unencrypted Websockets.";
+ host = mkOption {
+ type = types.str;
+ default = "";
+ example = "10.11.12.14";
+ };
+ port = mkOption {
+ type = types.int;
+ default = 1884;
+ };
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+
+ systemd.services.mosquitto = {
+ enable = true;
+ description = "Mosquitto MQTT broker";
+ wants = [ "network.target" ];
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ DynamicUser = true;
+ RuntimeDirectory = systemdDirectoryName;
+ StateDirectory = systemdDirectoryName;
+ ExecStart = "${pkgs.mosquitto}/bin/mosquitto -c ${mosquittoConf}";
+ NoNewPrivileges = true;
+ ProtectHome = true;
+ ProtectKernelTunables = true;
+ ProtectControlGroups = true;
+ ProtectKernelModules = true;
+ RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX";
+ RestrictNamespaces = true;
+ };
+ };
+ };
+}
diff --git a/nixos/modules/services/snapclient.nix b/nixos/modules/services/snapclient.nix
new file mode 100644
index 0000000..9f93131
--- /dev/null
+++ b/nixos/modules/services/snapclient.nix
@@ -0,0 +1,44 @@
+{ config, lib, pkgs, ... }:
+with lib;
+
+let
+
+ cfg = config.eth.services.snapclient;
+
+in {
+
+ options.eth.services.snapclient = {
+
+ enable = mkEnableOption "Whether to enable snapclient.";
+
+ hostID = mkOption {
+ type = types.str;
+ default = config.networking.hostName;
+ description = "The name to give to the snapserver.";
+ example = "Living Room";
+ };
+ };
+
+ config = mkIf cfg.enable {
+
+ systemd.services.snapclient = {
+ enable = true;
+ description = "Snapcast client";
+ wants = [ "network.target" "sound.target" ];
+ after = [ "network.target" "sound.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ DynamicUser = "yes";
+ Group = "audio";
+ ExecStart = "${pkgs.snapcast}/bin/snapclient --hostID ${escapeShellArg cfg.hostID}";
+ NoNewPrivileges = true;
+ ProtectHome = true;
+ ProtectKernelTunables = true;
+ ProtectControlGroups = true;
+ ProtectKernelModules = true;
+ RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX";
+ RestrictNamespaces = true;
+ };
+ };
+ };
+}
diff --git a/nixos/modules/services/ssh.nix b/nixos/modules/services/ssh.nix
new file mode 100644
index 0000000..d965472
--- /dev/null
+++ b/nixos/modules/services/ssh.nix
@@ -0,0 +1,29 @@
+{ config, lib, pkgs, ... }:
+with lib;
+
+let
+ cfg = config.eth.services.ssh;
+
+in {
+ options.eth.services.ssh = {
+ enable = mkEnableOption "Whether to enable SSHd with Eth's defaults.";
+
+ passwordAuthentication = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to allow password authentication. Occasionally useful, used sparingly.";
+ };
+ };
+
+ config = mkIf cfg.enable {
+
+ security.pam.enableSSHAgentAuth = true;
+ security.pam.services.sudo.sshAgentAuth = true;
+
+ services.openssh = {
+ enable = true;
+ permitRootLogin = "no";
+ passwordAuthentication = cfg.passwordAuthentication;
+ };
+ };
+}
diff --git a/nixos/modules/services/upmpdcli.nix b/nixos/modules/services/upmpdcli.nix
new file mode 100644
index 0000000..d301a49
--- /dev/null
+++ b/nixos/modules/services/upmpdcli.nix
@@ -0,0 +1,82 @@
+{ config, lib, pkgs, ... }:
+with lib;
+
+let
+ cfg = config.eth.services.upmpdcli;
+
+ cacheDir = "upmpdcli";
+
+ upmpdConf = pkgs.writeText "upmpd.conf" ''
+ cachedir = /var/cache/${cacheDir}
+
+ friendlyname = ${cfg.friendlyName}
+
+ mpdhost = ${cfg.mpd.host}
+ mpdport = ${toString cfg.mpd.port}
+
+ ${optionalString (cfg.mpd.password != "") "${cfg.mpd.password}"}
+
+ ${cfg.extraConfig}
+ '';
+
+in {
+ options.eth.services.upmpdcli = {
+ enable = mkEnableOption "Run upmpdcli server";
+
+ friendlyName = mkOption {
+ type = types.str;
+ default = "UpMpd (${config.networking.hostName})";
+ description = "Friendly Name used for UPnP discovery.";
+ };
+
+ mpd = {
+ host = mkOption {
+ type = types.str;
+ default = config.services.mpd.network.listenAddress;
+ description = "Host of the MPD server.";
+ };
+ port = mkOption {
+ type = types.int;
+ default = config.services.mpd.network.port;
+ description = "Port of the MPD server.";
+ };
+ password = mkOption {
+ type = types.str;
+ default = "";
+ description = "Password of the MPD server.";
+ };
+ };
+
+ extraConfig = mkOption {
+ type = types.lines;
+ default = "";
+ };
+ };
+
+ config = mkIf cfg.enable {
+ systemd.services.upmpdcli = {
+ enable = true;
+ description = "";
+ wants = [ "network.target" ];
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ path = [ pkgs.openssl pkgs.python3 ];
+ serviceConfig = {
+ DynamicUser = true;
+
+ CacheDirectory = cacheDir;
+
+ Type = "simple";
+ ExecStart="${pkgs.eth.upmpdcli}/bin/upmpdcli -c ${upmpdConf}";
+ Restart = "always";
+ RestartSec = "1min";
+
+ NoNewPrivileges = true;
+ ProtectHome = true;
+ ProtectKernelTunables = true;
+ ProtectControlGroups = true;
+ ProtectKernelModules = true;
+ };
+ };
+ };
+}
diff --git a/nixos/modules/users.nix b/nixos/modules/users.nix
new file mode 100644
index 0000000..ea08cf5
--- /dev/null
+++ b/nixos/modules/users.nix
@@ -0,0 +1,42 @@
+{ config, lib, pkgs, ... }:
+with lib;
+
+let
+ cfg = config.eth.users;
+
+ defaultPackages = with pkgs; [
+ direnv
+ dnsutils
+ killall
+ tmux
+ vim
+ wget
+ ];
+
+in {
+
+ options.eth.users = {
+ eth = {
+ enable = mkEnableOption "Create the user eth";
+
+ extraPackages = mkOption {
+ type = types.listOf types.package;
+ default = [];
+ };
+ };
+ };
+
+ config = {
+
+ users.users.eth = mkIf cfg.eth.enable {
+ isNormalUser = true;
+ extraGroups = [ "wheel" ];
+ shell = pkgs.fish;
+ packages = defaultPackages ++ cfg.eth.extraPackages;
+ openssh.authorizedKeys.keys = [
+ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqcW3HzqQxPUjZteAs5HmDbCEAtHcThnj7qfJacEXBmpO5srinU3mhV/EhrqcAMkEoEIS2az2uQQEsF13nEqDD1uZh/Q7qwEnZepzElgBOIToQ+Np2qziRExV3ROBddJfmD3XBTPc7wA5BohYku+eCsfR37ZrRTgKUIALhZ4MSRxgQqnhtgaxHpL2Nk6ZdxRHO1ISlcmiWhOETP0fj76zN4+CgSv4rkPdYxKYpWVT8XTdKgu6ENbAPbOBzplui9MmrdS17ZaWy0KrKCiyMjhA5qSsOxWLXKL9P8lRuuXkWAl5cpt3vWWKAOzlLV1UCUbtlBblyH2KkeIKfO8AC45wX keychain@eth.moe"
+ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGf+geluXR5/hxK2OthfS+bG+7QbUVqV25bslT4KgMid+zkOVeWfA49n8/iuXUjYZmB0hP9oiFkM1wjFfC5JtET1OX3V8r0nuexXfhvG4gtWIk6Yw5HfPLv1qYYti4SrPKgQlP+C2i6WjHO6Y4VWSpJkgXgO+XvEa57fGSsjcy3rV6l/B56tpIhNchvwVxm1gHJnb4eZAKtQYcz8Pven2TFNFGLMMzQ7Y7JWAH80TDrdUywxfktaKmswo4rQ6i3zUKXrzaPuaH+egoNLqfZqM3+Q92PWs8bU2Y7uxXUQJXD32KuStRUwEz32A+O55nVVGTrnwKUUqnx9H04KCYBOVP backup@eth.moe"
+ ];
+ };
+ };
+}
diff --git a/nixos/modules/yubikey.nix b/nixos/modules/yubikey.nix
new file mode 100644
index 0000000..0c16807
--- /dev/null
+++ b/nixos/modules/yubikey.nix
@@ -0,0 +1,47 @@
+{ config, lib, pkgs, ... }:
+with lib;
+
+let
+ cfg = config.eth.yubikey;
+
+in {
+
+ options.eth.yubikey = {
+ enable = mkEnableOption "Set up Yubikey";
+ };
+
+ config = mkIf cfg.enable {
+
+ hardware.u2f.enable = true;
+
+ programs.ssh.startAgent = false;
+
+ programs.gnupg.agent = {
+ enable = true;
+ enableSSHSupport = true;
+ pinentryFlavor = "curses";
+ };
+
+ services.pcscd.enable = true;
+
+ services.udev.packages = with pkgs; [
+ libu2f-host
+ yubikey-personalization
+ ];
+
+ environment.systemPackages = with pkgs; [
+ gnupg
+ pinentry-curses
+ ];
+
+ environment.shellInit = ''
+ gpg-connect-agent /bye
+ export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
+ '';
+ programs.fish.shellInit = ''
+ gpg-connect-agent /bye
+ set -Ux SSH_AUTH_SOCK (gpgconf --list-dirs agent-ssh-socket)
+ '';
+
+ };
+}