docker-alpine: update-ca-certificates fails

When run under Docker, update-ca-certificates (from the package ca-certificates) fails with the line . All the information I can find seems to suggest it’s a locale issue but the system profile seems to have the correct information. Any ideas?

The failure:

bash-4.3# update-ca-certificates
WARNING: ca-certificates.crt does not contain exactly one certificate or CRL: skipping

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 19
  • Comments: 56 (9 by maintainers)

Commits related to this issue

Most upvoted comments

FROM alpine:3.5

RUN apk add --no-cache ca-certificates && \
    update-ca-certificates

WARNING: ca-certificates.crt does not contain exactly one certificate or CRL: skipping

The message says that something is skipped. It makes an impression that user get incomplete set of root certificates. Could you, please, rephrase, remove or fix this message, so people are not getting confused about the message?

Just don’t use Alpine & Docker. Nobody cares if you shave 100 MB off an image. 2 hours of your work is a terabyte disk.

+1

What about this guys:

FROM alpine:3.7

RUN apk update \
    && apk upgrade \
    && apk add --no-cache \
        ca-certificates \
    && update-ca-certificates 2>/dev/null || true

This is still a problem.

The warning is just a warning. It doesn’t affect anything.

WARNING: nothing is wrong

The message above should be either reworded so it makes sense or removed. It’s useless and people, like me, are wasting their time trying to figure out what it means.

Months later, still a problem. Issue should not be closed.

This still doesn’t work (produces the warning, doesn’t add stuff to /etc/ssl/certs/ca-certificates.crt) with alpine 3.9:

COPY ca-cert-XXX.pem /etc/ssl/certs/
update-ca-certificates

my workaround:

COPY ca-cert-XXX.pem /etc/ssl/certs/
RUN cat ca-cert-XXX.pem >> /etc/ssl/certs/ca-certificates.crt

@andyshinn so shouldn’t the issue be reopened?

I think there are two separate issues here, stemming from the same root cause. It looks like update-ca-certificates skips any PEM file in /usr/local/share/ca-certificates if it contains more than one certificate.

If you only get a warning about ca-certificates.crt it’s harmless, but if you just added a new PEM file and you want to import it (e.g. the RDS certificate chain), you will get a warning for that file, and the certificates will not be imported. Confusing.

The workaround I found is to split the new PEM file into individual files first, one per certificate:

cd "/usr/local/share/ca-certificates" && curl "https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem" | csplit -f "rds-" - '/-----BEGIN CERTIFICATE-----/' '{*}'`

This should be brought up on http://bugs.alpinelinux.org/projects/alpine/issues. It comes from the utility in the ca-certificates package at https://git.alpinelinux.org/cgit/aports/tree/main/ca-certificates/c_rehash.c#n210. I agree, the warning could be better or ignored altogether if the file is ca-certificates.crt.

I think it’s great for a workaround, but the command shouldn’t exit 1 on a warning. Or we should be able to ignore warnings. I have implemented this workaround in my Dockerfile, but I don’t think I can really assume that everything is fine certificate wise anymore.

I have looked into this a bit closer.

The reason for this warning is the c_rehash program that runs at the very end of update-ca-certificates. Its purpose is to (re)generate the hash symlinks in /etc/ssl/certs. This is only possible if a file contains a single certificate (or revocation list).

When c_rehash encountersca-certificates.crt which contains the concatenation of all certificates, it rightly complains that this file cannot be hashed. But as noted above, this is indeed just a warning and the update of the certificates did work.

Source: https://git.alpinelinux.org/ca-certificates/

I suggest to close this issue.

Do you have an example CA PEM or a command I can use to generate one? I’ll see if I can reproduce.

To clarify: the CA is not getting added to the ca-certificates.crt file regardless of the error message?

It may be a warning, but why does the message include skipping. This is misleading as others have mentioned.

That isn’t necessarily a failure. It is just saying “the ca-certificates.crt file has multiple certificates so we are not considering it to be symlinked”. What is the actual problem here? Do you have an example I can try to reproduce?

haha. oh my. still an issue all these years later.

@vitruvvius What have you contributed to fixing the issue?

Still a problem, wow.

The following warning is not an error. It’s just how the command works: It checks all certs, including the main file, which contains more than one file. The error message just could be improved:

WARNING: ca-certificates.crt does not contain exactly one certificate or CRL: skipping

For what it’s worth, the exit code for this warning now appears to be 0, fortunately:

bash-5.1# update-ca-certificates --fresh
WARNING: ca-certificates.crt does not contain exactly one certificate or CRL: skipping
bash-5.1# echo $?
0

Message is misleading, but it’s only a warning. It doesn’t mean it failed to run update-ca-certificates as according to exit code, it did succeed if it continues to next step.

In case you have access to python inside your docker image and really want to make sure the certificate was correctly added, here’s an example with a verification.

ARG CA_BUNDLE_SOURCE=https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem
ARG CA_BUNDLE_DESTINATION=/usr/local/share/ca-certificates/rds-combined-ca-bundle.pem

ADD $CA_BUNDLE_SOURCE $CA_BUNDLE_DESTINATION
RUN update-ca-certificates
RUN python -c "x=open('$CA_BUNDLE_DESTINATION').read(); y=open('/etc/ssl/certs/ca-certificates.crt').read(); exit(0) if x in y else exit(-1)"

Above python trick comes from https://unix.stackexchange.com/a/114882/63222 and was adapted to fail if file doesn’t contain other file. There are probably much better ways out there.

At this point, it’s probably easier to append the bundle directly to /etc/ssl/certs/ca-certificates.crt like this:

ARG CA_BUNDLE_SOURCE=https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem
ARG CA_BUNDLE_DESTINATION=/usr/local/share/ca-certificates/rds-combined-ca-bundle.pem

ADD $CA_BUNDLE_SOURCE $CA_BUNDLE_DESTINATION
RUN cat $CA_BUNDLE_DESTINATION >> /etc/ssl/certs/ca-certificates.crt

@andyshinn mentioned that this is just a warning and shouldn’t affect anything. However, update-ca-certificates is exiting with code 1, and I took some time to find out why my command list was failing…

@Acerinth I’m not sure honestly, though I managed to evade that warning somehow. I still mount the CA in the gitlab-runner config.toml as shown above, but I also build my own dind image.

FROM docker:dind

COPY CA.pem /usr/local/share/ca-certificates/ca.crt # <- IMPORTANT to be *.crt
RUN update-ca-certificates --fresh

haha. oh my. still an issue all these years later.

Just ran into this today, not able to add a CA.

I see this “warning” does not contain exactly one certificate or CRL and then immediately try to use my supposedly newly trusted certificate to make a TLS connection using curl and it fails curl: (60) SSL certificate problem: self signed certificate in certificate chain

So in my case it does seem the addition to the trust store was indeed skipped as well. I guess results may vary depending on versions or some other lurking variable.

The issue still persists. I get the warning both for a cert and the store file:

Reproduce:

  1. Try to install cert

     /etc/ssl/certs # update-ca-certificates 
    WARNING: ca-certificates.crt does not contain exactly one certificate or CRL: skipping
    WARNING: ca-cert-<DOMAIN>.<TLD>.pem does not contain exactly one certificate or CRL: skipping
    
  2. Checking, if the cert was added to the store: The solution by @GabLeRoux is good, but probably an overkill. There’s no need for python in your container: Alpine Linux ships with comm (a reverse diff):

    comm -12 /etc/ssl/certs/ca-cert-<DOMAIN>.<TLD>.pem  /etc/ssl/certs/ca-certificates.crt
    

    The result, that you should see if the cert was added to the ca-certificates.crt-store is:

    -----BEGIN CERTIFICATE-----
    

    …or nothing. If you see a complete cert, then it tells you that the cert wasn’t successfully added. In my case, the cert was added, still the WARNING about the single cert is there.

  3. Try to fetch from a local URl:

    /etc/ssl/certs # wget -qO- http://127.0.0.1/nginx_status 
    ssl_client: <DOMAIN>.<TLD>: certificate verification failed: unable to get local issuer certificate
    wget: error getting response: Connection reset by peer
    
  4. Ignore the cert for a wget call. Does not work for other connections where you do not have access to request args:

    /etc/ssl/certs # wget --no-check-certificate -qO- http://127.0.0.1/nginx_status 
    Active connections: 1 
    server accepts handled requests
    10 10 8 
    Reading: 0 Writing: 1 Waiting: 0
    

/ # mv DigiCertSHA2SecureServerCA.crt.pem /usr/local/share/ca-certificates/DigiCertSHA2SecureServerCA.crt / # update-ca-certificates WARNING: ca-certificates.crt does not contain exactly one certificate or CRL: skipping I’m running this in the image itself and get that warning, and I don’t know if my certificates are updated or not.

Problem still exists

Indeed, looks like an upstream bug. The line at https://github.com/alpinelinux/aports/blob/master/main/ca-certificates/update-ca-certificates#L50 should be for key,fn in pairs(certlist) do. I’ll poke upstream and try to get a patch out.