Container port forwarding doesn't work when using vpn

On my home server, I’m trying to set up a container to use OpenVPN for external networking. I also need to access some services running in this container from internal network, so I want to forward those ports to the host.

Network setup I’m trying to achieve (slightly simplified, actually I want to forward multiple ports):

desktop
ip 192.168.1.10

nix-host:
eno1 ip 192.168.1.20
ve-container ip 192.168.10.1
port forward port 8000 to 192.168.10.2:8000

container:
eth0 ip 192.168.10.2
tun0 ip xxx.xxx.xxx.xxx (whatever VPN ip)

The config I’m currently using

  networking.nat = {
    enable = true;
    externalInterface = "eno1";
    internalInterfaces = ["ve-container"];
  };

  networking.firewall.allowedTCPPorts = [ 8000 ];

  containers.container = {
    ephemeral = true;
    autoStart = true;
    enableTun = true;
    privateNetwork = true;
    hostAddress = "192.168.10.1";
    localAddress = "192.168.10.2";

    forwardPorts = [
        { protocol = "tcp"; hostPort = 8000; containerPort = 8000; }
      ];
    config = {
      networking.defaultGateway.address = "192.168.10.1";
      networking.nameservers = [ "8.8.8.8" ];
      networking.firewall.interfaces = {
        "eth0".allowedTCPPorts = [ 8000 ];
       };
       networking.useDHCP = false;
 
       # openvpn config
       services.openvpn.servers = {
         myVPN = {
             # ...
          }; 
        };
     };
  };
}

What works

  • VPN, verified by doing curl ifconfig.me in the container.
  • Connections from nix-host to container with port 8000, verified with nc (and other software)

What doesn’t work

  • Connections from desktop to nix-host:8000

Weird stuff

  • If I disable the VPN, port forwarding works as expected.

What I’ve tried

  • Putting the port forward in networking.nat.forwardPorts instead of containers.container.forwardPorts. This also only works when VPN is not enabled.
  • Creating a bridge interface to give the container its own IP in host’s network. I wasn’t able to make this work even without VPN yet though.

Any ideas for what to try next? Is there some detail or quirk I’m missing?

Looks like I solved it. Posting here in hopes that it will be helpful to others:

I needed to add a route in the container so that connections from my desktop were routed back properly. I just needed to add this to the container config:

networking.interfaces."eth0".ipv4.routes = [
  {
    address = "192.168.1.0";
    prefixLength = 24;
    via = "192.168.10.1";
   }
];