tilt icon indicating copy to clipboard operation
tilt copied to clipboard

Forwarding from privileged ports (< 1024) not possible without sudo

Open tamer-hassan opened this issue 5 years ago • 7 comments

The docs don't mention anything about port-forwarding from privileged ports on the host. That is, ports less than 1024... On MacOS, for example, I get error in Tilt logs that it could not forward from either ports 80 / 443 (http / https) , but with no clue as to why.. Of course, I figured I have to run tilt up with sudo, and now it works, but I'm afraid of side effects of that.

It could be possible to only elevate privileges when port forwarding from a port < 1024, such as with launchd (for MacOS). See: https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/AccessControl.html#//apple_ref/doc/uid/TP40002589-SW4 Would be a nice feature to have.

tamer-hassan avatar Jul 25 '19 15:07 tamer-hassan

Second that ^ I spent more hours then I'd like to admit trying to figure out what's going on

epotex avatar Jul 29 '19 06:07 epotex

For linux, there's PolKit (formerly PolicyKit) framework, and the pkexec command:

https://www.freedesktop.org/software/polkit/docs/latest/ https://www.freedesktop.org/software/polkit/docs/latest/pkexec.1.html

tamer-hassan avatar Jul 29 '19 08:07 tamer-hassan

For posterity, here's the error message Tilt currently generates: Error port-forwarding vigoda: error forwarding port: Unable to listen on any of the requested ports: [{901 8081}] That should definitely be improved.

As to forwarding ports without sudoing Tilt - is using an unpriveleged port a reasonable option for you?

landism avatar Jul 29 '19 14:07 landism

It's not ideal, we'll have to have an extra logic in the service run script to check if "environment == dev" the server start on a different port - which will introduce more complexity to point other services to this service, this is a real pain around port 80/443 (for us we use nginx but I can see that happens with every web server defaulting to port 80)

epotex avatar Jul 29 '19 23:07 epotex

we'll have to have an extra logic in the service run script to check if "environment == dev" the server start on a different port

Ah, I wasn't suggesting changing the port on which the server is listening, but rather only changing the port that's getting forwarded. e.g., k8s_forward('myservice', port_forwards=8080) will forward localhost:8080 (non-priveleged) to whatever port the container has open (presumably 80).

This is also useful when you're running multiple services in different containers that are all listening on the same port. We do this in one of our sample projects here.

(which maybe means the title of this bug should be "Forwarding from privileged ports...")

landism avatar Jul 30 '19 14:07 landism

Now that https://github.com/windmilleng/tilt/issues/2013 has been merged, a strange workaround that we have been using on macOS is to set port_forwards to 0.0.0.0:$PRIVILEGED_PORT instead of just $PRIVILEGED_PORT.

This makes Tilt bind to 0.0.0.0 instead of 127.0.0.1, which (interestingly!) seems to bypass Apple's restrictions on which users can bind to privileged ports.

For example we have been able to do the following as a normal user on both Mojave and Catalina:

$ nc -l 127.0.0.1 80   # fails (as expected)
nc: Permission denied

$ nc -l 0.0.0.0 80    # succeeds!
                      # pointing a browser at "http://localhost" shows nc is receiving the GET request... 
GET / HTTP/1.1
Host: localhost
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.29 Safari/537.36
Sec-Fetch-User: ?1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

^C

This does not seem like intended behavior on Apple's part and may break without warning (🤐🤐🤐🤐), but it's been "good enough" for us for now.

On linux, we do

sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/tilt

and are done.

andymartin-sch avatar Nov 13 '19 18:11 andymartin-sch

@andymartin-sch Thank you, it was a lifesaver comment! Just a note, it's still working with the following code k8s_resource('nginx', port_forwards=['0.0.0.0:80:80'])

borosr avatar Feb 13 '23 14:02 borosr