feat: new host - shoukei

This commit is contained in:
Ryan Yin
2023-12-24 00:36:20 +08:00
parent 73a746cebd
commit 03c1d14ed9
25 changed files with 869 additions and 197 deletions

View File

@@ -0,0 +1,10 @@
{pkgs, ...}:
pkgs.stdenvNoCC.mkDerivation {
name = "brcm-firmware";
nativeBuildInputs = with pkgs; [gnutar xz];
buildCommand = ''
dir="$out/lib/"
mkdir -p "$dir"
tar -axvf ${./firmware.tar.xz} -C "$dir"
'';
}

Binary file not shown.

View File

@@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1703068421,
"narHash": "sha256-WSw5Faqlw75McIflnl5v7qVD/B3S2sLh+968bpOGrWA=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "d65bceaee0fb1e64363f7871bc43dc1c6ecad99f",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-23.11",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

View File

@@ -0,0 +1,10 @@
{
# a flake for testing
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
outputs = {nixpkgs, ...}: let
system = "x86_64-linux";
pkgs = import nixpkgs {inherit system;};
in {
packages."${system}".default = pkgs.callPackage ./default.nix {};
};
}

View File

@@ -0,0 +1,48 @@
{
pkgs,
nixos-hardware,
...
} @ args:
#############################################################
#
# Shoukei - NixOS running on Macbook Pro 2020 I5 16G
# https://github.com/NixOS/nixos-hardware/tree/master/apple/t2
#
#############################################################
{
imports = [
nixos-hardware.nixosModules.apple-t2
{hardware.apple-t2.enableAppleSetOsLoader = true;}
./hardware-configuration.nix
./impermanence.nix
];
networking = {
hostName = "shoukei"; # Define your hostname.
# configures the network interface(include wireless) via `nmcli` & `nmtui`
networkmanager.enable = true;
# Configure network proxy if necessary
# proxy.default = "http://user:password@proxy:port/";
# proxy.noProxy = "127.0.0.1,localhost,internal.domain";
# Configure network proxy if necessary
# proxy.default = "http://user:password@proxy:port/";
# proxy.noProxy = "127.0.0.1,localhost,internal.domain";
defaultGateway = "192.168.5.201";
nameservers = [
"119.29.29.29" # DNSPod
"223.5.5.5" # AliDNS
];
};
# 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. Its 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.11"; # Did you read the comment?
}

View File

@@ -0,0 +1,130 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}: {
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
hardware.firmware = [
(import ./brcm-firmware { inherit pkgs;})
];
boot.initrd.availableKernelModules = ["xhci_pci" "nvme" "usbhid" "usb_storage" "sd_mod"];
boot.initrd.kernelModules = [];
boot.kernelModules = ["kvm-intel"];
boot.extraModulePackages = [];
# Use the EFI boot loader.
boot.loader.efi.canTouchEfiVariables = true;
# depending on how you configured your disk mounts, change this to /boot or /boot/efi.
boot.loader.efi.efiSysMountPoint = "/boot";
boot.loader.systemd-boot.enable = true;
# Enable binfmt emulation of aarch64-linux, this is required for cross compilation.
boot.binfmt.emulatedSystems = ["aarch64-linux" "riscv64-linux"];
# supported fil systems, so we can mount any removable disks with these filesystems
boot.supportedFilesystems = lib.mkForce [
"ext4"
"btrfs"
"xfs"
"ntfs"
"fat"
"vfat"
"cifs" # mount windows share
];
# clear /tmp on boot to get a stateless /tmp directory.
boot.tmp.cleanOnBoot = true;
boot.initrd = {
# unlocked luks devices via a keyfile or prompt a passphrase.
luks.devices."crypted-nixos" = {
device = "/dev/nvme0n1p4";
# the keyfile(or device partition) that should be used as the decryption key for the encrypted device.
# if not specified, you will be prompted for a passphrase instead.
#keyFile = "/root-part.key";
# whether to allow TRIM requests to the underlying device.
# it's less secure, but faster.
allowDiscards = true;
};
};
# equal to `mount -t tmpfs tmpfs /`
fileSystems."/" = {
device = "tmpfs";
fsType = "tmpfs";
# set mode to 755, otherwise systemd will set it to 777, which cause problems.
# relatime: Update inode access times relative to modify or change time.
options = ["relatime" "mode=755"];
};
fileSystems."/boot" = {
device = "/dev/nvme0n1p1";
fsType = "vfat";
};
fileSystems."/nix" = {
device = "/dev/disk/by-uuid/2f4db246-e65d-4808-8ab4-5365f9dea1ef";
fsType = "btrfs";
options = ["subvol=@nix" "noatime" "compress-force=zstd:1"];
};
fileSystems."/tmp" = {
device = "/dev/disk/by-uuid/2f4db246-e65d-4808-8ab4-5365f9dea1ef";
fsType = "btrfs";
options = ["subvol=@tmp" "noatime" "compress-force=zstd:1"];
};
fileSystems."/persistent" = {
device = "/dev/disk/by-uuid/2f4db246-e65d-4808-8ab4-5365f9dea1ef";
fsType = "btrfs";
options = ["subvol=@persistent" "noatime" "compress-force=zstd:1"];
# impermanence's data is required for booting.
neededForBoot = true;
};
fileSystems."/snapshots" = {
device = "/dev/disk/by-uuid/2f4db246-e65d-4808-8ab4-5365f9dea1ef";
fsType = "btrfs";
options = ["subvol=@snapshots" "noatime" "compress-force=zstd:1"];
};
# mount swap subvolume in readonly mode.
fileSystems."/swap" = {
device = "/dev/disk/by-uuid/2f4db246-e65d-4808-8ab4-5365f9dea1ef";
fsType = "btrfs";
options = ["subvol=@swap" "ro"];
};
# remount swapfile in read-write mode
fileSystems."/swap/swapfile" = {
# the swapfile is located in /swap subvolume, so we need to mount /swap first.
depends = ["/swap"];
device = "/swap/swapfile";
fsType = "none";
options = ["bind" "rw"];
};
swapDevices = [
{device = "/swap/swapfile";}
];
# 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.enp230s0f1u1.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp229s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@@ -0,0 +1,118 @@
{
impermanence,
pkgs,
...
}: {
imports = [
impermanence.nixosModules.impermanence
];
environment.systemPackages = [
# `sudo ncdu -x /`
pkgs.ncdu
];
# There are two ways to clear the root filesystem on every boot:
## 1. use tmpfs for /
## 2. (btrfs/zfs only)take a blank snapshot of the root filesystem and revert to it on every boot via:
## boot.initrd.postDeviceCommands = ''
## mkdir -p /run/mymount
## mount -o subvol=/ /dev/disk/by-uuid/UUID /run/mymount
## btrfs subvolume delete /run/mymount
## btrfs subvolume snapshot / /run/mymount
## '';
#
# See also https://grahamc.com/blog/erase-your-darlings/
# NOTE: impermanence only mounts the directory/file list below to /persistent
# If the directory/file already exists in the root filesystem, you should
# move those files/directories to /persistent first!
environment.persistence."/persistent" = {
# sets the mount option x-gvfs-hide on all the bind mounts
# to hide them from the file manager
hideMounts = true;
directories = [
"/etc/NetworkManager/system-connections"
"/etc/ssh"
"/etc/nix/inputs"
"/etc/secureboot" # lanzaboote - secure boot
# my secrets
"/etc/agenix/"
"/var/log"
"/var/lib"
# created by modules/nixos/misc/fhs-fonts.nix
# for flatpak apps
# "/usr/share/fonts"
# "/usr/share/icons"
];
files = [
"/etc/machine-id"
];
# the following directories will be passed to /persistent/home/$USER
users.ryan = {
directories = [
"codes"
"nix-config"
"tmp"
"Downloads"
"Music"
"Pictures"
"Documents"
"Videos"
{
directory = ".gnupg";
mode = "0700";
}
{
directory = ".ssh";
mode = "0700";
}
{
directory = ".aws";
mode = "0700";
}
{
directory = ".docker";
mode = "0700";
}
{
directory = ".kube";
mode = "0700";
}
# misc
".config/pulse"
".pki"
# remote desktop
".config/remmina"
".config/freerdp"
# browsers
".mozilla"
".config/google-chrome"
# neovim / remmina / flatpak / ...
".local/share"
".local/state"
# language package managers
".npm"
"go"
# neovim plugins(wakatime & copilot)
".wakatime"
".config/github-copilot"
];
files = [
".wakatime.cfg"
".config/nushell/history.txt"
];
};
};
}

View File

@@ -1,6 +1,4 @@
{
config,
username,
nixos-rk3588,
...
}:
@@ -15,8 +13,6 @@
nixos-rk3588.nixosModules.orangepi5
];
users.users.root.openssh.authorizedKeys.keys = config.users.users."${username}".openssh.authorizedKeys.keys;
networking = {
hostName = "suzu"; # Define your hostname.
wireless.enable = false; # Enables wireless support via wpa_supplicant.

View File

@@ -61,6 +61,7 @@
device = "tmpfs";
fsType = "tmpfs";
# set mode to 755, otherwise systemd will set it to 777, which cause problems.
# relatime: Update inode access times relative to modify or change time.
options = ["relatime" "mode=755"];
};

View File

@@ -1,3 +0,0 @@
result
result/
.DS_Store

View File

@@ -1,243 +0,0 @@
# Nix Environment for Deploying my NixOS Configuration
This flake prepares a Nix environment for setting my desktop [/hosts/idols/ai](/hosts/idols/ai/)(on main flake) up on a new machine.
TODOs:
- [ ] dcalarative disk partitioning with [disko](https://github.com/nix-community/disko)
## Why an extra flake is needed?
The configuration of the main flake, [/flake.nix](/flake.nix), is heavy, and it takes time to debug & deploy.
This simplified flake is tiny and can be deployed very quickly, it helps me to:
1. Adjust & verify my `hardware-configuration.nix` modification quickly before deploying the `main` flake.
2. Test some new filesystem related features on a NixOS virtual machine, such as impermanence, Secure Boot, TMP2, Encryption, etc.
## Steps to Deploying the `main` flake
First, create a USB install medium from NixOS's official ISO image and boot from it.
### 1. Encrypting with LUKS(everything except ESP)
> https://nixos.org/manual/nixos/stable/#sec-installation-manual-partitioning
> [dm-crypt/Encrypting an entire system - Arch Wiki](https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system)
> [Encrypted /boot - GRUB2 - Arch Wiki](https://wiki.archlinux.org/title/GRUB#Encrypted_/boot)
> [Frequently asked questions (FAQ) - cryptsetup](https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions)
Securing a root file system is where dm-crypt excels, feature and performance-wise.
An encrypted root file system protects everything on the system, it make the system a black box to the attacker.
1. The EFI system partition(ESP) must be left unencrypted, and is mounted at `/boot`
1. Since the UEFI firmware can only load boot loaders from unencrypted partitions.
2. Secure Boot is enabled, everything in ESP is signed.
3. The BTRFS file system with subvolumes is used for the root partition, and the swap area is a swapfile on a dedicated BTRFS subvolume, thus the swap area is also encrypted.
And the boot flow is:
1. The UEFI firmware loads the boot loader from the ESP(`/boot`).
2. The boot loader loads the kernel and initrd from the ESP(`/boot`).
3. **The initrd prompts for the passphrase to unlock the root partition**.
4. The initrd unlocks the root partition and mounts it at `/`.
5. The initrd continues the boot process, and hands over the control to the kernel.
Partitioning the disk:
```bash
# Create a GPT partition table
parted /dev/nvme0n1 -- mklabel gpt
# NixOS by default uses the ESP (EFI system partition) as its /boot partition
# Create a 512MB EFI system partition
parted /dev/nvme0n1 -- mkpart ESP fat32 2MB 629MB
# set the boot flag on the ESP partition
# Format:
# set partition flag state
parted /dev/nvme0n1 -- set 1 esp on
# Create the root partition using the rest of the disk
# Format:
# mkpart [part-type name fs-type] start end
parted /dev/nvme0n1 -- mkpart primary 630MB 100%
# show disk status
lsblk
```
Encrypting the root partition:
```bash
lsblk
# show cryptsetup's compiled in defualts
cryptsetup --help
# encrypt the root partition with luks2 and argon2id, will prompt for a passphrase, which will be used to unlock the partition.
cryptsetup luksFormat --type luks2 --pbkdf argon2id --cipher aes-xts-plain64 --key-size 512 --hash sha512 /dev/nvme0n1p2
# show status
cryptsetup luksDump /dev/nvme0n1p2
# open(unlock) the device with the passphrase you just set
cryptsetup luksOpen /dev/nvme0n1p2 crypted-nixos
# show disk status
lsblk
```
Formatting the root partition:
```bash
mkfs.fat -F 32 -n ESP /dev/nvme0n1p1
# format the root partition with btrfs and label it
mkfs.btrfs -L crypted-nixos /dev/mapper/crypted-nixos
# mount the root partition and create subvolumes
mount /dev/mapper/crypted-nixos /mnt
btrfs subvolume create /mnt/@nix
btrfs subvolume create /mnt/@tmp
btrfs subvolume create /mnt/@swap
btrfs subvolume create /mnt/@persistent
btrfs subvolume create /mnt/@snapshots
umount /mnt
# Use tmpfs for root - stateless
mount -t tmpfs tmpfs /mnt
# Remount the root partition with the subvolumes you just created
#
# Enable zstd compression to:
# 1. Reduce the read/write operations, which helps to:
# 1. Extend the life of the SSD.
# 2. improve the performance of disks with low IOPS / RW throughput, such as HDD and SATA SSD.
# 2. Save the disk space.
mkdir /mnt/{nix,tmp,swap,persistent,snapshots,boot}
mount -o compress-force=zstd:1,noatime,subvol=@nix /dev/mapper/crypted-nixos /mnt/nix
mount -o compress-force=zstd:1,subvol=@tmp /dev/mapper/crypted-nixos /mnt/tmp
mount -o subvol=@swap /dev/mapper/crypted-nixos /mnt/swap
mount -o compress-force=zstd:1,noatime,subvol=@persistent /dev/mapper/crypted-nixos /mnt/persistent
mount -o compress-force=zstd:1,noatime,subvol=@snapshots /dev/mapper/crypted-nixos /mnt/snapshots
mount /dev/nvme0n1p1 /mnt/boot
# create a swapfile on btrfs file system
# This command will disable CoW / compression on the swap subvolume and then create a swapfile.
# because the linux kernel requires that swapfile must not be compressed or have copy-on-write(CoW) enabled.
btrfs filesystem mkswapfile --size 96g --uuid clear /mnt/swap/swapfile
# check whether the swap subvolume has CoW disabled
# the output of `lsattr` for the swap subvolume should be:
# ---------------C------ /swap/swapfile
# if not, delete the swapfile, and rerun the commands above.
lsattr /mnt/swap
# mount the swapfile as swap area
swapon swapfile
```
Now, the disk status should be:
```bash
# show disk status
$ lsblk
nvme0n1 259:0 0 1.8T 0 disk
├─nvme0n1p1 259:2 0 600M 0 part /mnt/boot
└─nvme0n1p2 259:3 0 1.8T 0 part
└─crypted-nixos 254:0 0 1.8T 0 crypt /mnt/swap
/mnt/persistent
/mnt/snapshots
/mnt/nix
/mnt/tmp
# show swap status
$ swapon -s
Filename Type Size Used Priority
/swap/swapfile file 100663292 0 -2
```
### 2. Generating the NixOS Configuration and Installing NixOS
Clone this repository:
```bash
# enter an shell with git/vim/ssh-agent/gnumake available
nix-shell -p git vim gnumake
# clone this repository
git clone https://github.com/ryan4yin/nix-config.git
```
Then, generate the NixOS configuration:
```bash
# nixos configurations
nixos-generate-config --root /mnt
# we need to update our filesystem configs in old hardware-configuration.nix according to the generated one.
cp /etc/nixos/hardware-configuration.nix ./nix-config/hosts/idols/ai/hardware-configuration-new.nix
vim .
```
Then, Install NixOS:
```bash
cd ~/nix-config
# run this command if you're retrying to run nixos-install
rm -rf /mnt/etc
# install nixos
# NOTE: the root password you set here will be discarded when reboot
nixos-install --root /mnt --flake .#ai --no-root-password
# if you want to use a cache mirror, run this command instead
# replace the mirror url with your own
nixos-install --root /mnt --flake .#ai --no-root-password --option substituters "https://mirror.sjtu.edu.cn/nix-channels/store"
# enter into the installed system, check password & users
nixos-enter
# copy the essential files into /persistent
# otherwise the / will be cleared and data will lost
## NOTE: impermanence just create links from / to /persistent
## We need to copy files into /persistent manually!!!
mv /etc/machine-id /persistent/etc/
mv /etc/ssh /persistent/etc/
# delte the generated configuration after editing
rm -f /mnt/etc/nixos
rm ~/nix-config/hosts/idols/ai/hardware-configuration-new.nix
# commit the changes after installing nixos successfully
git config --global user.email "ryan4yin@linux.com"
git config --global user.name "Ryan Yin"
git commit -am "feat: update hardware-configuration"
# copy our configuration to the installed file system
cp -r ../nix-config /mnt/etc/nixos
```
And then reboot.
## Deploying the main flake's NixOS configuration
After rebooting, we can deploy the main flake's NixOS configuration by running:
```bash
# 1. Add the ssh key to the ssh-agent, so that nixos-rebuild can use it to pull my private git repositories.
ssh-add ~/.ssh/xxx
sudo mv /etc/nixos ~/nix-config
chown -R ryan:ryan ~/nix-config
cd ~/nix-config
# deploy the configuration
make hypr
```
Finally, to enable secure boot, follow the instructions in [lanzaboote - Quick Start](https://github.com/nix-community/lanzaboote/blob/master/docs/QUICK_START.md) and [nix-config/ai/secure-boot.nix](https://github.com/ryan4yin/nix-config/blob/main/hosts/idols/ai/secureboot.nix)

View File

@@ -1,8 +0,0 @@
_: {
networking = {
hostName = "ai";
defaultGateway = "192.168.5.201";
networkmanager.enable = true;
};
system.stateVersion = "23.11";
}

View File

@@ -1,43 +0,0 @@
{
"nodes": {
"impermanence": {
"locked": {
"lastModified": 1697303681,
"narHash": "sha256-caJ0rXeagaih+xTgRduYtYKL1rZ9ylh06CIrt1w5B4g=",
"owner": "nix-community",
"repo": "impermanence",
"rev": "0f317c2e9e56550ce12323eb39302d251618f5b5",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "impermanence",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1701389149,
"narHash": "sha256-rU1suTIEd5DGCaAXKW6yHoCfR1mnYjOXQFOaH7M23js=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "5de0b32be6e85dc1a9404c75131316e4ffbc634c",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-23.11",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"impermanence": "impermanence",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

View File

@@ -1,24 +0,0 @@
{
description = "NixOS configuration of Ryan Yin";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
impermanence.url = "github:nix-community/impermanence";
};
outputs = inputs @ {nixpkgs, ...}: {
nixosConfigurations = {
ai = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = inputs;
modules = [
./configuration.nix
./system.nix
../hardware-configuration.nix
../impermanence.nix
];
};
};
};
}

View File

@@ -1,57 +0,0 @@
{pkgs, ...}: {
# Set your time zone.
time.timeZone = "Asia/Shanghai";
# Select internationalisation properties.
i18n.defaultLocale = "en_US.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "zh_CN.UTF-8";
LC_IDENTIFICATION = "zh_CN.UTF-8";
LC_MEASUREMENT = "zh_CN.UTF-8";
LC_MONETARY = "zh_CN.UTF-8";
LC_NAME = "zh_CN.UTF-8";
LC_NUMERIC = "zh_CN.UTF-8";
LC_PAPER = "zh_CN.UTF-8";
LC_TELEPHONE = "zh_CN.UTF-8";
LC_TIME = "zh_CN.UTF-8";
};
# ssh-agent is used to pull my private secrets repo from github when depoloying my nixos config.
programs.ssh.startAgent = true;
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
neovim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
git
gnumake
wget
curl
nix-output-monitor
];
users.groups = {
"ryan" = {};
};
# Don't allow mutation of users outside the config.
users = {
mutableUsers = false;
# Define a user account. Don't forget to set a password with passwd.
users = {
ryan = {
# generated by `mkpasswd -m scrypt`
# we have to use initialHashedPassword here, if your'are using tmpfs for /
initialHashedPassword = "$7$CU..../....Sdl/JRH..9eIvZ6mE/52r.$xeR6lyvTcVVKt28Owcoc/vPOOECcYSiq1xjw/QCz2t0";
isNormalUser = true;
description = "ryan";
extraGroups = ["ryan" "networkmanager" "wheel"];
};
root.initialHashedPassword = "$7$CU..../....X6uvZYnFD.i1CqqFFNl4./$4vgqzIPyw5XBr0aCDFbY/UIRRJr7h5SMGoQ/ZvX3FP2";
};
};
# make ryan a trusted user so he can set custom nix substituters url(cache mirror) to speed up nixos-rebuild.
nix.settings.trusted-users = ["ryan"];
}