Allow Caddy to bind privileged ports as www-data#2321
Allow Caddy to bind privileged ports as www-data#2321Binero wants to merge 1 commit intopelican-dev:mainfrom
Conversation
Grant cap_net_bind_service to /usr/sbin/caddy so it can bind :80/:443 without running as root. Previously this only worked in bridge networking, where Docker sets net.ipv4.ip_unprivileged_port_start=0 in the container netns; under network_mode: host the host sysctl applies and Caddy fails with "bind: permission denied" on :443.
|
All contributors have signed the CLA ✍️ ✅ |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughBoth production and development Dockerfiles are updated to grant the Caddy binary capability to bind to privileged ports (80/443) without container elevation. ChangesPrivileged Port Binding via Capabilities
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
I have read the CLA Document and I hereby sign the CLA |
|
Hey thanks for your contribution, I don't think we should do it this way the current docker and log config to get the proper client ip header seems fine but we'll see what @parkervcp has to say about it, he is the one mainly managing docker stuff. |
|
in my caddy logs i have the correct client_ip, just remote_ip is the one my proxy is on, that one is always my docker network gateway |
|
I was surprised by your seemingly different results, but I figured it out, and the answer is somewhere in the middle. The So even though the main reason I gave why someone might not want to run over the bridge network might be more limited as I first understood it to be, there are many reasons why one might want to run over the host network (e.g. cleaner IPv6 support), and this small change would support those setups without requiring people to undo some of the security hardening the image already has built-in. The addition to the Dockerfile seems to be self-contained enough to not pose any significant maintenance burden, while still opening the door for this common type of setup. |
This adds the
cap_net_bind_servicefile capability to the Caddy binary, letting it bind:80/:443as the unprivilegedwww-datauser the image already drops to.RUN apk add --no-cache --virtual .setcap-deps libcap \ && setcap cap_net_bind_service+ep /usr/sbin/caddy \ && apk del .setcap-depsThis would allow us to listen on port 443 when using host networking.
The reason to want host networking is that bridge mode obscures real client IPs and doesn't do public IPv6 without significant Docker daemon reconfiguration. The former additionally means that in access logs rather than the real user IP showing up, it will show Docker's internal virtual IP address, which is the main reason I want to pitch this PR.
Another way to achieve the same is to run the entire container as root, but that would defeat the existing
USER www-datadirective, and basically boils down to deploying a nuke to squash a mosquito.People who are using bridge networking are unaffected by this change; they already have privilege over
:80/:443by default.