feat: add policestation
Some checks failed
Build and Deploy / build (push) Has been cancelled
Flake check / Check flake (push) Has been cancelled
Build and Deploy / deploy (push) Has been cancelled

This commit is contained in:
Leon Schwarzäugl 2026-03-25 22:51:31 +01:00
parent 361f77a447
commit a2b9cc78b5
Signed by: swarsel
GPG key ID: 26A54C31F2A4FD84
7 changed files with 360 additions and 23 deletions

1
.github/README.md vendored
View file

@ -185,6 +185,7 @@
|🪟 **chaostheater** | Asus Z97-A, i7-4790k, GTX970, 32GB RAM | Home Game Streaming Server (Windows/AtlasOS, not nix-managed) |
|📱 **magicant** | Samsung Galaxy Z Flip 6 | Phone |
|💿 **drugstore** | - | NixOS-installer ISO for bootstrapping new hosts |
|💿 **policestation** | - | NixOS live ISO for generating cryptographic keys |
|💿 **brickroad** | - | Kexec tarball for bootstrapping low-memory machines |
|❔ **hotel** | - | Demo config for checking out this configuration |
|❔ **toto** | - | Helper configuration for testing purposes |

View file

@ -30,6 +30,9 @@ This configuration is part of a NixOS system that is for the most part fully dec
The literate configuration approach lets me explain my choices to my future self as well as you, the reader. I go to great lengths to explain the choices for all design steps that I take in order for me to pay due diligence in crafting my setup, and not simply copying big chunks of other peoples code. Also, this is very convenient to me as I only need to keep of (ideally) a single file to manage all of my configuration. I hope that this documentation will make it easier for beginners to get into NixOS (and, to some extent, Emacs) as I know it can be a struggle in the beginning.
** What I achieve with this project
:PROPERTIES:
:CUSTOM_ID: h:150ce3b3-20c6-4dc1-afcd-381cb9101719
:END:
[[https://github.com/Swarsel/.dotfiles/tree/main/files/topology/topology.png][file:./files/topology/topology_small.png]]
@ -318,6 +321,7 @@ Here I give a brief overview over the host machines that I am using. This is hel
|🪟 **chaostheater** | Asus Z97-A, i7-4790k, GTX970, 32GB RAM | Home Game Streaming Server (Windows/AtlasOS, not nix-managed) |
|📱 **magicant** | Samsung Galaxy Z Flip 6 | Phone |
|💿 **drugstore** | - | NixOS-installer ISO for bootstrapping new hosts |
|💿 **policestation** | - | NixOS live ISO for generating cryptographic keys |
|💿 **brickroad** | - | Kexec tarball for bootstrapping low-memory machines |
|❔ **hotel** | - | Demo config for checking out this configuration |
|❔ **toto** | - | Helper configuration for testing purposes |
@ -3385,8 +3389,19 @@ This is an improvement to what I did earlier, where I did not use =nixos-generat
inputs.home-manager.nixosModules.home-manager
"${self}/install/installer-config.nix"
];
format =
{
format = {
x86_64-linux = "install-iso";
aarch64-linux = "sd-aarch64-installer";
}.${system};
};
keygen = inputs.nixos-generators.nixosGenerate {
inherit pkgs system;
modules = [
inputs.home-manager.nixosModules.home-manager
"${self}/install/keygen-config.nix"
];
format = {
x86_64-linux = "install-iso";
aarch64-linux = "sd-aarch64-installer";
}.${system};
@ -8064,8 +8079,157 @@ Steps to recover using live ISO:
};
}
#+end_src
**** Policestation (live ISO key generator config)
:PROPERTIES:
:CUSTOM_ID: h:ab5924ed-9c36-4bda-9b90-d6ae1143f5c8
:END:
This live ISO config provides a secure environment for setting up cryptographic keys. All networking capabilities are turned off and only necessary tools for generating the keys are enabled.
#+begin_src nix-ts :tangle install/keygen-config.nix
{ config, pkgs, lib, ... }:
{
config = {
home-manager.users.nixos = {
home = {
inherit (config.system) stateVersion;
username = "nixos";
homeDirectory = "/home/nixos";
keyboard.layout = "us";
file.".gnupg/gpg-hardened.conf" = {
text = ''
personal-cipher-preferences AES256 AES192 AES
personal-digest-preferences SHA512 SHA384 SHA256
personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed
default-preference-list SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed
cert-digest-algo SHA512
s2k-digest-algo SHA512
s2k-cipher-algo AES256
charset utf-8
no-comments
no-emit-version
no-greeting
keyid-format 0xlong
list-options show-uid-validity
verify-options show-uid-validity
with-fingerprint
require-cross-certification
require-secmem
no-symkey-cache
armor
use-agent
throw-keyids
'';
};
};
services.gpg-agent = {
enable = true;
enableBashIntegration = true;
enableSshSupport = true;
pinentry = {
package = pkgs.pinentry-curses;
program = "pinentry-curses";
};
defaultCacheTtl = 60;
maxCacheTtl = 120;
};
programs.gpg = {
enable = true;
};
};
programs = {
ssh.startAgent = false;
gnupg = {
dirmngr.enable = true;
agent = {
enable = true;
enableSSHSupport = true;
};
};
};
swapDevices = [ ];
services = {
pcscd.enable = true;
udev.packages = [ pkgs.yubikey-personalization ];
getty.autologinUser = "nixos";
};
nix = {
channel.enable = false;
settings.experimental-features = [ "nix-command" "flakes" ];
};
environment.interactiveShellInit = ''
unset HISTFILE
export GNUPGHOME="/run/user/$(id -u)/gnupg"
if [ ! -d "$GNUPGHOME" ]; then
install -m=0700 --directory="$GNUPGHOME"
fi
[ ! -f "$GNUPGHOME/gpg.conf" ] && cp /home/nixos/gpg-hardened.conf "$GNUPGHOME/gpg.conf"
[ ! -f "$GNUPGHOME/gpg-agent.conf" ] && cp /home/nixos/gpg-agent.conf "$GNUPGHOME/gpg-agent.conf"
'';
environment.systemPackages = with pkgs; [
paperkey
pgpdump
parted
cryptsetup
yubikey-manager
yubikey-personalization
pcsc-tools
];
boot = {
initrd.network.enable = false;
tmp.cleanOnBoot = true;
kernel.sysctl = {
"kernel.unprivileged_bpf_disabled" = 1;
};
};
networking = {
hostName = "policestation";
resolvconf.enable = false;
dhcpcd.enable = false;
dhcpcd.allowInterfaces = [];
interfaces = {};
firewall.enable = true;
useDHCP = false;
useNetworkd = false;
wireless.enable = false;
networkmanager.enable = lib.mkForce false;
};
users.users.nixos = {
isNormalUser = true;
extraGroups = [ "wheel" ];
initialHashedPassword = "";
};
security.sudo = {
enable = true;
wheelNeedsPassword = false;
};
systemd = {
targets = {
sleep.enable = false;
suspend.enable = false;
hibernate.enable = false;
hybrid-sleep.enable = false;
};
};
system.stateVersion = lib.mkForce "23.05";
};
}
#+end_src
**** Brick Road (kexec image)
@ -10415,6 +10579,9 @@ Here I disable global completion to prevent redundant compinit calls and cache i
}
#+end_src
***** nautilus
:PROPERTIES:
:CUSTOM_ID: h:e31fa37e-220f-4e97-89ae-6a5219309a05
:END:
This enabled the right-click context menu entry in nautilus that allows to open a folder in a terminal - I never use this to be honest, but I feel like the file explorer would not be complete otherwise.
@ -11430,6 +11597,9 @@ Here we just define some aliases for rebuilding the system, and we allow some in
#+end_src
**** Persistent user/group IDs
:PROPERTIES:
:CUSTOM_ID: h:2ae284ba-423e-4181-9447-a45ff7187591
:END:
When using microvms, I opted to use ZFS with it, and mount datasets into the microvms. That however means that we need to make sure that userids stay consistent between microvm reboots. This could be done by persisting =/var/lib/nixos=, but even then it would not be guaranteed that all UIDs/GIDs match up with the hypervising host, which would not be a big problem, but I like to keep it consistent anyways.
@ -20163,10 +20333,10 @@ When setting up a new machine:
};
};
udev.extraRules = ''
# lock screen when yubikey removed
ACTION=="remove", ENV{PRODUCT}=="3/1050/407/110", RUN+="${pkgs.systemd}/bin/systemctl suspend"
'';
# udev.extraRules = ''
# # lock screen when yubikey removed
# ACTION=="remove", ENV{PRODUCT}=="3/1050/407/110", RUN+="${pkgs.systemd}/bin/systemctl suspend"
# '';
};
@ -20318,6 +20488,9 @@ Some standard options that should be set for every microvm guest. We set the def
#+end_src
**** microvm-guest-shares
:PROPERTIES:
:CUSTOM_ID: h:1ba0d688-e20c-418f-bb73-6c73662e20e9
:END:
Some standard options that should be set for every microvm guest. We set the default
#+begin_src nix-ts :tangle modules/nixos/optional/microvm-guest-shares.nix
@ -25572,6 +25745,9 @@ Currently, I am too lazy to explain every option here, but most of it is very se
#+end_src
**** Shikane
:PROPERTIES:
:CUSTOM_ID: h:6b44b706-bda6-4238-aa97-84ec91b2718a
:END:
#+begin_src nix-ts :tangle modules/home/common/shikane.nix
{ lib, config, confLib, ... }:
@ -25704,6 +25880,7 @@ When setting up a new machine:
enable = true;
scdaemonSettings = {
disable-ccid = true; # prevent conflicts between pcscd and scdameon
# pcsc-shared = true; # as long as only one key is used, this prevents key from not being detected sometimes
};
publicKeys = [
{
@ -26390,6 +26567,9 @@ This service changes the screen hue at night. I am not sure if that really does
#+end_src
**** Khal
:PROPERTIES:
:CUSTOM_ID: h:771a6e35-9299-4df0-8d07-0a3443099484
:END:
#+begin_src nix-ts :tangle modules/home/common/khal.nix
{ lib, config, pkgs, ... }:
@ -33687,13 +33867,13 @@ When holding presentations, I think it is important to not have too many distrac
(defun swarsel/org-present-start ()
(setq-local face-remapping-alist `((default (:height 1.5) variable-pitch)
(header-line (:height 4.0) variable-pitch)
(org-document-title (:height 1.75) org-document-title)
(org-document-title (:height 2.75) org-document-title)
(org-code (:height 1.2) org-code)
(org-verbatim (:height 1.0) org-verbatim)
(org-verbatim (:family ,swarsel/fixed-font :height 1.0) org-verbatim)
(org-quote (:height 1.0) org-quote)
(org-verse (:height 1.0) org-verse)
(org-table (:family ,swarsel/fixed-font :weight regular :height 1.2) org-table)
(org-block (:height 1.25) org-block)
(org-table (:family ,swarsel/fixed-font :weight regular :height 1.0) org-table)
(org-block (:height 0.9) org-block)
(org-link (:underline nil) org-link)
(org-block-begin-line (:height 0.7) org-block)
))
@ -39399,6 +39579,9 @@ jobs:
#+end_src
** Private topology flake
:PROPERTIES:
:CUSTOM_ID: h:7967d45f-5b37-4580-8a4c-fa5ba0ce7a25
:END:
This flake is automatically loaded as an override when building the repo topology using the alias =build-topology= defined in [[#h:91dd4cc4-aada-4e74-be23-0cc69ed85af5][zsh]].

View file

@ -1074,13 +1074,13 @@ create a new one."
(defun swarsel/org-present-start ()
(setq-local face-remapping-alist `((default (:height 1.5) variable-pitch)
(header-line (:height 4.0) variable-pitch)
(org-document-title (:height 1.75) org-document-title)
(org-document-title (:height 2.75) org-document-title)
(org-code (:height 1.2) org-code)
(org-verbatim (:height 1.0) org-verbatim)
(org-verbatim (:family ,swarsel/fixed-font :height 1.0) org-verbatim)
(org-quote (:height 1.0) org-quote)
(org-verse (:height 1.0) org-verse)
(org-table (:family ,swarsel/fixed-font :weight regular :height 1.2) org-table)
(org-block (:height 1.25) org-block)
(org-table (:family ,swarsel/fixed-font :weight regular :height 1.0) org-table)
(org-block (:height 0.9) org-block)
(org-link (:underline nil) org-link)
(org-block-begin-line (:height 0.7) org-block)
))

141
install/keygen-config.nix Normal file
View file

@ -0,0 +1,141 @@
{ config, pkgs, lib, ... }:
{
config = {
home-manager.users.nixos = {
home = {
inherit (config.system) stateVersion;
username = "nixos";
homeDirectory = "/home/nixos";
keyboard.layout = "us";
file.".gnupg/gpg-hardened.conf" = {
text = ''
personal-cipher-preferences AES256 AES192 AES
personal-digest-preferences SHA512 SHA384 SHA256
personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed
default-preference-list SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed
cert-digest-algo SHA512
s2k-digest-algo SHA512
s2k-cipher-algo AES256
charset utf-8
no-comments
no-emit-version
no-greeting
keyid-format 0xlong
list-options show-uid-validity
verify-options show-uid-validity
with-fingerprint
require-cross-certification
require-secmem
no-symkey-cache
armor
use-agent
throw-keyids
'';
};
};
services.gpg-agent = {
enable = true;
enableBashIntegration = true;
enableSshSupport = true;
pinentry = {
package = pkgs.pinentry-curses;
program = "pinentry-curses";
};
defaultCacheTtl = 60;
maxCacheTtl = 120;
};
programs.gpg = {
enable = true;
};
};
programs = {
ssh.startAgent = false;
gnupg = {
dirmngr.enable = true;
agent = {
enable = true;
enableSSHSupport = true;
};
};
};
swapDevices = [ ];
services = {
pcscd.enable = true;
udev.packages = [ pkgs.yubikey-personalization ];
getty.autologinUser = "nixos";
};
nix = {
channel.enable = false;
settings.experimental-features = [ "nix-command" "flakes" ];
};
environment.interactiveShellInit = ''
unset HISTFILE
export GNUPGHOME="/run/user/$(id -u)/gnupg"
if [ ! -d "$GNUPGHOME" ]; then
install -m=0700 --directory="$GNUPGHOME"
fi
[ ! -f "$GNUPGHOME/gpg.conf" ] && cp /home/nixos/gpg-hardened.conf "$GNUPGHOME/gpg.conf"
[ ! -f "$GNUPGHOME/gpg-agent.conf" ] && cp /home/nixos/gpg-agent.conf "$GNUPGHOME/gpg-agent.conf"
'';
environment.systemPackages = with pkgs; [
paperkey
pgpdump
parted
cryptsetup
yubikey-manager
yubikey-personalization
pcsc-tools
];
boot = {
initrd.network.enable = false;
tmp.cleanOnBoot = true;
kernel.sysctl = {
"kernel.unprivileged_bpf_disabled" = 1;
};
};
networking = {
hostName = "policestation";
resolvconf.enable = false;
dhcpcd.enable = false;
dhcpcd.allowInterfaces = [ ];
interfaces = { };
firewall.enable = true;
useDHCP = false;
useNetworkd = false;
wireless.enable = false;
networkmanager.enable = lib.mkForce false;
};
users.users.nixos = {
isNormalUser = true;
extraGroups = [ "wheel" ];
initialHashedPassword = "";
};
security.sudo = {
enable = true;
wheelNeedsPassword = false;
};
systemd = {
targets = {
sleep.enable = false;
suspend.enable = false;
hibernate.enable = false;
hybrid-sleep.enable = false;
};
};
system.stateVersion = lib.mkForce "23.05";
};
}

View file

@ -30,6 +30,7 @@ in
enable = true;
scdaemonSettings = {
disable-ccid = true; # prevent conflicts between pcscd and scdameon
# pcsc-shared = true; # as long as only one key is used, this prevents key from not being detected sometimes
};
publicKeys = [
{

View file

@ -252,10 +252,10 @@ in
};
};
udev.extraRules = ''
# lock screen when yubikey removed
ACTION=="remove", ENV{PRODUCT}=="3/1050/407/110", RUN+="${pkgs.systemd}/bin/systemctl suspend"
'';
# udev.extraRules = ''
# # lock screen when yubikey removed
# ACTION=="remove", ENV{PRODUCT}=="3/1050/407/110", RUN+="${pkgs.systemd}/bin/systemctl suspend"
# '';
};

View file

@ -11,8 +11,19 @@
inputs.home-manager.nixosModules.home-manager
"${self}/install/installer-config.nix"
];
format =
{
format = {
x86_64-linux = "install-iso";
aarch64-linux = "sd-aarch64-installer";
}.${system};
};
keygen = inputs.nixos-generators.nixosGenerate {
inherit pkgs system;
modules = [
inputs.home-manager.nixosModules.home-manager
"${self}/install/keygen-config.nix"
];
format = {
x86_64-linux = "install-iso";
aarch64-linux = "sd-aarch64-installer";
}.${system};