mirror of
https://github.com/dehydrated-io/dehydrated.git
synced 2026-01-11 22:30:44 +01:00
Sharing with the ssl-cert group
#534
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @kousu on GitHub (Apr 24, 2021).
dehydrated deploys certs with permissions
0600 root:root, because of91cccc0c23/dehydrated (L14)I respect the motivation for that but it makes dehydrated incompatible with some daemons. Many daemons start as root, load their certs, then drop privs by switching to their daemon user; but others start as their daemon user and stay there, which they argue is a more secure choice.
So someone needs to budge to get things working.
Debian has a solution for this:
chgrp ssl-cert <all certs> && chmod g+rX <all certs>and then, for each daemon in the latter camp,usermod -a -G ssl-cert _daemon.Would you be willing to consider supporting this? It would be helpful I could do, say
and have all the permissions work out correctly.
@kousu commented on GitHub (Apr 24, 2021):
I'm going to solve this for now with a hook that does
chgrp -R ssl-cert /var/lib/dehydrated && chmod -R g+rX /var/lib/dehydrated/on every renewal, but I don't want to use too many hooks because the lack of #270 means it's easy for them to get out of hand or be accidentally broken when combining features using ansible or other config-management setups.@kousu commented on GitHub (Apr 24, 2021):
Just to compare, I've solved this in the past with
certboton linux by doing:And iirc on BSD systems, the group is just inherited by default so it's even easier there. But dehydrated would still need this patch:
to be compatible with that.
Indeed, this seems to solve my problem without deploying a hook:
which is a less invasive patch than adding a new config option.
@egberts commented on GitHub (Apr 25, 2021):
First of all,
ssl-certgroup is for admins who are tasked with creation and distribution of TLS/SSL, et. al., only.To give
ssl-certgroup to any servers would be giving away the store to all things, PEM-wise.Which is not a good thing.
The proper thing to do is to use your openssl after changing to this group, then copy/move the files into each server’s own /etc subdirectories using its server’s file ownership/permission.
@kousu commented on GitHub (Apr 25, 2021):
Thanks for chiming in. That's an interesting approach. I can't tell if it's "proper" though. I get the sense there is no consensus around managing certs.
You're suggesting something like this?
On my systems
/etc/isroot:rooteverywhere, so the custom permissions would stick out oddly.Plus it would be hard to maintain since you'd have a hard time remembering what to copy where. I could do most of it with dehydrated's hook feature, but what's on disk and what's in the script could fall out of sync, especially if I removed certs.
Most linuxes come with /etc/ssl/certs and /etc/ssl/private, because that's what
opensslexpects, which would seem to be another option, but I've never seen/etc/ssl/privateactually used. Debian comes with/etc/ssl/private/ssl-cert-snakeoil.keybut I've never seen it used; itscertbotuses/etc/letsencryptand itsdehydrateduses/var/lib/dehydrated/certs.This is probably what I meant by "imperfect" above. But I don't think it's that big of a problem.
In the common case, I have a single server, with a single domain, with multiple daemons, and I want them all to share the same single cert. Then, it doesn't matter if the daemons can see each others certs, they're all the same cert. That's my current use-case.
In the vhosting case, with multiple sites on single daemons, unix permissions aren't enough to save you; if you have, say, nginx or postfix running multiple domains, they're running them all as the
www-dataorpostfixuser, so if one domain is compromised they all are. That's just the risk of vhosting, and part of why vhosting is cheaper than other plans.The only imperfect case I see is if you have different daemons running different subdomains. In that case, I agree you can do better than the status quo. You can give postfix access to
/var/lib/dehydrated/mail.example.org/(or copy the contents elsewhere if you want) and nginx/var/lib/dehydrated/www.example.organd they don't need to cross paths. In fact, if you did have certs segrated to specific daemons, maybe you could even make it permanent bychgrp www-data /var/lib/dehydrated/www.example.org; chmod u+rXs /var/lib/dehydrated/www.example.org--- except that won't work with dehydrated because of theumask 077above; it needs to becomeumask 027orumask 007.The most common status quo I know of -- nginx is an example -- is for daemons to start as root, load their certs, and then
setuid()to become their real user. In that case, you can isolate the different certs, because aftersetuid()no certs are readable anymore by the different daemons. But also in that case there's no need to copy your certs to any special folders in the first place.But other daemons, like
netdata, disagree with usingsetuid(). They would rather start as their daemon user immediately. It's these daemons that I'm having trouble integrating withdehydrated, and these daemons that made mechgrp ssl-cert /etc/letsencryptback in the day, andchgrp ssl-cert /var/lib/dehydrated/certsnow.I think, probably, the "right" answer is to make everything root:root and rely on daemons doing
setuid(). But I can't control all the daemons. So personally, I don't think there really is a right answer, only best efforts.Andddd to bring this back on topic, my best effort would be helped a lot with this patch:
But maybe there's a better solution floating out there?
@txr13 commented on GitHub (Apr 25, 2021):
First off, dehydrated does use permissions
0600, but not necessarilyroot:root. Literally the first two options in the config file are the user and group you want it to run as. So if you want the group set to something custom likessl-certor whatever, set theDEHYDRATED_GROUPin your config file as that. Now dehydrated runs asroot:$DEHYDRATED_GROUPand you can use thedeploy_certhook to set whatever permissions you want.Alternately, if you call dehydrated from a non-root crontab, it will happily create files as whatever user it runs under. Doesn't have to be root. I use this for my own central certificate management server. Still creates the permissions as
0600, but that doesn't matter to me because of my export process.Because I have a central certificate management server, I have a separate, non-dehydrated update script which compares the hash of the current certificate on disk against the recorded hash of the last update run. If the current certificate on disk has been updated, the script then checks for a certificate-specific export script or otherwise runs the default certificate export options I desire. The export script for each certificate will handle the necessary steps for whatever the target use is, including concatenating the files into the target format (eg. privkey/fullchain, or fullchain/privkey, or fullchain and privkey in separate files, or export to PKCS#8, or export to PKCS#12, etc.), sending the certificate to a different server (via file mounts for Windows or scp for *nix), and calling the daemon's update script on those servers.
The point being, dehydrated just does what it does--request and write out certificates. There's enough different options out there that it's far easier to simply write yourself an export / update script per certificate (for large installations) or do the necessary in your
deploy_certhook (for small installations). I mean, that's why thedeploy_certhook exists--to make any needed modifications and/or move the certificate to its final location and/or call whatever update process needs to be invoked. I much prefer dehydrated itself to simply write the certificates in a reasonably locked-down fashion, especially since you can use the config file to specify which user and group to run as.@lukas2511 commented on GitHub (Apr 25, 2021):
Yea, like @txr13 mentioned it's not easy to implement a solution that will fit all use-cases, that's why dehydrated just tries to create the files with secure permissions and it is up to your hook scripts to change ownership/permissions, deploy the certificate to somewhere else, reload services, etc.
I will not add any more privilege-modifying or -seperating stuff to dehydrated in the near future. Tbh I now think it was a big mistake to add even the sudo stuff in the first place, but now it's here and I don't want to break compatibility.
@stokito commented on GitHub (Jun 8, 2022):
@kousu you made very good points. I think that it should be the centralized location of certs and all ACME clients should place certs there with the same permissions. Please see my comment for Let's Encrypt https://github.com/certbot/certbot/issues/1425#issuecomment-1150116062
@egberts commented on GitHub (Jun 8, 2022):
I am not saying that there is a right way but it is very clear that there is a severe divergence of repositories of PKI Root CAs.
I even have a problem with Debian PKI Root CA approach. Of which I’ve detailed here:
https://egbert.net/blog/articles/ca-certificates-rebuild-on-debian.html
@egberts commented on GitHub (Jun 8, 2022):
Also, it does make it easier to managed multiple (but private) PKI Root CAs when having a centralized SSL directory as I do here for my some-23 odd CA certificate types.
https://github.com/egberts/tls-ca-manage
@kousu commented on GitHub (Jun 8, 2022):
Those links are interesting, @egberts, but I'm not sure I understand why they're relevant. It sounds like
tls-ca-managedoes the same thing asdehydratedbut with a private CA? I'm usingdehydratedbecause I want to use a public CA that my users won't have trouble with.Anyway the point is, this was wontfixed. The best I can do is write a
deploy_hookthat doeschown -R :ssl-cert ... && chmod -R g+rX ....That's not so bad. It at least doesn't require writing one hook per daemon. I means I can treat my ansible role that uses
dehydratedas dependency of other ansible roles: I just need to make sure they deploy daemons to:ssl-certwith their TLS configs pointed at/etc/ssl/acme.What I was trying to avoid was having to have each ansible role write hooks into
dehydrated(which would break encapsulation IMO). "Just use hooks to solve it" is a reasonable answer for managing individual servers by hand, but it's a stretch when managing a fleet. I think anyone with a fleet to manage is going to have the same problem, no matter whether they're using ansible or puppet or terraform or whatever other configuration tool. I think this is the point @stokito is making to certbot, too, who apparently also haven't figured out how to handle giving SSL to more than one daemon on a server at a time?@egberts commented on GitHub (Jun 8, 2022):
These given links are only examples of why no daemon should ever use the
ssl-certgroup ID/name.No Daemons are privileged to examine keys of other servers’ PEM through
ssl-certsupplementary group name/ID.@stokito commented on GitHub (Jun 8, 2022):
Maybe as a default behavior that may be fine for most cases. Those who need more can adjust users manually. You know, today almost everything is dockerized so files are isolated.
Personally I working in direction of self hosting when non experienced users can install their own services on their RaspberryPi or even on a router with OpenWrt. And ideally they shouldn't even open a terminal to edit something.
@egberts commented on GitHub (Jun 8, 2022):
I am quite sure that this (mis-)use of
ssl-certis just fine for just the confining environs (such as Docker); I wanted to alert others that in the direction of NixOS singular-directory package installer, this issue (of cross-reading of PEM keyfiles) would too get amplified there as well.For Dehydrated-IO, shell hook is a fine compromise here; it is what ISC DHCP server, NetworkManager, ifup/ifdown and OpenSSH uses too.
Edit: and what certbot uses (shell hooks) also!
@kousu commented on GitHub (Jun 10, 2022):
My servers aren't containerized. I very much want to have a single cert that all daemons on the same server share. It seems like a big waste of resources to me to do anything else.
Sounds like we're on the same wavelength! I also support the self-hosting scene. If your perspective is the corporate one-app-one-container-one-ip then it seems unthinkable and confusing to loosen the permissions on your certs, but if your perspective is a small time server in your house or on a cheap VPS plan, you aren't going to pay for separate IPs and you must have a cert that web/mail/chat/whatever can share.
@stokito commented on GitHub (Jun 10, 2022):
Sorry, but I didn't get why this is a misuse. This is not ideal solution but at least some improving of security. As I mentioned in https://github.com/certbot/certbot/issues/1425#issuecomment-1150116062 there may be some certs management tool for non trivial usage like a per-daemon certs.
We should start at least from something and later the process may be improved. Because now after installing of my package my users should perform some untrivial operations to set up permissions right. And this is heavily depends on their ACME client. But just adding a user to the
ssl-certgroup can make the process easier. And all existing daemons started as root are still have an access to certs. Maybe I'm missing something but this looks like a safe and proper change.@kousu It's great to see that so many people get's involded. BTW your journal looks similar to https://github.com/LukeSmithxyz/lb so hope it might be interesting for you. Personally I working on YurtPage so once I'll perform a first release I'll send you an invention :)
@egberts commented on GitHub (Jun 11, 2022):
It can only be a misuse when an errant daemon starts to accessing cert keyfile(s) not of their own usage by this leveraging of the
ssl-certowner/group ID/name.Otherwise, carry on.