Closed ngwese closed 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.
@ngwese have you tried AmbientCapabilities=CAP_NET_BIND_SERVICE
option in the systemd service file?
@artfwo yes - that only allows capabilities set via setcap
to take effect.
@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.
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.
@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.
@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...
@ngwese sure, happy to investigate.
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.
Should this be closed now? 😊
@nf : just loaded this change. so nice. cheers! 🍻
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