mirror of
https://github.com/ryan4yin/nix-config.git
synced 2026-05-28 18:39:31 +02:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0693713e94 | |||
| 1bf67acde9 | |||
| f1a5d419fb | |||
| e8be41f8e1 | |||
| d853036fb1 | |||
| df1f9b0070 | |||
| 4def213b08 | |||
| 35eb6ed5c9 | |||
| 07178984b1 | |||
| eb83e88267 | |||
| 6c8e8111c6 | |||
| 62e96cde7e | |||
| 4bb53d0190 | |||
| 41af2c1444 | |||
| 43db6bcf63 | |||
| e17bc1ec23 | |||
| c9954c009a | |||
| e68a43edce | |||
| 08a6885873 | |||
| 930d8322d1 | |||
| 2363ab59c4 | |||
| 1394e26a59 | |||
| 940367c790 | |||
| cae48ede1b | |||
| 9535c09a33 | |||
| 194c3d9895 |
@@ -14,6 +14,10 @@ utils_nu := absolute_path("utils.nu")
|
|||||||
#
|
#
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
|
# List all the just commands
|
||||||
|
default:
|
||||||
|
@just --list
|
||||||
|
|
||||||
# Run eval tests
|
# Run eval tests
|
||||||
[group('nix')]
|
[group('nix')]
|
||||||
test:
|
test:
|
||||||
@@ -41,6 +45,7 @@ repl:
|
|||||||
nix repl -f flake:nixpkgs
|
nix repl -f flake:nixpkgs
|
||||||
|
|
||||||
# remove all generations older than 7 days
|
# remove all generations older than 7 days
|
||||||
|
# on darwin, you may need to switch to root user to run this command
|
||||||
[group('nix')]
|
[group('nix')]
|
||||||
clean:
|
clean:
|
||||||
sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --older-than 7d
|
sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --older-than 7d
|
||||||
@@ -48,8 +53,11 @@ clean:
|
|||||||
# Garbage collect all unused nix store entries
|
# Garbage collect all unused nix store entries
|
||||||
[group('nix')]
|
[group('nix')]
|
||||||
gc:
|
gc:
|
||||||
# garbage collect all unused nix store entries
|
# garbage collect all unused nix store entries(system-wide)
|
||||||
sudo nix-collect-garbage --delete-old
|
sudo nix-collect-garbage --delete-older-than 7d
|
||||||
|
# garbage collect all unused nix store entries(for the user - home-manager)
|
||||||
|
# https://github.com/LnL7/nix-darwin/issues/237
|
||||||
|
nix-collect-garbage --delete-older-than 7d
|
||||||
|
|
||||||
# Enter a shell session which has all the necessary tools for this flake
|
# Enter a shell session which has all the necessary tools for this flake
|
||||||
[linux]
|
[linux]
|
||||||
@@ -68,6 +76,11 @@ fmt:
|
|||||||
# format the nix files in this repo
|
# format the nix files in this repo
|
||||||
nix fmt
|
nix fmt
|
||||||
|
|
||||||
|
# Show all the auto gc roots in the nix store
|
||||||
|
[group('nix')]
|
||||||
|
gcroot:
|
||||||
|
ls -al /nix/var/nix/gcroots/auto/
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
#
|
#
|
||||||
# NixOS Desktop related commands
|
# NixOS Desktop related commands
|
||||||
@@ -277,7 +290,7 @@ kana-local mode="default":
|
|||||||
# Build and upload a vm image
|
# Build and upload a vm image
|
||||||
[linux]
|
[linux]
|
||||||
[group('homelab')]
|
[group('homelab')]
|
||||||
upload-k3s mode="default":
|
upload-k3s-prod mode="default":
|
||||||
#!/usr/bin/env nu
|
#!/usr/bin/env nu
|
||||||
use {{utils_nu}} *;
|
use {{utils_nu}} *;
|
||||||
upload-vm k3s-prod-1-master-1 {{mode}};
|
upload-vm k3s-prod-1-master-1 {{mode}};
|
||||||
@@ -298,82 +311,14 @@ upload-k3s-test mode="default":
|
|||||||
|
|
||||||
[linux]
|
[linux]
|
||||||
[group('homelab')]
|
[group('homelab')]
|
||||||
k3s:
|
k3s-prod:
|
||||||
colmena apply --on '@k3s-*' --verbose --show-trace
|
colmena apply --on '@k3s-prod-*' --verbose --show-trace
|
||||||
|
|
||||||
[linux]
|
|
||||||
[group('homelab')]
|
|
||||||
master:
|
|
||||||
colmena apply --on '@k3s-prod-1-master-*' --verbose --show-trace
|
|
||||||
|
|
||||||
[linux]
|
|
||||||
[group('homelab')]
|
|
||||||
worker:
|
|
||||||
colmena apply --on '@k3s-prod-1-worker-*' --verbose --show-trace
|
|
||||||
|
|
||||||
[linux]
|
[linux]
|
||||||
[group('homelab')]
|
[group('homelab')]
|
||||||
k3s-test:
|
k3s-test:
|
||||||
colmena apply --on '@k3s-test-*' --verbose --show-trace
|
colmena apply --on '@k3s-test-*' --verbose --show-trace
|
||||||
|
|
||||||
############################################################################
|
|
||||||
#
|
|
||||||
# RISC-V related commands
|
|
||||||
#
|
|
||||||
############################################################################
|
|
||||||
|
|
||||||
[linux]
|
|
||||||
[group('homelab')]
|
|
||||||
riscv:
|
|
||||||
colmena apply --on '@riscv' --verbose --show-trace
|
|
||||||
|
|
||||||
[linux]
|
|
||||||
[group('homelab')]
|
|
||||||
nozomi:
|
|
||||||
colmena apply --on '@nozomi' --verbose --show-trace
|
|
||||||
|
|
||||||
[linux]
|
|
||||||
[group('homelab')]
|
|
||||||
yukina:
|
|
||||||
colmena apply --on '@yukina' --verbose --show-trace
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
#
|
|
||||||
# Aarch64 related commands
|
|
||||||
#
|
|
||||||
############################################################################
|
|
||||||
|
|
||||||
[linux]
|
|
||||||
[group('homelab')]
|
|
||||||
rakushun:
|
|
||||||
colmena apply --on '@rakushun' --build-on-target --verbose --show-trace
|
|
||||||
|
|
||||||
[linux]
|
|
||||||
[group('homelab')]
|
|
||||||
rakushun-local mode="default":
|
|
||||||
#!/usr/bin/env nu
|
|
||||||
use {{utils_nu}} *;
|
|
||||||
nixos-switch rakushun {{mode}}
|
|
||||||
|
|
||||||
[linux]
|
|
||||||
[group('homelab')]
|
|
||||||
suzu-set-proxy:
|
|
||||||
ip route del default via 192.168.5.1
|
|
||||||
ip route add default via 192.168.5.178
|
|
||||||
|
|
||||||
[linux]
|
|
||||||
[group('homelab')]
|
|
||||||
suzu-unset-proxy:
|
|
||||||
ip route del default via 192.168.5.178
|
|
||||||
ip route add default via 192.168.5.1
|
|
||||||
|
|
||||||
[linux]
|
|
||||||
[group('homelab')]
|
|
||||||
suzu-local mode="default":
|
|
||||||
#!/usr/bin/env nu
|
|
||||||
use {{utils_nu}} *;
|
|
||||||
nixos-switch suzu {{mode}}
|
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
#
|
#
|
||||||
# Neovim related commands
|
# Neovim related commands
|
||||||
@@ -457,4 +402,14 @@ game:
|
|||||||
# Delete all failed pods
|
# Delete all failed pods
|
||||||
[group('k8s')]
|
[group('k8s')]
|
||||||
del-failed:
|
del-failed:
|
||||||
kubectl delete pod --all-namespaces --field-selector="status.phase==Failed"
|
kubectl delete pod --all-namespaces --field-selector="status.phase==Failed"
|
||||||
|
|
||||||
|
[linux]
|
||||||
|
[group('services')]
|
||||||
|
list-inactive:
|
||||||
|
systemctl list-units -all --state=inactive
|
||||||
|
|
||||||
|
[linux]
|
||||||
|
[group('services')]
|
||||||
|
list-failed:
|
||||||
|
systemctl list-units -all --state=failed
|
||||||
|
|||||||
Generated
+95
-656
File diff suppressed because it is too large
Load Diff
@@ -101,19 +101,11 @@
|
|||||||
|
|
||||||
nuenv.url = "github:DeterminateSystems/nuenv";
|
nuenv.url = "github:DeterminateSystems/nuenv";
|
||||||
|
|
||||||
daeuniverse.url = "github:daeuniverse/flake.nix";
|
|
||||||
# daeuniverse.url = "github:daeuniverse/flake.nix/exp";
|
|
||||||
|
|
||||||
haumea = {
|
haumea = {
|
||||||
url = "github:nix-community/haumea/v0.2.2";
|
url = "github:nix-community/haumea/v0.2.2";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
microvm = {
|
|
||||||
url = "github:astro/microvm.nix";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
|
|
||||||
######################## Some non-flake repositories #########################################
|
######################## Some non-flake repositories #########################################
|
||||||
|
|
||||||
# doom-emacs is a configuration framework for GNU Emacs.
|
# doom-emacs is a configuration framework for GNU Emacs.
|
||||||
@@ -146,12 +138,5 @@
|
|||||||
url = "github:ryan4yin/nur-packages";
|
url = "github:ryan4yin/nur-packages";
|
||||||
# inputs.nixpkgs.follows = "nixpkgs";
|
# inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
# riscv64 SBCs
|
|
||||||
nixos-licheepi4a.url = "github:ryan4yin/nixos-licheepi4a";
|
|
||||||
# nixos-jh7110.url = "github:ryan4yin/nixos-jh7110";
|
|
||||||
|
|
||||||
# aarch64 SBCs
|
|
||||||
nixos-rk3588.url = "github:ryan4yin/nixos-rk3588";
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
go-containerregistry # provides `crane` & `gcrane`, it's similar to skopeo
|
go-containerregistry # provides `crane` & `gcrane`, it's similar to skopeo
|
||||||
|
|
||||||
kubectl
|
kubectl
|
||||||
|
kubectx
|
||||||
kubebuilder
|
kubebuilder
|
||||||
istioctl
|
istioctl
|
||||||
clusterctl # for kubernetes cluster-api
|
clusterctl # for kubernetes cluster-api
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
pkgs-unstable,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@@ -25,6 +26,7 @@ in {
|
|||||||
programs = {
|
programs = {
|
||||||
neovim = {
|
neovim = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
package = pkgs-unstable.neovim-unwrapped;
|
||||||
|
|
||||||
defaultEditor = true;
|
defaultEditor = true;
|
||||||
viAlias = true;
|
viAlias = true;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ return {
|
|||||||
opts.ensure_installed = require("astrocore").list_insert_unique(opts.ensure_installed, {
|
opts.ensure_installed = require("astrocore").list_insert_unique(opts.ensure_installed, {
|
||||||
-- please add only the tree-sitters that are not available in nixpkgs here
|
-- please add only the tree-sitters that are not available in nixpkgs here
|
||||||
|
|
||||||
|
"just",
|
||||||
"kdl",
|
"kdl",
|
||||||
"csv",
|
"csv",
|
||||||
"xml",
|
"xml",
|
||||||
|
|||||||
@@ -1,157 +0,0 @@
|
|||||||
# Rakushun - Disk and Installation
|
|
||||||
|
|
||||||
Disk layout:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
[ryan@rakushun:~]$ lsblk
|
|
||||||
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
|
|
||||||
sda 8:0 1 58.6G 0 disk
|
|
||||||
└─sda1 8:1 1 487M 0 part
|
|
||||||
mtdblock0 31:0 0 16M 0 disk
|
|
||||||
zram0 254:0 0 0B 0 disk
|
|
||||||
nvme0n1 259:0 0 1.8T 0 disk
|
|
||||||
├─nvme0n1p1 259:1 0 630M 0 part /boot
|
|
||||||
└─nvme0n1p2 259:2 0 1.8T 0 part
|
|
||||||
└─encrypted 253:0 0 1.8T 0 crypt /tmp
|
|
||||||
/swap
|
|
||||||
/snapshots
|
|
||||||
/home/ryan/tmp
|
|
||||||
/home/ryan/nix-config
|
|
||||||
/home/ryan/go
|
|
||||||
/home/ryan/codes
|
|
||||||
/home/ryan/.ssh
|
|
||||||
/home/ryan/.local/state
|
|
||||||
/home/ryan/.npm
|
|
||||||
/home/ryan/.local/share
|
|
||||||
/home/ryan/.conda
|
|
||||||
/etc/ssh
|
|
||||||
/etc/nix/inputs
|
|
||||||
/etc/secureboot
|
|
||||||
/etc/agenix
|
|
||||||
/etc/NetworkManager/system-connections
|
|
||||||
/etc/machine-id
|
|
||||||
/nix/store
|
|
||||||
/var/log
|
|
||||||
/var/lib
|
|
||||||
/nix
|
|
||||||
/persistent
|
|
||||||
|
|
||||||
[ryan@rakushun:~]$ df -Th
|
|
||||||
Filesystem Type Size Used Avail Use% Mounted on
|
|
||||||
devtmpfs devtmpfs 785M 0 785M 0% /dev
|
|
||||||
tmpfs tmpfs 7.7G 0 7.7G 0% /dev/shm
|
|
||||||
tmpfs tmpfs 3.9G 6.8M 3.9G 1% /run
|
|
||||||
tmpfs tmpfs 7.7G 1.9M 7.7G 1% /run/wrappers
|
|
||||||
none tmpfs 4.0G 48K 4.0G 1% /
|
|
||||||
/dev/mapper/crypted btrfs 1.9T 19G 1.8T 2% /persistent
|
|
||||||
/dev/mapper/crypted btrfs 1.9T 19G 1.8T 2% /nix
|
|
||||||
/dev/mapper/crypted btrfs 1.9T 19G 1.8T 2% /snapshots
|
|
||||||
/dev/mapper/crypted btrfs 1.9T 19G 1.8T 2% /swap
|
|
||||||
/dev/mapper/crypted btrfs 1.9T 19G 1.8T 2% /tmp
|
|
||||||
/dev/nvme0n1p1 vfat 629M 96M 534M 16% /boot
|
|
||||||
tmpfs tmpfs 1.6G 4.0K 1.6G 1% /run/user/1000
|
|
||||||
```
|
|
||||||
|
|
||||||
CPU info:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
[ryan@rakushun:~]$ lscpu
|
|
||||||
Architecture: aarch64
|
|
||||||
CPU op-mode(s): 32-bit, 64-bit
|
|
||||||
Byte Order: Little Endian
|
|
||||||
CPU(s): 8
|
|
||||||
On-line CPU(s) list: 0-7
|
|
||||||
Vendor ID: ARM
|
|
||||||
Model name: Cortex-A55
|
|
||||||
Model: 0
|
|
||||||
Thread(s) per core: 1
|
|
||||||
Core(s) per socket: 4
|
|
||||||
Socket(s): 1
|
|
||||||
Stepping: r2p0
|
|
||||||
CPU(s) scaling MHz: 67%
|
|
||||||
CPU max MHz: 1800.0000
|
|
||||||
CPU min MHz: 408.0000
|
|
||||||
BogoMIPS: 48.00
|
|
||||||
Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
|
|
||||||
Model name: Cortex-A76
|
|
||||||
Model: 0
|
|
||||||
Thread(s) per core: 1
|
|
||||||
Core(s) per socket: 2
|
|
||||||
Socket(s): 2
|
|
||||||
Stepping: r4p0
|
|
||||||
CPU(s) scaling MHz: 18%
|
|
||||||
CPU max MHz: 2256.0000
|
|
||||||
CPU min MHz: 408.0000
|
|
||||||
BogoMIPS: 48.00
|
|
||||||
Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
|
|
||||||
Caches (sum of all):
|
|
||||||
L1d: 384 KiB (8 instances)
|
|
||||||
L1i: 384 KiB (8 instances)
|
|
||||||
L2: 2.5 MiB (8 instances)
|
|
||||||
L3: 3 MiB (1 instance)
|
|
||||||
```
|
|
||||||
|
|
||||||
## How to install NixOS on Orange Pi 5 Plus
|
|
||||||
|
|
||||||
### 1. Prepare a USB LUKS key
|
|
||||||
|
|
||||||
Generate LUKS keyfile to encrypt the root partition, it's used by disko.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# partition the usb stick
|
|
||||||
DEV=/dev/sdX
|
|
||||||
parted ${DEV} -- mklabel gpt
|
|
||||||
parted ${DEV} -- mkpart OPI5P_DSC fat32 0% 512MB
|
|
||||||
mkfs.fat -F 32 -n OPI5P_DSC ${DEV}1
|
|
||||||
|
|
||||||
# Generate a keyfile from the true random number generator
|
|
||||||
KEYFILE=./orangepi5plus-luks-keyfile
|
|
||||||
dd bs=512 count=64 iflag=fullblock if=/dev/random of=$KEYFILE
|
|
||||||
|
|
||||||
# copy the keyfile and token to the usb stick
|
|
||||||
KEYFILE=./orangepi5plus-luks-keyfile
|
|
||||||
DEVICE=/dev/disk/by-label/OPI5P_DSC
|
|
||||||
# seek=128 skip N obs-sized output blocks to avoid overwriting the filesystem header
|
|
||||||
dd bs=512 count=64 iflag=fullblock seek=128 if=$KEYFILE of=$DEVICE
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Partition the SSD & install NixOS via disko
|
|
||||||
|
|
||||||
First, follow
|
|
||||||
[UEFI - ryan4yin/nixos-rk3588](https://github.com/ryan4yin/nixos-rk3588/blob/main/UEFI.md) to
|
|
||||||
install UEFI bootloader and boot into NixOS live environment via a USB stick.
|
|
||||||
|
|
||||||
Then, run the following commands:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# transfer the nix-config to the target machine
|
|
||||||
rsync -avzP ~/nix-config rk@<ip-addr>:/home/rk/
|
|
||||||
|
|
||||||
# login via ssh
|
|
||||||
ssh rk@<ip-addr>
|
|
||||||
|
|
||||||
cd ~/nix-config/hosts/12kingdoms_rakushun
|
|
||||||
# 1. change the disk device path in ./disko-fs.nix to the disk you want to use
|
|
||||||
# 2. partition & format the disk via disko
|
|
||||||
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko -- --mode disko ./disko-fs.nix
|
|
||||||
|
|
||||||
|
|
||||||
cd ~/nix-config
|
|
||||||
# install nixos
|
|
||||||
sudo nixos-install --root /mnt --flake .#rakushun --no-root-password --show-trace --verbose
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# NOTE: DO NOT skip this step!!!
|
|
||||||
# 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/
|
|
||||||
mkdir -p /persistent/home/ryan
|
|
||||||
chown -R ryan:ryan /persistent/home/ryan
|
|
||||||
```
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
# Rakushun - Orange Pi 5 Plus
|
|
||||||
|
|
||||||
LUKS encrypted SSD for NixOS, on Orange Pi 5 Plus.
|
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
||||||
## Showcases
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Misc
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# copy closure to another arm64 machine
|
|
||||||
nix-copy-closure --to root@suzu /run/current-system
|
|
||||||
```
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
mylib,
|
|
||||||
disko,
|
|
||||||
nixos-rk3588,
|
|
||||||
myvars,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
#############################################################
|
|
||||||
#
|
|
||||||
# Suzu - Orange Pi 5 Plus, RK3588 + 16GB RAM
|
|
||||||
#
|
|
||||||
#############################################################
|
|
||||||
let
|
|
||||||
hostName = "rakushun"; # Define your hostname.
|
|
||||||
in {
|
|
||||||
imports =
|
|
||||||
(mylib.scanPaths ./.)
|
|
||||||
++ [
|
|
||||||
# import the rk3588 module, which contains the configuration for bootloader/kernel/firmware
|
|
||||||
nixos-rk3588.nixosModules.orangepi5plus.core
|
|
||||||
disko.nixosModules.default
|
|
||||||
];
|
|
||||||
|
|
||||||
networking = {
|
|
||||||
inherit hostName;
|
|
||||||
inherit (myvars.networking) defaultGateway nameservers;
|
|
||||||
inherit (myvars.networking.hostsInterface.${hostName}) interfaces;
|
|
||||||
networkmanager.enable = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
# 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 = "24.05"; # Did you read the comment?
|
|
||||||
}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
{
|
|
||||||
# required by impermanence
|
|
||||||
fileSystems."/persistent".neededForBoot = true;
|
|
||||||
|
|
||||||
disko.devices = {
|
|
||||||
nodev."/" = {
|
|
||||||
fsType = "tmpfs";
|
|
||||||
mountOptions = [
|
|
||||||
"size=4G"
|
|
||||||
"defaults"
|
|
||||||
# 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.
|
|
||||||
"mode=755"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# TODO: rename to main
|
|
||||||
disk.sda = {
|
|
||||||
type = "disk";
|
|
||||||
# When using disko-install, we will overwrite this value from the commandline
|
|
||||||
device = "/dev/nvme0n1"; # The device to partition
|
|
||||||
content = {
|
|
||||||
type = "gpt";
|
|
||||||
partitions = {
|
|
||||||
# The EFI & Boot partition
|
|
||||||
ESP = {
|
|
||||||
size = "630M";
|
|
||||||
type = "EF00";
|
|
||||||
content = {
|
|
||||||
type = "filesystem";
|
|
||||||
format = "vfat";
|
|
||||||
mountpoint = "/boot";
|
|
||||||
mountOptions = [
|
|
||||||
"defaults"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# The root partition
|
|
||||||
luks = {
|
|
||||||
size = "100%";
|
|
||||||
content = {
|
|
||||||
type = "luks";
|
|
||||||
name = "encrypted";
|
|
||||||
settings = {
|
|
||||||
keyFile = "/dev/disk/by-label/OPI5P_DSC"; # The keyfile is stored on a USB stick
|
|
||||||
# The maximum size of the keyfile is 8192 KiB
|
|
||||||
# type `cryptsetup --help` to see the compiled-in key and passphrase maximum sizes
|
|
||||||
keyFileSize = 512 * 64; # match the `bs * count` of the `dd` command
|
|
||||||
keyFileOffset = 512 * 128; # match the `bs * skip` of the `dd` command
|
|
||||||
fallbackToPassword = true;
|
|
||||||
allowDiscards = true;
|
|
||||||
};
|
|
||||||
# Whether to add a boot.initrd.luks.devices entry for the specified disk.
|
|
||||||
initrdUnlock = true;
|
|
||||||
|
|
||||||
# encrypt the root partition with luks2 and argon2id, will prompt for a passphrase, which will be used to unlock the partition.
|
|
||||||
# cryptsetup luksFormat
|
|
||||||
extraFormatArgs = [
|
|
||||||
"--type luks2"
|
|
||||||
"--cipher aes-xts-plain64"
|
|
||||||
"--hash sha512"
|
|
||||||
"--iter-time 5000"
|
|
||||||
"--key-size 256"
|
|
||||||
"--pbkdf argon2id"
|
|
||||||
# use true random data from /dev/random, will block until enough entropy is available
|
|
||||||
"--use-random"
|
|
||||||
];
|
|
||||||
extraOpenArgs = [
|
|
||||||
"--timeout 10"
|
|
||||||
];
|
|
||||||
content = {
|
|
||||||
type = "btrfs";
|
|
||||||
extraArgs = ["-f"]; # Force override existing partition
|
|
||||||
subvolumes = {
|
|
||||||
# mount the top-level subvolume at /btr_pool
|
|
||||||
# it will be used by btrbk to create snapshots
|
|
||||||
"/" = {
|
|
||||||
mountpoint = "/btr_pool";
|
|
||||||
# btrfs's top-level subvolume, internally has an id 5
|
|
||||||
# we can access all other subvolumes from this subvolume.
|
|
||||||
mountOptions = ["subvolid=5"];
|
|
||||||
};
|
|
||||||
"@nix" = {
|
|
||||||
mountpoint = "/nix";
|
|
||||||
mountOptions = ["compress-force=zstd:1" "noatime"];
|
|
||||||
};
|
|
||||||
"@persistent" = {
|
|
||||||
mountpoint = "/persistent";
|
|
||||||
mountOptions = ["compress-force=zstd:1" "noatime"];
|
|
||||||
};
|
|
||||||
"@tmp" = {
|
|
||||||
mountpoint = "/tmp";
|
|
||||||
mountOptions = ["compress-force=zstd:1" "noatime"];
|
|
||||||
};
|
|
||||||
"@snapshots" = {
|
|
||||||
mountpoint = "/snapshots";
|
|
||||||
mountOptions = ["compress-force=zstd:1" "noatime"];
|
|
||||||
};
|
|
||||||
"@swap" = {
|
|
||||||
mountpoint = "/swap";
|
|
||||||
swap.swapfile.size = "16384M";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
imports = [
|
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
|
||||||
];
|
|
||||||
|
|
||||||
boot.loader = {
|
|
||||||
# depending on how you configured your disk mounts, change this to /boot or /boot/efi.
|
|
||||||
efi.efiSysMountPoint = "/boot/";
|
|
||||||
efi.canTouchEfiVariables = true;
|
|
||||||
# do not use systemd-boot here, it has problems when running `nixos-install`
|
|
||||||
grub = {
|
|
||||||
device = "nodev";
|
|
||||||
efiSupport = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# clear /tmp on boot to get a stateless /tmp directory.
|
|
||||||
boot.tmp.cleanOnBoot = true;
|
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = ["nvme" "usbhid" "usb_storage"];
|
|
||||||
boot.initrd.kernelModules = [];
|
|
||||||
boot.kernelModules = [];
|
|
||||||
boot.extraModulePackages = [];
|
|
||||||
|
|
||||||
# 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.enP3p49s0.useDHCP = lib.mkDefault true;
|
|
||||||
# networking.interfaces.enP4p65s0.useDHCP = lib.mkDefault true;
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
{
|
|
||||||
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"
|
|
||||||
];
|
|
||||||
files = [
|
|
||||||
"/etc/machine-id"
|
|
||||||
];
|
|
||||||
|
|
||||||
# the following directories will be passed to /persistent/home/$USER
|
|
||||||
users.ryan = {
|
|
||||||
directories = [
|
|
||||||
"codes"
|
|
||||||
"nix-config"
|
|
||||||
"tmp"
|
|
||||||
|
|
||||||
{
|
|
||||||
directory = ".ssh";
|
|
||||||
mode = "0700";
|
|
||||||
}
|
|
||||||
|
|
||||||
# neovim / remmina / flatpak / ...
|
|
||||||
".local/share"
|
|
||||||
".local/state"
|
|
||||||
|
|
||||||
# language package managers
|
|
||||||
".npm"
|
|
||||||
".conda" # generated by `conda-shell`
|
|
||||||
"go"
|
|
||||||
];
|
|
||||||
files = [
|
|
||||||
".config/nushell/history.txt"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
# Suzu - Disk and Installation
|
|
||||||
|
|
||||||
Disk layout:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
[ryan@suzu:~]$ lsblk
|
|
||||||
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
|
|
||||||
sda 8:0 1 58.6G 0 disk
|
|
||||||
└─sda1 8:1 1 486M 0 part
|
|
||||||
mtdblock0 31:0 0 16M 0 disk
|
|
||||||
zram0 254:0 0 0B 0 disk
|
|
||||||
nvme0n1 259:0 0 238.5G 0 disk
|
|
||||||
├─nvme0n1p1 259:1 0 630M 0 part /boot
|
|
||||||
└─nvme0n1p2 259:2 0 237.9G 0 part
|
|
||||||
└─encrypted 253:0 0 237.8G 0 crypt /tmp
|
|
||||||
/snapshots
|
|
||||||
/swap
|
|
||||||
/home/ryan/tmp
|
|
||||||
/home/ryan/nix-config
|
|
||||||
/home/ryan/go
|
|
||||||
/home/ryan/.local/state
|
|
||||||
/home/ryan/codes
|
|
||||||
/home/ryan/.npm
|
|
||||||
/home/ryan/.ssh
|
|
||||||
/home/ryan/.local/share
|
|
||||||
/etc/ssh
|
|
||||||
/home/ryan/.conda
|
|
||||||
/etc/secureboot
|
|
||||||
/etc/agenix
|
|
||||||
/etc/nix/inputs
|
|
||||||
/etc/NetworkManager/system-connections
|
|
||||||
/nix/store
|
|
||||||
/var/log
|
|
||||||
/var/lib
|
|
||||||
/nix
|
|
||||||
/persistent
|
|
||||||
|
|
||||||
[ryan@suzu:~]$ df -Th
|
|
||||||
Filesystem Type Size Used Avail Use% Mounted on
|
|
||||||
devtmpfs devtmpfs 383M 0 383M 0% /dev
|
|
||||||
tmpfs tmpfs 3.8G 0 3.8G 0% /dev/shm
|
|
||||||
tmpfs tmpfs 1.9G 6.2M 1.9G 1% /run
|
|
||||||
tmpfs tmpfs 3.8G 1.9M 3.8G 1% /run/wrappers
|
|
||||||
none tmpfs 2.0G 48K 2.0G 1% /
|
|
||||||
/dev/mapper/crypted btrfs 238G 11G 226G 5% /persistent
|
|
||||||
/dev/mapper/crypted btrfs 238G 11G 226G 5% /nix
|
|
||||||
/dev/mapper/crypted btrfs 238G 11G 226G 5% /swap
|
|
||||||
/dev/mapper/crypted btrfs 238G 11G 226G 5% /snapshots
|
|
||||||
/dev/mapper/crypted btrfs 238G 11G 226G 5% /tmp
|
|
||||||
/dev/nvme0n1p1 vfat 629M 86M 543M 14% /boot
|
|
||||||
tmpfs tmpfs 766M 4.0K 766M 1% /run/user/1000
|
|
||||||
```
|
|
||||||
|
|
||||||
CPU info:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
[ryan@suzu:~]$ lscpu
|
|
||||||
Architecture: aarch64
|
|
||||||
CPU op-mode(s): 32-bit, 64-bit
|
|
||||||
Byte Order: Little Endian
|
|
||||||
CPU(s): 8
|
|
||||||
On-line CPU(s) list: 0-7
|
|
||||||
Vendor ID: ARM
|
|
||||||
Model name: Cortex-A55
|
|
||||||
Model: 0
|
|
||||||
Thread(s) per core: 1
|
|
||||||
Core(s) per socket: 4
|
|
||||||
Socket(s): 1
|
|
||||||
Stepping: r2p0
|
|
||||||
CPU(s) scaling MHz: 56%
|
|
||||||
CPU max MHz: 1800.0000
|
|
||||||
CPU min MHz: 408.0000
|
|
||||||
BogoMIPS: 48.00
|
|
||||||
Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
|
|
||||||
Model name: Cortex-A76
|
|
||||||
Model: 0
|
|
||||||
Thread(s) per core: 1
|
|
||||||
Core(s) per socket: 2
|
|
||||||
Socket(s): 2
|
|
||||||
Stepping: r4p0
|
|
||||||
CPU(s) scaling MHz: 18%
|
|
||||||
CPU max MHz: 2256.0000
|
|
||||||
CPU min MHz: 408.0000
|
|
||||||
BogoMIPS: 48.00
|
|
||||||
Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
|
|
||||||
Caches (sum of all):
|
|
||||||
L1d: 384 KiB (8 instances)
|
|
||||||
L1i: 384 KiB (8 instances)
|
|
||||||
L2: 2.5 MiB (8 instances)
|
|
||||||
L3: 3 MiB (1 instance)
|
|
||||||
```
|
|
||||||
|
|
||||||
## How to install NixOS on Orange Pi 5
|
|
||||||
|
|
||||||
### 1. Prepare a USB LUKS key
|
|
||||||
|
|
||||||
Generate LUKS keyfile to encrypt the root partition, it's used by disko.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# partition the usb stick
|
|
||||||
DEV=/dev/sdX
|
|
||||||
parted ${DEV} -- mklabel gpt
|
|
||||||
parted ${DEV} -- mkpart primary 2M 512MB
|
|
||||||
mkfs.fat -F 32 -n OPI5_DSC ${DEV}1
|
|
||||||
|
|
||||||
|
|
||||||
# Generate a keyfile from the true random number generator
|
|
||||||
KEYFILE=./orangepi5-luks-keyfile
|
|
||||||
dd bs=512 count=64 iflag=fullblock if=/dev/random of=$KEYFILE
|
|
||||||
|
|
||||||
# copy the keyfile and token to the usb stick
|
|
||||||
KEYFILE=./orangepi5-luks-keyfile
|
|
||||||
DEVICE=/dev/disk/by-label/OPI5_DSC
|
|
||||||
# seek=128 skip N obs-sized output blocks to avoid overwriting the filesystem header
|
|
||||||
dd bs=512 count=64 iflag=fullblock seek=128 if=$KEYFILE of=$DEVICE
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Partition the SSD & install NixOS via disko
|
|
||||||
|
|
||||||
First, follow
|
|
||||||
[UEFI - ryan4yin/nixos-rk3588](https://github.com/ryan4yin/nixos-rk3588/blob/main/UEFI.md) to
|
|
||||||
install UEFI bootloader and boot into NixOS live environment via a USB stick.
|
|
||||||
|
|
||||||
Then, run the following commands:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# login via ssh
|
|
||||||
ssh rk@<ip-addr>
|
|
||||||
|
|
||||||
git clone https://github.com/ryan4yin/nix-config.git
|
|
||||||
|
|
||||||
cd ~/nix-config/hosts/12kingdoms_suzu
|
|
||||||
# 1. change the disk device path in ./disko-fs.nix to the disk you want to use
|
|
||||||
# 2. partition & format the disk via disko
|
|
||||||
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko -- --mode disko ./disko-fs.nix
|
|
||||||
|
|
||||||
|
|
||||||
cd ~/nix-config
|
|
||||||
# install nixos
|
|
||||||
sudo nixos-install --root /mnt --flake .#suzu --no-root-password --show-trace --verbose
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# NOTE: DO NOT skip this step!!!
|
|
||||||
# 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/
|
|
||||||
mkdir -p /persistent/home/ryan
|
|
||||||
chown -R ryan:ryan /persistent/home/ryan
|
|
||||||
```
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
# Suzu - Orange Pi 5
|
|
||||||
|
|
||||||
LUKS encrypted SSD for NixOS, on Orange Pi 5.
|
|
||||||
|
|
||||||
## TODOs
|
|
||||||
|
|
||||||
- [ ] Add support for BGP routing.
|
|
||||||
- [Comparing Open Source BGP Stacks](https://elegantnetwork.github.io/posts/comparing-open-source-bgp-stacks/)
|
|
||||||
- [`services.frr.*` - search.nixos.org](https://search.nixos.org/options?channel=unstable&query=services.frr)
|
|
||||||
|
|
||||||
## Showcases
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
Micro VMs:
|
|
||||||
|
|
||||||
1. suzi: dae router(transparent proxy, dhcp)
|
|
||||||
1. mitsuha: tailscale gateway(sub router)
|
|
||||||
|
|
||||||
Services:
|
|
||||||
|
|
||||||
1. OCI Containers: to run some servides that's not available in NixOS.
|
|
||||||
1. ddns
|
|
||||||
1. uptime-kuma: uptime monitoring
|
|
||||||
1. excalidraw/DDTV/owncast/jitsi-meet/...
|
|
||||||
|
|
||||||
All the services assumes a reverse proxy to be setup in the front, they are all listening on
|
|
||||||
localhost, and a caddy service is listening on the local network interface and proxy the requests to
|
|
||||||
the services.
|
|
||||||
|
|
||||||
TODO: create a private PKI for caddy, to achieve end-to-end encryption between caddy and the
|
|
||||||
services.
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
{
|
|
||||||
disko,
|
|
||||||
nixos-rk3588,
|
|
||||||
mylib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
#############################################################
|
|
||||||
#
|
|
||||||
# Suzu - Orange Pi 5 Plus, RK3588 + 16GB RAM
|
|
||||||
#
|
|
||||||
# https://github.com/astro/microvm.nix
|
|
||||||
#
|
|
||||||
#############################################################
|
|
||||||
let
|
|
||||||
hostName = "suzu"; # Define your hostname.
|
|
||||||
in {
|
|
||||||
imports =
|
|
||||||
(mylib.scanPaths ./.)
|
|
||||||
++ [
|
|
||||||
# import the rk3588 module, which contains the configuration for bootloader/kernel/firmware
|
|
||||||
nixos-rk3588.nixosModules.orangepi5plus.core
|
|
||||||
disko.nixosModules.default
|
|
||||||
];
|
|
||||||
|
|
||||||
networking = {inherit hostName;};
|
|
||||||
|
|
||||||
# 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 = "24.05"; # Did you read the comment?
|
|
||||||
}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
{
|
|
||||||
# required by impermanence
|
|
||||||
fileSystems."/persistent".neededForBoot = true;
|
|
||||||
|
|
||||||
disko.devices = {
|
|
||||||
nodev."/" = {
|
|
||||||
fsType = "tmpfs";
|
|
||||||
mountOptions = [
|
|
||||||
"size=2G"
|
|
||||||
"defaults"
|
|
||||||
# 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.
|
|
||||||
"mode=755"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# TODO: rename to main
|
|
||||||
disk.sda = {
|
|
||||||
type = "disk";
|
|
||||||
# When using disko-install, we will overwrite this value from the commandline
|
|
||||||
device = "/dev/nvme0n1"; # The device to partition
|
|
||||||
content = {
|
|
||||||
type = "gpt";
|
|
||||||
partitions = {
|
|
||||||
# The EFI & Boot partition
|
|
||||||
ESP = {
|
|
||||||
size = "630M";
|
|
||||||
type = "EF00";
|
|
||||||
content = {
|
|
||||||
type = "filesystem";
|
|
||||||
format = "vfat";
|
|
||||||
mountpoint = "/boot";
|
|
||||||
mountOptions = [
|
|
||||||
"defaults"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# The root partition
|
|
||||||
luks = {
|
|
||||||
size = "100%";
|
|
||||||
content = {
|
|
||||||
type = "luks";
|
|
||||||
name = "encrypted";
|
|
||||||
settings = {
|
|
||||||
keyFile = "/dev/disk/by-label/OPI5_DSC"; # The keyfile is stored on a USB stick
|
|
||||||
# The maximum size of the keyfile is 8192 KiB
|
|
||||||
# type `cryptsetup --help` to see the compiled-in key and passphrase maximum sizes
|
|
||||||
keyFileSize = 512 * 64; # match the `bs * count` of the `dd` command
|
|
||||||
keyFileOffset = 512 * 128; # match the `bs * skip` of the `dd` command
|
|
||||||
fallbackToPassword = true;
|
|
||||||
allowDiscards = true;
|
|
||||||
};
|
|
||||||
# Whether to add a boot.initrd.luks.devices entry for the specified disk.
|
|
||||||
initrdUnlock = true;
|
|
||||||
|
|
||||||
# encrypt the root partition with luks2 and argon2id, will prompt for a passphrase, which will be used to unlock the partition.
|
|
||||||
# cryptsetup luksFormat
|
|
||||||
extraFormatArgs = [
|
|
||||||
"--type luks2"
|
|
||||||
"--cipher aes-xts-plain64"
|
|
||||||
"--hash sha512"
|
|
||||||
"--iter-time 5000"
|
|
||||||
"--key-size 256"
|
|
||||||
"--pbkdf argon2id"
|
|
||||||
# use true random data from /dev/random, will block until enough entropy is available
|
|
||||||
"--use-random"
|
|
||||||
];
|
|
||||||
extraOpenArgs = [
|
|
||||||
"--timeout 10"
|
|
||||||
];
|
|
||||||
content = {
|
|
||||||
type = "btrfs";
|
|
||||||
extraArgs = ["-f"]; # Force override existing partition
|
|
||||||
subvolumes = {
|
|
||||||
# mount the top-level subvolume at /btr_pool
|
|
||||||
# it will be used by btrbk to create snapshots
|
|
||||||
"/" = {
|
|
||||||
mountpoint = "/btr_pool";
|
|
||||||
# btrfs's top-level subvolume, internally has an id 5
|
|
||||||
# we can access all other subvolumes from this subvolume.
|
|
||||||
mountOptions = ["subvolid=5"];
|
|
||||||
};
|
|
||||||
"@nix" = {
|
|
||||||
mountpoint = "/nix";
|
|
||||||
mountOptions = ["compress-force=zstd:1" "noatime"];
|
|
||||||
};
|
|
||||||
"@persistent" = {
|
|
||||||
mountpoint = "/persistent";
|
|
||||||
mountOptions = ["compress-force=zstd:1" "noatime"];
|
|
||||||
};
|
|
||||||
"@tmp" = {
|
|
||||||
mountpoint = "/tmp";
|
|
||||||
mountOptions = ["compress-force=zstd:1" "noatime"];
|
|
||||||
};
|
|
||||||
"@snapshots" = {
|
|
||||||
mountpoint = "/snapshots";
|
|
||||||
mountOptions = ["compress-force=zstd:1" "noatime"];
|
|
||||||
};
|
|
||||||
"@swap" = {
|
|
||||||
mountpoint = "/swap";
|
|
||||||
swap.swapfile.size = "8192M";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
imports = [
|
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
|
||||||
];
|
|
||||||
|
|
||||||
boot.loader = {
|
|
||||||
# depending on how you configured your disk mounts, change this to /boot or /boot/efi.
|
|
||||||
efi.efiSysMountPoint = "/boot/";
|
|
||||||
efi.canTouchEfiVariables = true;
|
|
||||||
# do not use systemd-boot here, it has problems when running `nixos-install`
|
|
||||||
grub = {
|
|
||||||
device = "nodev";
|
|
||||||
efiSupport = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# clear /tmp on boot to get a stateless /tmp directory.
|
|
||||||
boot.tmp.cleanOnBoot = true;
|
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = ["nvme" "usbhid" "usb_storage"];
|
|
||||||
boot.initrd.kernelModules = [];
|
|
||||||
boot.kernelModules = [];
|
|
||||||
boot.extraModulePackages = [];
|
|
||||||
|
|
||||||
# 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.enP3p49s0.useDHCP = lib.mkDefault true;
|
|
||||||
# networking.interfaces.enP4p65s0.useDHCP = lib.mkDefault true;
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
{
|
|
||||||
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"
|
|
||||||
];
|
|
||||||
files = [
|
|
||||||
"/etc/machine-id"
|
|
||||||
];
|
|
||||||
|
|
||||||
# the following directories will be passed to /persistent/home/$USER
|
|
||||||
users.ryan = {
|
|
||||||
directories = [
|
|
||||||
"codes"
|
|
||||||
"nix-config"
|
|
||||||
"tmp"
|
|
||||||
|
|
||||||
{
|
|
||||||
directory = ".ssh";
|
|
||||||
mode = "0700";
|
|
||||||
}
|
|
||||||
|
|
||||||
# neovim / remmina / flatpak / ...
|
|
||||||
".local/share"
|
|
||||||
".local/state"
|
|
||||||
|
|
||||||
# language package managers
|
|
||||||
".npm"
|
|
||||||
".conda" # generated by `conda-shell`
|
|
||||||
"go"
|
|
||||||
];
|
|
||||||
files = [
|
|
||||||
".config/nushell/history.txt"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
# microvm.nix
|
|
||||||
|
|
||||||
## Commands
|
|
||||||
|
|
||||||
> https://github.com/astro/microvm.nix/blob/main/doc/src/microvm-command.md
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# list vm
|
|
||||||
microvm -l
|
|
||||||
|
|
||||||
# update vm
|
|
||||||
microvm -u my-microvm
|
|
||||||
|
|
||||||
|
|
||||||
# show logs of a vm
|
|
||||||
journalctl -u microvm@my-microvm -n 50
|
|
||||||
|
|
||||||
# stop vm
|
|
||||||
systemctl stop microvm@$NAME
|
|
||||||
|
|
||||||
# remove vm
|
|
||||||
rm -rf /var/lib/microvms/$NAME
|
|
||||||
|
|
||||||
# Run a MicroVM in foreground(for testing)
|
|
||||||
# You have to stop the vm before running this command!
|
|
||||||
microvm -r my-microvm
|
|
||||||
|
|
||||||
# Stop a MicroVM that is running in foreground
|
|
||||||
## 1. run `sudo shutdown -h now` in the vm
|
|
||||||
## 2. run `systemctl stop microvm@my-microvm` in the host
|
|
||||||
```
|
|
||||||
|
|
||||||
## VM's pros compared to container
|
|
||||||
|
|
||||||
1. VM has its own kernel, so it can use a fullfeatured kernel or customise the kernel's
|
|
||||||
configuration, without affecting the host.
|
|
||||||
1. VM use a fullfeatured init system, so it can run services like a real machine.
|
|
||||||
1. VM can use a fullfeatured network stack, so it can run network services like a real machine. it's
|
|
||||||
very useful for hosting some network services(such as tailscale, dae, etc).
|
|
||||||
|
|
||||||
## FAQ
|
|
||||||
|
|
||||||
### 1. enter the vm without ssh
|
|
||||||
|
|
||||||
[Enter running machine as systemd service](https://github.com/astro/microvm.nix/issues/123)
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
{
|
|
||||||
myvars,
|
|
||||||
mylib,
|
|
||||||
daeuniverse,
|
|
||||||
agenix,
|
|
||||||
microvm,
|
|
||||||
mysecrets,
|
|
||||||
nuenv,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
imports = [
|
|
||||||
# Include the microvm host module
|
|
||||||
microvm.nixosModules.host
|
|
||||||
];
|
|
||||||
|
|
||||||
microvm.vms = {
|
|
||||||
suzi = {
|
|
||||||
autostart = true;
|
|
||||||
restartIfChanged = true;
|
|
||||||
|
|
||||||
specialArgs = {inherit myvars mylib daeuniverse agenix mysecrets nuenv;};
|
|
||||||
|
|
||||||
config.imports = [./suzi];
|
|
||||||
};
|
|
||||||
|
|
||||||
mitsuha = {
|
|
||||||
autostart = true;
|
|
||||||
restartIfChanged = true;
|
|
||||||
|
|
||||||
specialArgs = {inherit myvars mylib nuenv;};
|
|
||||||
|
|
||||||
config.imports = [./mitsuha];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
{mylib, ...}: {
|
|
||||||
imports =
|
|
||||||
(mylib.scanPaths ./.)
|
|
||||||
++ [
|
|
||||||
../../../../modules/nixos/base/ssh.nix
|
|
||||||
../../../../modules/nixos/base/user-group.nix
|
|
||||||
../../../../modules/base.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
microvm = {
|
|
||||||
mem = 1024; # RAM allocation in MB
|
|
||||||
vcpu = 1; # Number of Virtual CPU cores
|
|
||||||
|
|
||||||
interfaces = [
|
|
||||||
{
|
|
||||||
type = "tap";
|
|
||||||
id = "vm-mitsuha"; # should be prefixed with "vm-"
|
|
||||||
mac = "02:00:00:00:00:02"; # Unique MAC address
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
# Block device images for persistent storage
|
|
||||||
# microvm use tmpfs for root(/), so everything else
|
|
||||||
# is ephemeral and will be lost on reboot.
|
|
||||||
#
|
|
||||||
# you can check this by running `df -Th` & `lsblk` in the VM.
|
|
||||||
volumes = [
|
|
||||||
{
|
|
||||||
mountPoint = "/var";
|
|
||||||
image = "var.img";
|
|
||||||
size = 512;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
mountPoint = "/etc";
|
|
||||||
image = "etc.img";
|
|
||||||
size = 50;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
# shares can not be set to `neededForBoot = true;`
|
|
||||||
# so if you try to use a share in boot script(such as system.activationScripts), it will fail!
|
|
||||||
shares = [
|
|
||||||
{
|
|
||||||
# It is highly recommended to share the host's nix-store
|
|
||||||
# with the VMs to prevent building huge images.
|
|
||||||
# a host's /nix/store will be picked up so that no
|
|
||||||
# squashfs/erofs will be built for it.
|
|
||||||
#
|
|
||||||
# by this way, /nix/store is readonly in the VM,
|
|
||||||
# and thus the VM can't run any command that modifies
|
|
||||||
# the store. such as nix build, nix shell, etc...
|
|
||||||
# if you want to run nix commands in the VM, see
|
|
||||||
# https://github.com/astro/microvm.nix/blob/main/doc/src/shares.md#writable-nixstore-overlay
|
|
||||||
tag = "ro-store"; # Unique virtiofs daemon tag
|
|
||||||
proto = "virtiofs"; # virtiofs is faster than 9p
|
|
||||||
source = "/nix/store";
|
|
||||||
mountPoint = "/nix/.ro-store";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
hypervisor = "qemu";
|
|
||||||
# Control socket for the Hypervisor so that a MicroVM can be shutdown cleanly
|
|
||||||
socket = "control.socket";
|
|
||||||
};
|
|
||||||
|
|
||||||
system.stateVersion = "24.05";
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
{myvars, ...}: let
|
|
||||||
hostName = "mitsuha";
|
|
||||||
inherit (myvars.networking) mainGateway nameservers;
|
|
||||||
inherit (myvars.networking.hostsAddr.${hostName}) ipv4;
|
|
||||||
|
|
||||||
ipv4WithMask = "${ipv4}/24";
|
|
||||||
in {
|
|
||||||
systemd.network.enable = true;
|
|
||||||
|
|
||||||
systemd.network.networks."20-lan" = {
|
|
||||||
matchConfig.Type = "ether";
|
|
||||||
networkConfig = {
|
|
||||||
Address = [ipv4WithMask];
|
|
||||||
Gateway = mainGateway;
|
|
||||||
DNS = nameservers;
|
|
||||||
DHCP = "no";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
{pkgs, ...}:
|
|
||||||
# =============================================================
|
|
||||||
#
|
|
||||||
# Tailscale - your own private network(VPN) that uses WireGuard
|
|
||||||
#
|
|
||||||
# It's open source and free for personal use,
|
|
||||||
# and it's really easy to setup and use.
|
|
||||||
# Tailscale has great client coverage for Linux, windows, Mac, android, and iOS.
|
|
||||||
# Tailscale is more mature and stable compared to other alternatives such as netbird/netmaker.
|
|
||||||
# Maybe I'll give netbird/netmaker a try when they are more mature, but for now, I'm sticking with Tailscale.
|
|
||||||
#
|
|
||||||
# How to use:
|
|
||||||
# 1. Create a Tailscale account at https://login.tailscale.com
|
|
||||||
# 2. Login via `tailscale login`
|
|
||||||
# 3. join into your Tailscale network via `tailscale up --advertise-routes 192.168.5.0/24`
|
|
||||||
# 4. If you prefer automatic connection to Tailscale, use the `authKeyFile` option` in the config below.
|
|
||||||
#
|
|
||||||
# Status Data:
|
|
||||||
# `journalctl -u tailscaled` shows tailscaled's logs
|
|
||||||
# logs indicate that tailscale store its data in /var/lib/tailscale
|
|
||||||
# which is already persistent across reboots(via impermanence.nix)
|
|
||||||
#
|
|
||||||
# References:
|
|
||||||
# https://github.com/NixOS/nixpkgs/blob/nixos-24.05/nixos/modules/services/networking/tailscale.nix
|
|
||||||
#
|
|
||||||
# =============================================================
|
|
||||||
{
|
|
||||||
# make the tailscale command usable to users
|
|
||||||
environment.systemPackages = [pkgs.tailscale];
|
|
||||||
|
|
||||||
# enable the tailscale service
|
|
||||||
services.tailscale = {
|
|
||||||
enable = true;
|
|
||||||
port = 41641;
|
|
||||||
interfaceName = "tailscale0";
|
|
||||||
# allow the Tailscale UDP port through the firewall
|
|
||||||
openFirewall = true;
|
|
||||||
useRoutingFeatures = "server";
|
|
||||||
extraUpFlags = "--advertise-routes 192.168.5.0/24";
|
|
||||||
# authKeyFile = "/var/lib/tailscale/authkey";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
# Dae - NixOS Router
|
|
||||||
|
|
||||||
A router(IPv4 only) with a transparent proxy to bypass the G|F|W.
|
|
||||||
|
|
||||||
NOTE: dae do not provides a http/socks5 proxy server, so a v2ray server is running on
|
|
||||||
[idols_kana](../idols_kana/proxy.nix) to provides a http/socks5 proxy service.
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Can not access the global internet
|
|
||||||
|
|
||||||
1. Check whether the subscription url is accessible.
|
|
||||||
- If not, then you need to get a new subscription url and update the `dae`'s configuration.
|
|
||||||
1. Check the `dae` service's log by `journalctl -u dae -n 1000`.
|
|
||||||
|
|
||||||
### DNS cannot be resolved
|
|
||||||
|
|
||||||
1. `sudo systemctl stop dae`, then try to resolve the domain name again.
|
|
||||||
- If it works, the problem is caused by `dae` service.
|
|
||||||
- check dae's log by `journalctl -u dae -n 1000`
|
|
||||||
1. DNS & DHCP is provided by `dnsmasq` service, check the configuration of `dnsmasq`.
|
|
||||||
|
|
||||||
### DHCP cannot be obtained
|
|
||||||
|
|
||||||
1. `ss -tunlp`, check if `dnsmasq` is running and listening on udp port 67.
|
|
||||||
1. `journalctl -u dnsmasq -n 1000` to check the log of `dnsmasq`.
|
|
||||||
1. Request a new IP address by disconnect and reconnect one of your devices' wifi.
|
|
||||||
1. `nix shell nixpkgs#dhcpdump` and then `sudo dhcpdump -i br-lan`, check if the DHCP request is
|
|
||||||
received by `dnsmasq`.
|
|
||||||
1. The server listens on UDP port number 67, and the client listens on UDP port number 68.
|
|
||||||
1. DHCP operations fall into four phases:
|
|
||||||
1. Server **discovery**: The DHCP client broadcasts a DHCPDISCOVER message on the network
|
|
||||||
subnet using the destination address 255.255.255.255 (limited broadcast) or the specific
|
|
||||||
subnet broadcast address (directed broadcast).
|
|
||||||
1. IP lease **offer**: When a DHCP server receives a DHCPDISCOVER message from a client, which
|
|
||||||
is an IP address lease request, the DHCP server reserves an IP address for the client and
|
|
||||||
makes a lease offer by sending a DHCPOFFER message to the client.
|
|
||||||
1. IP lease **request**: In response to the DHCP offer, the client replies with a DHCPREQUEST
|
|
||||||
message, broadcast to the server,[a] requesting the offered address.
|
|
||||||
1. IP lease **acknowledgement**: When the DHCP server receives the DHCPREQUEST message from
|
|
||||||
the client, it sends a DHCPACK packet to the client, which includes the lease duration and
|
|
||||||
any other configuration information that the client might have requested.
|
|
||||||
1. So if you see only `DISCOVER` messages, the dhsmasq is not working properly.
|
|
||||||
|
|
||||||
## References
|
|
||||||
|
|
||||||
- <https://github.com/ghostbuster91/blogposts/blob/main/router2023-part2/main.md>
|
|
||||||
- <https://github.com/ghostbuster91/nixos-router>
|
|
||||||
@@ -1,326 +0,0 @@
|
|||||||
# https://github.com/daeuniverse/dae/discussions/81
|
|
||||||
# https://github.com/daeuniverse/dae/blob/main/example.dae
|
|
||||||
|
|
||||||
# load all dae files placed in ./config.d/
|
|
||||||
include {
|
|
||||||
config.d/*.dae
|
|
||||||
}
|
|
||||||
global {
|
|
||||||
##### Software options.
|
|
||||||
|
|
||||||
# tproxy port to listen on. It is NOT a HTTP/SOCKS port, and is just used by eBPF program.
|
|
||||||
# In normal case, you do not need to use it.
|
|
||||||
tproxy_port: 12345
|
|
||||||
|
|
||||||
# Set it true to protect tproxy port from unsolicited traffic. Set it false to allow users to use self-managed
|
|
||||||
# iptables tproxy rules.
|
|
||||||
tproxy_port_protect: true
|
|
||||||
|
|
||||||
# If not zero, traffic sent from dae will be set SO_MARK. It is useful to avoid traffic loop with iptables tproxy
|
|
||||||
# rules.
|
|
||||||
so_mark_from_dae: 1
|
|
||||||
|
|
||||||
# Log level: error, warn, info, debug, trace.
|
|
||||||
log_level: info
|
|
||||||
|
|
||||||
# Disable waiting for network before pulling subscriptions.
|
|
||||||
disable_waiting_network: false
|
|
||||||
|
|
||||||
|
|
||||||
##### Interface and kernel options.
|
|
||||||
|
|
||||||
# The LAN interface to bind. Use it if you want to proxy LAN.
|
|
||||||
# Multiple interfaces split by ",".
|
|
||||||
lan_interface: br-lan
|
|
||||||
|
|
||||||
# The WAN interface to bind. Use it if you want to proxy localhost.
|
|
||||||
# Multiple interfaces split by ",". Use "auto" to auto detect.
|
|
||||||
#
|
|
||||||
# Disable this to avoid problems with the proxy server that prevent the subscription link from being updated
|
|
||||||
# wan_interface: auto
|
|
||||||
|
|
||||||
# Automatically configure Linux kernel parameters like ip_forward and send_redirects. Check out
|
|
||||||
# https://github.com/daeuniverse/dae/blob/main/docs/en/user-guide/kernel-parameters.md to see what will dae do.
|
|
||||||
auto_config_kernel_parameter: false
|
|
||||||
|
|
||||||
##### Node connectivity check.
|
|
||||||
|
|
||||||
# Host of URL should have both IPv4 and IPv6 if you have double stack in local.
|
|
||||||
# First is URL, others are IP addresses if given.
|
|
||||||
# Considering traffic consumption, it is recommended to choose a site with anycast IP and less response.
|
|
||||||
#tcp_check_url: 'http://cp.cloudflare.com'
|
|
||||||
tcp_check_url: 'http://cp.cloudflare.com,1.1.1.1,2606:4700:4700::1111'
|
|
||||||
|
|
||||||
# The HTTP request method to `tcp_check_url`. Use 'HEAD' by default because some server implementations bypass
|
|
||||||
# accounting for this kind of traffic.
|
|
||||||
tcp_check_http_method: HEAD
|
|
||||||
|
|
||||||
# This DNS will be used to check UDP connectivity of nodes. And if dns_upstream below contains tcp, it also be used to check
|
|
||||||
# TCP DNS connectivity of nodes.
|
|
||||||
# First is URL, others are IP addresses if given.
|
|
||||||
# This DNS should have both IPv4 and IPv6 if you have double stack in local.
|
|
||||||
#udp_check_dns: 'dns.google.com:53'
|
|
||||||
udp_check_dns: 'dns.google.com:53,8.8.8.8,2001:4860:4860::8888'
|
|
||||||
|
|
||||||
check_interval: 30s
|
|
||||||
|
|
||||||
# Group will switch node only when new_latency <= old_latency - tolerance.
|
|
||||||
check_tolerance: 50ms
|
|
||||||
|
|
||||||
|
|
||||||
##### Connecting options.
|
|
||||||
|
|
||||||
# Optional values of dial_mode are:
|
|
||||||
# 1. "ip". Dial proxy using the IP from DNS directly. This allows your ipv4, ipv6 to choose the optimal path
|
|
||||||
# respectively, and makes the IP version requested by the application meet expectations. For example, if you
|
|
||||||
# use curl -4 ip.sb, you will request IPv4 via proxy and get a IPv4 echo. And curl -6 ip.sb will request IPv6.
|
|
||||||
# This may solve some weird full-cone problem if your are be your node support that. Sniffing will be disabled
|
|
||||||
# in this mode.
|
|
||||||
# 2. "domain". Dial proxy using the domain from sniffing. This will relieve DNS pollution problem to a great extent
|
|
||||||
# if have impure DNS environment. Generally, this mode brings faster proxy response time because proxy will
|
|
||||||
# re-resolve the domain in remote, thus get better IP result to connect. This policy does not impact routing.
|
|
||||||
# That is to say, domain rewrite will be after traffic split of routing and dae will not re-route it.
|
|
||||||
# 3. "domain+". Based on domain mode but do not check the reality of sniffed domain. It is useful for users whose
|
|
||||||
# DNS requests do not go through dae but want faster proxy response time. Notice that, if DNS requests do not
|
|
||||||
# go through dae, dae cannot split traffic by domain.
|
|
||||||
# 4. "domain++". Based on domain+ mode but force to re-route traffic using sniffed domain to partially recover
|
|
||||||
# domain based traffic split ability. It doesn't work for direct traffic and consumes more CPU resources.
|
|
||||||
dial_mode: domain
|
|
||||||
|
|
||||||
# Allow insecure TLS certificates. It is not recommended to turn it on unless you have to.
|
|
||||||
allow_insecure: false
|
|
||||||
|
|
||||||
# Timeout to waiting for first data sending for sniffing. It is always 0 if dial_mode is ip. Set it higher is useful
|
|
||||||
# in high latency LAN network.
|
|
||||||
sniffing_timeout: 100ms
|
|
||||||
|
|
||||||
# TLS implementation. tls is to use Go's crypto/tls. utls is to use uTLS, which can imitate browser's Client Hello.
|
|
||||||
tls_implementation: tls
|
|
||||||
|
|
||||||
# The Client Hello ID for uTLS to imitate. This takes effect only if tls_implementation is utls.
|
|
||||||
# See more: https://github.com/daeuniverse/dae/blob/331fa23c16/component/outbound/transport/tls/utls.go#L17
|
|
||||||
utls_imitate: chrome_auto
|
|
||||||
}
|
|
||||||
|
|
||||||
# See https://github.com/daeuniverse/dae/blob/main/docs/en/configuration/dns.md for full examples.
|
|
||||||
dns {
|
|
||||||
# For example, if ipversion_prefer is 4 and the domain name has both type A and type AAAA records, the dae will only
|
|
||||||
# respond to type A queries and response empty answer to type AAAA queries.
|
|
||||||
ipversion_prefer: 4
|
|
||||||
|
|
||||||
# Give a fixed ttl for domains. Zero means that dae will request to upstream every time and not cache DNS results
|
|
||||||
# for these domains.
|
|
||||||
#fixed_domain_ttl {
|
|
||||||
# ddns.example.org: 10
|
|
||||||
# test.example.org: 3600
|
|
||||||
#}
|
|
||||||
|
|
||||||
upstream {
|
|
||||||
# Value can be scheme://host:port, where the scheme can be tcp/udp/tcp+udp.
|
|
||||||
# If host is a domain and has both IPv4 and IPv6 record, dae will automatically choose
|
|
||||||
# IPv4 or IPv6 to use according to group policy (such as min latency policy).
|
|
||||||
# Please make sure DNS traffic will go through and be forwarded by dae, which is REQUIRED for domain routing.
|
|
||||||
# If dial_mode is "ip", the upstream DNS answer SHOULD NOT be polluted, so domestic public DNS is not recommended.
|
|
||||||
|
|
||||||
alidns: 'udp://223.5.5.5:53'
|
|
||||||
googledns: 'tcp+udp://8.8.8.8:53'
|
|
||||||
}
|
|
||||||
routing {
|
|
||||||
# According to the request of dns query, decide to use which DNS upstream.
|
|
||||||
# Match rules from top to bottom.
|
|
||||||
request {
|
|
||||||
# Lookup China mainland domains using alidns, otherwise googledns.
|
|
||||||
qname(geosite:cn) -> alidns
|
|
||||||
# fallback is also called default.
|
|
||||||
fallback: googledns
|
|
||||||
|
|
||||||
# other custom rules
|
|
||||||
qname(full:analytics.google.com) -> googledns # do not block google analytics(console)
|
|
||||||
qname(regex: '.+\.nixos.org$') -> googledns
|
|
||||||
qname(geosite:category-ads) -> reject
|
|
||||||
qname(geosite:category-ads-all) -> reject
|
|
||||||
qtype(aaaa) -> reject
|
|
||||||
qname(regex: '.+\.linkedin$') -> googledns
|
|
||||||
}
|
|
||||||
|
|
||||||
# According to the response of dns query, decide to accept or re-lookup using another DNS upstream.
|
|
||||||
# Match rules from top to bottom.
|
|
||||||
response {
|
|
||||||
# Trusted upstream. Always accept its result.
|
|
||||||
upstream(googledns) -> accept
|
|
||||||
|
|
||||||
# Possibly polluted(domain resolved to a private ip), re-lookup using googledns.
|
|
||||||
ip(geoip:private) && !qname(geosite:cn) -> googledns
|
|
||||||
|
|
||||||
fallback: accept
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Node group (outbound).
|
|
||||||
group {
|
|
||||||
proxy {
|
|
||||||
filter: name(keyword: 'Hong Kong')
|
|
||||||
filter: name(keyword: '香港')
|
|
||||||
filter: name(keyword: 'Singapore')
|
|
||||||
filter: name(keyword: '新加坡')
|
|
||||||
# Filter nodes and give a fixed latency offset to archive latency-based failover.
|
|
||||||
# In this example, there is bigger possibility to choose US node even if original latency of US node is higher.
|
|
||||||
filter: name(keyword: 'USA') [add_latency: -500ms]
|
|
||||||
filter: name(keyword: '美国') [add_latency: -500ms]
|
|
||||||
filter: name(keyword: 'UK') [add_latency: -300ms]
|
|
||||||
# filter: name(keyword: '英国') [add_latency: -300ms]
|
|
||||||
# filter: name(keyword: 'Japan') [add_latency: 300ms]
|
|
||||||
# filter: name(keyword: '日本') [add_latency: 300ms]
|
|
||||||
|
|
||||||
# Other filters:
|
|
||||||
# Filter nodes from the global node pool defined by the subscription and node section above.
|
|
||||||
# filter: subtag(regex: '^my_', another_sub) && !name(keyword: 'ExpireAt:')
|
|
||||||
# Filter nodes from the global node pool defined by tag.
|
|
||||||
# filter: name('node_a','node_b')
|
|
||||||
|
|
||||||
# Select the node with min average of the last 10 latencies from the group for every connection.
|
|
||||||
policy: min_avg10
|
|
||||||
# Other policies:
|
|
||||||
# random - Randomly select a node from the group for every connection.
|
|
||||||
# fixed(0) - Select the first node from the group for every connection.
|
|
||||||
# min - Select the node with min last latency from the group for every connection.
|
|
||||||
# min_moving_avg - Select the node with min moving average of latencies from the group for every connection.
|
|
||||||
}
|
|
||||||
|
|
||||||
media {
|
|
||||||
filter: name(keyword: 'Hong Kong')
|
|
||||||
filter: name(keyword: '香港')
|
|
||||||
filter: name(keyword: 'Singapore')
|
|
||||||
filter: name(keyword: '新加坡')
|
|
||||||
filter: name(keyword: 'USA') [add_latency: -500ms]
|
|
||||||
filter: name(keyword: '美国') [add_latency: -500ms]
|
|
||||||
filter: name(keyword: 'UK') [add_latency: -300ms]
|
|
||||||
filter: name(keyword: '英国') [add_latency: -300ms]
|
|
||||||
filter: name(keyword: 'Japan') [add_latency: 300ms]
|
|
||||||
filter: name(keyword: '日本') [add_latency: 300ms]
|
|
||||||
|
|
||||||
policy: min_avg10
|
|
||||||
}
|
|
||||||
|
|
||||||
ssh-proxy {
|
|
||||||
filter: name(keyword: 'UK')
|
|
||||||
filter: name(keyword: '英国')
|
|
||||||
policy: min_avg10
|
|
||||||
}
|
|
||||||
|
|
||||||
sg {
|
|
||||||
filter: name(keyword: 'Singapore')
|
|
||||||
filter: name(keyword: '新加坡')
|
|
||||||
policy: min_avg10
|
|
||||||
}
|
|
||||||
|
|
||||||
usa {
|
|
||||||
filter: name(keyword: 'USA')
|
|
||||||
filter: name(keyword: '美国')
|
|
||||||
policy: min_avg10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# See https://github.com/daeuniverse/dae/blob/main/docs/en/configuration/routing.md for full examples.
|
|
||||||
# Pname has the highest priority, so should be placed in the front.
|
|
||||||
# Priority of other rules is the same as the order of the rules defined in this file.
|
|
||||||
routing {
|
|
||||||
### Preset rules.
|
|
||||||
|
|
||||||
# Network managers in localhost should be direct to
|
|
||||||
# avoid false negative network connectivity check when binding to WAN.
|
|
||||||
pname(NetworkManager) -> direct
|
|
||||||
pname(systemd-networkd) -> direct
|
|
||||||
|
|
||||||
# Put it in the front to prevent broadcast, multicast and other packets that should be sent to the LAN from being
|
|
||||||
# forwarded by the proxy.
|
|
||||||
# "dip" means destination IP.
|
|
||||||
dip(224.0.0.0/3, 'ff00::/8') -> direct
|
|
||||||
|
|
||||||
# This line allows you to access private addresses directly instead of via your proxy. If you really want to access
|
|
||||||
# private addresses in your proxy host network, modify the below line.
|
|
||||||
dip(geoip:private) -> direct
|
|
||||||
|
|
||||||
# --- Core rules ---#
|
|
||||||
|
|
||||||
# Disable HTTP3(QUIC) because it usually consumes too much cpu/mem resources.
|
|
||||||
l4proto(udp) && dport(443) -> block
|
|
||||||
|
|
||||||
# Direct access to all Chinese mainland-related IP addresses
|
|
||||||
dip(geoip:cn) -> direct
|
|
||||||
domain(geosite:cn) -> direct
|
|
||||||
|
|
||||||
# Block ads
|
|
||||||
domain(full:analytics.google.com) -> proxy # do not block google analytics(console)
|
|
||||||
domain(geosite:category-ads) -> block
|
|
||||||
domain(geosite:category-ads-all) -> block
|
|
||||||
|
|
||||||
# DNS
|
|
||||||
dip(8.8.8.8, 8.8.4.4) -> proxy
|
|
||||||
dip(223.5.5.5, 223.6.6.6) -> direct
|
|
||||||
domain(full:dns.alidns.com) -> direct
|
|
||||||
domain(full:dns.googledns.com) -> proxy
|
|
||||||
domain(full:dns.opendns.com) -> proxy
|
|
||||||
|
|
||||||
# --- Rules for other commonly used sites ---#
|
|
||||||
|
|
||||||
# SSH - tcp port 22 is blocked by many proxy servers.
|
|
||||||
dport(22) && !dip(geoip:cn) && !domain(geosite:cn) -> ssh-proxy
|
|
||||||
|
|
||||||
### OpenAI
|
|
||||||
domain(geosite:openai) -> sg
|
|
||||||
domain(regex:'.+\.openai$') -> sg
|
|
||||||
|
|
||||||
# Steam
|
|
||||||
domain(suffix: steampowered.com) -> direct
|
|
||||||
domain(suffix: steamserver.net) -> direct
|
|
||||||
domain(geosite:steam@cn) -> direct
|
|
||||||
domain(geosite:steam) -> proxy
|
|
||||||
|
|
||||||
### Media
|
|
||||||
domain(geosite:netflix) -> media
|
|
||||||
|
|
||||||
### Proxy
|
|
||||||
domain(suffix: linkedin.com) -> proxy
|
|
||||||
domain(keyword:'linkedin') -> proxy
|
|
||||||
domain(regex:'.+\.linkedin\.com$') -> proxy
|
|
||||||
domain(regex:'.+\.quay\.io$') -> proxy
|
|
||||||
domain(regex:'.+\.notion\.so$') -> proxy
|
|
||||||
domain(regex:'.+\.amazon\.com$') -> proxy
|
|
||||||
domain(regex:'.+\.oracle\.com$') -> proxy
|
|
||||||
domain(regex:'.+\.docker\.com$') -> proxy
|
|
||||||
domain(regex:'.+\.kubernetes\.io$') -> proxy
|
|
||||||
domain(regex:'.+\.nixos\.org$') -> proxy
|
|
||||||
|
|
||||||
domain(geosite:microsoft) -> proxy
|
|
||||||
domain(geosite:linkedin) -> proxy
|
|
||||||
domain(geosite:twitter) -> proxy
|
|
||||||
domain(geosite:telegram) -> proxy
|
|
||||||
domain(geosite:google) -> proxy
|
|
||||||
domain(geosite:apple) -> proxy
|
|
||||||
domain(geosite:category-container) -> proxy
|
|
||||||
domain(geosite:category-dev) -> proxy
|
|
||||||
domain(geosite:google-scholar) -> proxy
|
|
||||||
domain(geosite:category-scholar-!cn) -> proxy
|
|
||||||
|
|
||||||
### Direct
|
|
||||||
domain(regex:'.+\.edu\.cn$') -> direct
|
|
||||||
domain(keyword:'baidu') -> direct
|
|
||||||
domain(keyword:'bilibili') -> direct
|
|
||||||
domain(keyword:'taobao') -> direct
|
|
||||||
domain(keyword:'alibabadns') -> direct
|
|
||||||
domain(keyword:'alicdn') -> direct
|
|
||||||
domain(keyword:'tbcache') -> direct
|
|
||||||
domain(keyword:'zhihu') -> direct
|
|
||||||
domain(keyword:'douyu') -> direct
|
|
||||||
domain(geosite:cloudflare-cn) -> direct
|
|
||||||
|
|
||||||
# --- Fallback rules ---#
|
|
||||||
|
|
||||||
# Access all other foreign sites
|
|
||||||
domain(geosite:geolocation-!cn) -> proxy
|
|
||||||
!dip(geoip:cn) -> proxy
|
|
||||||
|
|
||||||
fallback: direct
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
daeuniverse,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
# https://github.com/daeuniverse/flake.nix
|
|
||||||
let
|
|
||||||
daeConfigPath = "/etc/dae/config.dae";
|
|
||||||
subscriptionConfigPath = "/etc/dae/config.d/subscription.dae";
|
|
||||||
in {
|
|
||||||
imports = [
|
|
||||||
daeuniverse.nixosModules.dae
|
|
||||||
];
|
|
||||||
|
|
||||||
# dae - eBPF-based Linux high-performance transparent proxy.
|
|
||||||
services.dae = {
|
|
||||||
enable = true;
|
|
||||||
package = daeuniverse.packages.${pkgs.system}.dae;
|
|
||||||
disableTxChecksumIpGeneric = false;
|
|
||||||
configFile = daeConfigPath;
|
|
||||||
assets = with pkgs; [v2ray-geoip v2ray-domain-list-community];
|
|
||||||
# alternatively, specify assets dir
|
|
||||||
# assetsPath = "/etc/dae";
|
|
||||||
openFirewall = {
|
|
||||||
enable = true;
|
|
||||||
port = 12345;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.dae.serviceConfig = {
|
|
||||||
Restart = "on-failure";
|
|
||||||
RestartSec = 10;
|
|
||||||
};
|
|
||||||
|
|
||||||
# dae supports two types of subscriptions: base64 encoded proxies, and sip008.
|
|
||||||
# subscription can be a url return the subscription, or a file path that contains the subscription.
|
|
||||||
#
|
|
||||||
# Nix decrypt and merge my dae's base config and subscription config here.
|
|
||||||
# the subscription config is something like:
|
|
||||||
# ```
|
|
||||||
# subscription {
|
|
||||||
# 'https://www.example.com/subscription/link'
|
|
||||||
# 'https://example.com/no_tag_link'
|
|
||||||
# }
|
|
||||||
# node {
|
|
||||||
# # Support socks5, http, https, ss, ssr, vmess, vless, trojan, trojan-go, tuic, juicity
|
|
||||||
# node_a: 'trojan://'
|
|
||||||
# node_b: 'trojan://'
|
|
||||||
# node_c: 'vless://'
|
|
||||||
# node_d: 'vless://'
|
|
||||||
# node_e: 'vmess://'
|
|
||||||
# node_f: 'tuic://'
|
|
||||||
# node_h: 'juicity://'
|
|
||||||
# }
|
|
||||||
# ```
|
|
||||||
system.activationScripts.installDaeConfig = ''
|
|
||||||
install -Dm 600 ${./config.dae} ${daeConfigPath}
|
|
||||||
install -Dm 600 ${config.age.secrets."dae-subscription.dae".path} ${subscriptionConfigPath}
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
{mylib, ...}: {
|
|
||||||
imports =
|
|
||||||
(mylib.scanPaths ./.)
|
|
||||||
++ [
|
|
||||||
../../../../secrets/nixos.nix
|
|
||||||
../../../../modules/nixos/base/ssh.nix
|
|
||||||
../../../../modules/nixos/base/user-group.nix
|
|
||||||
../../../../modules/base.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
modules.secrets.server.network.enable = true;
|
|
||||||
|
|
||||||
microvm = {
|
|
||||||
mem = 1024; # RAM allocation in MB
|
|
||||||
vcpu = 1; # Number of Virtual CPU cores
|
|
||||||
|
|
||||||
interfaces = [
|
|
||||||
{
|
|
||||||
type = "tap";
|
|
||||||
id = "vm-suzi"; # should be prefixed with "vm-"
|
|
||||||
mac = "02:00:00:00:00:01"; # unique MAC address
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
# Block device images for persistent storage
|
|
||||||
# microvm use tmpfs for root(/), so everything else
|
|
||||||
# is ephemeral and will be lost on reboot.
|
|
||||||
#
|
|
||||||
# you can check this by running `df -Th` & `lsblk` in the VM.
|
|
||||||
volumes = [
|
|
||||||
{
|
|
||||||
mountPoint = "/var";
|
|
||||||
image = "var.img";
|
|
||||||
size = 512;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
mountPoint = "/etc";
|
|
||||||
image = "etc.img";
|
|
||||||
size = 50;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
# shares can not be set to `neededForBoot = true;`
|
|
||||||
# so if you try to use a share in boot script(such as system.activationScripts), it will fail!
|
|
||||||
shares = [
|
|
||||||
{
|
|
||||||
# It is highly recommended to share the host's nix-store
|
|
||||||
# with the VMs to prevent building huge images.
|
|
||||||
# a host's /nix/store will be picked up so that no
|
|
||||||
# squashfs/erofs will be built for it.
|
|
||||||
#
|
|
||||||
# by this way, /nix/store is readonly in the VM,
|
|
||||||
# and thus the VM can't run any command that modifies
|
|
||||||
# the store. such as nix build, nix shell, etc...
|
|
||||||
# if you want to run nix commands in the VM, see
|
|
||||||
# https://github.com/astro/microvm.nix/blob/main/doc/src/shares.md#writable-nixstore-overlay
|
|
||||||
tag = "ro-store"; # Unique virtiofs daemon tag
|
|
||||||
proto = "virtiofs"; # virtiofs is faster than 9p
|
|
||||||
source = "/nix/store";
|
|
||||||
mountPoint = "/nix/.ro-store";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
hypervisor = "qemu";
|
|
||||||
# Control socket for the Hypervisor so that a MicroVM can be shutdown cleanly
|
|
||||||
socket = "control.socket";
|
|
||||||
};
|
|
||||||
|
|
||||||
system.stateVersion = "24.05";
|
|
||||||
}
|
|
||||||
@@ -1,180 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
myvars,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
hostName = "suzi";
|
|
||||||
inherit (myvars.networking) mainGateway nameservers;
|
|
||||||
inherit (myvars.networking.hostsAddr.${hostName}) ipv4;
|
|
||||||
|
|
||||||
ipv4WithMask = "${ipv4}/24";
|
|
||||||
dhcpRange = {
|
|
||||||
start = "192.168.5.5";
|
|
||||||
end = "192.168.5.99";
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
boot.kernel.sysctl = {
|
|
||||||
# https://github.com/ghostbuster91/blogposts/blob/main/router2023-part2/main.md
|
|
||||||
# https://github.com/daeuniverse/dae/blob/main/docs/en/user-guide/kernel-parameters.md
|
|
||||||
# forward network packets that are not destined for the interface on which they were received
|
|
||||||
"net.ipv4.conf.all.forwarding" = true;
|
|
||||||
"net.ipv6.conf.all.forwarding" = true;
|
|
||||||
"net.ipv4.conf.br-lan.rp_filter" = 1;
|
|
||||||
"net.ipv4.conf.br-lan.send_redirects" = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Docker uses iptables internally to setup NAT for containers.
|
|
||||||
# This module disables the ip_tables kernel module, which is required for nftables to work.
|
|
||||||
# So make sure to disable docker here.
|
|
||||||
virtualisation.docker.enable = lib.mkForce false;
|
|
||||||
networking = {
|
|
||||||
useNetworkd = true;
|
|
||||||
|
|
||||||
useDHCP = false;
|
|
||||||
networkmanager.enable = false;
|
|
||||||
wireless.enable = false; # Enables wireless support via wpa_supplicant.
|
|
||||||
# No local firewall.
|
|
||||||
nat.enable = false;
|
|
||||||
firewall.enable = false;
|
|
||||||
|
|
||||||
# https://github.com/NixOS/nixpkgs/blob/nixos-24.05/nixos/modules/services/networking/nftables.nix
|
|
||||||
nftables = {
|
|
||||||
enable = true;
|
|
||||||
# Check the applied rules with `nft -a list ruleset`.
|
|
||||||
# Since this is a internal bypass router, we don't need to do NAT & can forward all traffic.
|
|
||||||
ruleset = ''
|
|
||||||
# Check out https://wiki.nftables.org/ for better documentation.
|
|
||||||
# Table for both IPv4 and IPv6.
|
|
||||||
table inet filter {
|
|
||||||
chain input {
|
|
||||||
type filter hook input priority 0;
|
|
||||||
|
|
||||||
# accept any localhost traffic
|
|
||||||
iifname lo accept
|
|
||||||
|
|
||||||
# accept any lan traffic
|
|
||||||
iifname br-lan accept
|
|
||||||
|
|
||||||
# count and drop any other traffic
|
|
||||||
counter drop
|
|
||||||
}
|
|
||||||
|
|
||||||
# Allow all outgoing connections.
|
|
||||||
chain output {
|
|
||||||
type filter hook output priority 0;
|
|
||||||
accept
|
|
||||||
}
|
|
||||||
|
|
||||||
# Allow all forwarding all traffic.
|
|
||||||
chain forward {
|
|
||||||
type filter hook forward priority 0;
|
|
||||||
accept
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# https://nixos.wiki/wiki/Systemd-networkd
|
|
||||||
systemd.network = {
|
|
||||||
netdevs = {
|
|
||||||
# Create the bridge interface
|
|
||||||
"20-br-lan" = {
|
|
||||||
netdevConfig = {
|
|
||||||
Kind = "bridge";
|
|
||||||
Name = "br-lan";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# This is a bypass router, so we do not need a wan interface here.
|
|
||||||
networks = {
|
|
||||||
"30-lan0" = {
|
|
||||||
# match the interface by type
|
|
||||||
matchConfig.Type = "ether";
|
|
||||||
# Connect to the bridge
|
|
||||||
networkConfig = {
|
|
||||||
Bridge = "br-lan";
|
|
||||||
ConfigureWithoutCarrier = true;
|
|
||||||
};
|
|
||||||
linkConfig.RequiredForOnline = "enslaved";
|
|
||||||
};
|
|
||||||
# Configure the bridge device we just created
|
|
||||||
"40-br-lan" = {
|
|
||||||
matchConfig.Name = "br-lan";
|
|
||||||
address = [
|
|
||||||
# configure addresses including subnet mask
|
|
||||||
ipv4WithMask # forwards all traffic to the gateway except for the router address itself
|
|
||||||
];
|
|
||||||
routes = [
|
|
||||||
# forward all traffic to the main gateway
|
|
||||||
{routeConfig.Gateway = mainGateway;}
|
|
||||||
];
|
|
||||||
bridgeConfig = {};
|
|
||||||
linkConfig.RequiredForOnline = "routable";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# resolved is conflict with dnsmasq
|
|
||||||
services.resolved.enable = false;
|
|
||||||
services.dnsmasq = {
|
|
||||||
enable = true;
|
|
||||||
# resolve local queries (add 127.0.0.1 to /etc/resolv.conf)
|
|
||||||
resolveLocalQueries = true; # may be conflict with dae, disable this.
|
|
||||||
alwaysKeepRunning = true;
|
|
||||||
# https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=tree
|
|
||||||
settings = {
|
|
||||||
# upstream DNS servers
|
|
||||||
server = nameservers;
|
|
||||||
# forces dnsmasq to try each query with each server strictly
|
|
||||||
# in the order they appear in the config.
|
|
||||||
strict-order = true;
|
|
||||||
|
|
||||||
# Never forward plain names (without a dot or domain part)
|
|
||||||
domain-needed = true;
|
|
||||||
# Never forward addresses in the non-routed address spaces(e.g. private IP).
|
|
||||||
bogus-priv = true;
|
|
||||||
# don't needlessly read /etc/resolv.conf which only contains the localhost addresses of dnsmasq itself.
|
|
||||||
no-resolv = true;
|
|
||||||
|
|
||||||
# Cache dns queries.
|
|
||||||
cache-size = 1000;
|
|
||||||
|
|
||||||
dhcp-range = ["${dhcpRange.start},${dhcpRange.end},24h"];
|
|
||||||
interface = "br-lan";
|
|
||||||
dhcp-sequential-ip = true;
|
|
||||||
dhcp-option = [
|
|
||||||
# Override the default route supplied by dnsmasq, which assumes the
|
|
||||||
# router is the same machine as the one running dnsmasq.
|
|
||||||
"option:router,${ipv4}"
|
|
||||||
"option:dns-server,${ipv4}"
|
|
||||||
];
|
|
||||||
|
|
||||||
# local domains
|
|
||||||
local = "/lan/";
|
|
||||||
domain = "lan";
|
|
||||||
expand-hosts = true;
|
|
||||||
|
|
||||||
# don't use /etc/hosts
|
|
||||||
no-hosts = true;
|
|
||||||
address = [
|
|
||||||
# "/surfer.lan/192.168.10.1"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# monitoring with prometheus
|
|
||||||
# https://github.com/NixOS/nixpkgs/blob/nixos-24.05/nixos/modules/services/monitoring/prometheus/exporters/dnsmasq.nix
|
|
||||||
services.prometheus.exporters.dnsmasq = {
|
|
||||||
enable = true;
|
|
||||||
listenAddress = "0.0.0.0";
|
|
||||||
port = 9153;
|
|
||||||
openFirewall = false;
|
|
||||||
leasesPath = "/var/lib/dnsmasq/dnsmasq.leases";
|
|
||||||
};
|
|
||||||
|
|
||||||
# The service irqbalance is useful as it assigns certain IRQ calls to specific CPUs instead of
|
|
||||||
# letting the first CPU core to handle everything.
|
|
||||||
# This is supposed to increase performance by hitting CPU cache more often.
|
|
||||||
services.irqbalance.enable = false;
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
{myvars, ...}: let
|
|
||||||
hostName = "suzu";
|
|
||||||
inherit (myvars.networking) mainGateway nameservers;
|
|
||||||
inherit (myvars.networking.hostsAddr.${hostName}) iface ipv4;
|
|
||||||
|
|
||||||
ipv4WithMask = "${ipv4}/24";
|
|
||||||
in {
|
|
||||||
boot.kernel.sysctl = {
|
|
||||||
# forward network packets that are not destined for the interface on which they were received
|
|
||||||
"net.ipv4.conf.all.forwarding" = true;
|
|
||||||
"net.ipv6.conf.all.forwarding" = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.useNetworkd = true;
|
|
||||||
systemd.network.enable = true;
|
|
||||||
|
|
||||||
# A bridge to link all VM's TAP interfaces into local network.
|
|
||||||
# https://github.com/astro/microvm.nix/blob/main/doc/src/simple-network.md
|
|
||||||
systemd.network.networks."10-lan" = {
|
|
||||||
# match on the main interface and all VM interfaces
|
|
||||||
matchConfig.Name = [iface "vm-*"];
|
|
||||||
networkConfig = {
|
|
||||||
Bridge = "br0";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.network.netdevs."br0" = {
|
|
||||||
netdevConfig = {
|
|
||||||
Name = "br0";
|
|
||||||
Kind = "bridge";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Add ipv4 address to the bridge.
|
|
||||||
systemd.network.networks."10-lan-bridge" = {
|
|
||||||
matchConfig.Name = "br0";
|
|
||||||
networkConfig = {
|
|
||||||
Address = [ipv4WithMask];
|
|
||||||
Gateway = mainGateway;
|
|
||||||
DNS = nameservers;
|
|
||||||
IPv6AcceptRA = true;
|
|
||||||
};
|
|
||||||
linkConfig.RequiredForOnline = "routable";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
+2
-10
@@ -2,13 +2,6 @@
|
|||||||
|
|
||||||
1. `12kingdoms`:
|
1. `12kingdoms`:
|
||||||
1. `shoukei`: NixOS on Macbook Pro 2020 Intel i5, 13.3-inch, 16G RAM + 512G SSD.
|
1. `shoukei`: NixOS on Macbook Pro 2020 Intel i5, 13.3-inch, 16G RAM + 512G SSD.
|
||||||
1. `suzu`: Orange Pi 5, RK3588s(4xA76 + 4xA55), GPU(4Cores, Mail-G610), NPU(6Tops@int8), 8G RAM +
|
|
||||||
256G SSD.
|
|
||||||
- Network related services running via microvm.nix, such as router(transparent proxy - dae),
|
|
||||||
tailscale subrouter, etc.
|
|
||||||
1. `rakushun`: Orange Pi 5 Plus, RK3588(4xA76 + 4xA55), GPU(4Cores, Mail-G610), NPU(6Tops@int8),
|
|
||||||
16G RAM + 2T SSD.
|
|
||||||
- Not used now.
|
|
||||||
1. `darwin`(macOS)
|
1. `darwin`(macOS)
|
||||||
1. `fern`: MacBook Pro 2022 13-inch M2 16G, mainly for business.
|
1. `fern`: MacBook Pro 2022 13-inch M2 16G, mainly for business.
|
||||||
1. `harmonica`: MacBook Pro 2020 13-inch i5 16G, for personal use.
|
1. `harmonica`: MacBook Pro 2020 13-inch i5 16G, for personal use.
|
||||||
@@ -20,9 +13,8 @@
|
|||||||
and other services.
|
and other services.
|
||||||
3. `ruby`: Not used now.
|
3. `ruby`: Not used now.
|
||||||
4. `kana`: Not used now.
|
4. `kana`: Not used now.
|
||||||
1. `rolling_girls`: My RISCV64 hosts.
|
1. Other aarch64/riscv64 SBCs:
|
||||||
1. `nozomi`: Lichee Pi 4A, TH1520(4xC910@2.0G), 16GB RAM + 32G eMMC + 128G SD Card.
|
[ryan4yin/nixos-config-sbc](https://github.com/ryan4yin/nixos-config-sbc)
|
||||||
2. `yukina`: Milk-V Mars, JH7110(4xU74@1.5 GHz), 4G RAM + No eMMC + 64G SD Card.
|
|
||||||
|
|
||||||
## How to add a new host
|
## How to add a new host
|
||||||
|
|
||||||
|
|||||||
@@ -1,42 +1,96 @@
|
|||||||
# auto disk partitioning:
|
# auto disk partitioning:
|
||||||
# nix run github:nix-community/disko -- --mode disko ./disko-fs.nix
|
# nix run github:nix-community/disko -- --mode disko ./disko-fs.nix
|
||||||
{
|
let
|
||||||
|
cryptKeyFile = "/etc/agenix/hdd-luks-crypt-key";
|
||||||
|
unlockDisk = "data-encrypted";
|
||||||
|
in {
|
||||||
|
fileSystems."/data/fileshare/public".depends = ["/data/fileshare"];
|
||||||
|
|
||||||
|
# By adding this crypttab entry, the disk will be unlocked by systemd-cryptsetup@xxx.service at boot time.
|
||||||
|
# This systemd service is running after agenix, so that the keyfile is already available.
|
||||||
|
environment.etc = {
|
||||||
|
"crypttab".text = ''
|
||||||
|
${unlockDisk} /dev/disk/by-partlabel/disk-${unlockDisk}-luks ${cryptKeyFile} luks,discard,keyfile-size=32768,keyfile-offset=65536
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
disko.devices = {
|
disko.devices = {
|
||||||
disk.data-apps = {
|
disk.data-encrypted = {
|
||||||
type = "disk";
|
type = "disk";
|
||||||
device = "/dev/disk/by-id/ata-WDC_WD40EJRX-89T1XY0_WD-WCC7K0XDCZE6";
|
device = "/dev/disk/by-id/ata-WDC_WD40EZRZ-22GXCB0_WD-WCC7K7VV9613";
|
||||||
content = {
|
content = {
|
||||||
type = "gpt";
|
type = "gpt";
|
||||||
partitions.data-apps = {
|
partitions = {
|
||||||
size = "100%";
|
luks = {
|
||||||
content = {
|
size = "100%";
|
||||||
type = "btrfs";
|
content = {
|
||||||
# extraArgs = ["-f"]; # Override existing partition
|
type = "luks";
|
||||||
subvolumes = {
|
name = "data-encrypted";
|
||||||
"@persistent" = {
|
settings = {
|
||||||
mountpoint = "/data/apps";
|
keyFile = cryptKeyFile;
|
||||||
mountOptions = [
|
# The maximum size of the keyfile is 8192 KiB
|
||||||
"compress-force=zstd:1"
|
# type `cryptsetup --help` to see the compiled-in key and passphrase maximum sizes
|
||||||
# https://www.freedesktop.org/software/systemd/man/latest/systemd.mount.html
|
# to generate a key file:
|
||||||
"nofail"
|
# dd bs=512 count=1024 iflag=fullblock if=/dev/random of=./hdd-luks-crypt-key
|
||||||
];
|
keyFileSize = 512 * 64; # match the `bs * count` of the `dd` command
|
||||||
|
keyFileOffset = 512 * 128; # match the `bs * skip` of the `dd` command
|
||||||
|
fallbackToPassword = true;
|
||||||
|
allowDiscards = true;
|
||||||
};
|
};
|
||||||
"@backups" = {
|
# Whether to add a boot.initrd.luks.devices entry for the specified disk.
|
||||||
mountpoint = "/data/backups";
|
# The keyfile do not exist before agenix decrypts its data, do we have to disable this option.
|
||||||
mountOptions = ["compress-force=zstd:1" "noatime" "nofail"];
|
# Otherwise, the initrd will fail to unlock the disk, which causes the boot process to fail.
|
||||||
};
|
initrdUnlock = false;
|
||||||
"@snapshots" = {
|
|
||||||
mountpoint = "/data/apps-snapshots";
|
# encrypt the root partition with luks2 and argon2id, will prompt for a passphrase, which will be used to unlock the partition.
|
||||||
mountOptions = ["compress-force=zstd:1" "noatime" "nofail"];
|
# cryptsetup luksFormat
|
||||||
|
extraFormatArgs = [
|
||||||
|
"--type luks2"
|
||||||
|
"--cipher aes-xts-plain64"
|
||||||
|
"--hash sha512"
|
||||||
|
"--iter-time 5000"
|
||||||
|
"--key-size 256"
|
||||||
|
"--pbkdf argon2id"
|
||||||
|
# use true random data from /dev/random, will block until enough entropy is available
|
||||||
|
"--use-random"
|
||||||
|
];
|
||||||
|
extraOpenArgs = [
|
||||||
|
"--timeout 10"
|
||||||
|
];
|
||||||
|
content = {
|
||||||
|
type = "btrfs";
|
||||||
|
extraArgs = ["-f"]; # Force override existing partition
|
||||||
|
subvolumes = {
|
||||||
|
"@apps" = {
|
||||||
|
mountpoint = "/data/apps";
|
||||||
|
mountOptions = [
|
||||||
|
"compress-force=zstd:1"
|
||||||
|
# https://www.freedesktop.org/software/systemd/man/latest/systemd.mount.html
|
||||||
|
"nofail"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"@fileshare" = {
|
||||||
|
mountpoint = "/data/fileshare";
|
||||||
|
mountOptions = ["compress-force=zstd:1" "noatime" "nofail"];
|
||||||
|
};
|
||||||
|
"@backups" = {
|
||||||
|
mountpoint = "/data/backups";
|
||||||
|
mountOptions = ["compress-force=zstd:1" "noatime" "nofail"];
|
||||||
|
};
|
||||||
|
"@snapshots" = {
|
||||||
|
mountpoint = "/data/apps-snapshots";
|
||||||
|
mountOptions = ["compress-force=zstd:1" "noatime" "nofail"];
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
disk.data-fileshare = {
|
disk.data-public = {
|
||||||
type = "disk";
|
type = "disk";
|
||||||
device = "/dev/disk/by-id/ata-WDC_WD40EZRZ-22GXCB0_WD-WCC7K7VV9613";
|
device = "/dev/disk/by-id/ata-WDC_WD40EJRX-89T1XY0_WD-WCC7K0XDCZE6";
|
||||||
content = {
|
content = {
|
||||||
type = "gpt";
|
type = "gpt";
|
||||||
partitions.data-fileshare = {
|
partitions.data-fileshare = {
|
||||||
@@ -46,13 +100,9 @@
|
|||||||
# extraArgs = ["-f"]; # Override existing partition
|
# extraArgs = ["-f"]; # Override existing partition
|
||||||
subvolumes = {
|
subvolumes = {
|
||||||
"@persistent" = {
|
"@persistent" = {
|
||||||
mountpoint = "/data/fileshare";
|
mountpoint = "/data/fileshare/public";
|
||||||
mountOptions = ["compress-force=zstd:1" "nofail"];
|
mountOptions = ["compress-force=zstd:1" "nofail"];
|
||||||
};
|
};
|
||||||
"@snapshots" = {
|
|
||||||
mountpoint = "/data/fileshare-snapshots";
|
|
||||||
mountOptions = ["compress-force=zstd:1" "noatime" "nofail"];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
myvars,
|
myvars,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
dataDir = "/data/apps/transmission";
|
dataDir = "/data/fileshare/public/transmission";
|
||||||
name = "transmission";
|
name = "transmission";
|
||||||
in {
|
in {
|
||||||
# the headless Transmission BitTorrent daemon
|
# the headless Transmission BitTorrent daemon
|
||||||
|
|||||||
+1
-5
@@ -28,11 +28,7 @@ Clusters running as virtual machines on the KubeVirt cluster, for testing and pr
|
|||||||
1. `k3s-prod-1-worker-1`
|
1. `k3s-prod-1-worker-1`
|
||||||
1. `k3s-prod-1-worker-2`
|
1. `k3s-prod-1-worker-2`
|
||||||
1. `k3s-prod-1-worker-3`
|
1. `k3s-prod-1-worker-3`
|
||||||
1. For testing:.
|
1. For testing:. 2. `k3s-test-1-master-1` 3. `k3s-test-1-master-2` 4. `k3s-test-1-master-3`
|
||||||
1. `k3s-test-1-master-1`
|
|
||||||
2. `k3s-test-1-worker-1`
|
|
||||||
3. `k3s-test-1-worker-2`
|
|
||||||
4. `k3s-test-1-worker-3`
|
|
||||||
|
|
||||||
## Kubernetes Resources
|
## Kubernetes Resources
|
||||||
|
|
||||||
|
|||||||
@@ -58,8 +58,8 @@ in {
|
|||||||
#
|
#
|
||||||
# pre-allocate hugepages manually(for kubevirt guest vms)
|
# pre-allocate hugepages manually(for kubevirt guest vms)
|
||||||
# NOTE: the hugepages allocated here can not be used for other purposes!
|
# NOTE: the hugepages allocated here can not be used for other purposes!
|
||||||
# so we should left some memory for the host OS
|
# so we should left some memory for the host OS and other vms that don't use hugepages
|
||||||
"hugepagesz=1G"
|
"hugepagesz=1G"
|
||||||
"hugepages=54"
|
"hugepages=48" # use 75% of the total memory for hugepages
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ in {
|
|||||||
#
|
#
|
||||||
# pre-allocate hugepages manually(for kubevirt guest vms)
|
# pre-allocate hugepages manually(for kubevirt guest vms)
|
||||||
# NOTE: the hugepages allocated here can not be used for other purposes!
|
# NOTE: the hugepages allocated here can not be used for other purposes!
|
||||||
# so we should left some memory for the host OS
|
# so we should left some memory for the host OS and other vms that don't use hugepages
|
||||||
"hugepagesz=1G"
|
"hugepagesz=1G"
|
||||||
"hugepages=55"
|
"hugepages=48" # use 75% of the total memory for hugepages
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,9 +52,9 @@ in {
|
|||||||
#
|
#
|
||||||
# pre-allocate hugepages manually(for kubevirt guest vms)
|
# pre-allocate hugepages manually(for kubevirt guest vms)
|
||||||
# NOTE: the hugepages allocated here can not be used for other purposes!
|
# NOTE: the hugepages allocated here can not be used for other purposes!
|
||||||
# so we should left some memory for the host OS
|
# so we should left some memory for the host OS and other vms that don't use hugepages
|
||||||
"hugepagesz=1G"
|
"hugepagesz=1G"
|
||||||
"hugepages=16"
|
"hugepages=15" # use 15/24 of the total memory for hugepages
|
||||||
|
|
||||||
# https://kubevirt.io/user-guide/compute/host-devices/
|
# https://kubevirt.io/user-guide/compute/host-devices/
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
{
|
|
||||||
nixos-licheepi4a,
|
|
||||||
myvars,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
#############################################################
|
|
||||||
#
|
|
||||||
# Nozomi - NixOS configuration for Lichee Pi 4A
|
|
||||||
#
|
|
||||||
#############################################################
|
|
||||||
let
|
|
||||||
hostName = "nozomi"; # Define your hostname.
|
|
||||||
in {
|
|
||||||
imports = [
|
|
||||||
# import the licheepi4a module, which contains the configuration for bootloader/kernel/firmware
|
|
||||||
(nixos-licheepi4a + "/modules/licheepi4a.nix")
|
|
||||||
# import the sd-image module, which contains the fileSystems & kernel parameters for booting from sd card.
|
|
||||||
(nixos-licheepi4a + "/modules/sd-image/sd-image-lp4a.nix")
|
|
||||||
];
|
|
||||||
|
|
||||||
# Set static IP address / gateway / DNS servers.
|
|
||||||
networking = {
|
|
||||||
inherit hostName;
|
|
||||||
inherit (myvars.networking) defaultGateway nameservers;
|
|
||||||
inherit (myvars.networking.hostsInterface.${hostName}) interfaces;
|
|
||||||
|
|
||||||
wireless = {
|
|
||||||
# https://wiki.archlinux.org/title/wpa_supplicant
|
|
||||||
enable = true;
|
|
||||||
# The path to the file containing the WPA passphrase.
|
|
||||||
# secrets are not supported well on riscv64, I nned to create this file manually.
|
|
||||||
# Format: "PSK_WEMEET_PRIVATE_WIFI=your_password"
|
|
||||||
environmentFile = "/etc/wpa_supplicant.env";
|
|
||||||
# The network definitions to automatically connect to when wpa_supplicant is running.
|
|
||||||
networks = {
|
|
||||||
# read WPAPSK from environmentFile
|
|
||||||
"shadow_light_ryan".psk = "@PSK_WEMEET_PRIVATE_WIFI@";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Failed to enable firewall due to the following error:
|
|
||||||
# firewall-start[2300]: iptables: Failed to initialize nft: Protocol not supported
|
|
||||||
firewall.enable = false;
|
|
||||||
|
|
||||||
# Configure network proxy if necessary
|
|
||||||
# proxy.default = "http://user:password@proxy:port/";
|
|
||||||
# proxy.noProxy = "127.0.0.1,localhost,internal.domain";
|
|
||||||
|
|
||||||
# LPI4A's first ethernet interface
|
|
||||||
# interfaces.end0 = {
|
|
||||||
# useDHCP = false;
|
|
||||||
# ipv4.addresses = [
|
|
||||||
# {
|
|
||||||
# address = "192.168.5.104";
|
|
||||||
# prefixLength = 24;
|
|
||||||
# }
|
|
||||||
# ];
|
|
||||||
# };
|
|
||||||
# LPI4A's second ethernet interface
|
|
||||||
# interfaces.end1 = {
|
|
||||||
# useDHCP = false;
|
|
||||||
# ipv4.addresses = [
|
|
||||||
# {
|
|
||||||
# address = "192.168.xx.xx";
|
|
||||||
# prefixLength = 24;
|
|
||||||
# }
|
|
||||||
# ];
|
|
||||||
# };
|
|
||||||
};
|
|
||||||
|
|
||||||
# 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?
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
{
|
|
||||||
nixos-licheepi4a,
|
|
||||||
myvars,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
#############################################################
|
|
||||||
#
|
|
||||||
# Yukina - NixOS configuration for Lichee Pi 4A
|
|
||||||
#
|
|
||||||
#############################################################
|
|
||||||
let
|
|
||||||
hostName = "yukina"; # Define your hostname.
|
|
||||||
in {
|
|
||||||
imports = [
|
|
||||||
# import the licheepi4a module, which contains the configuration for bootloader/kernel/firmware
|
|
||||||
(nixos-licheepi4a + "/modules/licheepi4a.nix")
|
|
||||||
# import the sd-image module, which contains the fileSystems & kernel parameters for booting from sd card.
|
|
||||||
(nixos-licheepi4a + "/modules/sd-image/sd-image-lp4a.nix")
|
|
||||||
];
|
|
||||||
|
|
||||||
# Set static IP address / gateway / DNS servers.
|
|
||||||
networking = {
|
|
||||||
inherit hostName;
|
|
||||||
inherit (myvars.networking) defaultGateway nameservers;
|
|
||||||
inherit (myvars.networking.hostsInterface.${hostName}) interfaces;
|
|
||||||
|
|
||||||
wireless = {
|
|
||||||
# https://wiki.archlinux.org/title/wpa_supplicant
|
|
||||||
enable = true;
|
|
||||||
# The path to the file containing the WPA passphrase.
|
|
||||||
# secrets are not supported well on riscv64, I nned to create this file manually.
|
|
||||||
# Format: "PSK_WEMEET_PRIVATE_WIFI=your_password"
|
|
||||||
environmentFile = "/etc/wpa_supplicant.env";
|
|
||||||
# The network definitions to automatically connect to when wpa_supplicant is running.
|
|
||||||
networks = {
|
|
||||||
# read WPAPSK from environmentFile
|
|
||||||
"shadow_light_ryan".psk = "@PSK_WEMEET_PRIVATE_WIFI@";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Failed to enable firewall due to the following error:
|
|
||||||
# firewall-start[2300]: iptables: Failed to initialize nft: Protocol not supported
|
|
||||||
firewall.enable = false;
|
|
||||||
|
|
||||||
# Configure network proxy if necessary
|
|
||||||
# proxy.default = "http://user:password@proxy:port/";
|
|
||||||
# proxy.noProxy = "127.0.0.1,localhost,internal.domain";
|
|
||||||
|
|
||||||
# LPI4A's first ethernet interface
|
|
||||||
# interfaces.end0 = {
|
|
||||||
# useDHCP = false;
|
|
||||||
# ipv4.addresses = [
|
|
||||||
# {
|
|
||||||
# address = "192.168.5.104";
|
|
||||||
# prefixLength = 24;
|
|
||||||
# }
|
|
||||||
# ];
|
|
||||||
# };
|
|
||||||
# LPI4A's second ethernet interface
|
|
||||||
# interfaces.end1 = {
|
|
||||||
# useDHCP = false;
|
|
||||||
# ipv4.addresses = [
|
|
||||||
# {
|
|
||||||
# address = "192.168.xx.xx";
|
|
||||||
# prefixLength = 24;
|
|
||||||
# }
|
|
||||||
# ];
|
|
||||||
# };
|
|
||||||
};
|
|
||||||
|
|
||||||
# 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?
|
|
||||||
}
|
|
||||||
+1
-5
@@ -74,11 +74,7 @@
|
|||||||
# ```
|
# ```
|
||||||
# 2. Never leave the device and never sent over the network.
|
# 2. Never leave the device and never sent over the network.
|
||||||
# 2. Or just use hardware security keys like Yubikey/CanoKey.
|
# 2. Or just use hardware security keys like Yubikey/CanoKey.
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = myvars.sshAuthorizedKeys;
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIKlN+Q/GxvwxDX/OAjJHaNFEznEN4Tw4E4TwqQu/eD6 ryan@idols-ai"
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPoa9uEI/gR5+klqTQwvCgD6CD5vT5iD9YCNx2xNrH3B ryan@fern"
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPwZ9MdotnyhxIJrI4gmVshExHiZOx+FGFhcW7BaYkfR ryan@harmonica"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
nix.settings = {
|
nix.settings = {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
_: {
|
{
|
||||||
# Network discovery, mDNS
|
# Network discovery, mDNS
|
||||||
# With this enabled, you can access your machine at <hostname>.local
|
# With this enabled, you can access your machine at <hostname>.local
|
||||||
# it's more convenient than using the IP address.
|
# it's more convenient than using the IP address.
|
||||||
@@ -12,4 +12,10 @@ _: {
|
|||||||
userServices = true;
|
userServices = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Use an NTP server located in the mainland of China to synchronize the system time
|
||||||
|
networking.timeServers = [
|
||||||
|
"ntp.aliyun.com" # Aliyun NTP Server
|
||||||
|
"ntp.tencent.com" # Tencent NTP Server
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
users.users."${myvars.username}" = {
|
users.users."${myvars.username}" = {
|
||||||
# generated by `mkpasswd -m scrypt`
|
# generated by `mkpasswd -m scrypt`
|
||||||
# we have to use initialHashedPassword here when using tmpfs for /
|
# we have to use initialHashedPassword here when using tmpfs for /
|
||||||
initialHashedPassword = "$7$CU..../....KDvTIXqLTXpmCaoUy2yC9.$145eM358b7Q0sRXgEBvxctd5EAuEEdao57LmZjc05D.";
|
inherit (myvars) initialHashedPassword;
|
||||||
home = "/home/${myvars.username}";
|
home = "/home/${myvars.username}";
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = [
|
extraGroups = [
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
../../base.nix
|
../../base.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.loader.timeout = lib.mkForce 3; # wait for 3 seconds to select the boot entry
|
boot.loader.timeout = lib.mkForce 7; # wait for x seconds to select the boot entry
|
||||||
# Fix: jasper is marked as broken, refusing to evaluate.
|
# Fix: jasper is marked as broken, refusing to evaluate.
|
||||||
environment.enableAllTerminfo = lib.mkForce false;
|
environment.enableAllTerminfo = lib.mkForce false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,5 +15,5 @@
|
|||||||
../../base.nix
|
../../base.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.loader.timeout = lib.mkForce 3; # wait for 3 seconds to select the boot entry
|
boot.loader.timeout = lib.mkForce 7; # wait for x seconds to select the boot entry
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,5 +3,5 @@
|
|||||||
../base
|
../base
|
||||||
../../base.nix
|
../../base.nix
|
||||||
];
|
];
|
||||||
boot.loader.timeout = lib.mkDefault 3; # wait for 3 seconds to select the boot entry
|
boot.loader.timeout = lib.mkForce 7; # wait for x seconds to select the boot entry
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
inputs,
|
|
||||||
...
|
|
||||||
} @ args: let
|
|
||||||
inherit (inputs) haumea;
|
|
||||||
|
|
||||||
# Contains all the flake outputs of this system architecture.
|
|
||||||
data = haumea.lib.load {
|
|
||||||
src = ./src;
|
|
||||||
inputs = args;
|
|
||||||
};
|
|
||||||
# nix file names is redundant, so we remove it.
|
|
||||||
dataWithoutPaths = builtins.attrValues data;
|
|
||||||
|
|
||||||
# Merge all the machine's data into a single attribute set.
|
|
||||||
outputs = {
|
|
||||||
nixosConfigurations = lib.attrsets.mergeAttrsList (map (it: it.nixosConfigurations or {}) dataWithoutPaths);
|
|
||||||
packages = lib.attrsets.mergeAttrsList (map (it: it.packages or {}) dataWithoutPaths);
|
|
||||||
# colmena contains some meta info, which need to be merged carefully.
|
|
||||||
colmenaMeta = {
|
|
||||||
nodeNixpkgs = lib.attrsets.mergeAttrsList (map (it: it.colmenaMeta.nodeNixpkgs or {}) dataWithoutPaths);
|
|
||||||
nodeSpecialArgs = lib.attrsets.mergeAttrsList (map (it: it.colmenaMeta.nodeSpecialArgs or {}) dataWithoutPaths);
|
|
||||||
};
|
|
||||||
# colmena's per-machine data.
|
|
||||||
colmena = lib.attrsets.mergeAttrsList (map (it: it.colmena or {}) dataWithoutPaths);
|
|
||||||
};
|
|
||||||
in
|
|
||||||
outputs
|
|
||||||
// {
|
|
||||||
inherit data; # for debugging purposes
|
|
||||||
|
|
||||||
# NixOS's unit tests.
|
|
||||||
evalTests = haumea.lib.loadEvalTests {
|
|
||||||
src = ./tests;
|
|
||||||
inputs = args // {inherit outputs;};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
{
|
|
||||||
# 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
|
|
||||||
# 楽俊, Rakushun
|
|
||||||
name = "rakushun";
|
|
||||||
tags = [name "aarch"];
|
|
||||||
ssh-user = "root";
|
|
||||||
|
|
||||||
modules = {
|
|
||||||
nixos-modules =
|
|
||||||
(map mylib.relativeToRoot [
|
|
||||||
"secrets/nixos.nix"
|
|
||||||
"modules/nixos/server/server-aarch64.nix"
|
|
||||||
# host specific modules
|
|
||||||
"hosts/12kingdoms-${name}"
|
|
||||||
])
|
|
||||||
++ [
|
|
||||||
];
|
|
||||||
home-modules =
|
|
||||||
map mylib.relativeToRoot [
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
inherit (inputs) nixos-rk3588;
|
|
||||||
baseSpecialArgs = genSpecialArgs system;
|
|
||||||
|
|
||||||
rk3588Pkgs = import nixos-rk3588.inputs.nixpkgs {inherit system;};
|
|
||||||
rk3588SpecialArgs = let
|
|
||||||
# using the same nixpkgs as nixos-rk3588
|
|
||||||
inherit (nixos-rk3588.inputs) nixpkgs;
|
|
||||||
# use aarch64-linux's native toolchain
|
|
||||||
pkgsKernel = import nixpkgs {inherit system;};
|
|
||||||
in
|
|
||||||
baseSpecialArgs
|
|
||||||
// {
|
|
||||||
inherit nixpkgs;
|
|
||||||
# Provide rk3588 inputs as special argument
|
|
||||||
rk3588 = {inherit nixpkgs pkgsKernel;};
|
|
||||||
};
|
|
||||||
|
|
||||||
rk3588SystemArgs =
|
|
||||||
modules
|
|
||||||
// args
|
|
||||||
// {
|
|
||||||
inherit (nixos-rk3588.inputs) nixpkgs; # or nixpkgs-unstable
|
|
||||||
specialArgs = rk3588SpecialArgs;
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
nixosConfigurations.${name} = mylib.nixosSystem rk3588SystemArgs;
|
|
||||||
|
|
||||||
colmenaMeta = {
|
|
||||||
nodeSpecialArgs.${name} = rk3588SpecialArgs;
|
|
||||||
nodeNixpkgs.${name} = rk3588Pkgs;
|
|
||||||
};
|
|
||||||
colmena.${name} =
|
|
||||||
mylib.colmenaSystem
|
|
||||||
(rk3588SystemArgs // {inherit tags ssh-user;});
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
{
|
|
||||||
# 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
|
|
||||||
# 大木 鈴, Ōki Suzu
|
|
||||||
name = "suzu";
|
|
||||||
tags = [name "aarch"];
|
|
||||||
ssh-user = "root";
|
|
||||||
|
|
||||||
modules = {
|
|
||||||
nixos-modules =
|
|
||||||
(map mylib.relativeToRoot [
|
|
||||||
"secrets/nixos.nix"
|
|
||||||
"modules/nixos/server/server-aarch64.nix"
|
|
||||||
# host specific modules
|
|
||||||
"hosts/12kingdoms-${name}"
|
|
||||||
])
|
|
||||||
++ [
|
|
||||||
{modules.secrets.server.network.enable = true;}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
inherit (inputs) nixos-rk3588;
|
|
||||||
baseSpecialArgs = genSpecialArgs system;
|
|
||||||
|
|
||||||
rk3588Pkgs = import nixos-rk3588.inputs.nixpkgs {inherit system;};
|
|
||||||
rk3588SpecialArgs = let
|
|
||||||
# using the same nixpkgs as nixos-rk3588
|
|
||||||
inherit (nixos-rk3588.inputs) nixpkgs;
|
|
||||||
# use aarch64-linux's native toolchain
|
|
||||||
pkgsKernel = import nixpkgs {inherit system;};
|
|
||||||
in
|
|
||||||
baseSpecialArgs
|
|
||||||
// {
|
|
||||||
inherit nixpkgs;
|
|
||||||
# Provide rk3588 inputs as special argument
|
|
||||||
rk3588 = {inherit nixpkgs pkgsKernel;};
|
|
||||||
};
|
|
||||||
|
|
||||||
rk3588SystemArgs =
|
|
||||||
modules
|
|
||||||
// args
|
|
||||||
// {
|
|
||||||
inherit (nixos-rk3588.inputs) nixpkgs; # or nixpkgs-unstable
|
|
||||||
specialArgs = rk3588SpecialArgs;
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
nixosConfigurations.${name} = mylib.nixosSystem rk3588SystemArgs;
|
|
||||||
|
|
||||||
colmenaMeta = {
|
|
||||||
nodeSpecialArgs.${name} = rk3588SpecialArgs;
|
|
||||||
nodeNixpkgs.${name} = rk3588Pkgs;
|
|
||||||
};
|
|
||||||
colmena.${name} =
|
|
||||||
mylib.colmenaSystem
|
|
||||||
(rk3588SystemArgs // {inherit tags ssh-user;});
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
outputs,
|
|
||||||
}: let
|
|
||||||
hostsNames = builtins.attrNames outputs.nixosConfigurations;
|
|
||||||
expected = lib.genAttrs hostsNames (name: name);
|
|
||||||
in
|
|
||||||
expected
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
outputs,
|
|
||||||
}:
|
|
||||||
lib.genAttrs
|
|
||||||
(builtins.attrNames outputs.nixosConfigurations)
|
|
||||||
(
|
|
||||||
name: outputs.nixosConfigurations.${name}.config.networking.hostName
|
|
||||||
)
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
outputs,
|
|
||||||
}: let
|
|
||||||
hostsNames = builtins.attrNames outputs.nixosConfigurations;
|
|
||||||
expected = lib.genAttrs hostsNames (_: true);
|
|
||||||
in
|
|
||||||
expected
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
outputs,
|
|
||||||
}:
|
|
||||||
lib.genAttrs
|
|
||||||
(builtins.attrNames outputs.nixosConfigurations)
|
|
||||||
(
|
|
||||||
# test only if kernelPackages is set, to avoid build the kernel.
|
|
||||||
# name: outputs.nixosConfigurations.${name}.config.boot.kernelPackages.kernel.system
|
|
||||||
name: outputs.nixosConfigurations.${name}.config.boot.kernelPackages != null
|
|
||||||
)
|
|
||||||
+2
-2
@@ -34,8 +34,8 @@
|
|||||||
# modules for each supported system
|
# modules for each supported system
|
||||||
nixosSystems = {
|
nixosSystems = {
|
||||||
x86_64-linux = import ./x86_64-linux (args // {system = "x86_64-linux";});
|
x86_64-linux = import ./x86_64-linux (args // {system = "x86_64-linux";});
|
||||||
aarch64-linux = import ./aarch64-linux (args // {system = "aarch64-linux";});
|
# aarch64-linux = import ./aarch64-linux (args // {system = "aarch64-linux";});
|
||||||
riscv64-linux = import ./riscv64-linux (args // {system = "riscv64-linux";});
|
# riscv64-linux = import ./riscv64-linux (args // {system = "riscv64-linux";});
|
||||||
};
|
};
|
||||||
darwinSystems = {
|
darwinSystems = {
|
||||||
aarch64-darwin = import ./aarch64-darwin (args // {system = "aarch64-darwin";});
|
aarch64-darwin = import ./aarch64-darwin (args // {system = "aarch64-darwin";});
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
inputs,
|
|
||||||
...
|
|
||||||
} @ args: let
|
|
||||||
inherit (inputs) haumea;
|
|
||||||
|
|
||||||
# Contains all the flake outputs of this system architecture.
|
|
||||||
data = haumea.lib.load {
|
|
||||||
src = ./src;
|
|
||||||
inputs = args;
|
|
||||||
};
|
|
||||||
# nix file names is redundant, so we remove it.
|
|
||||||
dataWithoutPaths = builtins.attrValues data;
|
|
||||||
|
|
||||||
# Merge all the machine's data into a single attribute set.
|
|
||||||
outputs = {
|
|
||||||
nixosConfigurations = lib.attrsets.mergeAttrsList (map (it: it.nixosConfigurations or {}) dataWithoutPaths);
|
|
||||||
packages = lib.attrsets.mergeAttrsList (map (it: it.packages or {}) dataWithoutPaths);
|
|
||||||
# colmena contains some meta info, which need to be merged carefully.
|
|
||||||
colmenaMeta = {
|
|
||||||
nodeNixpkgs = lib.attrsets.mergeAttrsList (map (it: it.colmenaMeta.nodeNixpkgs or {}) dataWithoutPaths);
|
|
||||||
nodeSpecialArgs = lib.attrsets.mergeAttrsList (map (it: it.colmenaMeta.nodeSpecialArgs or {}) dataWithoutPaths);
|
|
||||||
};
|
|
||||||
# colmena's per-machine data.
|
|
||||||
colmena = lib.attrsets.mergeAttrsList (map (it: it.colmena or {}) dataWithoutPaths);
|
|
||||||
};
|
|
||||||
in
|
|
||||||
outputs
|
|
||||||
// {
|
|
||||||
inherit data; # for debugging purposes
|
|
||||||
|
|
||||||
# NixOS's unit tests.
|
|
||||||
evalTests = haumea.lib.loadEvalTests {
|
|
||||||
src = ./tests;
|
|
||||||
inputs = args // {inherit outputs;};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
{
|
|
||||||
# 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
|
|
||||||
# 森友 望未, Moritomo Nozomi
|
|
||||||
name = "nozomi";
|
|
||||||
tags = [name "riscv"];
|
|
||||||
ssh-user = "root";
|
|
||||||
|
|
||||||
modules = {
|
|
||||||
nixos-modules =
|
|
||||||
(map mylib.relativeToRoot [
|
|
||||||
"modules/nixos/server/server-riscv64.nix"
|
|
||||||
# host specific modules
|
|
||||||
"hosts/rolling-girls-${name}"
|
|
||||||
])
|
|
||||||
++ [
|
|
||||||
# cross-compilation this flake.
|
|
||||||
{nixpkgs.crossSystem.system = "riscv64-linux";}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
inherit (inputs) nixos-licheepi4a;
|
|
||||||
baseSpecialArgs = genSpecialArgs system;
|
|
||||||
|
|
||||||
# using the same nixpkgs as nixos-licheepi4a to utilize the cross-compilation cache.
|
|
||||||
lpi4aPkgs = import nixos-licheepi4a.inputs.nixpkgs {inherit system;};
|
|
||||||
lpi4aSpecialArgs =
|
|
||||||
baseSpecialArgs
|
|
||||||
// {
|
|
||||||
inherit (nixos-licheepi4a.inputs) nixpkgs;
|
|
||||||
pkgsKernel = nixos-licheepi4a.packages.${system}.pkgsKernelCross;
|
|
||||||
}
|
|
||||||
// args;
|
|
||||||
lpi4aSystemArgs =
|
|
||||||
modules
|
|
||||||
// args
|
|
||||||
// {
|
|
||||||
inherit (nixos-licheepi4a.inputs) nixpkgs;
|
|
||||||
specialArgs = lpi4aSpecialArgs;
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
nixosConfigurations.${name} = mylib.nixosSystem lpi4aSystemArgs;
|
|
||||||
|
|
||||||
colmenaMeta = {
|
|
||||||
nodeSpecialArgs.${name} = lpi4aSpecialArgs;
|
|
||||||
nodeNixpkgs.${name} = lpi4aPkgs;
|
|
||||||
};
|
|
||||||
colmena.${name} =
|
|
||||||
mylib.colmenaSystem
|
|
||||||
(lpi4aSystemArgs // {inherit tags ssh-user;});
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
{
|
|
||||||
# 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
|
|
||||||
# 小坂 結季奈, Kosaka Yukina
|
|
||||||
name = "yukina";
|
|
||||||
tags = [name "riscv"];
|
|
||||||
ssh-user = "root";
|
|
||||||
|
|
||||||
modules = {
|
|
||||||
nixos-modules =
|
|
||||||
(map mylib.relativeToRoot [
|
|
||||||
"modules/nixos/server/server-riscv64.nix"
|
|
||||||
# host specific modules
|
|
||||||
"hosts/rolling-girls-${name}"
|
|
||||||
])
|
|
||||||
++ [
|
|
||||||
# cross-compilation this flake.
|
|
||||||
{nixpkgs.crossSystem.system = "riscv64-linux";}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
inherit (inputs) nixos-licheepi4a;
|
|
||||||
baseSpecialArgs = genSpecialArgs system;
|
|
||||||
|
|
||||||
# using the same nixpkgs as nixos-licheepi4a to utilize the cross-compilation cache.
|
|
||||||
lpi4aPkgs = import nixos-licheepi4a.inputs.nixpkgs {inherit system;};
|
|
||||||
lpi4aSpecialArgs =
|
|
||||||
baseSpecialArgs
|
|
||||||
// {
|
|
||||||
inherit (nixos-licheepi4a.inputs) nixpkgs;
|
|
||||||
pkgsKernel = nixos-licheepi4a.packages.${system}.pkgsKernelCross;
|
|
||||||
}
|
|
||||||
// args;
|
|
||||||
lpi4aSystemArgs =
|
|
||||||
modules
|
|
||||||
// args
|
|
||||||
// {
|
|
||||||
inherit (nixos-licheepi4a.inputs) nixpkgs;
|
|
||||||
specialArgs = lpi4aSpecialArgs;
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
nixosConfigurations.${name} = mylib.nixosSystem lpi4aSystemArgs;
|
|
||||||
|
|
||||||
colmenaMeta = {
|
|
||||||
nodeSpecialArgs.${name} = lpi4aSpecialArgs;
|
|
||||||
nodeNixpkgs.${name} = lpi4aPkgs;
|
|
||||||
};
|
|
||||||
colmena.${name} =
|
|
||||||
mylib.colmenaSystem
|
|
||||||
(lpi4aSystemArgs // {inherit tags ssh-user;});
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
outputs,
|
|
||||||
}: let
|
|
||||||
hostsNames = builtins.attrNames outputs.nixosConfigurations;
|
|
||||||
expected = lib.genAttrs hostsNames (name: name);
|
|
||||||
in
|
|
||||||
expected
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
outputs,
|
|
||||||
}:
|
|
||||||
lib.genAttrs
|
|
||||||
(builtins.attrNames outputs.nixosConfigurations)
|
|
||||||
(
|
|
||||||
name: outputs.nixosConfigurations.${name}.config.networking.hostName
|
|
||||||
)
|
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
{modules.secrets.server.application.enable = true;}
|
{modules.secrets.server.application.enable = true;}
|
||||||
{modules.secrets.server.operation.enable = true;}
|
{modules.secrets.server.operation.enable = true;}
|
||||||
{modules.secrets.server.webserver.enable = true;}
|
{modules.secrets.server.webserver.enable = true;}
|
||||||
|
{modules.secrets.server.storage.enable = true;}
|
||||||
];
|
];
|
||||||
home-modules = map mylib.relativeToRoot [
|
home-modules = map mylib.relativeToRoot [
|
||||||
"home/linux/tui.nix"
|
"home/linux/tui.nix"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ from pathlib import Path
|
|||||||
NIX_DAEMON_PLIST = Path("/Library/LaunchDaemons/org.nixos.nix-daemon.plist")
|
NIX_DAEMON_PLIST = Path("/Library/LaunchDaemons/org.nixos.nix-daemon.plist")
|
||||||
NIX_DAEMON_NAME = "org.nixos.nix-daemon"
|
NIX_DAEMON_NAME = "org.nixos.nix-daemon"
|
||||||
# http proxy provided by my homelab's bypass router
|
# http proxy provided by my homelab's bypass router
|
||||||
HTTP_PROXY = "http://192.168.5.179:7890"
|
HTTP_PROXY = "http://192.168.5.101:7890"
|
||||||
|
|
||||||
PLIST = plistlib.loads(NIX_DAEMON_PLIST.read_bytes())
|
PLIST = plistlib.loads(NIX_DAEMON_PLIST.read_bytes())
|
||||||
|
|
||||||
@@ -55,5 +55,5 @@ def unset_proxy():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# set_proxy()
|
set_proxy()
|
||||||
unset_proxy()
|
# unset_proxy()
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ in {
|
|||||||
server.operation.enable = mkEnableOption "NixOS Secrets for Operation Servers(Backup, Monitoring, etc)";
|
server.operation.enable = mkEnableOption "NixOS Secrets for Operation Servers(Backup, Monitoring, etc)";
|
||||||
server.kubernetes.enable = mkEnableOption "NixOS Secrets for Kubernetes";
|
server.kubernetes.enable = mkEnableOption "NixOS Secrets for Kubernetes";
|
||||||
server.webserver.enable = mkEnableOption "NixOS Secrets for Web Servers(contains tls cert keys)";
|
server.webserver.enable = mkEnableOption "NixOS Secrets for Web Servers(contains tls cert keys)";
|
||||||
|
server.storage.enable = mkEnableOption "NixOS Secrets for HDD Data's LUKS Encryption";
|
||||||
|
|
||||||
impermanence.enable = mkEnableOption "whether use impermanence and ephemeral root file system";
|
impermanence.enable = mkEnableOption "whether use impermanence and ephemeral root file system";
|
||||||
};
|
};
|
||||||
@@ -249,5 +250,24 @@ in {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
|
(mkIf cfg.server.storage.enable {
|
||||||
|
age.secrets = {
|
||||||
|
"hdd-luks-crypt-key" = {
|
||||||
|
file = "${mysecrets}/hdd-luks-crypt-key.age";
|
||||||
|
mode = "0400";
|
||||||
|
owner = "root";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# place secrets in /etc/
|
||||||
|
environment.etc = {
|
||||||
|
"agenix/hdd-luks-crypt-key" = {
|
||||||
|
source = config.age.secrets."hdd-luks-crypt-key".path;
|
||||||
|
mode = "0400";
|
||||||
|
user = "root";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,4 +3,23 @@
|
|||||||
userfullname = "Ryan Yin";
|
userfullname = "Ryan Yin";
|
||||||
useremail = "xiaoyin_c@qq.com";
|
useremail = "xiaoyin_c@qq.com";
|
||||||
networking = import ./networking.nix {inherit lib;};
|
networking = import ./networking.nix {inherit lib;};
|
||||||
|
# generated by `mkpasswd -m scrypt`
|
||||||
|
initialHashedPassword = "$7$CU..../....KDvTIXqLTXpmCaoUy2yC9.$145eM358b7Q0sRXgEBvxctd5EAuEEdao57LmZjc05D.";
|
||||||
|
# Public Keys that can be used to login to all my PCs, Macbooks, and servers.
|
||||||
|
#
|
||||||
|
# Since its authority is so large, we must strengthen its security:
|
||||||
|
# 1. The corresponding private key must be:
|
||||||
|
# 1. Generated locally on every trusted client via:
|
||||||
|
# ```bash
|
||||||
|
# # KDF: bcrypt with 256 rounds, takes 2s on Apple M2):
|
||||||
|
# # Passphrase: digits + letters + symbols, 12+ chars
|
||||||
|
# ssh-keygen -t ed25519 -a 256 -C "ryan@xxx" -f ~/.ssh/xxx`
|
||||||
|
# ```
|
||||||
|
# 2. Never leave the device and never sent over the network.
|
||||||
|
# 2. Or just use hardware security keys like Yubikey/CanoKey.
|
||||||
|
sshAuthorizedKeys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIKlN+Q/GxvwxDX/OAjJHaNFEznEN4Tw4E4TwqQu/eD6 ryan@idols-ai"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPoa9uEI/gR5+klqTQwvCgD6CD5vT5iD9YCNx2xNrH3B ryan@fern"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPwZ9MdotnyhxIJrI4gmVshExHiZOx+FGFhcW7BaYkfR ryan@harmonica"
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user