Skip to content

Fixing certificate errors with cron

Jamen edited this page Nov 13, 2020 · 14 revisions

If you're seeing the error

TokenStore::Refresh: http error: error setting certificate verify locations: ...

Make a small bash script, I named mine fix_certs.sh

This will copy over new certificate files in the event that ca-certificates is updated.

#!/bin/bash
mkdir -p /var/spool/postfix/etc/ssl/certs
cp /etc/ssl/certs/ca-certificates.crt /var/spool/postfix/etc/ssl/certs/ca-certificates.crt

# and if you're using postmulti add multiple instances.
mkdir -p /var/spool/postfix-2/etc/ssl/certs
cp /etc/ssl/certs/ca-certificates.crt /var/spool/postfix-2/etc/ssl/certs/ca-certificates.crt

Make the script executable with chmod +x

$ sudo chmod +x fix_certs.sh

Run it as often as you'd like with cron.

If you have multiple instances of postmulti, check out this gist for dynamically managing postmulti instances.

If you're seeing the error (and you're chrooted)

TokenStore::Refresh: http error: SSL certificate problem: unable to get local issuer certificate

The locally installed version of CURL might be looking for a certificate that it doesn't have access to in the chroot environment.

An strace test might be valuable to see where CURL is trying to read certs from:

if strace is not installed, the following command will output nothing. strace can be installed with apt-get install strace or apt install strace

$ strace curl https://www.google.com |& grep 'open.*ssl'
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libssl.so.1.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/ssl/openssl.cnf", O_RDONLY) = 3
openat(AT_FDCWD, "/usr/lib/ssl/openssl.cnf", O_RDONLY) = 6
openat(AT_FDCWD, "/etc/ssl/certs/ca-certificates.crt", O_RDONLY) = 6

If the last line does not match /etc/ssl/certs/ca-certificates.crt you can do the following:

Take the path of the last line and find out what it is. for example, it could be /etc/ssl/certs/4a6481c9.0

Take note of the file name, we'll be updating the symlink later. In this case it's 4a6481c9.0

$ stat /etc/ssl/certs/4a6481c9.0
File: /etc/ssl/certs/4a6481c9.0 -> GlobalSign_Root_CA_-_R2.pem
Size: ... symbolic link
...
$

Use the readlink command to find the actual file, readlink will recurse through multiple symlinks with the -f parameter. $ readlink -f /etc/ssl/certs/4a6481c9.0 /usr/share/ca-certificates/mozilla/GlobalSign_Root_CA_-_R2.crt $

As you can see, the /usr/share/ca-certificates is probably not available for the chrooted environment. Any symlink that points to a directory outside of the chroot environment would end up with an error like this.

You can do any of the following to fix this certificate issue:

1.) Copy the real file to /var/spool/postfix/etc/ssl/certs/ and update the symlink that CURL is using.

$ cp /usr/share/ca-certificates/mozilla/GlobalSign_Root_CA_-_R2.crt /var/spool/postfix/etc/ssl/certs/
$ ln -sfn GlobalSign_Root_CA_-_R2.crt 4a6481c9.0
$

2.) Copy the real file to the name of the symlink.

$ rm /var/spool/postfix/etc/ssl/certs/4a6481c9.0
$ cp /usr/share/ca-certificates/mozilla/GlobalSign_Root_CA_-_R2.crt /var/spool/postfix/etc/ssl/certs/4a6481c9.0
$

3.) Copy the entire directory of /usr/share/ca-certificates to /var/spool/postfix/usr/share/

$ mkdir -p /var/spool/postfix/usr/share/
$ cp /usr/share/ca-certificates /var/spool/postfix/usr/share/ -r
$

If you have multiple instances of postmulti, check out this gist for dynamically managing postmulti instances with symlinked certificates.

Clone this wiki locally