Skip to content

2. Installation, configuration and usage

unrooted edited this page Mar 22, 2023 · 2 revisions

Installation and usage

Note: all commands mentioned here should be run as root

Imperative

Note: some features of this container can be limited if you go imperative way.

nixos-container create --flake github:redcode-labs/rednix#<arch> rednix

Where <arch> is one of {aarch64,x86_64}-{linux,darwin}.

That will create a container, but it won't start it. To start the container, run:

nixos-container start rednix

To check the status of it, do:

systemctl status container@rednix

If it started, you can login:

nixos-container root-login rednix

Declarative

As mentioned earlier, this container can be added to your system config. To do this, you have to add RedNix as an input to your system flake, then include container in your config like this:

# system configuration
{ config, pkgs, inputs, ... }: {
  imports = [ inputs.rednix.container ];
}

When you run nixos-rebuild switch, your container will be built.

Furthermore, if the container was running, it will be updated without rebooting.

You can autostart it as well, if you add the following to your system config:

containers.rednix.autoStart = true;

Configuration

This container can be configured to your needs. Whether you just want less packages or more fancy things, such as port forwarding.

Networking

By default, next free address in 10.233.0.0/16 subnet will be container's IP. You can edit this, doing, for instance:

nixos-container create --flake github:redcode-labs/rednix#<arch> rednix --local-address 10.235.1.2 --host-address 10.235.1.1

If you create a container using nixos-container create, it will get its own private IPv4 in the range mentioned before.

To check container's IPv4, do:

nixos-container show-ip rednix

The network interface inside the container is called eth0, and the matching interface on host is called ve-rednix. It can perform arbitraty network configuration, for example, setting up firewall rules, without affecting the host.

If you need to talk to the outside network with RedNix, you can do so with Network Address Translation rules aka NAT. RedNix comes with this pre-configured like this:

networking = {
  nat = {
    enable = true;
    internalInterfaces = [ "ve-rednix" ];
    externalInterface = "eth0";
  };
};

Little notes:

  • eth0 should be replaced with the desired external interface name.

  • ve-+ will match all containers' interfaces.

  • If you're using Network Manager, prevent it from managing container interfaces:

networking.networkmanager.unmanaged = [ "interface-name:ve-*" ];

Now, time for the declarative way.

RedNix comes with pre-configured IP addresses as examples in its configuration.nix file:

privateNetwork = true;
hostAddress = "192.168.100.2";
localAddress = "192.168.100.11";

You can also do port forwarding inside the container. This can be achieved by doing:

forwardPorts = [
  {
    containerPort = 22;
    hostPort = 2222;
    protocol = "tcp";
  }
  {
    containerPort = 80;
    hostPort = 8080;
    protocol = "tcp";
  }
];

As you can see, RedNix comes with a little preloaded config there.

Furthermore, you can change the protocol used to forward ports.

If you're going the declarative way, you just need to edit the lines mentioned above and you'll be fine. Remember to nixos-rebuild switch in order to apply changes made to the container's configuration.

Note: if you're going the imperative way, container will share the network namespace of the host. Given that, they can listen on priviliged ports. But they can NOT change the network config.

Lines mentioned above will give the container a private virtual Ethernet interface with address 192.168.100.11, which is hooked up to a virtual Ethernet interface on the host with IP address 192.168.100.10.

Updating

You can just rebuild your host system as following:

nixos-rebuild switch

But you can as well run nixos-rebuild switch inside the container.

You can also edit configuration found under /var/lib/container/rednix/etc/nixos directory and then perform:

nixos-container update rednix

Which will build and activate the new config.

Usage

You can start/stop a container imperatively using:

nixos-container start/stop rednix

If you want to start/stop a declarative container, do:

systemctl start/stop container@rednix

In order to disable the declarative container, remove its part from your system config and nixos-rebuild switch. This will delete the root directory of RedNix from /var/lib/containers directory.

Containers, done both imperatively and declaratively, can be destroyed imperatively:

nixos-container destroy rednix

Troubleshooting

You may encounter that the package is marked as broken or just isn't updated in nixpkgs yet. You can face errors as the one below:

error: builder for '/nix/store/ql7091k2bb5g7y7rbwlfdddrh3i8vkm1-python3.10-json-stream-rs-tokenizer-0.4.13.drv' failed with exit code 1;

In such case, you need to run the following, but replace your .#devShells with the package group you want to build, and nixpkgs#python3Packages.json-stream-rs-tokenizer with the package in question:

nix why-depends --derivation .#devShells.x86_64-linux.default "nixpkgs#python3Packages.json-stream-rs-tokenizer"

Which would result in something like that:

/nix/store/hi964b4zc7gyiv5ldxf9bybyrqfia7r1-default.drv
└───/nix/store/qj7scgsfzq3wz7lsvy9ldd09xlzp4m96-mitmproxy2swagger-0.8.2.drv
    └───/nix/store/n2vf9y1fdxm43g601gh24k1hxcjy7hzb-python3.10-json-stream-2.2.0.drv
        └───/nix/store/ql7091k2bb5g7y7rbwlfdddrh3i8vkm1-python3.10-json-stream-rs-tokenizer-0.4.13.d
rg "mitmproxy2"
packages.nix
578:      mitmproxy2swagger

All done for now - just comment out the package causing errors and rebuild.