Nix + NixOS, magic of reproducibility

A quick guide how to make your system easily reproducible with the magic of Nix and NixOS

*

19 Apr 2021

unrooted

Introduction

You might be a user of a normal GNU/Linux or Linux distro as of right now, and you might come across an idea behind Nix and NixOS. I’d love to spread the word about it, because it can be quite useful and fast way to make your OS reproducible in a few little steps.

Nix? NixOS? What the f#ck?

If you haven’t heard about Nix and NixOS you probably live in a cave or live a healthy life without pursing after every new techie thing that comes out every few years. tl;dr = Nix is both package manager and language to describe packages for that manager, you get reproducible builds, cross-distro compatibility and other cool sh#t. Also, it’s bigger than AUR (just mentioning, you btwOS fags). Nix is almost pure functional language with dynamic typing specialized in building packages. If you want to learn more, there’s a cool blog post on Serokell’s website here

Since Red Code Labs is an Offensive Security Software House, I’ll be mentioning the security topic, and it’s relation to NixOS quite a lot in this post.

Where to start?

Well, first things first, you should grab an .iso from NixOS website here

You should be able to follow instructions on NixOS’ Wiki and be able to install this, but please, edit your configs, remember to do that. Please.

Configs, emmm, what?

NixOS is configured with the magic of config files. In your basic setup, your configuration.nix should be your main file, where you set up system-wide stuff (display manager, desktop environment and sh#t like that). But, you can grow that to the higher levels.

Basically, once you write a config, you can keep it for the rest of your life, once you have NixOS’ .iso file, you just download your config, tell NixOS which configs to use for install/rebuild if the NixOS is already installed and voilà! You have all your beloved apps and all your sh#t.

Furthermore, you can start using home-manager, which is quite cool (tl;dr it manages your home directory as the name implies). You can use it to manage your configs for WMs and other sh#t you use without messing with system configs, so they can stay quite lightweight without useless bullsh#t.

Why should I choose NixOS?

Well, it’s your choice, I mean, some skids and hax00rs already have their shitty lovely Kali Linux pretty setup, so why should you try NixOS instead? Well, because once you have your configs, other hax00rs can easily replicate your stuff on their local machines, without waiting for their package manager to finish installing stuff one after another. It’s just quite handy thing, which you might not notice now, but imagine that you’re running a company. You write one config and every one of your employee gets the same things and quite easily, just running one command. Nothing more. That’s all. And now imagine you, screwing something up with your partitions or something, such config can save your ass (it did for me lmfao).

What tools for hax00rs are currently available on NixOS/in nixpkgs?

Quite a lot to be honest, I mean, it’s not BlackArch repo, but it’s still growing. If you wonder which packages are available and which are not, check Are We Hackers Yet website, which tells you about current state of different Kali Linux packages and their availbility for Nix/NixOS.

Ok, but I don’t want to leave my lovely Kali/Parrot/BlackArch/[insert another sh#tty distro ‘for pentesters], then what?

Well, you can use Nix as a package manager standalone. You lose system configurations, but you don’t loose user configurations. You can still use home manager, and you can still use most of the nixpkgs (to be honest, you can try using even NixOS build tools, it’s doable, you just change your Nixpkgs channel).

Given that, imagine a distro where you can have your user-land configured in declarative and functional way with Nix, using Nixpkgs and even configuring your whole system in declarative and functional way. For me (functional programming fetishist), it’s like a wet dream. Tho, NixOS can have its downsides for you. For example, not all your Kali Linux packages are available just yet, so you’d either have to wait till someone makes Nix expressions for your fav. tools or you write Nix expressions or your own. It’s good to give back to community, I always liked people who do that. I’d try myself, but I’m waaaay too stupid to do so at the time of writing this shitpost.

Oh, and I forgot to mention, NixOS does have systemd, if that’s your thing, just mentioning. It does have pros and cons, it’s just a personal preference, but with NixOS, you’ll be forced to systemd (there are no other init-system options available, and afaik, SLNOS - Suckless NixOS project is dead, so, just keep that in mind). BUT, Nix as a standalone package manager and home manager sh#t and even flakes will work perfectly fine on distros with other init system (I do that on Artix hijacked by Bedrock, it works perfectly fine).

How can I quickly write a config for my system?

Basically if you followed steps on NixOS’ Wiki, you should have already generated config in /etc/nixos, but you’d want to edit it. Given so, your configuration.nix can look like:

{ config, pkgs, ... }:

{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
      # Include the package list.
      ./packages.nix
    ];

  # Use the systemd-boot EFI boot loader.
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  # Hardware
  hardware = {
    cpu.intel.updateMicrocode = true;
    enableRedistributableFirmware = true;
    pulseaudio.enable = true;
    pulseaudio.package = pkgs.pulseaudioFull;
    bluetooth.enable = true;
    opengl.enable = true;
    opengl.driSupport = true;
  };

  # Networking
  networking = { 
    hostName = "NaughtyOne";
    networkmanager.enable = true; 
    firewall.enable = true;
    firewall.allowPing = true;
    # firewall.allowedUDPPorts = [];
    # firewall.allowedTCPPorts = [];
  };

  # Timezone
  time.timeZone = "Europe/Warsaw";

  # Network Proxy
  # networking.proxy.default = "http://user:password@proxy:port/";
  # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";

  # Locales
  i18n.defaultLocale = "en_US.UTF-8";
  console = {
    font = "Lat2-Terminus16";
    keyMap = "pl";
  };

  # X config
  services.xserver = {
    enable = true;
    layout = "pl";
    libinput.enable = true;
    videoDrivers = [ "modesetting"  ];
    displayManager.gdm.enable = true;
    desktopManager.gnome3.enable = true;
  };

  # CUPS
  services.printing.enable = true;

  # Sound
  sound.enable = true;

  # User accounts
  users.users.unrooted = {
    isNormalUser = true;
    home = "/home/unrooted";
    description = "Konrad Unrooted";
    extraGroups = [ "wheel" "networkmanager" ];
  };

  # Sudo
  security.sudo = {
    enable = true;
    wheelNeedsPassword = true;
  };

  # Time
  services.timesyncd = {
    enable = true;
    servers = [ "pl.pool.ntp.org"  ];
  };

  # Virtualization/other OS's support
  virtualisation.docker = {
    enable = true;
  };

  # OpenSSH daemon
  # services.openssh.enable = true;

  system.stateVersion = "21.05";

}

Which, as you can see, is quite big. But well, you get Docker, Gnome, some enabled services and it’s quite easy to read and understand. I’ve left some things commented out if you don’t want to use them.

As you can see, I also import packages.nix, I do that to make system config more of a system config, than a config and shitload of packages.

For example, quite simple but yet enough packages.nix can look like:

{ pkgs, ... }:
{
  environment.systemPackages = with pkgs; [
    # Basic CLI
    bash
    git
    wget
    zip
    unzip
    htop
    coreutils
    killall
    usbutils
    ripgrep
    ripgrep-all

    # Terminal emulators
    alacritty

    # Text editors
    vim

    # File managers
    ranger

    # Browsers
    chromium
  ];
}

As you can see, it’s quite simple, but enough for the start in my opinion.

But where are those fancy tools you’re mentioning man?

I’ve mentioned a website where you can check the status of different security-related packages from Kali and their availbility on NixOS, if you want to grab one of it, just put it in your packages.nix file and you’d be fine. To search for more exact package name, you should check out this. But check the proper channel for your Nix/NixOS install. In this post I’ve used the latest unstable version 21.05, but you can use a stable version of NixOS which is 20.09, it’s fine as well, but there are fewer packages on that channel, keep that in mind.

Ok, ok, and those NixOS fancy things like home-manager?

There’s quite a good guide to home-manager on its repo, you should be fine with instructions from there.

What if I get stuck somewhere?

Well, we have subreddit, Matrix, IRC, Discord, we’re everywhere, and there are plenty of people there who can always help you. Thanks to them, I got into Nix and NixOS world in the first place.

Matrix: #nixos:matrix.org and #nix:matrix.org IRC: https://vector.im/beta/#/room/#freenode_#nixos:matrix.org Discord: https://discord.gg/VSkbp5MwWg FP Slack: https://functionalprogramming.slack.com

What else?

You can always take inspiration from my dotfiles, which you can find on my repo on Github. Tho keep that in mind that I use flakes and home manager and other cool stuff which NixOS offers.

As you might have seen, we already have one Nixerized tool, and I’m looking forward to Nixerize even more of them in the near future (read: as soon as I’m good enough to write good Nix expressions to pack our stuff around it).

Well, have fun fellow reader. Nix and NixOS might be taking the tech world to an awesome journey during next years. I see more and more of my friends switching over to NixOS or at least using Nix.