0

[originally asked at Stack Overflow but put on hold there with the suggestion that I ask here.]

I have a web app, written in go, which accepts traffic on ports 80 and 443. It works fine if I:

  • copy the executable binary to a server running CoreOS
  • sudo setcap 'cap_net_bind_service=+eip' executable-name
  • invoke the program manually, as an unprivileged user

I am now trying to run it under rkt, in a container built with acbuild:

acbuild begin
acbuild set-name myapp
acbuild copy myapp /app/myapp
acbuild set-exec -- /app/myapp
acbuild set-working-directory /app
acbuild mount add etcssl /etc/ssl
acbuild mount add cacert /usr/share/ca-certificates
acbuild set-user 500
acbuild set-group 500
acbuild write --overwrite myapp.aci
acbuild end

...

sudo rkt run  ...  --net=host

This works fine if I have the app listen on high-numbered ports, but I have been unable to get it to work listening on ports 80 and 443.

I have tried:

  1. echo '{ "set": ["CAP_NET_BIND_SERVICE"] }' | acbuild isolator add "os/linux/capabilities-retain-set" -

    sudo rkt run ... --net=host

    This does not appear to have any effect, since ListenAndServeTLS returns:

    listen tcp :443: bind: permission denied

  2. Change the app to listen on 8480 and 8443.

    acbuild port add http tcp 8480

    acbuild port add https tcp 8443

    sudo rkt run ... --port=http:80 --port=https:443

    The app runs and does not report any errors but never sees any in-coming requests.

  3. Change the app to listen on 8480 and 8443.

    sudo iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 8480

    sudo iptables -A PREROUTING -t nat -p tcp --dport 443 -j REDIRECT --to-port 8443

    sudo rkt run ... --net=host

    The app runs and does not report any errors but never sees any in-coming requests.

    Note: I am not experienced with iptables, and I may very well be doing something incorrectly. iptables -nvL gives the same output before and after I run the above two commands, so I'm not sure they are actually doing anything.

  4. I tried running rkt under systemd with AmbientCapabilities=CAP_NET_BIND_SERVICE, but that also fails with bind: permission denied

  5. I also tried adding --caps-retain=CAP_NET_BIND_SERVICE to the rkt run command line, but that didn't help.

  6. If I remove the set-user and set-group acbuild lines, the app does work, but it runs as root, which negates one of the main purposes of running in a container - reducing privilege for the sake of security.

I'd appreciate any insight anyone can offer. Thanks.

EDIT: There has been a brief discussion of this in the rkt-dev group and there is a github issue tracking it. For my current purposes, I have found that systemd alone, without rkt or any other container runtime, provides sufficient protection, and I've switched to it, so I won't be following this issue any longer.

2
  • Try reading this. Ports below 1024 are privileged.
    – Tim
    May 5, 2017 at 1:59
  • Thanks, but I'd already seen that page and tried everything listed there, as detailed above. (I did not mention authbind, but my CoreOS installation doesn't have it, nor am I aware of an easy way to install it in CoreOS.) My problem is that I'm not able to make any of those solutions work with a program running inside a container under rkt. May 5, 2017 at 2:29

0

You must log in to answer this question.

Browse other questions tagged .