feat: new host - idols-akane, hardens VFAT /boot mounts (#245)

* feat: new host - idols-akane

* fix: missing efi files

* fix: efi partition - permission issue
This commit is contained in:
Ryan Yin
2026-03-07 23:54:13 +08:00
committed by GitHub
parent f9596089b3
commit 69f77fecca
10 changed files with 276 additions and 63 deletions

View File

@@ -87,8 +87,9 @@ in
device = "/dev/disk/by-uuid/01CE-1DFD";
fsType = "vfat";
options = [
"fmask=0022"
"dmask=0022"
"fmask=0177" # File mask: 777-177=600 (Owner: rw-, Group/Others: ---)
"dmask=0077" # Directory mask: 777-077=700 (Owner: rwx, Group/Others: ---)
"noexec,nosuid,nodev" # Security: Block execution, ignore setuid, and disable device nodes
];
};

View File

@@ -174,6 +174,11 @@
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/90FB-9F88";
fsType = "vfat";
options = [
"fmask=0177" # File mask: 777-177=600 (Owner: rw-, Group/Others: ---)
"dmask=0077" # Directory mask: 777-077=700 (Owner: rwx, Group/Others: ---)
"noexec,nosuid,nodev" # Security: Block execution, ignore setuid, and disable device nodes
];
};
swapDevices = [

View File

@@ -0,0 +1,21 @@
# Idols - Akane
VM running on macOS's UTM App.
Steps to install:
```bash
# 1. format & mount the filesystem
nix-shell -p disko
sudo disko --mode destroy,format,mount hosts/idols-akane/disko-fs.nix
# 2. install nixos
nixos-install --root /mnt --flake .#akane --no-root-password --show-trace --verbose --option substituters "https://mirrors.ustc.edu.cn/nix-channels/store https://cache.nixos.org/" # install-2
# enter into the installed system, check password & users
# `su ryan` => `sudo -i` => enter ryan's password => successfully login
# if login failed, check the password you set in install-1, and try again
nixos-enter
reboot
```

View File

@@ -0,0 +1,62 @@
{
disko,
mylib,
lib,
...
}:
#############################################################
#
# Akane - a NixOS VM running on macOS's UTM App
#
#############################################################
let
hostName = "akane"; # Define your hostname.
in
{
imports = (mylib.scanPaths ./.) ++ [
disko.nixosModules.default
];
# supported file systems, so we can mount any removable disks with these filesystems
boot.supportedFilesystems = [
"ext4"
"btrfs"
"xfs"
#"zfs"
"ntfs"
"fat"
"vfat"
"exfat"
];
boot.initrd.availableKernelModules = [
"xhci_pci"
"virtio_pci"
"usbhid"
"usb_storage"
"sr_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
networking = {
inherit hostName;
networkmanager.enable = true;
};
# 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 = "26.05"; # Did you read the comment?
}

View File

@@ -0,0 +1,65 @@
{
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/vda"; # the virtual disk
content = {
type = "gpt";
partitions = {
ESP = {
priority = 1;
name = "ESP";
start = "1M";
end = "450M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"fmask=0177" # File mask: 777-177=600 (Owner: rw-, Group/Others: ---)
"dmask=0077" # Directory mask: 777-077=700 (Owner: rwx, Group/Others: ---)
"noexec,nosuid,nodev" # Security: Block execution, ignore setuid, and disable device nodes
];
};
};
root = {
size = "100%";
content = {
type = "btrfs";
extraArgs = [ "-f" ]; # Override existing partition
subvolumes = {
"@root" = {
mountpoint = "/";
};
"@nix" = {
mountpoint = "/nix";
mountOptions = [
"compress-force=zstd:1"
"noatime"
];
};
"@home" = {
mountOptions = [ "compress=zstd:1" ];
mountpoint = "/home";
};
"@tmp" = {
mountpoint = "/tmp";
mountOptions = [
"noatime"
];
};
"@swap" = {
mountpoint = "/swap";
swap.swapfile.size = "4096M";
};
};
};
};
};
};
};
};
};
}

View File

@@ -37,7 +37,9 @@
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"defaults"
"fmask=0177" # File mask: 777-177=600 (Owner: rw-, Group/Others: ---)
"dmask=0077" # Directory mask: 777-077=700 (Owner: rwx, Group/Others: ---)
"noexec,nosuid,nodev" # Security: Block execution, ignore setuid, and disable device nodes
];
};
};

View File

@@ -1,41 +1,17 @@
{
modulesPath,
lib,
...
}:
##############################################################################
#
# Template for KubeVirt's VM, mainly based on:
# https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/virtualisation/kubevirt.nix
#
# We write our hardware-configuration.nix, so that we can do some customization more easily.
#
# the url above is used by `nixos-generator` to generate the KubeVirt's qcow2 image file.
#
##############################################################################
{
imports = [
"${toString modulesPath}/profiles/qemu-guest.nix"
./qemu-guest.nix
];
config = {
# disable backups in the VM
services.btrbk.instances = lib.mkForce { };
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
fsType = "ext4";
autoResize = true;
};
boot.growPartition = true;
boot.kernelParams = [ "console=ttyS0" ];
boot.loader.grub.device = "/dev/vda";
services.qemuGuest.enable = true; # qemu-guest-agent
services.openssh.enable = true;
# we configure the host via nixos itself, so we don't need the cloud-init
services.cloud-init.enable = lib.mkForce false;
systemd.services."serial-getty@ttyS0".enable = true;
};
}

View File

@@ -0,0 +1,35 @@
{
modulesPath,
lib,
...
}:
##############################################################################
#
# Template for KubeVirt's VM, mainly based on:
# https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/virtualisation/kubevirt.nix
#
# We write our hardware-configuration.nix, so that we can do some customization more easily.
#
# the url above is used by `nixos-generator` to generate the KubeVirt's qcow2 image file.
#
##############################################################################
{
imports = [
"${toString modulesPath}/profiles/qemu-guest.nix"
];
config = {
# disable backups in the VM
services.btrbk.instances = lib.mkForce { };
boot.growPartition = true;
boot.kernelParams = [ "console=ttyS0" ];
boot.loader.grub.device = "/dev/vda";
services.qemuGuest.enable = true; # qemu-guest-agent
services.openssh.enable = true;
# we configure the host via nixos itself, so we don't need the cloud-init
services.cloud-init.enable = lib.mkForce false;
systemd.services."serial-getty@ttyS0".enable = true;
};
}

View File

@@ -0,0 +1,42 @@
{
# NOTE: the args not used in this file CAN NOT be removed!
# because haumea pass argument lazily,
# and these arguments are used in the functions like `mylib.nixosSystem`, `mylib.colmenaSystem`, etc.
inputs,
lib,
mylib,
myvars,
system,
genSpecialArgs,
...
}@args:
let
# 黒川 茜, Kurokawa Akane
name = "akane";
tags = [
name
"homelab-app"
];
ssh-user = "root";
modules = {
nixos-modules =
(map mylib.relativeToRoot [
# common
"secrets/nixos.nix"
"modules/nixos/server/server-aarch64.nix"
"modules/nixos/server/qemu-guest.nix"
# host specific
"hosts/idols-${name}"
])
++ [
];
};
systemArgs = modules // args;
in
{
nixosConfigurations.${name} = mylib.nixosSystem systemArgs;
colmena.${name} = mylib.colmenaSystem (systemArgs // { inherit tags ssh-user; });
}

View File

@@ -1,4 +1,5 @@
{lib}: rec {
{ lib }:
rec {
mainGateway = "192.168.5.1"; # main router
mainGateway6 = "fe80::5"; # main router's link-local address
# use suzi as the default gateway
@@ -41,6 +42,11 @@
ipv4 = "192.168.5.100";
ipv6 = "fe80::10"; # Link-local Address
};
# akane = {
# # VM (running in macOS's UTM App), using DHCP instead of static ip.
# iface = "enp0s1";
# ipv4 = "192.168.64.2";
# };
aquamarine = {
# VM
iface = "enp2s0";
@@ -151,19 +157,17 @@
};
};
hostsInterface =
lib.attrsets.mapAttrs (key: val: {
interfaces."${val.iface}" = {
useDHCP = false;
ipv4.addresses = [
{
inherit prefixLength;
address = val.ipv4;
}
];
};
})
hostsAddr;
hostsInterface = lib.attrsets.mapAttrs (key: val: {
interfaces."${val.iface}" = {
useDHCP = false;
ipv4.addresses = [
{
inherit prefixLength;
address = val.ipv4;
}
];
};
}) hostsAddr;
ssh = {
# define the host alias for remote builders
@@ -178,14 +182,13 @@
extraConfig = (
lib.attrsets.foldlAttrs (
acc: host: val:
acc
+ ''
Host ${host}
HostName ${val.ipv4}
Port 22
''
) ""
hostsAddr
acc
+ ''
Host ${host}
HostName ${val.ipv4}
Port 22
''
) "" hostsAddr
);
# this config will be written to /etc/ssh/ssh_known_hosts
@@ -197,21 +200,22 @@
# { x = "a"; y = "b"; }
# => { x = "bar-a"; y = "bar-b"; }
lib.attrsets.mapAttrs
(host: value: {
hostNames = [host] ++ (lib.optional (hostsAddr ? host) hostsAddr.${host}.ipv4);
publicKey = value.publicKey;
})
{
# Define the root user's host key for remote builders, so that nix can verify all the remote builders
(host: value: {
hostNames = [ host ] ++ (lib.optional (hostsAddr ? host) hostsAddr.${host}.ipv4);
publicKey = value.publicKey;
})
{
# Define the root user's host key for remote builders, so that nix can verify all the remote builders
aquamarine.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEOXFhFu9Duzp6ZBE288gDZ6VLrNaeWL4kDrFUh9Neic root@aquamarine";
# ruby.publicKey = "";
# kana.publicKey = "";
aquamarine.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEOXFhFu9Duzp6ZBE288gDZ6VLrNaeWL4kDrFUh9Neic root@aquamarine";
# ruby.publicKey = "";
# kana.publicKey = "";
# ==================================== Other SSH Service's Public Key =======================================
# ==================================== Other SSH Service's Public Key =======================================
# https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints
"github.com".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
};
# https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints
"github.com".publicKey =
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
};
};
}