Running certbot non-privileged - self help

Please fill out the fields below so we can help you better. Note: you must provide your domain name to get help. Domain names for issued certificates are all made public in Certificate Transparency logs (e.g. |, so withholding your domain name here does not increase secrecy, but only makes it harder for us to provide help.

My domain is:

I ran this command: (as non-privileged user) certbot certonly --webroot --webroot-path /var/www/ --staple-ocsp --preferred-challenges=http --preferred-chain "ISRG Root X1" -d -d

It produced this output:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/
Key is saved at: /etc/letsencrypt/live/

My web server is (include version): httpd-2.4.41-6.1.fc30

The operating system my web server runs on is (include version): Fedora-30 linux

My hosting provider, if applicable, is: self

I can login to a root shell on my machine (yes or no, or I don't know): yes

I'm using a control panel to manage my site (no, or provide the name and version of the control panel): no

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot): certbot-1.29.0-1 (modified)

Hi gang. This is self-help entry, for those, who like me, would like to run certbot as a non-privileged user, simply because that is how we do things in Linux (Unix) if we can. This works for me under Fedora Linux on my own systems and using the --webroot option.
The clue is that certbot tries to change the ownership of the secret key to root, which a non-privileged user is not permitted to do. The function that does that is in the


file, nicely packaged with all OS dependent routines. By commenting out one line, the routine is effectively no-op, which then allows certbot to run non-privileged. This is the patch file I generated:

--- certbot/compat/       2022-05-04 16:25:23.000000000 -0400
+++ certbot/compat/        2022-09-03 14:39:05.069708491 -0400
@@ -105,7 +105,7 @@
         # On Windows, os.chown does not exist. This is checked through POSIX_MODE value,
         # but MyPy/PyLint does not know it and raises an error here on Windows.
         # We disable specifically the check to fix the issue.
-        os.chown(dst, user_id, group_id)
+        # os.chown(dst, user_id, group_id)
     elif copy_user:
         # There is no group handling in Windows
         _copy_win_ownership(src, dst)

I apologize to the certbot developers for hacking their code.

Of course, I then changed the ownership of the entire /etc/letsencrypt directory tree to the unprivileged user. In a corporate environment, a user acme would probably work best, but I have to entertain myself, so I have it as:

wecoyote:x:348:48:Wile E. Coyote, ACME client:/home/wecoyote:/sbin/nologin

By making the gid=apache, this user can write to the


directory to create the acme-challenge directory and challenge file.
Of course under Linux/Unix a key file owned by a no-login unprivileged user, is just as secure as one owned by root. And the apache user, running the web server will just as happily read the certificate owned by my unprivileged user, as it has the same gid.

1 Like

Hi @crashulatand Welcome back to the community!

The certonly option obtains the certs but does not install them on your web server.

You have certs! However, you will need to manually configure them in your server configuration and restart httpd for them to be active.


Also, I am not a Fedora user but I found some relevant information here:


I see your server using the new cert just fine. The only thing I noticed is you do not redirect HTTP requests to HTTPS. That's just something to adjust in your Apache VirtualHost for port 80.


Sorry guys for typing so long you already jumped in. All is well and for once: under control. Have a nice day.
@Rip Thanks. I symlink the links in the ./live/ directory from a fixed location, so updates are never needed. Just an apache "reload" will do.
@MikeMcQ Thanks for the tip. It may go against the the goals of Let's Encrypt, but I like to leave it up to the clients to decide http/https. Then I don't have to worry about somebody with an old Android phone, not being able to browse my consulting site (since I have now switched away from that). Rest assured that a login into my application is secured.


@crashulater As far as I know, that piece of code does not try to change ownership to root if Certbot is ran by a regular user. The problem users would run into when running Certbot as non-root, is that most of the directories used are owned by root, so there's no write permission. If all directories used by Certbot (/etc/letsencrypt/, /var/log/letsencrypt/ and /var/lib/letsencrypt/) are actually owned by the regular user, Certbot will run just fine. No hacks required.

Note that the --apache and --nginx plugin won't work as non-root, as usually one requires root to reload the webserver.


@Osiris Thanks for your response. Of course, I tried just changing ownership first. Changed all of /etc/letsencrypt, /var/log/letsencrypt, and /var/lib/letsencrypt to ownership of the non-privileged user. It got me as far as generating the key pair, but then I got:

        Unable to change owner and uid of webroot directory
        An unexpected error occurred:
        PermissionError: [Errno 1] Operation not permitted: '/etc/letsencrypt/archive/'

As I didn't see any reason why any files should change ownership, in my setup, I hunted down the responsible function and changed it. That made it work for me. I realize that for many of the other options and environments root permissions are needed. But, not in mine.