NixOS

1058 readers
1 users here now

NixOS is a Linux distribution built on top of the Nix package manager. Its declarative configuration allows reliable system upgrades via several official channels of stability and size.

This community discusses NixOS, Nix, and everything related.

founded 2 years ago
MODERATORS
1
 
 

We present a real-world use-case of NixOS to manage an highly distributed fleet of servers & VMs in low-resource settings used for mission critical applications. After a brief overview of who MSF is and what we do, we'll dive into the technical details of how we manage our fleet with NixOS and the unique strengths that NixOS brings to the table.

2
 
 

Hi everyone I'm currently in the process to move one of my RPI4s from RaspberryOS to NixOS and I'm struggling to setup one of the services.

On the RPI I have a python script that is creating offsite backups via a Wireguard tunnel:

  • Open the wg tunnel
  • mount and encrypt the external disk on the offsite RPI
  • mount the source from my nas
  • start the restic-rest server container offsite
  • trigger the restic command to backup to the restic repo

allthough it's a bit overkill it works quite well for a few years now. Since most of the tasks are actually outsourced to systemd units those where quite easy to setup in nixOS. What I'm struggling is, how can I create a virtual python env to run the python script. All the guides I found for managing python dependencies are usually for development and use nix shell

My current workaround is, that I copy the script and requirements.txt from my script repo and create the venv manually. This does work, but I feel there is a better way, maybe the whole setup is already on the wrong pat as I tried to solve each hurdle separately?

Here's my current implementation of the remotebackup module (the wireguard and mount units are in different modules):

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

let configpath = builtins.toString inputs.infra-configs;
in
{
systemd.tmpfiles.settings = {
  "remotebackup" = {
    "/var/lib/remotebackup" = {

      d = {
        group = "root";
        user = "root";
        mode = "755";
      };
    };
    "/var/lib/remotebackup/assets" = {

      d = {
        group = "root";
        user = "root";
        mode = "755";
        };
      };

    };
  };

sops.secrets = {
  "restic/remotebackup/rest" = {};
  "restic/remotebackup/restic" = {};
};

sops.templates."remotebackup" = {
  content = ''
  {
    "rest" : "${config.sops.placeholder."restic/remotebackup/rest"}",
    "restic": "${config.sops.placeholder."restic/remotebackup/restic"}",
  }
  '';
  path = "/var/lib/remotebackup/assets/restic.cred";
  };


system.activationScripts.addPythonScript = lib.stringAfter ["var"] ''
    cp ${configpath}/scripts/remotebackup/script/restic_remotebackup.py /var/lib/remotebackup/restic_remotebackup.py
    cp ${configpath}/scripts/remotebackup/script/requirements.txt /var/lib/remotebackup/requirements.txt
    chmod 733 /var/lib/remotebackup/restic_remotebackup.py
    cp ${configpath}/scripts/remotebackup/script/assets/backup_paths.txt /var/lib/remotebackup/assets/backup_paths.txt
    '';

}

Also, on the RPI I'm triggering the script with cron, according to the wiki cron should be replaced by systemd.timers. Would you also suggest moving to systemd.timers

P.S.: If at all possible, I'd like to keep the script within my script repo...

3
4
 
 

Meaning, VMs with Xen and hardware virtualization support

The system VM/Qube for USBs is isolated, the Network VM/Qube is separate and isolated, the windowing system and OS housing the qubes is isolated....

And being able to configure all of those with Nix would be a wet dream come true

5
6
7
8
9
 
 
10
11
 
 
12
 
 
13
14
 
 

NixOS Facter aims to be an alternative to projects such as NixOS Hardware and nixos-generate-config. It solves the problem of bootstrapping NixOS configurations by deferring decisions about hardware and other aspects of the target platform to NixOS modules.

15
24
submitted 6 months ago* (last edited 6 months ago) by demesisx@infosec.pub to c/nixos@infosec.pub
 
 

cross-posted from: https://infosec.pub/post/15780978

Am I out of touch?

No, it's the forward-thinking generation of software engineers that want elegant, reliable, declarative systems that are wrong.

16
 
 

Had a lot of headaches the last week or two trying to optimize star citizen as well as fix a vulkan RHI bug which was affecting unreal engine games.

Apparently rolling release schedules (like NixOS23.05, 23.11, 24.05...) are better for servers since they're less prone to change, where as nightlies like for the unstable Branch are better for gaming since those latest drivers are likely the current ones for a newly released game

17
 
 

This idea is inspired by nixos-mailserver. It was so easy to spin up the mailserver after changing some DNS records and putting in some settings. I thought it might be a good idea to do the same for services that need public, decentralized infrastructure to support. Some ideas include

  • Tor relay, or exit node
  • Encrypted messaging nodes. It looks like SimpleX chat relies on SMP servers to relay communication
  • Crypto miners (I know, I know, but you understand how it fits the "public contribution" usecase)
  • Search engines like searxng (I currently use a public instance)
  • Libredirect services, like proxy clients for social media

Maybe federated services, but those require more than just the software running on the public internet. Those require moderation and long term maintenance. Ideally, the services in this config would be ephemeral.

Does this sound like a good idea? Would you spin one of these up on a $10 VPS? I understand that this is the NixOS community, not necessarily the privacy community, but I figured thered be overlap.

What other services do you think would be applicable?

18
 
 

Went through the pain of packaging a python project on Nixos. Here's some issues I hit, and how I got lucky resolving them. I feel the most reliable way of doing this in the future is to use docker and just imperatively build.

Here's how I got web drivers, AI dependencies, gpu dependencies, and an api dependency bundled together into an ephemeral shell for python development, on NixOS 23.11

  1. Enable Flakes

  2. Start with setting up poetry2nix

  3. Get the template flake by running nix flake init --template github:nix-community/poetry2nix

  4. in the flake.nix, sometimes changing projectDir = self to projectDir = ./. fixed some issues

  5. in your terminal, run nix develop . to build the poetry app with python packages described in pyproject.toml

  6. By default, just poetry and python latest should be installed. the dependencies for the project (which gets reflected in the pyproject.toml) are updated with poetry add, such as poetry add numpy selenium scikit-learn

  7. Exit out of the ephemeral shell from nix develop ., and rerun to have poetry2nix rebuild and link the newly declared packages

Poetry2nix has worked pretty well for the more obscure python packages, but failed in others. For example, sentence-transformers would depend on maturin, which would fail to link setuptools. If poetry doesn't work, you can try and get the package from nixpkgs, or specify sha256s from pypi.org

Here's an example of what I added to my flake.nix to get gpu acceleration, sentence-transfomers, firefox drivers for selenium, and other packages poetry failed to setup:

packages = [ pkgs.poetry pkgs.python311Packages.sentence-transformers pkgs.firefox 
            pkgs.python311Packages.openai pkgs.python311Packages.yt-dlp pkgs.python311Packages.pyopencl
];

was added to this flake.nix, as in,

{
  description = "Application packaged using poetry2nix";

  inputs = {
    flake-utils.url = "github:numtide/flake-utils";
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    poetry2nix = {
      url = "github:nix-community/poetry2nix";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
  outputs = { self, nixpkgs, flake-utils, poetry2nix }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        # see https://github.com/nix-community/poetry2nix/tree/master#api for more functions and examples.
        pkgs = nixpkgs.legacyPackages.${system};
        inherit (poetry2nix.lib.mkPoetry2Nix { inherit pkgs; }) mkPoetryApplication;
      in
      {
        packages = {
          myapp = mkPoetryApplication {
            projectDir = ./.;
          };
          default = self.packages.${system}.myapp;
        };
        devShells.default = pkgs.mkShell {
          inputsFrom = [ self.packages.${system}.myapp ];
          packages = [ pkgs.poetry pkgs.python311Packages.sentence-transformers pkgs.firefox 
            pkgs.python311Packages.openai pkgs.python311Packages.yt-dlp pkgs.python311Packages.pyopencl
          ];
          nativeBuildInputs = [(
            pkgs.python311Packages.buildPythonPackage rec {
              pname = "serpapi";
              version = "0.1.5";
              src = pkgs.python311Packages.fetchPypi {
                inherit pname version;
                sha256 = "b9707ed54750fdd2f62dc3a17c6a3fb7fa421dc37902fd65b2263c0ac765a1a5";
              };
            }
          )];
        };
      });
}

There was one package (serpapi), which was not in nixpkgs, and poetry failed as well. Adding this to native build inputs got serpapi installed

nativeBuildInputs = [(
            pkgs.python311Packages.buildPythonPackage rec {
              pname = "serpapi";
              version = "0.1.5";
              src = pkgs.python311Packages.fetchPypi {
                inherit pname version;
                sha256 = "b9707ed54750fdd2f62dc3a17c6a3fb7fa421dc37902fd65b2263c0ac765a1a5";
              };
            }
)];

All in all, it works, and I have no doubt I've made a reproducible environment. What attracts me is I've never had an easier time setting up cuda/cudnn/tensorrt/... system drivers have been near effortless, and much faster to setup than on debian. Tools like sentence-transformers and torch default to packages which leverage the GPU.

What pushes me away, is I've had failures in each of the three methods for specifying package dependencies, even though one of the three eventually was the fix for integrating the dependencies into my shell. For now, I'll stick with it, but it's hard for me to suggest to a team we use this in development

19
20
21
 
 

I made a post a while ago asking what you do when NixOS isn't cutting it. You need a package that isn't available as a flatpak/appimage or already in nixpkgs. You don't want to build from source, because it's either too difficult or too time consuming. One suggestion was containerization or virtual machines, but those seemed too cumbersome. Well, distrobox is the tool that fixes it.

Distrobox is a shell script that wraps over docker/podman to run a container of a distribution of your choice. But it does it behind a very high level API, and integrates the container environment seemlessly with your host environment. It is seriously as easy as this, if you need to install something with apt inside debian.

$ distrobox create -n my_debian --image debian:latest
$ distrobox enter my_debian

And bang, your in a debian container and it won't even feel like it. It automatically integrates your shell environment and maps your root directory inside the container (or something like that.) You seriously wouldn't know unless you neofetch. Best part is that since everything is in the nix store, every program in your environment should work, for the most part, inside this container. I've not noticed problems yet.

Tada! apt is available in this environment and you can install what you need. Then you can run it while inside the container. From the host machine, outside the container, you can run it directly too. Say you installed program X in debian:

$ distrobox enter my_debian -- X

And it will just run the command and send you back to the host machine.

In the case of docker, you can type docker ps and it will show you your debian image my_debian listed.

There's two more things I want to do to really polish this workflow. The first is to change my shell prompt so I know that I'm actually in debian without typing neofetch! Inside the box the variable CONTAINER_ID is set and the hostname is modified. I've adjusted my starship prompt to look like this when inside the box:

distrobox:my_debian ~ $

And lastly, I really want to blur the lines. If I install X in debian, I want to just call it directly from the host as X, not invoke my debian instance with distrobox enter.

When you type X and the program is missing, bash (and fish and zsh I'm sure) runs a hook that you can look at by typing

$ declare -p -f command_not_found_handle

By overriding this, you could first have it try the inside container if it can't find the application in the host container, like so.

command_not_found_handle () {
  distrobox enter my_debian -- $@
}

This is not a perfect solution, but I'm still experimenting with how to integrate this both seamlessly and also not accidentally run things inside debian and not realize it. If you have suggestions for how to improve handling calling commands from the outside environment, please share. Best case might just be adding aliases for programs explicitly. For example, `alias X=distrobox enter my_debian -- X.

Anyway, distrobox is the solution! This is one more barrier removed that was preventing me from moving my main computer over to NixOS. I'm so happy to have found this and wanted to share.

22
 
 

Features

UnixPorn at its core

PwNixOS places a strong emphasis on delivering a top-notch graphical experience by providing a visually appealing and productivity-focused interface.

Hacking Tools

PwNixOS offers a wide array of tools and utilities out of the box to support your hacking endeavors. From advanced network analysis and penetration testing tools to powerful scripting languages and development environments, PwNixOS equips you with the necessary arsenal to explore and manipulate computer systems to your heart's content.

Package Management with Nix

One of the standout features of NixOS is its unique package management system called Nix. With Nix, you can easily install, update, and manage software packages on your system. What makes Nix special is its ability to provide isolated and reproducible environments for each package, ensuring that software installations do not interfere with one another. This allows for painless experimentation and easy rollback to previous configurations.

Declarative Configuration

NixOS follows a declarative approach to system configuration. Instead of making changes directly to the system, you define the desired state of your system in a configuration file or flake (like this one). This configuration specifies all the packages, services, and settings you want, providing a clear and reproducible blueprint for your system. This declarative nature simplifies system administration, enables easy replication of configurations across multiple machines, and facilitates version control of your system setup.

Custom packages

This flake has custom hacking tools that are uploaded to the NUR. The purpose of these tools is to fill in the gaps that exist today in the official repositories and create a full arsenal of tools, with well-known tools such as BloodHound and lesser-known tools such as psudohash.