Stay frosty like Tony
A home for my system configurations using Nix Flakes Be warned, I’m still learning and experimenting.
Nothing here should be construed as a model of good work!… yet.
Y’know, I’m starting to feel pretty good about this.
system.autoUpgrade.enable
make it Wednesday morning, after our scheduled CI flake updates/etc/kubernetes/pki
kubeadm:cluster-admins
O=cluster:nodes:$NAME
are working.buildEnv
over devShell
Pre-requisites:
systemctl reboot --firmware-setup
~ Future Ariel.HpSetup.txt
OR follow along the rest.root
nix-shell
to obtain Git and Helix/etc/nixos/hardware-configuration.nix
.
Place it in the machine’s hardware-configuration.nix
in the flake repo.
(This step may no longer be necessary)F10
to enter BIOS, boot update.
Enter 1
and it should update.curl https://github.com/arichtman.keys >> ~/.ssh/authorized_keys
/etc/network/interfaces
and switch the virtual bridge network configuration from manual
to dhcp
.efibootmgr -v
.
If GRUB, sed -i -r -e 's/(GRUB_CMDLINE_LINUX_DEFAULT=")(.*)"/\1\2 intel_iommu=on"/' /etc/default/grub
echo 'vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd' >> /etc/modules
apt install prometheus-node-exporter
.apt install avahi-daemon
.apt install grub-efi-amd64
.systemctl disable openipmi
.If I check /etc/grub.d/000_ proxmox whatever it says update-grub
isn’t the way and to use proxmox-boot-tool refresh
.
It also looks like there’s a specific proxmox grub config file under /etc/default/grub.d/proxmox-ve.cfg
.
I don’t expect it hurts much to have iommu on as a machine default, and we’re not booting anything else…
Might tidy up the sed config command though.
Looking at the systemd we could probably do both without harm.
That one’s also using the official proxmox command.
References:
We did run mkfs -t ext4
but it didn’t allow us to use the disk in the GUI.
So using GUI we wiped disk and initialized with GPT.
For the USB rust bucket we found the device name with fdisk -l
.
Then we
Never mind, same dance with the GUI, followed by heading to Node > Disks > Directory and creating one.mkfs -t ext4 /dev/sdb
, followed by a mount /dev/sdb /media/backup
.
Use blkid
to pull details and populate a line in /etc/fstab
for auto remount of backup disk.
Ref
/etc/fstab
:
# <file system> <mount point> <type> <options> <dump> <pass>
/dev/pve/root / ext4 errors=remount-ro 0 1
UUID=C61A-7940 /boot/efi vfat defaults 0 1
/dev/pve/swap none swap sw 0 0
proc /proc proc defaults 0 0
UUID=b35130d3-6351-4010-87dd-6f2dac34cfba /mnt/pve/Backup ext4 defaults,nofail,x-systemd.device-timeout=5 0 2
I used this to shift OPNsense to 999 and any templates to >=1000.
lvs -a
lvrename prod vm-100-disk-0 vm-999-disk-0
/etc/pve/nodes/proxmox/qemu-server
watchdog: model=i6300esb,action=reset
to the conf file in /etc/pve/qemu-server/
.nix-shell -p cloud-utils
growpart /dev/sda 1
resize2fs /dev/sda1
Features:
/var/lib/vz/template/iso
opkg update
or maybe system > firmwaredig +trace @4.4.4.4 bing.com
Follow one of the 6000 tutorials AKA yes, I forgot to document it.
Follow tutorial AKA forgot to document it.
See also wg0.conf
in this repo.
sysctl kern.ipc.maxsockbuf=16777216
as plugin post-install message suggests.
(Not immediately in use, for Cillium later)/usr/local/tftp
and download netboot.xyz.kpxe
.
I also downloaded netboot.xyz.efi
for good measure.
Enable TFTP and set listening IP to 0.0.0.0
.
This defaulted to 127.0.0.1
which may have worked but I didn’t test.os-wol
to wake on lan.
Add all physical machines to the list of known, you can use Kea DHCP leases to find all the MACs in one place.Notes:
I will revisit the resources supplied after running the box for a bit.
CPU seems fine, spikey with what I think are Python runtime startups from the control layer. RAM looks consistently under about 1Gb so I’ll trim that back from the recommended minimum 2Gb. We’re doing pretty well on space too but I’m less short on that.
References:
/etc/nixos/configuration.nix
security.sudo.wheelNeedsPassword = false
/dev/sda
mkdir ~~/.ssh && curl https://github.com/arichtman.keys -o ~/.ssh/authorized_keys && chmod 600 ~~/.ssh/authorized_keys
sudo nixos-rebuild switch --upgrade --upgrade-all
sudo nix-rebuild list-generations
sudo rm /nix/var/nix/profiles/system-#-profile
sudo nix-collect-garbage --delete-old
Arguably this mingles with substratum, as PKI/trust/TLS is required or very desirable for VPN/HTTPS etc. SPIFFE/SPIRE will address this somewhat.
xkcdpass --delimiter - --numwords 4 > root-ca.pass
step certificate create "ariel@richtman.au" ./root-ca.pem ./root-ca-key.pem --profile root-ca --password-file ./root-ca.pass
fetchUrl
callgarage layout assign --zone garage.services.richtman.au --capacity 128GB $(garage node id 2>/dev/null)
garage layout apply --version 1
# Create a client certificate with admin
step certificate create cluster-admin cluster-admin.pem cluster-admin-key.pem \
--ca ca.pem --ca-key ca-key.pem --insecure --no-password --template granular-dn-leaf.tpl --set-file dn-defaults.json --not-after 8760h \
--set organization=system:masters
# Construct the kubeconfig file
# Here we're embedding certificates to avoid breaking stuff if we move or remove cert files
kubectl config set-cluster home --server https://fat-controller.systems.richtman.au:6443 --certificate-authority ca.pem --embed-certs=true
kubectl config set-credentials home-admin --client-certificate cluster-admin.pem --client-key cluster-admin-key.pem --embed-certs=true
kubectl config set-context --user home-admin --cluster home home-admin
openssl genpkey -out klient-key.pem -algorithm ed25519
openssl req -new -config klient.csr.conf -key klient-key.pem -out klient.csr
export KLIENT_CSR=$(base64 klient.csr | tr -d "\n")
envsubst -i klient-csr.yaml | kubectly apply -f -
kubectl certificate user approve
For security reasons, it’s not possible for nodes to self-select roles.
We can label our nodes using label.sh
.
hmmm, deleting the nodes (reasonably) removes labels. …and since they can’t self-identify, we have to relabel every time. I expect taints would work the same way, so we couldn’t use a daemonset or spread topology with labeling privileges since it wouldn’t know what to label the node. Unless… we deploy it with a configMap? That’s kinda lame. I suppose all the nodes that need this are dynamic, ergo ephemeral and workers, so we could make something like that. Heck, a static pod would work fine for this and be simple as. But then it’d be a pod, which is a continuous workload, which we really don’t need. A job would suit better, but then it’s like, why even run this on the nodes themselves? Have the node self-delete (it’ll self-register again anyway), and have the admin box worry about admin like labelling. I wonder if there’s any better way security-wise to have nodes be trusted with certain labels. Already they need apiServer-trusted client certificates, it’d be cool if the metadata on those could determine labels.
NB: Future Ariel says there may be a kubelet option to register with properties.
kubectl get csr --no-headers -o jsonpath='{.items[*].metadata.name}' | xargs -r kubectl certificate approve
Checking builds manually: nix build .#nixosConfigurations.fat-controller.config.system.build.toplevel
Minimal install ~3.2 gigs
Lab-node with master node about 3.2 gb also, so will want more headroom.
Add to nomicon
Using tasker
Profile: AutoPrivateDNS
State: Wifi Connected [ SSID:sugar_monster_house MAC:* IP:* Active:Any ]
Enter: Anon
A1: Custom Setting [ Type:Global Name:private_dns_mode Value:opportunistic Use Root:Off Read Setting To: ]
Exit: Anon
A1: Custom Setting [ Type:Global Name:private_dns_mode Value:hostname Use Root:Off Read Setting To: ]
nix shell nixpkgs#android-tools -c adb shell pm grant net.dinglisch.android.taskerm android.permission.WRITE_SECURE_SETTINGS
References:
Trust chain system install:
sudo security add-trusted-cert -r trustRoot -k /Library/Keychains/System.keychain -d ~/Downloads/root-ca.pem
OPNsense/openssl’s ciphers are too new, to install client certificate you may need to pkcs12 bundle legacy.
openssl pkcs12 -export -legacy -out Certificate.p12 -in certificate.pem -inkey key.pem
softwareupdate -ia
softwareupdate --install-rosetta --agree-to-license
I didn’t explicitly install it but it’s on there somehow now.
There was some mention that it auto-installs if you try running x86_64 binaries.curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
sudo mv /etc/nix/nix.conf /etc/nix/.nix-darwin.bkp.nix.conf
nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A installer
./result/bin/darwin-installer
edit default configuration.nix? n
# Accept the option to manage nix-darwin using nix-channel or else it bombs
manage using channels? y
add to bashrc y
add to zshrc? y
create /run? y
# a nix-channel call will now fail
nix build github:arichtman/nix#darwinConfigurations.macbook-pro-work.system
./result/sw/bin/darwin-rebuild switch --flake .#macbook-pro-work
./result/sw/bin/darwin-rebuild switch --flake github:arichtman/nix
some very wip notes about the desktop.
bluetoothctl trust $MAC
to try and start off autoconnecttrusted-users = @wheel
to /etc/nix/nix.conf
nix shell helix home-manager
to bootstraphome-manager switch --flake . -b backup
sudo curl https://www.richtman.au/root-ca.pem -o source/anchors/root-ca.pem
sudo update-ca-trust
Some diagnostic tests for mDNS:
export HOST_NAME=fat-controller.systems.richtman.au.
# This is our bedrock of truth. It works consistently and can be easily viewed
avahi-resolve-host-name $HOST_NAME
tcpdump udp port 5353 # Optionally -Qin
# Supposedly a good test according to Arch wiki, has not once worked for me.
getent ahosts $HOST_NAME
# Sometimes worked but timed out on a 3rd imaginary server. Most verbose but leaks mDNS queries.
dig $HOST_NAME
# Sometimes worked but not very helpful output.
host $HOST_NAME
# Convenience aliases
alias rollall='sudo systemctl restart NetworkManager systemd-resolved systemd-networkd; sudo systemctl daemon-reload'
alias dtest4='dig -4 $HOST_NAME'
alias dtest6='dig -6 $HOST_NAME'
alias htest4='host -4 $HOST_NAME'
alias htest6='host -6 $HOST_NAME'
alias etest='getent ahosts $HOST_NAME'
alltest() {
dtest4
dtest6
htest4
htest6
etest
}
alias nm=nmcli
alias rc=resolvectl
alias as=authselect
So, turns out this whole resolution chain is a mess, some things use nsswitch, others don’t etc. We want consistent behaviour and caching, so we need the local stub resolver. We want it even more if we’re switching networks and VPNs as it can hold all the logic for changing shit.
Here’s some locations and commands for config. I tried valiantly to enable it at connection level and in nsswitch but ultimately there was always something that disobeyed the rules.
/etc/nsswitch.conf
:
This should be managed by authselect
.
Don’t ask why.
Fun fact: apparently the sssd
daemon totally doesn’t need to be running for this to work.
Why is DNS is entwined with an auth config management tool?
Because go fuck yourself, that’s why.
~ Poettering, probably.
authselect list
authselect current
authselect show sssd
# Yields some options
authselect select sssd with-mdns4 with-mdns6
/etc/resolv.conf
:
This one is managed by NetworkManager. Why is that capitalized? NFI. Go fuck yourself! ~ Probably Poettering, again.
I tried manually managing this one, no dice (to do that, stop NetworkManager, and remove the symlink).
Leave it symlinked to /run/systemd/resolve/stub-resolve.conf
.
That’s the managed file that will always point at the local stub resolver.
We can manage the actual settings with nmcli
.
mDNS is configured per connection, not interface, which I guess makes sense for laptops/WiFi.
nmcli connection show
# I tried this as 2 (resolve+publish) and I think it clashes with the stub resolver
nmcli conn mod enp3s0 connection.mdns 2
nmcli conn mod sugar_monster_house connection.mdns 2
# Yea it breaks v4 resolution somehow
# Not sure about this one... In theory we lose the domains config as well as our Unbound upstream,
# but resolved should have us covered? domain search might need to happen at the origin call site though.
nmcli conn mod enp3s0 ipv4.ignore-auto-dns no
nmcli conn mod enp3s0 ipv6.ignore-auto-dns no
Oh, the stub resolver doesn’t actually run on localhost:53
.
It’s 127.0.0.53
(and actually .54
also, according to man 8 systemd-resolved.service
).
Can ya guess why?
Yup. Had enough self-love yet?
Keep reading.
/etc/systemd/network/*.network
:
You can write files like:
[Network]
DHCP=yes
Domain=local internal
Except when I experimented resolvectl
didn’t edit the file and editing the file didn’t show in resolvectl
output.
So go figure.
I honestly can’t keep track of what this is relative to NetworkManager.
There is a service, systemd-networkd
.
By the way, systemd-resolved
used to be controlled by systemd-resolve
.
It’s now resolvectl
.
Guess I’m not mad about that one.
Now the fact that mDNS is configured per interface and not connection like before?
Get fuuuuuucked.
Oh and the daemon only listens on IPv4 (at least by default).
GFY!
sudo resolvectl mdns enp0s3 yes
sudo resolvectl domain enp0s3 local internal
echo 'DNSStubListenerExtra=[::1]:53' | sudo tee -a /etc/systemd/resolved.conf
/etc/NetworkManager
:
Whatever.
What worked in the end?
Well, still getting some odd behaviour with host
and IPv6 but…
No files in /etc/systemd/network
.
Disable networkd
.
Resolvectl set +mdns.
Symlinked /etc/resolv.conf
to the resolved
stub file.
Configured resolved
.
Avahi daemon enabled and running with defaults.
sudo systemctl disable --now systemd-networkd
sudo systemctl mask systemd-networkd
sudo systemctl daemon-reload
Final /etc/systemd/resolved.conf
:
[Resolve]
DNS=192.168.1.1,2403:580a:e4b1:0:aab8:e0ff:fe00:91ef
Domains=local internal
MulticastDNS=yes
DNSStubListenerExtra=[::1]:53
References:
PATH
correctlytracker-miner-fs-3.service
nano-default-editor
rpm-ostree override remove
nixpkgs
and NixOS-WSL
source Nix files