Linux

DIY Linux Router - Impermanence Storage

This is part of a multi-part series describing how to build your own Linux router.

In the part 1 of this series, the initial setup was installing NixOS on the Mac Mini as usual. We configured our partitions, and as we are doing everything using ZFS, we created our Datasets. But as our server will be connected directly to the internet, there are security measures I have to take to keep our server secure as possible and an optional step we can do as configuring the root filesystem as impermanent storage.

Hard Disk
Source:Deskdecode.com

Table of Contents

Impermanent storage

As standard, many Linux distributions follow what is called the POSIX Structure. meaning that there's a root filesystem identified by / path and there are expected folders on this path, being:

  • /bin - general commands.
  • /dev - as the devices path, like storage blocks, videocards and serial ports.
  • /etc - with configuration files managed by the system administrator.
  • /home - containing the home folder for users.
  • /lib - with libraries to be used by programs.
  • /var - containing configuration files managed by programs.
  • /sbin - Administrator commands.
  • /sys - Drivers and device paths.

However, NixOS does not follows the POSIX Structure. Instead, everything is stored at /nix as read-only and those standard paths are simply symbolic links to paths inside /nix for usability and compatibility.
The main paths for NixOS are:

  • /nix - Where NixOS is currently installed.
  • /etc/nixos - NixOS configuration files.
  • /var/lib/nixos - Runtime NixOS configuration.

TTo boot up the system, apart from the /nix path, everything can be mounted as temporary. Doing as is, it guarantees that every boot will be a clean installation and this is a good security measure.

Here I will configure the root filesystem as impermanent, only persisting what matters to have a properly working server with the intended services. Let's state what we want to persist.

  • NixOS Configuration /etc/nixos and /var/lib/nixos
  • SSH Keys /etc/ssh/keys*
  • Mountpoints on zdata storage pool, like home folders and Podman files.

Advantages

  • You have a clean installation on every reboot. If something goes wrong, simply rebooting will restore the system to its expected state.

Disavantages

  • You could lose some important settings needed for certain programs or services. Make sure to create a ZFS dataset or configuring this path on impermanence.nix to make sure that the intended path needed to be persisted will be persisted.
  • As the root filesystem and every path is stored as a temporary, there's an additional amount of RAM spent to store files that should be persisted to disk.

Setup

1. Create the impermanence.nix configuration file

Create the impermanent.nix configuration file as described on NixOS Wiki page

/etc/nixos/modules/impermanence.nix

{ config, pkgs, ... }:

let
  impermanence = builtins.fetchTarball "https://github.com/nix-community/impermanence/archive/master.tar.gz";
in
{
  imports = [ "${impermanence}/nixos.nix" ];

  environment.persistence."/nix/persist/system" = {
    hideMounts = true;
    directories = [
      "/var/lib/nixos"
    ];
    files = [
      "/etc/machine-id"
      "/etc/ssh/ssh_host_ed25519_key"
      "/etc/ssh/ssh_host_rsa_key"
      { file = "/etc/nix/id_rsa"; parentDirectory = { mode = "u=rwx,g=,o="; }; }
    ];
  };
}

2. Add the newly created file to configuration.nix

/etc/nixos/configuration.nix

{ config, lib, pkgs, ... }:

{
  imports =
    [ 
      ...
      ./modules/impermanence.nix
      ...
    ];
    ...
}

3. Set root mountpoint as tmpfs on hardware-configuration.nix file

Edit hardware-configuration.nix replacing the root filesystem setting from a ZFS dataset to tmpfs and remove any tmpfs mountpoints pointing to /tmp and /var/tmp. Here an example:

/etc/nixos/hardware-configuration.nix

{ config, lib, pkgs, modulesPath, ... }:

{
 ...
 fileSystems."/" =
   { device = "tmpfs";
     fsType = "tmpfs";
     options = [ "defaults" "size=2G" "mode=755" ];
 }; 
 fileSystems."/nix" =
   { device = "zroot/nix";
     fsType = "zfs";
   };

 fileSystems."/boot" =
   { device = "/dev/disk/by-uuid/EA49-B54F";
     fsType = "vfat";
     options = [ "fmask=0022" "dmask=0022" ];
   };

 swapDevices =
   [ { device = "/dev/disk/by-uuid/449dec38-ef32-44b1-8193-ea19dea4b324"; }
   ];
 ...
}

4. Rebuild the system

Make sure that you have a active internet connection before rebuilding.

nixos-rebuild switch

5. Reboot

Restart the computer and see if everything is working properly. Save something in the /, restart and see if the file vanishes after reboot.

Conclusion

This concludes this extra chapter about impermanent. It's a cool capability that NixOS offers, increasing the security and maintenance. If you choose to use it, ensure that all paths that need to be persisted are indeed persisted.

keywords: macmini • router • linux • nixos • pppoe • unifi • ubiquiti • apple • vlan • tl-sg108e

This article in other languages