srvrco / getssl

obtain free SSL certificates from letsencrypt ACME server Suitable for automating the process on remote servers.
GNU General Public License v3.0
2.08k stars 374 forks source link

Tokens in acme-challenge dir are created with root permissions #683

Open brzezins opened 3 years ago

brzezins commented 3 years ago

OS: Ubuntu Server 20.4 WWW server: Apache 2.4.41 getssl version: 2.37

The problem is that getssl creates tokens with permisions:

-rw-r--r-- 1 root root 87 Jul 22 09:40 YVsmmUX-rqwSRLZtkFDGj2OwAMkUfTTjyhHkqfI4nYc

So it cannot be read via HTTP and I'm getting an error while trying to renew certificate:

Verify error: "detail": "Invalid response from http://my-domain.com/.well-known/acme-challenge/YVsmmUX-rqwSRLZtkFDGj2OwAMkUfTTjyhHkqfI4nYc [91.236.128.27]: \"<!DOCTYPE html>\n<!--[if lt IE 7]> <html class=\\"no-js lt-ie9 lt-ie8 lt-ie7\\" lang=\\"pl-PL\\" prefix=\\"og: http://ogp.me/ns#\\"> <![endi\""

Dirs .well-known and acme-challenge have permissions:

drwxrwxr-x 2 www-data www-data

Domain config file:

PRIVATE_KEY_ALG="rsa"

SANS="www.my-domain.com"

ACL=('/var/www/html/my-domain.com/.well-known/acme-challenge')

USE_SINGLE_ACL="true"

DOMAIN_CERT_LOCATION="/etc/ssl/certs/ssl-cert-my-domain.com.cert" # this is domain cert
DOMAIN_KEY_LOCATION="/etc/ssl/private/ssl-cert-my-domain.com.key" # this is domain key
DOMAIN_CHAIN_LOCATION="/etc/ssl/my-domain.com.bundle"

Please, help...

tlhackque commented 3 years ago

The best approach is to add setgid to the .acme-challenge directory. This will copy the directory's group to the group of files created in it. httpd will then access the files via group permissions.

It's is often useful to do this for all the www directories. (Do not add setgid to files, especially executables, as it has a very different meaning.)

chmod g+s yourwell-knownpath/ame-challenge

In your case:

/var/www/html/my-domain.com/.well-known/acme-challenge

getssl could set permissions in some cases, but not all. For local files, the following code should work:

# Set ownership of files to match a (local) directory
# setown dir files
function setown() {
    local owns own grp
    local dir="$1"
    shift
    owns="$(ls -ld "$dir")"
    own="$(echo "$owns" | cut -d' ' -f3)"
    grp="$(echo "$owns" | cut -d' ' -f4)"
    owns="$own:$grp"

    chown "$owns" "$@"
    return
}
setown .well-known token1 token2 token3

However, for files copied to a remote filesystem (e.g. using scp), this won't work. But using setgid will.

So in any case, the documentation should be updated to reflect the use of setgid for acme-challenge, at least for the remote case.

tlhackque commented 3 years ago

On looking at the code, it also seems that "recent" versions of getssl support a brute force approach.

Add

TOKEN_USER_ID="www-data:www-data"

to your configuration file for this domain.

While it seems to be supported, it's not as robust as the other solutions that I noted.