This commit is contained in:
Casper V. Kristensen 2023-08-25 00:57:42 +02:00
parent cf31d39313
commit 56cba51af3
13 changed files with 104 additions and 21 deletions

View file

@ -1,4 +1,7 @@
{ pkgs, ... }: { { pkgs, ... }: {
# Fish is a Unix shell with a focus on interactivity and usability. Fish is
# designed to give the user features by default, rather than by
# configuration.
# https://nixos.wiki/wiki/Fish # https://nixos.wiki/wiki/Fish
# https://nixos.wiki/wiki/Command_Shell # https://nixos.wiki/wiki/Command_Shell
@ -23,16 +26,15 @@
# Add fish to the list of permissible login shells for user accounts # Add fish to the list of permissible login shells for user accounts
environment.shells = with pkgs; [ fish ]; environment.shells = with pkgs; [ fish ];
# Enabling fish in both NixOS and home manager is required to pick # Enabling fish in both NixOS and home manager is required to pick up
# up completions and environment variables set by NixOS nixpkgs _and_ # completions and environment variables set by NixOS nixpkgs _and_ home
# home manager modules at the same time. # manager modules at the same time. As a test, the environment variables from
# As a test, the environment variables from
# $ nix repl # $ nix repl
# > :lf . # > :lf .
# > :p nixosConfigurations.omega.config.home-manager.users.caspervk.home.sessionVariables # > :p nixosConfigurations.omega.config.home-manager.users.caspervk.home.sessionVariables
# > :p nixosConfigurations.omega.config.home-manager.users.caspervk.home.sessionVariablesExtra # > :p nixosConfigurations.omega.config.home-manager.users.caspervk.home.sessionVariablesExtra
# should be available in the desktop environment's shell. # should be available in the desktop environment's shell. See
# See https://nix-community.github.io/home-manager/index.html#_why_are_the_session_variables_not_set. # https://nix-community.github.io/home-manager/index.html#_why_are_the_session_variables_not_set.
home-manager.users.caspervk = { home-manager.users.caspervk = {
programs.fish.enable = true; programs.fish.enable = true;
}; };

View file

@ -1,4 +1,6 @@
{ home-manager, ... }: { { home-manager, ... }: {
# Git version control system.
# https://nixos.wiki/wiki/Git
home-manager.users.caspervk = { home-manager.users.caspervk = {
programs.git = { programs.git = {
@ -6,6 +8,8 @@
userName = "Casper V. Kristensen"; userName = "Casper V. Kristensen";
userEmail = "casper@vkristensen.dk"; userEmail = "casper@vkristensen.dk";
# Delta is a syntax-highlighting pager for git, diff, and grep output
# https://github.com/dandavison/delta
delta = { delta = {
enable = true; enable = true;
options = { options = {

View file

@ -1,7 +1,16 @@
{ config, home-manager, ... }: { { config, home-manager, ... }: {
# https://nix-community.github.io/home-manager/index.html#sec-flakes-nixos-module # Like NixOS manages the system configuration, Home Manager manages the user
# environment.
#
# A lot of people split their configuration into home/ and nixos/, and import
# both directly in flake.nix, but on a single-user system I find more value
# in a structure based on the program or service rather than the
# implementation-specific details of where the output is saved to disk.
# https://nix-community.github.io/home-manager/
# https://nixos.wiki/wiki/Home_Manager # https://nixos.wiki/wiki/Home_Manager
# https://nix-community.github.io/home-manager/options.html
# Import Home Manager to make it part of the NixOS configuration
imports = [ imports = [
home-manager.nixosModules.home-manager home-manager.nixosModules.home-manager
]; ];
@ -10,11 +19,13 @@
# Use the same nixpkgs as the system # Use the same nixpkgs as the system
useGlobalPkgs = true; useGlobalPkgs = true;
# Install packages to /etc/profiles instead of $HOME/.nix-profile, not sure why # Install packages to /etc/profiles instead of $HOME/.nix-profile.
# According to the Home Manager documentation, this option may become the
# default in the future, so it's probably a good idea.
useUserPackages = true; useUserPackages = true;
users.caspervk = {
# Define the user and path Home Manager should manage # Define the user and path Home Manager should manage
users.caspervk = {
home = with config.users.users; { home = with config.users.users; {
username = caspervk.name; username = caspervk.name;
homeDirectory = caspervk.home; homeDirectory = caspervk.home;

View file

@ -1,17 +1,29 @@
{ impermanence, pkgs, ... }: { { impermanence, ... }: {
# The impermanence module bind-mounts persistent files and directories, stored in /nix/persist, into the tmpfs root # Impermanence in NixOS is where the root directory isn't permanent, but gets
# partition on startup. For example: /nix/persist/etc/machine-id is mounted to /etc/machine-id. # wiped every reboot (such as by mounting it as tmpfs). Such a setup is
# possible because NixOS only needs /boot and /nix in order to boot, all
# other system files are simply links to files in /nix.
# The impermanence module bind-mounts persistent files and directories,
# stored in /nix/persist, into the tmpfs root partition on startup. For
# example: /nix/persist/etc/machine-id is mounted to /etc/machine-id.
# https://github.com/nix-community/impermanence # https://github.com/nix-community/impermanence
# https://nixos.wiki/wiki/Impermanence # https://nixos.wiki/wiki/Impermanence
# https://elis.nu/blog/2020/05/nixos-tmpfs-as-root/
imports = [ imports = [
impermanence.nixosModules.impermanence impermanence.nixosModules.impermanence
]; ];
# We *don't* want to use tmpfs for /tmp in case we have to put big files there. Instead, we mount it to the disk and # We *don't* want to use tmpfs for /tmp in case we have to put big files
# instruct systemd to clean it on boot. # there. Instead, we mount it to the disk and instruct systemd to clean it on
# boot.
# TODO: There might be a way to configure /tmp to be in-memory storage until
# it gets too big.
boot.tmp.cleanOnBoot = true; boot.tmp.cleanOnBoot = true;
# Each module will configure the paths they need persisted. Here we define
# some general system paths that don't really fit anywhere else.
environment.persistence."/nix/persist" = { environment.persistence."/nix/persist" = {
hideMounts = true; hideMounts = true;
directories = [ directories = [
@ -25,7 +37,7 @@
]; ];
users.caspervk = { users.caspervk = {
directories = [ directories = [
"/" # entire home directory "/" # entire home directory (TODO)
]; ];
}; };
}; };

View file

@ -1,6 +1,10 @@
{ ... }: { { ... }: {
# https://nixos.wiki/wiki/Networking
# https://nixos.wiki/wiki/Systemd-networkd
networking = { networking = {
firewall = { firewall = {
# Allow some ports for ad-hoc use
allowedTCPPorts = [ 1234 1337 8000 8080 ]; allowedTCPPorts = [ 1234 1337 8000 8080 ];
allowedUDPPorts = [ 1234 1337 8000 8080 ]; allowedUDPPorts = [ 1234 1337 8000 8080 ];
}; };
@ -10,14 +14,23 @@
# TODO: these systemd networkd settings will be the default once # TODO: these systemd networkd settings will be the default once
# https://github.com/NixOS/nixpkgs/pull/202488 is merged. # https://github.com/NixOS/nixpkgs/pull/202488 is merged.
networking.useNetworkd = true; networking.useNetworkd = true;
systemd.network = { systemd.network.enable = true;
enable = true;
wait-online.anyInterface = true;
};
# systemd-resolved provides DNS resolution to local applications through
# D-Bus, NSS, and a local stub resolver on 127.0.0.53. It implements caching
# and DNSSEC validation. We configure it to only, and always, use
# dns.caspervk.net over TLS. By the way, it's surprisingly hard to get the
# system to always follow the custom DNS servers rather than the
# DHCP-provided ones. Check the traffic with:
# sudo tcpdump -n --interface=any '(udp port 53) or (tcp port 853)'
# https://nixos.wiki/wiki/Encrypted_DNS
# https://nixos.wiki/wiki/Systemd-resolved
services.resolved = { services.resolved = {
enable = true; enable = true;
dnssec = "true"; dnssec = "true";
# Resolved falls back to DNS servers operated by American internet
# surveillance and adtech companies by default. No thanks, I'd rather have
# no DNS at all.
fallbackDns = [ "159.69.4.2#dns.caspervk.net" "2a01:4f8:1c0c:70d1::1#dns.caspervk.net" ]; fallbackDns = [ "159.69.4.2#dns.caspervk.net" "2a01:4f8:1c0c:70d1::1#dns.caspervk.net" ];
extraConfig = '' extraConfig = ''
DNS=159.69.4.2#dns.caspervk.net 2a01:4f8:1c0c:70d1::1#dns.caspervk.net DNS=159.69.4.2#dns.caspervk.net 2a01:4f8:1c0c:70d1::1#dns.caspervk.net
@ -25,5 +38,6 @@
''; '';
}; };
# vnStat keeps a log of hourly, daily and monthly network traffic
services.vnstat.enable = true; services.vnstat.enable = true;
} }

View file

@ -1,9 +1,14 @@
{ home-manager, ... }: { { home-manager, ... }: {
# ripgrep is a line-oriented search tool that recursively searches the
# current directory for a regex pattern.
# https://github.com/BurntSushi/ripgrep
home-manager.users.caspervk = { home-manager.users.caspervk = {
programs.ripgrep = { programs.ripgrep = {
enable = true; enable = true;
arguments = [ arguments = [
# Search case-insensitively by defaylt if the pattern is all lowercase.
# Use --case-sensitive or -s to override.
"--smart-case" "--smart-case"
]; ];
}; };

View file

@ -1,6 +1,8 @@
{ ... }: { { ... }: {
services.openssh = { services.openssh = {
enable = true; enable = true;
# Security by obscurity? Nah, but it certainly reduces the logs volume.
# Also, port 222 still requires root to bind.
ports = [ 222 ]; ports = [ 222 ];
settings = { settings = {
PasswordAuthentication = false; PasswordAuthentication = false;

View file

@ -2,13 +2,20 @@
users = { users = {
# Don't allow imperative modifications to users (incompatible with impermanence) # Don't allow imperative modifications to users (incompatible with impermanence)
mutableUsers = false; mutableUsers = false;
users = { users = {
root = { root = {
# TODO: The passwordfile is manually generated during the initial setup
# to avoid (hashed) secrets in the public git repo. It should replaced
# with a proper secret management scheme, such as agenix.
passwordFile = "/nix/persist/passwordfile"; passwordFile = "/nix/persist/passwordfile";
}; };
caspervk = { caspervk = {
isNormalUser = true; isNormalUser = true;
description = "Casper V. Kristensen"; description = "Casper V. Kristensen";
# TODO: The passwordfile is manually generated during the initial setup
# to avoid (hashed) secrets in the public git repo. It should replaced
# with a proper secret management scheme, such as agenix.
passwordFile = "/nix/persist/passwordfile"; passwordFile = "/nix/persist/passwordfile";
extraGroups = [ extraGroups = [
"networkmanager" "networkmanager"

View file

@ -1,4 +1,5 @@
{ home-manager, ... }: { { home-manager, ... }: {
# Terminal emulator
# https://wiki.archlinux.org/title/Alacritty # https://wiki.archlinux.org/title/Alacritty
home-manager.users.caspervk = { home-manager.users.caspervk = {
@ -6,6 +7,9 @@
enable = true; enable = true;
settings = { settings = {
key_bindings = [ key_bindings = [
# It's easy to open a new terminal using Mod+Enter in sway, but it
# always opens in the home directly. This binds Control+Shift+Enter
# to open a new terminal in the current directory.
{ key = "Return"; mods = "Control|Shift"; action = "SpawnNewInstance"; } { key = "Return"; mods = "Control|Shift"; action = "SpawnNewInstance"; }
]; ];
}; };

View file

@ -1,4 +1,8 @@
{ home-manager, lib, pkgs, ... }: { { home-manager, lib, pkgs, ... }: {
# Clipboard manager. It can help persist clipboard contents after closing an
# application - which otherwise isn't supported in Wayland - but that breaks
# rich content copying in general. Therefore, we only use it for clipboard
# history with wofi as a frontend.
# https://github.com/yory8/clipman # https://github.com/yory8/clipman
home-manager.users.caspervk = { home-manager.users.caspervk = {
@ -6,7 +10,8 @@
enable = true; enable = true;
}; };
# The home manager module doesn't use --no-persist, but it is required if you want to copy images # The home manager module doesn't use --no-persist, but it is required if
# you want to copy images. See:
# https://github.com/yory8/clipman/issues/59 # https://github.com/yory8/clipman/issues/59
# https://github.com/nix-community/home-manager/blob/master/modules/services/clipman.nix # https://github.com/nix-community/home-manager/blob/master/modules/services/clipman.nix
systemd.user.services.clipman = { systemd.user.services.clipman = {

View file

@ -1,5 +1,7 @@
{ lib, ... }: { { lib, ... }: {
networking = { networking = {
# It's a little too much to define every WiFi network declaratively.
# Instead, we enable NetworkManager and the nmtui interface.
networkmanager = { networkmanager = {
enable = true; enable = true;
dns = lib.mkForce "none"; dns = lib.mkForce "none";

View file

@ -1,9 +1,13 @@
{ home-manager, ... }: { { home-manager, ... }: {
# # https://nix-community.github.io/home-manager/options.html # https://nix-community.github.io/home-manager/options.html
home-manager.users.caspervk = { home-manager.users.caspervk = {
programs.ssh = { programs.ssh = {
enable = true; enable = true;
# ControlMaster enables the sharing of multiple sessions over a single
# network connection. When enabled, additional sessions to the same host
# will reuse the master session's connection rather than initiating a new
# one. This is especially useful when using SCP.
controlMaster = "yes"; controlMaster = "yes";
matchBlocks = { matchBlocks = {
"delta" = { "delta" = {
@ -27,6 +31,8 @@
}; };
}; };
extraConfig = '' extraConfig = ''
# Add ssh keys to the agent the first time we unlock them so we don't
# have to type the password all the time.
AddKeysToAgent yes AddKeysToAgent yes
''; '';
}; };

View file

@ -1,11 +1,20 @@
{ ... }: { { ... }: {
# Syncthing is a continuous file synchronization program. It synchronizes
# files between two or more computers in real time. It's basically a
# self-hosted Dropbox for Linux users, but without FTP, curlftpfs, and SVN.
# https://nixos.wiki/wiki/Syncthing # https://nixos.wiki/wiki/Syncthing
services.syncthing = { services.syncthing = {
enable = true; enable = true;
user = "caspervk"; user = "caspervk";
group = "users"; group = "users";
# The directory where synchronised directories will exist
dataDir = "/home/caspervk"; dataDir = "/home/caspervk";
# Devices ignore their own IDs, allowing for a single configuration.
# TODO: Syncthing generates a private key and ID the first time it is
# started. On first install, add the devices' ID here and apply to the
# other ones. When we get a proper secret management scheme, such as
# agenix, the private keys should be managed declaratively as well.
devices = { devices = {
"lambda" = { "lambda" = {
id = "WES3JH4-S34HTC5-42YZHUJ-MX3Z6PA-PFO72KA-YIJMDOB-GQWZXZ3-I7BBTAS"; id = "WES3JH4-S34HTC5-42YZHUJ-MX3Z6PA-PFO72KA-YIJMDOB-GQWZXZ3-I7BBTAS";