sslnginxopenssldocker-compose

nginx SSL no start line: expecting: TRUSTED CERTIFICATE


I'm out of ideas and I need help please!

I create my SSL using Openssl with this:

openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout key.pem -out cert.pem -days 3650

The cert.pem looks like this:

-----BEGIN CERTIFICATE-----
cert
-----END CERTIFICATE-----

The key.pem looks like this:

-----BEGIN PRIVATE KEY-----
key
-----END PRIVATE KEY-----

In docker-compose I have the cert/key sent to etc/nginx/ssl/...

volumes:
  - ./sites:/etc/nginx/conf.d
  - ./conf/nginx.conf:/etc/nginx/nginx.conf
  - ./ssl/cert.pem:/etc/nginx/ssl/cert.pem
  - ./ssl/key.pem:/etc/nginx/ssl/key.pem

In nginx I have it added like this:

  listen    443 ssl;
  server_name       localhost;
  ssl_certificate   ssl/cert.pem;
  ssl_certificate_key   ssl/key.pem;

When I start up docker-compose, I get this error with nginx:

web_1    | 2018/08/17 16:38:47 [emerg] 1#1: PEM_read_bio_X509_AUX("/etc/nginx/ssl/cert.pem") failed (SSL: error:0906D06C:PEM routines:PEM_read_bio:no start line:Expecting: TRUSTED CERTIFICATE)
web_1    | nginx: [emerg] PEM_read_bio_X509_AUX("/etc/nginx/ssl/cert.pem") failed (SSL: error:0906D06C:PEM routines:PEM_read_bio:no start line:Expecting: TRUSTED CERTIFICATE)

I've been working on this for several days now and I'm not sure why I keep getting this error. I've tried making it crt/key instead of .pem and I get the same error. If I just remove ssl all together the server works fine, but I need SSL very badly. Pleeeaaase help!


Solution

  • A "normal" certificate, once encoded in PEM will look like this:

    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
    

    (the ... is Base64 encoding of a DER structure)

    This is normally (with the associated key, typically in separate file) the thing needed by any TLS enabled application when it wants to show its identity to the remote end.

    As a side note, since it seems to be popular (wrong) belief, the filename by itself, including the extension, has explicitly no consequences on the working (or not) status of the content. You can name your files foobar.42 and buzz.666 and if their content is valid they will work as well... of course maintenance by the human would be harder, hence the convention of using often .crt for a certificate (or .cert for non-DOS based constrained environments) and .key for a keyfile, and using typically the site name (for a website) or part of it for the name, such as example.com.crt. But again, those are only one possible set of conventions, and any program needing these files do not care about the name, just the content. Some are using the .pem extension also.

    See https://en.wikipedia.org/wiki/X.509#Certificate_filename_extensions for all the above it has a good discussion/presentation of options.

    Now in your case the error message was telling you it expected to have a content written as such:

    -----BEGIN TRUSTED CERTIFICATE-----
    ...
    -----END TRUSTED CERTIFICATE-----
    

    the only difference being the added TRUSTED keyword. But why, and when does it happen?

    A certificate is signed by one "certificate authority" through one or more intermediates. This builds a chain of trust up to a root certificate, where the issuer is equal to the subject, this certificate signs itself.

    You generated your certificate yourself, so this is a "self-signed" certificate, indistinguishable technically from a CA certificate, except that no system by default, including your own, will give trust to such certificate without specific configuration.

    This is basically what the error message tells you: the application says it is loading a certificate based on your configuration that it can not validate (because it is self signed) and at the same time you did not explicitely configure it to trust it.

    This may be different depending on the application or its version, because the guide at https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-nginx-in-ubuntu-16-04 does basically the same thing as you and it works, but without showing the content of the certificate.

    In your openssl call, if you add -trustout it will generate BEGIN TRUSTED CERTIFICATE instead of BEGIN CERTIFICATE. This may happen by default also, depending on how openssl is installed/configured on your system. On the contrary, you have -clrtrust. See the "Trust Settings" section of the openssl x509 command at https://www.openssl.org/docs/man1.1.0/apps/x509.html