Hello , I am working on a web application which uses caddy. By default Caddy want to bind to port 80 and 443, but that is not allowed on NixOS. I could get around this by using the following command
However after restarting, this value is reset to 1024 again. I guess this could lead to other security problems as well. So my question is, how can I make my own user or all users able to bind to port 80 and 443?
If you run it as your user, you shouldnât be running it on ports below 1024.
Even though I do not know anything about devenv, but that it requires --impure and therefore is not an option for me, I think it should be possible to make it use some form of privilige (de-)escalation or capability settings and dropping.
Because --impure is a can of worms, which I do not want to open just to be able to fire up a database.
I have choosen flake as my main way to pin inputs rather than niv or anything else, for the fact that the pure evaluation gives some extra benefits. Using --impure then would just be absurd thenâŚ
Good question! Traditionally, those ports are reserved for root. The idea is that, in theory, when the system boots a non-privileged user may be able to start a service a bit more quickly than root, thereby reserving the port for their application before root has a chance to.
This would result in them being able to launch an ssh server or a web server, and take over the respective services. You can imagine how much of a security nightmare this could be if a malicious user does so. Hence, ports < 1024 are reserved for important services like httpd or sshd.
A lot of system security today relies on encapsulating services under different namespaces, which can do exactly the same thing as an unprivileged user, and are only prevented from doing so by this same security feature.
If you want to start caddy on low ports, Iâd suggest giving it the capability (CAP_NET_BIND_SERVICE, probably what the NixOS module does too) to do so instead. This also protects caddy from being taken over by a different unprivileged user, which is probably better than running it on high ports.
That said, on a dev machine this sysctl may be totally valid. Iâm not your mom, hereâs the scissors, donât tell me I didnât warn you if you end up running with them: NixOS Search
But another option to expand on this tho is NAT, you can setup some NAT rules for your firewall in the nix config to accept connections on port 80/443 and internally redirect to whichever port you want, or visa versa. This would deal with both problems at once without tainting
If not NAT you could also just port forward/redirect to 127.0.0.1
I am aware that things changed in the nearly 2 years since my post.
It still is not fully pure. And despite me knowing what the impure part is used for, it doesnât change, that the mere existence of --impure or --no-pure-eval can cause havoc on improperly written import nixpkgs {} stuations. Those are not always under your control.
As long as devenv is not usable without pure evaluation, it is simply not an option for me, and I will remain concerned about this fact.
I stumbled upon this thread when looking for a way to do what the title says on my NixOS installation (to allow an ssh client running as my user to forward low ports, nothing to do with âcaddyâ - no idea what that is..)
To achieve that on my Manjaro installation I just ran this once: sudo setcap 'cap_net_bind_service=+ep' "$(which ssh)"
On my NixOS this doesnât work:
Invalid file â/run/current-system/sw/bin/sshâ for capability operation.
But reading through the thread I found somebody said that running sudo sysctl -w net.ipv4.ip_unprivileged_port_start=0
works for him though it does not stick. Thatâs not optimal but okay for my use case for now.
Would love to have something to write into my configuration.nix file that achieves this (permanently) - does something like that exist?
Caddy is just another server someone wanted to run on a low port. Replace any mentions with caddy with ssh instead and everything here makes sense for your use case.
And, still:
That points to the sysctl option; you can just set the sudo sysctl thing with that instead of doing it in a terminal.