This commit is contained in:
Casper V. Kristensen 2023-08-01 15:35:09 +02:00
parent fa4588d6df
commit 7536e3a2b1
21 changed files with 633 additions and 0 deletions

View file

@ -1,2 +1,98 @@
# nixos
## Installation
Follow the [NixOS manual](https://nixos.org/manual/nixos/stable/index.html#ch-installation) to obtain and boot
the installation medium. Use the graphical ISO image since it ships with useful programs such as `nmtui`; the
installation can still be done through the terminal.
### Disk Partitioning
For [impermanence](https://nixos.wiki/wiki/Impermanence), partitioning should be done as outlined in the [tmpfs
as root](https://elis.nu/blog/2020/05/nixos-tmpfs-as-root/) blogpost, but with `/nix` as a [LUKS-encrypted file
system](https://nixos.org/manual/nixos/stable/index.html#sec-luks-file-systems). The boot partition will not be
encrypted, since that is poorly supported by systemd-boot. Persistent files will be saved under `/nix/persist`.
The following is based on the [tmpfs as root](https://elis.nu/blog/2020/05/nixos-tmpfs-as-root/) blogpost, the NixOS
manual's [partitioning](https://nixos.org/manual/nixos/stable/index.html#sec-installation-manual-partitioning),
[formatting](https://nixos.orgmanual/nixos/stable/index.html#sec-installation-manual-partitioning-formatting) and
[LUKS-Encrypted File Systems](https://nixos.org/manual/nixos/stable/index.html#sec-luks-file-systems) sections,
ArchWiki's [LVM on LUKS](https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS),
the unofficial NixOS wiki [Full Disk Encryption](https://nixos.wiki/wiki/Full_Disk_Encryption), and [this GitHub
gist](https://gist.github.com/martijnvermaat/76f2e24d0239470dd71050358b4d5134).
We create a 1GiB EFI boot partition (`/dev/sda1`) and the rest will be our LUKS-encrypted volume:
```bash
# Create partition table
parted /dev/sda -- mklabel gpt
# Create /boot partition
parted /dev/sda -- mkpart ESP fat32 1MiB 1024MiB
parted /dev/sda -- set 1 esp on
# Create /nix partition
parted /dev/sda -- mkpart primary 1024MiB 100%
# Create and open LUKS-encrypted container
cryptsetup --type=luks2 luksFormat --label=crypted /dev/sda2
cryptsetup open /dev/sda2 crypted
# Create LVM volume group
pvcreate /dev/mapper/crypted
vgcreate vg /dev/mapper/crypted
# Create root logical volume
lvcreate -l 100%FREE vg -n root
# Format partitions
mkfs.fat -F32 -n BOOT /dev/sda1
mkfs.ext4 -L nix /dev/vg/root
```
The result should be the following (`lsblk -f`):
```text
NAME FSTYPE FSVER LABEL
vda
├─vda1 vfat FAT32 BOOT
└─vda2 crypto_LUKS 2 crypted
└─crypted LVM2_member LVM2 001
└─vg-root ext4 1.0 nix
```
### Installation
Whereas the [NixOS manual](https://nixos.org/manual/nixos/stable/index.html#sec-installation-manual-installing) mounts
the newly-created `nixos` partition to `/mnt`, we will follow the _tmpfs as root_ blogpost and mount `/mnt` as `tmpfs`:
```bash
mount -t tmpfs none /mnt
mount --mkdir /dev/disk/by-label/BOOT /mnt/boot
mount --mkdir /dev/disk/by-label/nix /mnt/nix
mkdir -p /mnt/nix/persist/
```
The remaining installation can be done (more or less) according to the [NixOS
manual](https://nixos.org/manual/nixos/stable/index.html#sec-installation-manual-installing).
```bash
cd /mnt/nix
git clone https://git.caspervk.net/caspervk/nixos.git tmp
cd tmp/
nixos-generate-config --root /mnt --show-hardware-config
vim hosts/omega/hardware.nix
nixos-install --no-root-passwd --flake .#omega
# Make sure to set a password
mkpasswd > /mnt/nix/persist/passwordfile
chmod 400 /mnt/nix/persist/passwordfile
```
## Hardware Configuration
`hosts/*/hardware.nix`, while initially generated by `nixos-generate-config --show-hardware-config`, _is_ manually
modified. Irrelevant options are commented, instead of deleted, to allows for easier diffing on new versions of NixOS.
## Impermanence
To find out which of our darlings will be erased on reboot do `tree -x /`.
## Upgrading
```bash
sudo nixos-rebuild switch --flake .#omega
```

65
flake.lock Normal file
View file

@ -0,0 +1,65 @@
{
"nodes": {
"home-manager": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1687871164,
"narHash": "sha256-bBFlPthuYX322xOlpJvkjUBz0C+MOBjZdDOOJJ+G2jU=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "07c347bb50994691d7b0095f45ebd8838cf6bc38",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-23.05",
"repo": "home-manager",
"type": "github"
}
},
"impermanence": {
"locked": {
"lastModified": 1690797372,
"narHash": "sha256-GImz19e33SeVcIvBB7NnhbJSbTpFFmNtWLh7Z85Y188=",
"owner": "nix-community",
"repo": "impermanence",
"rev": "e3a7acd113903269a1b5c8b527e84ce7ee859851",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "impermanence",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1690630041,
"narHash": "sha256-gbnvqm5goS9DSKAqGFpq3398aOpwejmq4qWikqmQyRo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d57e8c535d4cbb07f441c30988ce52eec69db7a8",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-23.05",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"home-manager": "home-manager",
"impermanence": "impermanence",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

33
flake.nix Normal file
View file

@ -0,0 +1,33 @@
{
description = "NixOS system";
inputs = {
nixpkgs = {
url = "github:NixOS/nixpkgs/nixos-23.05";
};
impermanence = {
url = "github:nix-community/impermanence";
};
nix-index-database = {
url = "github:nix-community/nix-index-database";
inputs.nixpkgs.follows = "nixpkgs"; # use the same nixpkgs as the system
};
home-manager = {
url = "github:nix-community/home-manager/release-23.05";
inputs.nixpkgs.follows = "nixpkgs"; # use the same nixpkgs as the system
};
};
outputs = { self, nixpkgs, ... }@inputs: {
nixosConfigurations = {
# Home desktop
omega = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = inputs; # pass flake inputs to modules
modules = [
./hosts/omega
];
};
};
};
}

0
home/default.nix Normal file
View file

36
hosts/omega/default.nix Normal file
View file

@ -0,0 +1,36 @@
{ ... }:
{
imports = [
./hardware.nix
../../modules/base
../../modules/desktop
];
networking.hostName = "omega";
boot = {
loader = {
efi.canTouchEfiVariables = true;
systemd-boot.enable = true;
};
initrd.luks.devices.crypted.device = "/dev/disk/by-label/crypted";
};
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. It's perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "23.05"; # Did you read the comment?
# This value determines the Home Manager release that your
# configuration is compatible with. This helps avoid breakage
# when a new Home Manager release introduces backwards
# incompatible changes.
# You can update Home Manager without changing this value. See
# the Home Manager release notes for a list of state version
# changes in each release.
home-manager.users.caspervk.home.stateVersion = "23.05"; # Did you read the comment?
}

43
hosts/omega/hardware.nix Normal file
View file

@ -0,0 +1,43 @@
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "sr_mod" "virtio_blk" ];
boot.initrd.kernelModules = [ "dm-snapshot" ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
# https://elis.nu/blog/2020/05/nixos-tmpfs-as-root/
fileSystems."/" = {
device = "none";
fsType = "tmpfs";
options = [ "defaults" "size=2G" "mode=755" ]; # mode=755 so only root can write to those files
};
fileSystems."/boot" = {
device = "/dev/disk/by-label/BOOT";
fsType = "vfat";
};
fileSystems."/nix" = {
device = "/dev/disk/by-label/nix";
fsType = "ext4";
};
swapDevices = [
{
device = "/nix/persist/swapfile";
size = 16*1024; # 16 GiB
}
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp1s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

15
modules/base/default.nix Normal file
View file

@ -0,0 +1,15 @@
{ ... }:
{
imports = [
./fish.nix
./git.nix
./home-manager.nix
./impermanence.nix
./network.nix
./ssh.nix
./system.nix
./users.nix
./vim.nix
];
}

20
modules/base/fish.nix Normal file
View file

@ -0,0 +1,20 @@
{ pkgs, ... }: {
# https://nixos.wiki/wiki/Fish
# https://nixos.wiki/wiki/Command_Shell
environment.systemPackages = with pkgs; [
fishPlugins.colored-man-pages
fishPlugins.fzf-fish
fishPlugins.puffer
fishPlugins.pure
];
programs.fish = {
enable = true;
interactiveShellInit = ''
fzf_configure_bindings --directory=\cf --git_log=\cg
'';
};
users.defaultUserShell = pkgs.fish;
environment.shells = with pkgs; [ fish ];
}

21
modules/base/git.nix Normal file
View file

@ -0,0 +1,21 @@
{ home-manager, ... }: {
home-manager.users.caspervk = {
programs.git = {
enable = true;
userName = "Casper V. Kristensen";
userEmail = "casper@vkristensen.dk";
delta = {
enable = true;
};
extraConfig = {
init.defaultBranch = "master";
pull.rebase = true;
rebase.autoSquash = true;
rebase.autoStash = true;
};
};
};
}

View file

@ -0,0 +1,27 @@
{ home-manager, ... }: {
# https://nix-community.github.io/home-manager/index.html#sec-flakes-nixos-module
# https://nixos.wiki/wiki/Home_Manager
imports = [
home-manager.nixosModules.home-manager
];
home-manager = {
# Use the same nixpkgs as the system
useGlobalPkgs = true;
# Install packages to /etc/profiles instead of $HOME/.nix-profile, not sure why
useUserPackages = true;
users.caspervk = {
# Define the user and path Home Manager should manage
home = {
username = "caspervk";
homeDirectory = "/home/caspervk";
};
# Let Home Manager install and manage itself
programs.home-manager.enable = true;
};
};
}

View file

@ -0,0 +1,32 @@
{ pkgs, impermanence, ... }: {
# 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://nixos.wiki/wiki/Impermanence
imports = [
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
# instruct systemd to clean it on boot.
boot.tmp.cleanOnBoot = true;
environment.persistence."/nix/persist" = {
hideMounts = true;
directories = [
{ directory = "/tmp"; user = "root"; group = "root"; mode = "1777"; } # see comment above
# With great power comes great responsibility, we get it
{ directory = "/var/db/sudo/lectured"; user = "root"; group = "root"; mode = "0700"; }
{ directory = "/var/log"; user = "root"; group = "root"; mode = "0755"; }
];
files = [
"/etc/machine-id" # needed for /var/log
];
users.caspervk = {
directories = [
"/" # entire home directory
];
};
};
}

23
modules/base/network.nix Normal file
View file

@ -0,0 +1,23 @@
{ pkgs, ... }: {
networking = {
firewall = {
allowedTCPPorts = [ 1234 1337 8000 8080 ];
allowedUDPPorts = [ 1234 1337 8000 8080 ];
};
nameservers = [ "159.69.4.2#dns.caspervk.net" ];
networkmanager = {
enable = true;
};
};
services.resolved = {
enable = true;
dnssec = "true";
fallbackDns = [ "159.69.4.2#dns.caspervk.net" ];
extraConfig = ''
DNSOverTLS=yes
'';
};
services.vnstat.enable = true;
}

18
modules/base/ssh.nix Normal file
View file

@ -0,0 +1,18 @@
{ ... }: {
services.openssh = {
enable = true;
ports = [ 222 ];
settings = {
PasswordAuthentication = false;
};
};
environment.persistence."/nix/persist" = {
files = [
"/etc/ssh/ssh_host_ed25519_key"
"/etc/ssh/ssh_host_ed25519_key.pub"
"/etc/ssh/ssh_host_rsa_key"
"/etc/ssh/ssh_host_rsa_key.pub"
];
};
}

71
modules/base/system.nix Normal file
View file

@ -0,0 +1,71 @@
{ pkgs, nix-index-database, ... }: {
imports = [
nix-index-database.nixosModules.nix-index
];
nix = {
# https://nixos.wiki/wiki/Storage_optimization
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than=30d";
};
settings = {
auto-optimise-store = true;
experimental-features = [ "nix-command" "flakes" ];
};
};
nixpkgs.config.allowUnfree = true;
environment.systemPackages = with pkgs; [
bat
clang
curl
dig
fd
fzf
gcc
git
gnumake
htop
inetutils
jq
magic-wormhole
ntp
python3
pwgen
ripgrep
rsync
sqlite
tmux
traceroute
tree
unzip
wget
xkcdpass
yq
];
# https://github.com/nix-community/comma
programs.nix-index-database.comma.enable = true;
programs.command-not-found.enable = false;
i18n = {
defaultLocale = "en_DK.UTF-8";
extraLocaleSettings = {
LC_ADDRESS = "en_DK.UTF-8";
LC_IDENTIFICATION = "en_DK.UTF-8";
LC_MEASUREMENT = "en_DK.UTF-8";
LC_MONETARY = "en_DK.UTF-8";
LC_NAME = "en_DK.UTF-8";
LC_NUMERIC = "en_DK.UTF-8";
LC_PAPER = "en_DK.UTF-8";
LC_TELEPHONE = "en_DK.UTF-8";
LC_TIME = "en_DK.UTF-8";
};
};
time = {
timeZone = "Europe/Copenhagen";
};
}

28
modules/base/users.nix Normal file
View file

@ -0,0 +1,28 @@
{ pkgs, ... }: {
users = {
# Don't allow imperative modifications to users (incompatible with impermanence)
mutableUsers = false;
users = {
root = {
passwordFile = "/nix/persist/passwordfile";
};
caspervk = {
isNormalUser = true;
description = "Casper V. Kristensen";
passwordFile = "/nix/persist/passwordfile";
extraGroups = [
"networkmanager"
"wheel" # allows sudo
"video" # allows controlling brightness
# todo: docker, systemd-journal, audio, input, power, nix ?
];
uid = 1000;
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPB/qr63FB0ZqOe/iZGwIKNHD8a1Ud/mXVjQPmpIG7pM caspervk@omega"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII71DKQziktCkyMAmL25QKRK6nG2uJDkQXioIZp5JkMZ caspervk@zeta"
];
packages = with pkgs; [];
};
};
};
}

8
modules/base/vim.nix Normal file
View file

@ -0,0 +1,8 @@
{ ... }: {
programs.neovim = {
enable = true;
defaultEditor = true;
viAlias = true;
vimAlias = true;
};
}

View file

@ -0,0 +1,9 @@
{ ... }:
{
imports = [
./firefox.nix
./ssh.nix
./sway.nix
];
}

View file

@ -0,0 +1,7 @@
{ pkgs, ... }: {
# https://nixos.wiki/wiki/Firefox
environment.systemPackages = with pkgs; [
firefox-wayland
];
}

26
modules/desktop/ssh.nix Normal file
View file

@ -0,0 +1,26 @@
{ home-manager, ... }: {
# # https://nix-community.github.io/home-manager/options.html
home-manager.users.caspervk = {
programs.ssh = {
enable = true;
matchBlocks = {
"delta" = {
hostname = "delta.caspervk.net";
port = 222;
};
"lambda" = {
hostname = "lambda.caspervk.net";
port = 222;
};
"sigma" = {
hostname = "sigma.caspervk.net";
port = 222;
};
"git.caspervk.net" = {
port = 2222;
};
};
};
};
}

51
modules/desktop/sway.nix Normal file
View file

@ -0,0 +1,51 @@
{ pkgs, home-manager, ... }: {
# https://nixos.wiki/wiki/Sway
# https://nix-community.github.io/home-manager/options.html
home-manager.users.caspervk = {
wayland.windowManager.sway = {
enable = true;
config = {
assigns = {
"1: web" = [{ class = "^Firefox$"; }];
};
input = {
"*" = {
# Keyboard
xkb_layout = "us";
xkb_variant = "altgr-intl";
# Trackpad
tap = "enabled";
natural_scroll = "enable";
dwt = "disabled"; # don't disable-while-typing
};
};
modifier = "Mod4"; # super
terminal = "alacritty";
workspaceAutoBackAndForth = true;
};
};
};
environment.systemPackages = with pkgs; [
alacritty
];
# Audio
services.pipewire = {
enable = true;
alsa = {
enable = true;
support32Bit = true;
};
jack.enable = true;
pulse.enable = true;
};
# Video
programs.light.enable = true; # allows controlling screen brightness
# Allow sharing screen
#xdg.portal.wlr.enable = true;
}

4
todo Normal file
View file

@ -0,0 +1,4 @@
https://unix.stackexchange.com/questions/522822/different-methods-to-run-a-non-nixos-executable-on-nixos
https://discourse.nixos.org/t/tips-tricks-for-nixos-desktop/28488
https://github.com/sioodmy/dotfiles/blob/main/modules/core/users.nix
https://nixos.wiki/wiki/Comparison_of_secret_managing_schemes