Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apache warns that my self-signed certificate is a CA certificate

Tags:

As I don't know the openssl command's arguments by heart, I am used to referring to the same SO answer whenever I need to create self-signed certificates (for testing environments). The command looks like:

openssl req -x509 -nodes -newkey rsa:2048 -keyout mysite.key -out mysite.crt -days 365 

And it usually works, for instance on my current Ubuntu 15.10. Today I'm on a fresh install of Debian Jessie and it doesn't. Apache warns at startup that:

[ssl:warn] [pid 1040] AH01906: www.mysite.com:443:0 server certificate is a CA certificate (BasicConstraints: CA == TRUE !?) 

I looked for a solution to the problem and found an answer in a linux forum stating that the following should be used instead:

openssl genrsa -des3 -passout pass:x -out mysite.pass.key 2048 openssl rsa -passin pass:x -in mysite.pass.key -out mysite.key openssl req -new -key mysite.key -out mysite.csr openssl x509 -req -days 365 -in mysite.csr -signkey mysite.key -out mysite.crt 

And it's true, this way the Apache warning disappears.

As far as I understand, this creates a passphrase-protected key, then removes the passphrase, then creates a CSR, then generates the certificate with both the CSR and the key.

So the question is: what does this longer version do that the shorter doesn't, and why is it necessary in some cases (like today for me)?

like image 459
marcv Avatar asked Mar 21 '16 18:03

marcv


People also ask

How do you know if a CERT is self-signed or CA generated?

A certificate is self-signed if the subject and issuer match. A certificate is signed by a Certificate Authority (CA) if they are different. To validate a CA-signed certificate, you also need a CA certificate. The Details tab (not shown here) sections can be expanded to show each field in a certificate.

How do I add a self-signed certificate to trusted CA?

Import the self-signed certificate to the client Windows computer. On the Windows computer, start MMC (mmc.exe). Add the Certificates snap-in for the computer account and manage certificates for the local computer. Import the self-signed certificate into Trusted Root Certification Authorities > Certificates.


2 Answers

Short way (e.g. with OpenSSL 1.1.0f and Apache 2.4.37):

openssl genrsa -out notEncodedPk.key 3072 openssl req -new -out website.csr -sha256 -key notEncodedPk.key openssl x509 -req -in website.csr -days 365 -signkey notEncodedPk.key -out website.cert -outform PEM 

genrsa generates a 3072 bit RSA-Key. (The system should be online for some time to have good data in /dev/(u)random for seeding.) There is no need to generate an encrypted PK (1) and then use rsa to remove the password afterwards. (Maybe earlier versions of the tools required a password?)
req creates the certificate signing request and uses the PK for the signature. Providing something like -sha256 for the digest is optional. (3) Provide your infos in the interactive questionare. Ensure to put your site domain in "Common name:", otherwise the Apache will throw a warning (AH01909) and browsers will throw an "invalid certificate" message because the URL/domain does not match the certificate data (2). Leave "A challange password:" empty.
Use x509 to create a self-signed certificate with -signkey (the subject is copied to issuer). Normally the command works on certificates but with -req it accepts a CSR as an input. Then use your PK for signing the certificate. (-outform and -days are optional, with 30 days as the default value for the latter.)

Problem source:

As user207421 already stated: req creates a CSR OR it creates a self-signed root-CA-like certificate, therefore the typical tutorial tip

openssl req -x509 -nodes -days 365 -newkey rsa:3072 -sha256 -keyout website.key -out website.cert 

is short but normally not what you want. You can also compare created certificates with

openssl x509 -text -noout -in website.cert 

In the certificate, created with the single-line command, you see a section "X509v3 extensions:" with "X509v3 Basic Constraints: critical CA:TRUE". This is exactly the Apache warning message.
Instead, if you create the certificate with the three steps, the "X509v3 extensions:" section is not included into the certificate.

Appendix:

(1) Securing the PK with a password is a good idea in most cases. If the PK is stored without encryption, make sure to restrict access to root. If you use a password, you have to use the -passout/-passin options, but be aware that a simple "x" does not work anymore because some OpenSSL tools require at least 4 characters (otherwise: "result too small/bad password read"). Additionally in Apache you have to use something like SSLPassPhraseDialog buildin to manually enter the required password for the PK (or even for all PKs/certs) during Apache startup.

(2) Anyway, browsers will display a warning for self-signed certificates.

(3) Using SHA-1 would be inadequate for such a large RSA-key. In general, it is a good idea to review your openssl.conf, e.g. in Debian 9 in /etc/ssl/openssl.conf, which contains various defaults, for example signer_digest = sha256.
In the Debian 9 file, you also find in the [req] section a line x509_extensions=v3_ca and this is the reason, why the req command in combination with the -x509 option adds the CA-related extension (basicContraints=critical,CA:true), if used in the single-line style to create a self-signed certificate.

Addidionally you might notice a comment-line # req_extensions=v3_req. Because this line is commented out (in Debian 9 default openssl.cnf), the simple usage of the req command does not include any extensions.
Note that you might use this line in a modified file to add Subject Alternative Name's to the certificate, e.g. so it can handle multiple (sub-)domains (normally a much better choice than using e wildcard in CN, e.g. *.example.com).

like image 192
GerryH Avatar answered Sep 19 '22 21:09

GerryH


complete CA and SSL creation / setup help:

I created my own CA cert and used it to load into browser (as CA authority) and sign my self-created SSL cert for my Apache_on_ubuntu website.

steps:

  1. generate my CA private key:

    # openssl genrsa -des3 -out /etc/ssl/private/myCA.key 2048 
  2. generate root certificate: *****send myCA.pem to all desktop/client browsers.

    # openssl req -x509 -days 5475 -new -nodes -key /etc/ssl/private/myCA.key -sha256 -out /etc/ssl/certs/myCA.pem 
  3. Install the root CA in firefox. (cp myCA.pem to windows box) in firefox: options -> privacy_&_security -> view_certificates -> certificate_manager -> Authorities -> import

  4. Creating CA-Signed Certificates for Your Sites

4.1: create website private key:

# openssl genrsa -out /etc/ssl/private/www.mywebsite.com.key 2048 

4.2: create website CSR: Note: answers don’t need to match the CA cert ans.

# openssl req -new -key /etc/ssl/private/www.mywebsite.com.key -out /etc/ssl/private/www.mywebsite.com.csr 

4.3: Create config file: config file is needed to define the Subject Alternative Name (SAN) extension. "method to match a domain name against a certificate – using the available names within the subjectAlternativeName extension"

# vi /etc/ssl/private/www.mywebsite.com.ext 

...............I have not used the ext file option.....(for hosting multiple SSL sites and certs on same host)

4.4: Create the certificate:

# openssl x509 -req -in /etc/ssl/private/www.mywebsite.com.csr -CA /etc/ssl/certs/myCA.pem -CAkey /etc/ssl/private/myCA.key -CAcreateserial -out /etc/ssl/certs/www.mywebsite.com.crt -days 5475 -sha256 
  1. create ssl-conf file:

    # cat /etc/apache2/conf-available/ssl-params.conf # modern configuration, tweak to your needs 

    SSLProtocol -all +TLSv1.2 +TLSv1.3 SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 SSLHonorCipherOrder on SSLCompression off SSLSessionTickets off

  2. restart apache:

    # systemctl restart apache2 
like image 20
rajeev Avatar answered Sep 20 '22 21:09

rajeev