About me: My name is Solène Rapenne, pronouns she/her. I like learning and sharing knowledge. Hobbies: '(BSD OpenBSD Qubes OS Lisp cmdline gaming security QubesOS internet-stuff). I love percent and lambda characters. Qubes OS core team member, former OpenBSD developer solene@. No AI is involved in this blog.

Contact me: solene at dataswamp dot org or @solene@bsd.network (mastodon).

I'm a freelance OpenBSD, FreeBSD, Linux and Qubes OS consultant, this includes DevOps, DevSecOps, technical writing or documentation work. If you enjoy this blog, you can sponsor my open source work financially so I can write this blog and contribute to Free Software as my daily job.

My NixOS configuration

Written by Solène, on 21 December 2021.
Tags: #nixos #linux

Comments on Fediverse/Mastodon

Table of contents

1. Introduction §

Let me share my NixOS configuration file, the one in /etc/nixos/configuration.nix that describe what is installed on my Lenovo T470 laptop.

The base of NixOS is that you declare every user, services, network and system settings in a file, and finally it configures itself to match your expectations. You can also install global packages and per-user packages. It makes a system environment reproducible and reliable.

2. The file §

{ config, pkgs, ... }:

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

  # run garbage collector at 19h00 everyday
  # and remove stuff older than 60 days
  nix.gc.automatic = true;
  nix.gc.dates = "19:00";
  nix.gc.persistent = true;
  nix.gc.options = "--delete-older-than 60d";

  # clean /tmp at boot
  boot.cleanTmpDir = true;

  # latest kernel
  boot.kernelPackages = pkgs.linuxPackages_latest;

  # sync disk when buffer reach 6% of memory
  boot.kernel.sysctl = {
      "vm.dirty_ratio" = 6;
  };

  # allow non free stuff
  nixpkgs.config.allowUnfree = true;

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

  networking.hostName = "t470";
  time.timeZone = "Europe/Paris";
  networking.networkmanager.enable = true;

  # wireguard VPN
  networking.wireguard.interfaces = {
      wg0 = {
              ips = [ "192.168.5.1/24" ];
              listenPort = 1234;
              privateKeyFile = "/root/wg-private";
              peers = [
              { # server
               publicKey = "MY PUB KEY";
               endpoint = "SERVER:PORT";
               allowedIPs = [ "192.168.5.0/24" ];
              }];
      };
  };

  # firejail firefox by default
  programs.firejail.wrappedBinaries = {
      firefox = {
          executable = "${pkgs.lib.getBin pkgs.firefox}/bin/firefox";
          profile = "${pkgs.firejail}/etc/firejail/firefox.profile";
      };
  };


  # azerty keyboard <3
  i18n.defaultLocale = "fr_FR.UTF-8";
  console = {
  #   font = "Lat2-Terminus16";
    keyMap = "fr";
  };

  # clean logs older than 2d
  services.cron.systemCronJobs = [
      "0 20 * * * root journalctl --vacuum-time=2d"
  ];

  # nvidia prime offload rendering for eGPU
  hardware.nvidia.modesetting.enable = true;
  hardware.nvidia.prime.sync.allowExternalGpu = true;
  hardware.nvidia.prime.offload.enable = true;
  hardware.nvidia.prime.nvidiaBusId = "PCI:10:0:0";
  hardware.nvidia.prime.intelBusId = "PCI:0:2:0";
  services.xserver.videoDrivers = ["nvidia" ];

  # programs
  programs.steam.enable = true;
  programs.firejail.enable = true;
  programs.fish.enable = true;
  programs.gamemode.enable = true;
  programs.ssh.startAgent = true;

  # services
  services.acpid.enable = true;
  services.thermald.enable = true;
  services.fwupd.enable = true;
  services.vnstat.enable = true;

  # Enable the X11 windowing system.
  services.xserver.enable = true;
  services.xserver.displayManager.sddm.enable = true;
  services.xserver.desktopManager.plasma5.enable = true;
  services.xserver.desktopManager.xfce.enable = false;
  services.xserver.desktopManager.gnome.enable = false;

  # Configure keymap in X11
  services.xserver.layout = "fr";
  services.xserver.xkbOptions = "eurosign:e";

  # Enable sound.
  sound.enable = true;
  hardware.pulseaudio.enable = true;

  # Enable touchpad support
  services.xserver.libinput.enable = true;

  users.users.solene = {
     isNormalUser = true;
     shell = pkgs.fish;
     packages = with pkgs; [
        gajim audacity chromium dmd dtools
     	kate kdeltachat pavucontrol rclone rclone-browser
     	zim claws-mail mpv musikcube git-annex
     ];
     extraGroups = [ "wheel" "sudo" "networkmanager" ];
  };

  # my gaming users running steam/lutris/emulators
  users.users.gaming = {
     isNormalUser = true;
     shell = pkgs.fish;
     extraGroups = [ "networkmanager" "video" ];
     packages = with pkgs; [ lutris firefox ];
  };

  users.users.aria = {
     isNormalUser = true;
     shell = pkgs.fish;
     packages = with pkgs; [ aria2 ];
  };

  # global packages
  environment.systemPackages = with pkgs; [
      ncdu kakoune git rsync restic tmux fzf
  ];

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

  # Open ports in the firewall.
  networking.firewall.enable = true;
  networking.firewall.allowedTCPPorts = [ 22 ];
  networking.firewall.allowedUDPPorts = [ ];

  # user aria can only use tun0
  networking.firewall.extraCommands = "
iptables -A OUTPUT -o lo -m owner --uid-owner 1002 -j ACCEPT
iptables -A OUTPUT -o tun0 -m owner --uid-owner 1002 -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner 1002 -j REJECT
  ";

  # This value determines the NixOS release from which the default
  # settings for stateful data, like file locations and database versions
  # on your system were taken. It‘s perfectly fine and recommended to leave
  # this value at the release version of the first install of this system.
  # Before changing this value read the documentation for this option
  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
  system.stateVersion = "21.11"; # Did you read the comment?

}