certbot icon indicating copy to clipboard operation
certbot copied to clipboard

Issue #8070 should not have been auto-closed

Open micha030201 opened this issue 1 year ago • 4 comments

(Is this what I'm supposed to do? The github-actions bot said so.)

Issue https://github.com/certbot/certbot/issues/8070 was closed by github-actions despite still being present.

The function to change ownership is called unconditionally whenever a new private key is written: https://github.com/certbot/certbot/blob/985457e57bfde52d3702dea4e500a1b54ea1c745/certbot/certbot/_internal/storage.py#L1205-L1213

And the function that does the chown just calls chown expecting it to work: https://github.com/certbot/certbot/blob/985457e57bfde52d3702dea4e500a1b54ea1c745/certbot/certbot/compat/filesystem.py#L96-L130

The original issue describes the problem well, so I suggest you close this issue and reopen the original one.

micha030201 avatar Jan 07 '25 08:01 micha030201

@micha030201 do you have a use case that hits this issue in practice, or is this more a comment about general practices? Does @ xiruizhao's comment work as a workaround for your use case?

ohemorange avatar Jan 09 '25 23:01 ohemorange

My problem is self-inflicted. I created (or, rather, amended the one that came with the debian package for certbot) a systemd service file where I run certbot with

User=certbot
Group=www-data

but then created certificates using

sudo -u certbot certbot certonly --webroot -w ... -d ...

tested that renewal works with

sudo -u certbot certbot renew --no-random-sleep-on-renew

and thought that everything was good. However, the initial certificate files were owned by certbot:certbot, and when run as a service certbot tried to chown the new files in the archive directory to that as well (from certbot:www-data that they got created as by default), and failing to do so did not update the live certificates.

I only found out that my certificates weren't automatically renewing after I received an email from letsencrypt, got really confused because the last message I saw in the logs was

acme.messages.Error: urn:ietf:params:acme:error:rateLimited :: There were too many requests of a given type :: too many certificates (5) already issued for this exact set of domains in the last 168h0m0s, retry after 2025-01-07 09:02:05 UTC: see https://letsencrypt.org/docs/rate-limits/#new-certificates-per-exact-set-of-hostnames

but after scrolling back to the

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/certbot/_internal/renewal.py", line 532, in handle_renewal_request
    main.renew_cert(lineage_config, plugins, renewal_candidate)
  File "/usr/lib/python3/dist-packages/certbot/_internal/main.py", line 1540, in renew_cert
    renewed_lineage = _get_and_save_cert(le_client, config, lineage=lineage)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/certbot/_internal/main.py", line 126, in _get_and_save_cert
    renewal.renew_cert(config, domains, le_client, lineage)
  File "/usr/lib/python3/dist-packages/certbot/_internal/renewal.py", line 401, in renew_cert
    lineage.save_successor(prior_version, new_cert, new_key.pem, new_chain, config)
  File "/usr/lib/python3/dist-packages/certbot/_internal/storage.py", line 1225, in save_successor
    filesystem.copy_ownership_and_apply_mode(
  File "/usr/lib/python3/dist-packages/certbot/compat/filesystem.py", line 127, in copy_ownership_and_apply_mode
    os.chown(dst, user_id, group_id)
PermissionError: [Errno 1] Operation not permitted: '/etc/letsencrypt/archive/.../privkey15.pem'

and reading the code I figured it out and fixed it with

sudo chown -R certbot:www-data /etc/letsencrypt/live/
sudo chown -R certbot:www-data /etc/letsencrypt/archive/

and will run certbot as

sudo -u certbot -g www-data certbot ...

from now on.

If I understand correctly, certbot prefers to be run as root and installed through either pip (with renewal being done with cron apparently) or snap, neither of which I am eager to do. I understand that I am using certbot not in a way that is officially supported, and I am willing to face the consequences of my actions.

Nonetheless, I think this is a very non-obvious and difficult to debug failure mode, and given that a dev team member commented as such on the original issue, I thought I would let you know that the behaviour hasn't changed despite the issue having been closed by the bot. I might even submit a PR for it as @ bmw described if I have the time, but before that I kind of want to know whether that comment still stands, or if you changed your mind and don't consider this to be a problem anymore (which I would also understand).

micha030201 avatar Jan 10 '25 15:01 micha030201

Really appreciate the detailed write up! The comment still stands that even though we don't officially support running this way, we agree that it's not the best behavior for certbot to have. If not a behavior change PR, then a better error reporting situation could work. Since in addition only two people have mentioned hitting this though, I agree that while we'd accept a well-written PR to address it, we're unlikely to write a fix for it ourselves.

ohemorange avatar Jan 10 '25 23:01 ohemorange

Three people. Also the folks in https://github.com/certbot/certbot/issues/1795 from way back when.

My solution was just to patch it out when building a container:

# certbot
python3 -m venv /opt/certbot/
/opt/certbot/bin/pip install --upgrade pip
/opt/certbot/bin/pip install certbot
# stupid hack, this chown breaks webroot certbot for non-root users...
sed -i -e 's/os.chown/#os.chown/' /opt/certbot/lib/python*/site-packages/certbot/compat/filesystem.py

fffe avatar Jun 24 '25 06:06 fffe