4 ms·
> If the server is compromised they don't need to use meltdown/spectre to do damage since servers need root for everything useful (open port <1024)?! - there a
by minitech 6y ago
> If the server is compromised they don't need to use meltdown/spectre to do damage since servers need root for everything useful (open port <1024)?!
- there are lots of useful things you can do without root
- you don’t need root to bind to port numbers below 1024 on Linux, just CAP_NET_BIND_SERVICE
- when you do need root, you can usually drop it either partially or completely
- bullen 6y agoOk, thx! Can you combine that with nohup? nohup setcap 'cap_net_bind_service=+ep' blabla...
- minitech 6y agoYep! If you’re using file capabilities (setcap), it doesn’t look quite like that – you use setcap on the file separately, and then nohup when running it. You should probably run production services using something other than nohup, though, like systemd.
- amelius 6y ago> just CAP_NET_BIND_SERVICE How do you do that if you're not root? And if you are building an executable with that capability, how do you enable your Makefile to set it? I think we might need "CAP_SET_CAP_NET_BIND_SERVICE" as well. In fact, I might want to allow a user to bind to port 200 only. So in this case "CAP_SET_CAP_NET_BIND_SERVICE_PORT_200" is needed. And here we see the inflexibility of the entire approach :)
- Dylan16807 6y agoThe simple way is to use a process that has root for the smallest moment before dropping it. Which means it's vulnerable to a tiny subset of attacks, and it will never be root and serving requests at the same time.
- amelius 6y agoYes, that solves one of the problems, but it doesn't solve the problem where I want to prevent my process from binding to any other port than (say) specifically port 200.
- dasyatidprime 6y agoYour comment chain has taken a bit of a strange turn, but a suitable SELinux policy would work for that, which would be straightforward… ish. Alternatively, if you're only concerned about other privileged ports, with a systemd socket unit, you could have systemd do the binding and pass your unprivileged process the socket, so that your process no longer needs the privileged-bind capability at any time; that'd probably be the easiest way if you're willing to modify the application code a bit. If you don't like systemd, you could have another helper program do it. Or you could put your process in its own network namespace which has a filtered bridging or routing configuration between it and whichever namespace has the ‘real’ connectivity, which is complex and awkward but allows your process to ‘think’ it has full access, which might help if the code would otherwise balk. Or you could use various other userspace sandboxing frameworks that let you install a BPF syscall filter, which I like a lot in theory but don't currently have personal experience with.
- JetSpiegel 6y agoMake systemd bind to that port and let it pass the open fd to your process. See socket-activated services. http://0pointer.de/blog/projects/socket-activation.html http://0pointer.de/blog/projects/socket-activation.html
- deleted 6y ago[deleted]
- minitech 6y ago> How do you do that if you're not root? > And if you are building an executable with that capability, how do you enable your Makefile to set it? The goal is to bind without passing through root, not to never have root at all, so you could run the service with it as an ambient capability (supported by e.g. systemd). Or setcap as root after building. > In fact, I might want to allow a user to bind to port 200 only. Program with the capability on its file to check the user, bind the socket, drop the capability, and exec. (I’m sure something existing does that, but I don’t have one to recommend since I’ve never needed it.) But there’s also iptables and friends as alternative solutions to the same problem that still don’t require giving the process root at any point.