How should I configured permissions for this server

Hi, everybody

I have a question in regards to the permissions of /etc/letsencrypt/ archive and live folders and the .pem files within.

I have a radicale server for CalDAV (calendars & to-do) and CarDAV on my Raspberry Pi. This server is installed using python3 -m pip, where you have two options:

  • Install it as root for a systemwide installation
  • Installing using --user for just the current user.

When I created it, without having a domain and knowing nothing about servers and how to remote access them, etc... I chose --user option. The config file was way simpler and I didn't have to worry setting any permission's structure on the config...

Now I have a domain name and I have managed to configure the server to be accessed from the outside. So I wanted to configure SSL to secure the connection.

According with radicale docs, I only have to put this on the config:

ssl = True
certificate = /path/to/server_cert.pem
key = /path/to/server_key.pem
certificate_authority = /path/to/client_cert.pem

So I did. And run into permissions problems.

That's when I read this documentation on, and tried to change the directories /etc/letsencrypt/archive and live permissions to 0755. But, of course, my server is just under my regular user and the privkey.pem is with 0700 permissions and therefore I get this error on the log:

RuntimeError: Invalid filepath value for option 'key' in section 'server' in config file '/home/pi/.config/radicale/config': '/etc/letsencrypt/live/' ([Errno 13] Permission denied: '/etc/letsencrypt/live/')

The documentation suggests for servers that "drop root privileges before attempting to read the private key file" to change the group and 0640 the file.

Now I wonder the following:

  • Are there any risks on chgrp with the group pi (my server is on my pi user (of course strong password), owned by pi:pi) so it can has access?
  • Should I uninstall and remove the server... and start from the beginning installing it as root?

I don't really have the knowledge to understand the consequences of setting the privkey group as pi, so I don't want to make changes before having some info.

For now, the server will stay just on "local network" (which I can access with my personal vpn).

Thanks for the help!! :innocent: :innocent:

P.S.: As why I started a server from a regular user, this is what I thought at that time: "I don't have any network/security knowledge, so if I ever make this available throgh a domain name from the outside, I don't want to expose anything that is running with root privilegies" (because I don't know what the f* I'm doing). So it seemed "less risky" to my not-knowing brain to just install it under my regular user.

1 Like

Hello @PolGZ,

You should never change the perms under /etc/letsencrypt dir... never ever ;).

You could use a deploy script to copy the fullchain and private key from letsencrypt dir to a dir owned by the user you are using to start your radicale server and once done, issue the command to reload/restart your radicale server.

You can do this:

1.- Create a script called for example in /etc/letsencrypt/renew-hooks/deploy/

2.- The script should be something like this (I've used the same names for the files you are using in radicale conf):

basedomain="$(basename $RENEWED_LINEAGE)"
yourgroup="$(id -ng $youruser)"
commandtoreloadradicale="here the command you will use to reload your radicale server"

if [ "$domain" = "$basedomain" ];then
    cp "$RENEWED_LINEAGE/fullchain.pem" "$pathtoyourcertsdir/server_cert.pem"
    cp "$RENEWED_LINEAGE/privkey.pem" "$pathtoyourcertsdir/server_key.pem"
    chown $youruser:$yourgroup "$pathtoyourcertsdir/server_cert.pem"
    chown $youruser:$yourgroup "$pathtoyourcertsdir/server_key.pem"
    su - $youruser -c "$commandtoreloadradicale"

Note: you should change the value of variables; pathtoyourcertsdir, domain, youruser and commandtoreloadradicale

3.- Save the script file and modify its perms:

chmod 750 /etc/letsencrypt/renewal-hooks/deploy/

Next time you renew your cert, all the needed files should be copied to the right path, changed the owner and group so your radicale server can read them and if you provide a command to reload your radicale server you have all done automatically.

Good luck,


Thank you very much, @sahsanu! That's very useful!.

I really was worried about the idea of having a copy of the privkey.pem, that clearly by design is only meant to be read by root, in my regular Pi user, should that server ever get compromised. But at least everything under /etc/letsencrypt would be still safe from being altered (everything there is back to default permissions!).

I am getting a:

basename: missing operand
Try 'basename --help' for more information.

I suppose it's because RENEWED_LINEAGE is missing if I run it manually, right? So I should just cp and chown the files the first time, is that correct?

Thank you very much for your help! (you also answered me another doubt I had: which one of the privkey.pem, fullchain.pem, cert.pem and chain.pem would exactly correspond with the server_cert, server_key and client_cert indicated in Radicale documentation!)


Yes, that is the reason.

Once you have replaced the value of variables inside the script with your own data, you can launch the script like:

RENEWED_LINEAGE=/etc/letsencrypt/live/yourdomain /etc/letsencrypt/renewal-hooks/deploy/



Cool! I din't knew that either! Thanks for your help!

I'm getting a SSL_ERROR_RX_CERTIFICATE_REQUIRED_ALERT but I think that this has more to see with radicale now... I'm not sure how well they implement SSL...

But I think now this should be discussed with Radicale. Thanks again for your help!

1 Like

You are welcome :wink:

That is the problem, something (maybe radicale) is still up and running and listening on port 5232, double check radicale is stopped before trying to start it again.

1 Like

@sahsanu That is the problem, something (maybe radicale) is still up and running and listening on port 5232, double check radicale is stopped before trying to start it again.

Ups! you were fast! haha. Yep, that error got nothing to do with this. The SSL_ERROR persists, though, but that is not for here to discuss!

Once again, thanks, and I would mark the reply as the solution! so it can be closed.

EDIT: I got the error!

I searched for radicale SSL on git issues and found this SSL handshake failed when using letsencrypt-generated certificate. The error was not the same, but I realised he was using just the certificate and key components. Without the certificate_authority.

ssl = True
certificate = /home/radicale/cert.pem
key = /home/radicale/privkey.pem

I commented that line and, bum: https :heavy_check_mark:

I edited the script and now we can close!


Not yet my friend :wink:

If you only use the cert.pem you could have issues because browsers couldn't get the complete chain to trust your certificate (maybe you are not having problems now because the browser you are using has the intermediate certificate cached). Please, copy the fullchain.pem instead of the cert.pem and restart radicale, if that works I'll modify the script.

cp /etc/letsencrypt/live/yourdomain/fullchain.pem /home/radicale/cert.pem


God bless you, man. Leave your XMR wallet... haha.

It works indeed. I just renamed the cert.pem with the "radicale name" server_cert.pem we have used. And I edited my script, erasing the lines that are not needed anymore, used the RENEWED_LINEAGE=/etc/letsencrypt/live... command and it works perfectly. (I moved the .pem files out of the folder prior to executing, to be 100% sure)


Great :partying_face:

I've modified the script in post 2 so it uses fullchain.pem instead of cert.pem and removed the chain.pem line.

Have a nice day.


Thanks for the solution, I've a similar permission problem.

Please update post 2 again; the directory is called renewal-hooks (not renew-hooks). Adding a couple of words about what lives in that directory wouldn't hurt. I guess scripts in that directory are called whenever any certificate is renewed, but couldn't find any doc saying so.

Update: found that doc here:

Assuming your configuration directory is /etc/letsencrypt , any executable files found in /etc/letsencrypt/renewal-hooks/pre , /etc/letsencrypt/renewal-hooks/deploy , and /etc/letsencrypt/renewal-hooks/post will be run as pre, deploy, and post hooks respectively when any certificate is renewed with the renew subcommand. These hooks are run in alphabetical order and are not run for other subcommands. (The order the hooks are run is determined by the byte value of the characters in their filenames and is not dependent on your locale.)

1 Like

Thanks. I've edited the post.

1 Like