Using container environment for port forward config

Port forwarding is a bit of a pariah in the LXD world. Automating its management is left to third party scripts and services that use iptables, unless this has changed and I can’t find the documentation on changes. Some scripts allow you to populate the port config in a YAML file or similar. I’m considering using the containers environment config.

Let’s say I write a service that runs and monitors for currently running containers. We’ll call it open_ports. If open_ports sees a container running it can query a container environment:
lxc config get foo_container environment.PUBLISHED_PORTS

open_ports will then attempt to use iptables to create a forward based on the contents of the PUBLISHED_PORTS environment variable. This would allow my preferred port forwards to follow the container rather than the host config. Provided of course that all my hosts have open_ports running.

For the PUBLISHED_PORTS format, I considered one similar to docker and its publish argument:
<host port1>:<container port1>/<protocol1>,<host port2>:<container port2>/protocol2>
e.g.
80:8000/tcp,443:8443/tcp

The port specified could also be a port range and protocol would default to TCP unless otherwise specified.

I’m mainly concerned about what security risks this might open up. Any thoughts from the community?

1 Like

Not sure why you’d use environment.PUBLISHED_PORTS rather than user.PUBLISHED_PORTS.
environment.* only really makes sense if you need it exported as environment variables inside the container, but it doesn’t sound like you really need to here.

In any case, the container can’t modify any of those config, only a LXD admin can, so it should be perfectly safe to use this as trusted configuration.

That’s probably because of my user namespace ignorance at the time :slight_smile: I’m still a little green with LXD and its inner workings. Considering your answer, the only advantage to using environment, would be so an admin with only access to the container could see what port forwards they are configured for. In my use case, I don’t need that. So, I’ll be using the user namespace. Thanks!

Root in the container can also query the user.* keys through the /dev/lxd/sock interface, so if that somehow ends up being useful to them, they’ll still be able to do so (it’s a read-only interface).

Thanks again for the info. I’ve changed my mind and will be using something like user.port_forwards. I’ve also decided to go with a hash to store the data instead of the command line docker publish format. A hash seems to be more LXD’y :slight_smile: