Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

caddy 2.6.4 package setcaps directly #44500

Open
chexum opened this issue Jun 17, 2023 · 3 comments
Open

caddy 2.6.4 package setcaps directly #44500

chexum opened this issue Jun 17, 2023 · 3 comments
Labels
bug Something isn't working needs-testing Testing a PR or reproducing an issue needed

Comments

@chexum
Copy link
Contributor

chexum commented Jun 17, 2023

Is this a new report?

Yes

System Info

Void 6.3.6_1 x86_64 AuthenticAMD uptodate F

Package(s) Affected

caddy-2.6.4_2

Does a report exist for this bug with the project's home (upstream) and/or another distro?

Possibly not, it's directly related to the package's INSTALL file using setcap, which contradicts recommended operational practices.

Expected behaviour

caddy, when started by activating it in /var/service, should be able to open privileged ports such as 443 and 80, but it should not grant this permission to users in general.

Actual behaviour

When the caddy package is installed (does not even need to run), can squat on privileged ports as it has a capabilities directly set on the binary.

Steps to reproduce

Have a Caddyfile with the contents:

http://localhost:23 {
        root * /tmp
        file_server browse
}

caddy run --config ./Caddyfile then happily starts a server on port 23, when started as a normal user. (With an already running caddy with an enabled admin port, a minimal addition is needed for success)

I don't think this is desirable. Other distributions normally use systemd to grant this capability only the caddy service installed/started by the system, not to the installed binary.

I recommend dropping the INSTALL file with setcap, and instead of chpst (as it doesn't seem to be capabilities aware), perhaps use setpriv for a similar effect:

exec setpriv --reuid caddy --regid caddy --clear-groups \
  --ambient-caps -all,+net_bind_service \
  --inh-caps -all,+net_bind_service \
  --bounding-set -all,+net_bind_service \
  --no-new-privs -- caddy run ${OPTS} --config ${CONFFILE:-/etc/caddy/Caddyfile}

This has been tested to provide functionality matching the current setup when run via a /var/service link, but not allowing any user to squat unused privileged ports with a configuration in their control.

@chexum chexum added bug Something isn't working needs-testing Testing a PR or reproducing an issue needed labels Jun 17, 2023
@paper42
Copy link
Member

paper42 commented Jun 17, 2023

Alpine also sets this capability and I think our service might not work without it because caddy doesn't run as root there

@chexum
Copy link
Contributor Author

chexum commented Jun 18, 2023

Not running caddy as root is good. The suggested changes to use setpriv makes it work in an equivalent way. I am using caddy, and I am running with those changes. (Might need to change runtime pkg dependencies, as chpst does not have this, well, capability)

If Alpine distributes a setcap binary, then they too have an issue. Capabilities are not meant to be given to binaries that don't verify their uses. They are a responsibility of things split from the all-powerful root permissions. The binary installed here allows everyone to bind to nonprivileged ports, which normally is restricted to root. With this binary, it's possible to do that by any user. This might be a CVE level issue. It's not with caddy, caddy does not expect users to have this capability - it's only making single user development easier, but bad on a generic Linux/Unix system in general.

This is what Apache has to say about the scheme if used for development:
"with this setup, any nonprivileged user can now run Apache on privileged ports. So, be very careful about what you do. Additionally, you can further restrict execution of the httpd binary, either using standard credentials (chmod, chown et al) or, even better, ACLs;" (https://cwiki.apache.org/confluence/display/httpd/NonRootPortBinding)

Allow me to describe a full demonstration of what the problem is:

(void with no caddy installed, just to not disturb the configuration):

xbps-install -Su caddy
umask 022
mkdir /tmp/q1
echo good >/tmp/q1/myfile
sudo vi /etc/caddy/Caddyfile
contents:
http://localhost:80, http://127.0.0.1:80 {
  root * /tmp/q1
  file_server browse
}
ln -s /etc/sv/caddy /var/service

expected result:
curl -v http://localhost/myfile should work (as any user), no issue as web service was explicitly configured by root

after stopping it with sv stop caddy (again, not necessary, only to make the following configuration simpler without documenting the full way to take over a service port in case the caddy process is still running.)

as a nonroot user:

umask 022
mkdir /tmp/q2
echo badport >/tmp/q2/myfile
vi $HOME/Caddyfile
contents:
http://127.0.0.1:334 {
  root * /tmp/q2
  file_server browse
}
caddy run --config $HOME/Caddyfile

Now, in another window, curl -v http://127.0.0.1:334/myfile produces the file contents on a privileged port, while the process caddy is run by the user. Only root or the system startup scripts should be able to start the executable caddy this way, no exceptions. No addition verification of ports is done. This could let users take over ssh or smtp ports (as an example) if they are not in use, or provide an opportunity to take them over during service restarts.

@cattyhouse
Copy link

Alpine uses setcap for caddy because:

  1. alpine does not care about caddy, they removed setcap for most of their packages in favor of openrc's capbability function. but not for caddy.
  2. alpine thinks net_bind_service is not that dangerous. actually this is discussed here :https://gitlab.alpinelinux.org/alpine/tsc/-/issues/45#note_318163

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs-testing Testing a PR or reproducing an issue needed
Projects
None yet
Development

No branches or pull requests

3 participants