• Stars
    star
    135
  • Rank 269,297 (Top 6 %)
  • Language
    Nix
  • Created over 8 years ago
  • Updated 12 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

My NixOS configuration and assorted other crap.

nixfiles

My NixOS configuration and assorted other crap, powered by flakes. Clone to /etc/nixos.

CI checks ensure that code is formatted and passes linting. Run those locally with:

nix flake check
nix run .#fmt
nix run .#lint

Overview

This is an opinionated config making assumptions which work for me but might not for you:

  • These are primarily single-user hosts, with me being that user. While security and availability are important, convenience takes priority.
  • Observability is good but there's no central graphing or alerting stack, every host has to run their own.
  • Databases should not be shared, each service has its own containerised instance. This means a single host may run several instances of the same database software, but that's an acceptable overhead.
  • Persistent docker volumes should be backed by bind-mounts to the filesystem.
  • For ZFS systems, wiping / on boot is good actually.

Everything in shared/default.nix is enabled on every host by default. Notable decisions are:

  • Every user gets a ~/tmp directory with files cleaned out after 7 days.
  • Automatic upgrades (including reboots if needed), automatic deletions of generations older than 30 days, and automatic garbage collection are all enabled.
  • Locale, timezone, and keyboard layout all set to UK / GB values (yes, even on servers).
  • Firewall and fail2ban are enabled, but pings are explicitly allowed.
  • SSH accepts pubkey auth only: no passwords.
  • Syncthing is enabled.

For monitoring and alerting specifically:

  • Prometheus, Grafana, and Alertmanager are all enabled by default (Alertmanager needs AWS credentials provided to actually send alerts).
  • The Node Exporter is enabled, along with a dashboard.
  • cAdvisor is enabled, along with a dashboard.

If using ZFS there are a few more things configured:

  • All pools are scrubbed monthly.
  • The auto-trim and auto-snapshot jobs are enabled (for pools which have those configured).
  • There's a Prometheus alert for pools in a state other than "online".

Everything else in shared/ is available to every host, but disabled by default.

Hosts

Currently I have 3 NixOS machines. The naming convention is:

  • Local machines: beings (gods, people, etc) of the Cthulhu Mythos.
  • Remote machines: places of the Cthulhu Mythos.

azathoth

This is my desktop computer.

It dual-boots Windows and NixOS, so it doesnโ€™t run any services, as they won't be accessible half of the time. I don't bother backing up either OS: everything I care about is in Syncthing, on GitHub, or on some other cloud service (eg, Steam).

carcosa

This is a VPS (hosted by Hetzner Cloud).

It serves barrucadu.co.uk and other services on it, such as a bookdb instance and my blog. Websites are served with Caddy, with certs from Let's Encrypt.

It's set up in "erase your darlings" style, so most of the filesystem is wiped on boot and restored from the configuration, to ensure there's no accidentally unmanaged configuration or state hanging around. However, it doesn't reboot automatically, because I also use this server for a persistent IRC connection.

nyarlathotep

This is my home server.

It runs writable instances of the bookdb and bookmarks services, which have any updates copied across to carcosa hourly; it acts as a NAS; and it runs a few utility services, such as a dashboard of finance information from my hledger journal, and a script to automatically tag and organise new podcast episodes or CD rips which I copy over to it.

Like carcosa, this host is set up in "erase your darlings" style but, unlike carcosa, it automatically reboots to install updates: so that takes effect significantly more frequently.

Setting up a new host

See also the NixOS installation instructions.

  1. Create & format partitions
  2. Optional: Configure wiping / on boot (pre-first-boot steps)
  3. Install NixOS with the standard installer
  4. Reboot into the installed system
  5. Clone this repo to /etc/nixos
  6. Move the generated configuration to hosts/<hostname>/ and edit to fit repo conventions
  7. Add an entry for the host to flake.nix
  8. Optional: Add DNS records
  9. Optional: Configure secrets
  10. Optional: Configure wiping / on boot (post-first-boot steps)
  11. Optional: Configure backups
  12. Optional: Generate SSH key
  13. Build the new system configuration with sudo nixos-rebuild switch --flake '.#<hostname>'
  14. Reboot
  15. Commit, push, & merge

Optional: Configure wiping / on boot

Before installing NixOS, create the local pool and datasets:

zpool create -o mountpoint=legacy -o autotrim=on local <device>

zfs create -o mountpoint=legacy local/volatile
zfs create -o mountpoint=legacy local/volatile/root

zfs create -o mountpoint=legacy local/persistent
zfs create -o mountpoint=legacy -o com.sun:auto-snapshot=true local/persistent/home
zfs create -o mountpoint=legacy -o com.sun:auto-snapshot=true local/persistent/nix
zfs create -o mountpoint=legacy -o com.sun:auto-snapshot=true local/persistent/persist
zfs create -o mountpoint=legacy -o com.sun:auto-snapshot=true local/persistent/var-log

Take a snapshot of the empty root dataset:

zfs snapshot local/volatile/root@blank

Mount all the filesystems under /mnt:

mount -t zfs local/volatile/root /mnt

mkdir /mnt/boot
mkdir /mnt/home
mkdir /mnt/nix
mkdir /mnt/persist
mkdir -p /mnt/var/log

mount /dev/<boot device> /mnt/boot
mount -t zfs local/persistent/home /mnt/home
mount -t zfs local/persistent/nix /mnt/nix
mount -t zfs local/persistent/persist /mnt/persist
mount -t zfs local/persistent/var-log /mnt/var/log

Then run the installer, making sure to add ZFS details to the generated configuration:

networking.hostId = "<random 32-bit hex value>";
boot.supportedFilesystems = [ "zfs" ];

After first boot: copy any needed files (eg, SSH host keys) to the appropriate place in /persist, add the user password to the secrets, and set up nixfiles.eraseYourDarlings:

nixfiles.eraseYourDarlings.enable = true;
nixfiles.eraseYourDarlings.machineId = "<contents of /etc/machine-id>";
nixfiles.eraseYourDarlings.barrucaduPasswordFile = config.sops.secrets."users/barrucadu".path;
sops.secrets."users/barrucadu".neededForUsers = true;

Optional: Add DNS records

Add A / AAAA records to the ops repo and apply the change via Concourse.

Optional: Configure secrets

After first boot, generate an age public key from the host SSH key:

nix-shell -p ssh-to-age --run 'ssh-keyscan <hostname>.barrucadu.co.uk | ssh-to-age'

Add a new section with this key to .sops.yaml:

creation_rules:
  ...
  - path_regex: hosts/<hostname>/secrets(/[^/]+)?\.yaml$
    key_groups:
      - age:
          - *barrucadu
          - '<key>'

Enable sops in the host configuration:

sops.defaultSopsFile = ./secrets.yaml;

Optional: Configure backups

All hosts which run any sort of service with data I care about should take automatic backups.

Firstly, add the backup credentials to the secrets:

nix run .#secrets

Then enable backups in the host configuration:

nixfiles.backups.enable = true;
nixfiles.backups.environmentFile = config.sops.secrets."nixfiles/backups/env".path;
sops.secrets."nixfiles/backups/env" = { };

Most services define their own backup scripts. For any other needs, write a custom script:

nixfiles.backups.scripts.<name> = ''
  <script which copies files to backup to the current working directory>
'';

Optional: Generate SSH key

Generate an ed25519 SSH key:

ssh-keygen -t ed25519

If the host should be able to interact with GitHub: add the public key to the GitHub user configuration as an SSH key.

If the host should be able to push commits to GitHub: add the public key to the GitHub user configuration as a signing key, and also add it to the allowed_signers file.

If the host should be able to connect to other machines: add the public key to shared/default.nix.

Tools

Backups

Backups are managed by shared/backups and uploaded to S3 with Duplicity.

Check the status of a backup collection with:

nix run .#backups                   # for the current host
nix run .#backups status            # for the current host
nix run .#backups status <hostname> # for another host

Restore a backup to /tmp/backup-restore with:

nix run .#backups restore            # for the current host
nix run .#backups restore <hostname> # for another host

Change the restore target by setting $RESTORE_DIR.

Secrets

Secrets are managed with sops-nix. Create / edit secrets with:

nix run .#secrets                   # secrets.yaml for current host
nix run .#secrets <hostname>        # secrets.yaml for <hostname>
nix run .#secrets <hostname> <name> # <name>.yaml for <hostname>

More Repositories

1

markov

Markov chain text generator, as used for KingJamesProgramming
Python
452
star
2

dejafu

Systematic concurrency testing meets Haskell.
Haskell
188
star
3

hledger-scripts

Helpful scripts to do things with your hledger data.
Haskell
54
star
4

lainonlife

RIP lainchan radio, taken out by HDD failure.
Python
53
star
5

logdb

An efficient log-structured database supporting efficient insertion of new entries and removal from either end of the log.
Go
28
star
6

finances

A small tool to visualise my hledger journal. Your mileage may vary.
JavaScript
27
star
7

bookdb

Python
25
star
8

dotfiles

My dotfiles and assorted other crap, managed with chezmoi.
Python
25
star
9

resolved

A simple DNS server for home networks.
Rust
20
star
10

irc-client

This project is essentially abandonware!
Haskell
20
star
11

cv

My CV
TeX
19
star
12

minifu

A tutorial on writing a concurrency testing tool in Haskell
Haskell
13
star
13

bible

The King James Bible, typeset with LaTeX
TeX
12
star
14

irc-conduit

This project is essentially abandonware!
Haskell
11
star
15

yukibot

An IRC bot, and associated libraries, for the ##compsoc-uk-anime channel on Freenode
Haskell
10
star
16

meng-project

MEng project on verified garbage collection
TeX
8
star
17

quickie

A quick brainfuck compiler / JITed interpreter.
Haskell
6
star
18

bookmarks

A little search engine to manage my bookmarks
Python
5
star
19

memo.barrucadu.co.uk

My memos
Haskell
5
star
20

irc-ctcp

This project is essentially abandonware!
Haskell
4
star
21

coco

The Concurrency Commentator; giving you cheap remarks about concurrent programs.
Haskell
4
star
22

cabal-info

Read information from cabal files.
Haskell
4
star
23

search-party

A library for parallel, non-deterministic, search.
Haskell
4
star
24

pusher-ws

Implementation of the Pusher WebSocket protocol in Haskell
Haskell
3
star
25

aoc

Advent of Code
Haskell
3
star
26

bfo

Optimising brainfuck interpreter.
Rust
3
star
27

quantified-self-scripts

Grabbing data about me and pushing it into a dashboard
Python
3
star
28

barrucadu.co.uk

My personal website
HTML
2
star
29

prometheus-speedtest-exporter

Python
2
star
30

prometheus-awair-exporter

Go
2
star
31

barrucadu.dev

2
star
32

both

This project is essentially abandonware!
Haskell
2
star
33

phd

I have no idea what I'm doing
TeX
2
star
34

monad-monitor

Haskell
2
star
35

alphagov-backend.hs

Drop-in replacements for GOV.UK backend services, written in Haskell using servant.
Haskell
1
star
36

rogue-mayor

A town management game I'll probably never finish.
Rust
1
star
37

lambdamoo

C
1
star
38

king-james-programming

Markov chain text generator, as used for KingJamesProgramming (post-2024)
Shell
1
star
39

sat

Rust
1
star
40

packdeps-github

Open issues on GitHub about outdated dependencies automatically
Haskell
1
star
41

govuk-rota-generators

Generates rotas for GOV.UK teams.
Python
1
star
42

sed-as-a-service

An innovative solution to turn CPU-bound sed invocations into IO-bound network requests
Java
1
star