diff --git a/config.toml b/config.toml index 6e412f6..e31f593 100644 --- a/config.toml +++ b/config.toml @@ -9,20 +9,6 @@ pygmentsUseClasses = true dark = "auto" highlight = true -[menu] - [[menu.main]] - identifier = "👋" - name = "👋" - title = "👋" - url = "/info/" - weight = 20 - [[menu.main]] - identifier = "🔎" - name = "🔎" - title = "🔎" - url = "/search/" - weight = 20 - [permalinks] posts = "/:title/" diff --git a/content/posts/restic-nixos-hetzner.md b/content/posts/restic-nixos-hetzner.md index 94cb92e..cf72e70 100644 --- a/content/posts/restic-nixos-hetzner.md +++ b/content/posts/restic-nixos-hetzner.md @@ -4,17 +4,24 @@ date: 2026-02-16 tags: - nixos - restic -draft: true +draft: false --- I'm writing this so I can hopefully remember what I did in six months. As hard as you try to eliminate all state from your computing life with nixos, the fact remains that you can't get rid of all of it. For example, I run forgejo on my VPS. -Now I have my config which means I could set up a forgejo instance just how I like it if everything went to pot. +I have my config which means I could set up a forgejo instance just how I like it if everything went to pot. But that wouldn't bring back any of the repos I had there previously. -This is the method I cooked up for backing up some of those important bits and bob on my VPS. +This is the method I cooked up for backing up some of those important bits and bob from my VPS. + +### Restic + +[Restic](https://restic.net/) is a project which facilitates the encrypted, deduplicated backing up of your data to SFTP, S3, and various other cloud providers. +My backup target is a hetzner storage box which is compatible with SFTP so that's the route I chose. +After browsing the [available nixos options](https://search.nixos.org/options?channel=unstable&query=restic), I came up with this little config. +It sets up a restic job to be run daily by root backing up some of `/var/lib` over sftp to the hetzner storage box (I've put in placeholder values). ```nix { config, ... }: { @@ -24,9 +31,10 @@ This is the method I cooked up for backing up some of those important bits and b user = "root"; passwordFile = "/etc/nixos/secrets/restic"; paths = [ - "${config.services.forgejo.stateDir}" + "/var/lib/important" + "/var/lib/stuff" ]; - repository = "sftp:user@storagebox:/remotelab"; + repository = "sftp:user@storagebox:/payload"; extraOptions = [ "sftp.command='ssh user@storagebox -i /root/.ssh/id_ed25519 -s sftp'" ]; @@ -38,3 +46,48 @@ This is the method I cooked up for backing up some of those important bits and b }; } ``` + +### Security concerns + +The eagle-eyed among you will have noticed some GAPING security flaws in this setup. +Firstly, my root user needs passwordless ssh access to the storage box. +Secondly, the password used to encrypt the backup is sitting in plaintext on my server at `/etc/nixos/secrets/restic`. + +The first issue seems a little tricky to solve. +As far as I know there's no way round the passwordless detail if you want an automated backup. +It would be better to run the backup as a less privileged user that still has permissions to the stuff you want to backup. +I'm not sure how to do that though and the whole thing seemed sufficiently complicated alraedy for me. +I found something about it in the docs [here](https://restic.readthedocs.io/en/stable/080_examples.html#full-backup-without-root) + +The second issue is extremely solvable with something like [sops-nix](https://github.com/Mic92/sops-nix) which I really do intend to setup at some point I promise! + +### Bonus: notifications + +Seeing as these backups are going to be chugging away in the background in the middle of the night, it would be useful to be notified if they went wrong. +The nixos service sets up a systemd service for the restic job. +We can piggyback off this one with another systemd service which runs when the restic service fails. +This new service simply curls my [ntfy](https://ntfy.sh) server with an uh oh pay attention message. + +```nix + systemd.services.restic-backups-vps-storage-box = { + wantedBy = [ "multi-user.target" ]; + unitConfig = { + OnFailure = "restic-backups-failure-notify.service"; + }; + }; + + systemd.services.restic-backups-failure-notify = { + description = "Notify on restic backup failure"; + serviceConfig = { + Type = "oneshot"; + ExecStart = + "${pkgs.curl}/bin/curl -s -X POST https://ntfy.sh/restic-backups-topic " + + "-d 'Restic backup from VPS to storage box failed!' " + + "-H 'Title: Backup Failed' " + + "-H 'Priority: high' "; + User = "root"; + }; + }; +``` + +Thanks for reading :) diff --git a/content/posts/wuthering-heights.md b/content/posts/wuthering-heights.md index 7ec911f..43964fb 100644 --- a/content/posts/wuthering-heights.md +++ b/content/posts/wuthering-heights.md @@ -19,7 +19,7 @@ It felt like a set not something the characters actually inahbited. Even when they were banging on the moors they didn't seem to get muddy. This was a problem for me. - Fundamentally, once you got past the visual glitz and knowingly executed tropes it felt completely emotionally empty. -Given that it's a film about the enduring power of passionate undying love this was also a major problem. +Given that this version seems to be about the enduring power of passionate undying love this was also a major problem. ### Things that intrigued me diff --git a/content/posts/zen-twitch-viewing-script.md b/content/posts/zen-twitch-viewing-script.md index 5b355da..51e0217 100644 --- a/content/posts/zen-twitch-viewing-script.md +++ b/content/posts/zen-twitch-viewing-script.md @@ -1,7 +1,9 @@ --- title: Handy script for a more zen twitch experience date: 2025-08-13 -tags: bash, script, twitch +tags: + - bash + - twitch draft: false --- diff --git a/layouts/404.html b/layouts/404.html index 326ef8b..68e9847 100644 --- a/layouts/404.html +++ b/layouts/404.html @@ -1 +1,5 @@ -
The page you're looking for doesn't exist.
+ +{{ end }} diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index a2f1f55..d1bae5b 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -4,6 +4,6 @@ {{- partial "header.html" . -}}