How to make nixos container visible to the external network

3.2k views Asked by At

I'd like to have a nixos container that is visible to the outside network. I'd like to setup a static IP for that container that some other laptop on my network at home can ssh into the container. The container should be accessible to more than just the host it resides on. So lets label these computers. (A) is the nixos host. (B) is the container residing on (A). And (C) is a third separate computer on the network that wants to access (B) over the network. If someone could provide the simplest configuration that should be added to the /etc/nixos/configuration.nix file to achieve this that would be tremendously appreciated.

                                 +-------------------+
+--------+                       |                   |
|        |                       |  +--------+     A |
|      C |                       |  |        |       |
|   +----------------------------------->  B |       |
|        |                       |  |        |       |
+--------+                       |  |        |       |
                                 |  +--------+       |
                                 |                   |
                                 |                   |
                                 +-------------------+

2

There are 2 answers

1
danbst On

There are several ways to do that, and all aren't NixOS specific here.

  1. Organize a VPN between machines and containers. For example, launch OpenVPN master on your host and OpenVPN clients in containers and other machines. You will get a subnet where you can access your containers by separate IPs. Unfortunately, this requires lots of configuration (I've done this before).
  2. Don't use separate virtual ethernet devices for containers. Then all containers will share host's port addresses and be equally accessible from outside. This requires port remapping for conflicting services though.
  3. Proxy desired ports from host to container (I did this using haproxy)
1
mickours On

To complete danbst answer, for the option 2 you can use the container option privateNetwork = false; to disable the network namespace. See container.nix code for details. With this option you will share the same IP address between the host and the container.

An other option is to forward port from the container to the host with ForwardPorts options.

A more generic way (that works with NixOps too) it to use the host networking.nat option, for example:

networking.nat = {
    enable=true;
    internalInterfaces=["ve-+"];
    externalInterface = "enp0s3";
    forwardPorts = [
      {destination = "mycontainerIP:80"; sourcePort = 80;}
    ];
  };