Why isn’t HTTP(S) port forwarding working?

i’m trying to use the VSCode swift extension in a remote dev container. i used to have these lines in my dockerfile, which would remap ports 8080 and 8443 to the normal HTTP/HTTPS ports:

RUN echo 'iptables -t nat -A PREROUTING -p tcp --dport  80 -j REDIRECT --to-port 8080' >> .bashrc
RUN echo 'iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443' >> .bashrc

ENTRYPOINT /bin/bash --init-file .bashrc

but this doesn’t work anymore because i have no idea how to get VSCode to start the container with --cap-add=NET_ADMIN.

i also tried forwarding the ports directly with "forwardPorts": [80, 443] in devcontainer.json, but this did not work either, because VSCode refuses to forward privileged ports.

i also tried:

    "portsAttributes": 
    {
      "443": 
      {
        "label": "https",
        "elevateIfNeeded": true,
        "requireLocalPort": true
      }
    }

which had no effect.

You can use runArgs in your devcontainer as documented in the reference to add the capability.

1 Like

this enables the redirection from inside the container, but it doesn’t allow connections on port 80 from outside the container

1 Like

Sorry, let's step back: what problem are you trying to solve? Your above iptables rules were being run inside the container so you can listen on port 80 and port 443 publicly. Is that the intention here? Or are you trying to connect to port 80 and 443 outside the container and have that traffic end up inside the container at some other port?

1 Like

on the cloud machine, the application listens on ports 8080 and 8443, so that it does not need to run on root. since 8080 and 8443 are not the normal HTTP(S) ports, the cloud machine has a PREROUTING rule to remap them to the proper ports. the docker image contains an identical PREROUTING rule in order to replicate this environment.
runArgs would enable the remapping inside the container. but it would not actually expose the destination ports (80 and 443) such that they can be accessed from outside the container.

Did you run the container with -p 80:80 ?

Or maybe it ought to be -p 80:8080 ...

Right, so you have the same problem here: to expose ports 80 and 443 outside the container also requires running with root privilege. I believe Visual Studio is driving docker, so it should in principle be possible to do the equivalent of what @hacksaw proposes, with -p 80:80.

1 Like

i got it working, thanks!

1 Like

The workaround
From Dear Linux, Privileged Ports Must Die – Aral Balkan
On modern Linux systems, you can configure privileged ports using sysctl:
sudo sysctl -w net.ipv4.ip_unprivileged_port_start=80
However, that setting does not survive a reboot.
You can also configure the setting in a persistent way using a configuration file. e.g., by creating a file called /etc/sysctl.d/99-reduce-unprivileged-port-start-to-80.conf with the following content:

net.ipv4.ip_unprivileged_port_start=80

1 Like