monome / maiden

web based editor and repl for norns
GNU General Public License v3.0
47 stars 34 forks source link

change maiden to run on port 80 (instead of 5000) #92

Closed ngwese closed 6 years ago

ngwese commented 6 years ago

the solution should bind port 80 then lower permissions to run as we.

the systemd unit will need some adjustment and possibly the backend code to get the permissions lowering don correctly.

/cc @tehn

ngwese commented 6 years ago

well this is surprisingly thorny. the two most direct ways of doing this are via setcap or authbind. (there are myriad references out there but this one was probably the best https://superuser.com/questions/710253/allow-non-root-process-to-bind-to-port-80-and-443)

given that setcap was already installed i explored this route first. with minor tweaks to norns-maiden.service and manually running sudo setcap CAP_NET_BIND_SERVICE=-eip /home/we/maiden/maiden.arm things do work. _however, going this route requires rerunning sudo setcap CAP_NET_BIND_SERVICE=-eip /home/we/maiden/maiden.arm every time the maiden binary is change (like via an update)._

setcap seems error prone so i'll explore the authbind route.

artfwo commented 6 years ago

@ngwese have you tried AmbientCapabilities=CAP_NET_BIND_SERVICE option in the systemd service file?

ngwese commented 6 years ago

@artfwo yes - that only allows capabilities set via setcap to take effect.

artfwo commented 6 years ago

@ngwese ah, ok. as an alternative to consider, systemd can also listen to port 80 itself and pass a file descriptor to the underlying process which maiden can use for i/o.

ngwese commented 6 years ago

sigh. authbind doesn't appear to work - i'm guessing because the backend is written in go and statically linked so authbind's trick of injecting an new bind(...) system call via LD_PRELOAD does not work.

nf commented 6 years ago

@ngwese that's correct, Go doesn't use the libc bind function to listen, so any method that hijacks libc calls won't work.

Does norns use systemd for initialization? I think @artfwo's suggestion of listening in systemd and passing an fd to maiden should work.

You can create a net.Listener (that you can pass to http.Serve) from a fd number like so:

l, err = net.FileListener(os.NewFile(uintptr(fd), "http"))

This doc looks relevant.

I am happy to help with this any way I can.

ngwese commented 6 years ago

@nf - from the looks of things you know your way around go alot more that i do so if you see a path where systemd hands off sockets to the backend i'm all for it.

norns is using systemd to manage processes...

nf commented 6 years ago

@ngwese sure, happy to investigate.

nf commented 6 years ago

I just sent PR #94. The corresponding systemd change would be something like this:

$ cat /etc/systemd/system/maiden.socket
[Unit]
Description=maiden socket

[Socket]
ListenStream=80
NoDelay=true

And then in maiden.service (wherever that is) add this to the [Unit] section:

Requires=maiden.socket

and add -fd 3 to the maiden command line.

nf commented 6 years ago

Should this be closed now? 😊

pq commented 6 years ago

@nf : just loaded this change. so nice. cheers! 🍻