Self-host Nextcloud – Part 2 – Self-signed SSL Certificate

Background:

In Part 1 of the Nextcloud series we’ve discussed how to bring up a self-hosted Nextcloud instance. In this article I’d like to discuss the SSL troubleshooting process. Reference articles: article 1, article 2, article 3, video.

Issues:

  • SSL/HTTPS won’t go into effect even if I’ve enabled SSL in Apache, generated the certs, and configured the config files.
  • HTTPS goes into effect in Firefox but always said “Not Secure” or “Invalid” cert in Chrome.
  • Chrome errors: “NET::ERR_CERT_AUTHORITY_INVALID”, “NET::ERR_CERT_COMMON_NAME_INVALID”

Solutions:

1. Originally, I followed this article to generate my certs, but the cert won’t get accepted by Chrome even if I’ve imported it into Trusted Root Certification Authorities store. The certificate generation procedures that worked are:

# Generate a Certificate Authority (CA)

openssl genrsa -des3 -out nextcloudCA.key 2048
# A password needs to be created after this command is run.

openssl req -x509 -new -nodes -key nextcloudCA.key -sha256 -days 365 -out nextcloudCA.pem
# A series of information will be asked after this command is run. You can customize your own or just follow whatever is in the [dn] section below.

openssl x509 -outform pem -in nextcloudCA.pem -out nextcloudCA.crt
# Generate a crt file for future import. The pem file can also be used for import.

# Prepare the v3.ext and config files.
# cert.csr.cnf file
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

[dn]
C=Replace-with-Your-Info
ST=Replace-with-Your-Info
L=Replace-with-Your-Info
O=Replace-with-Your-Info
OU=Replace-with-Your-Info
emailAddress=Replace-with-Your-Info
CN=Replace-with-Your-Info

# v3.ext file
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = Replace-with-Your-Info-Or-Delete-Line
DNS.2 = Replace-with-Your-Info-Or-Delete-Line
DNS.3 = Replace-with-Your-Info-Or-Delete-Line
IP.1 = Replace-with-Your-Info-Or-Delete-Line
IP.2 = Replace-with-Your-Info-Or-Delete-Line

# Generate the domain name cert
openssl req -new -sha256 -nodes -out nextcloudDNCert.csr -newkey rsa:2048 -keyout nextcloudDNCert.key -config cert.csr.cnf

openssl x509 -req -in nextcloudDNCert.csr -CA nextcloudCA.crt -CAkey nextcloudCA.key -CAcreateserial -out nextcloudDNCert.crt -days 365 -sha256 -extfile v3.ext

2. Put your cert files (nextcloudDNCert.crt and nextcloudDNCert.key) in the directories that’s suitable for your setup, and modify your SSL config file or the nextcloud.conf file to point to the cert files. Sample config files can be downloaded here: sample.nextcloud.conf .

# Under /etc/apache2/sites-available, modify nextcloud.conf .

SSLCertificateFile Your-Cert-File-Path
SSLCertificateKeyFile Your-Cert-Key-File-Path

3. Restart Apache service

service apache2 restart

4. Import nextcloudCA.crt into your Trusted Root Certification Authorities store, clear your browser’s cookies, restart the browser and access your Nextcloud server again, this time the HTTPS padlock should be solid grey, no “Not Secure” and other errors.

Explanation about the certificate errors:

“NET::ERR_CERT_AUTHORITY_INVALID”

This is due to how the certs were generated, when using this method to generate, I always got the error, but after I switched to the method written in step #1 and the certs were properly imported, this error was gone.

“NET::ERR_CERT_COMMON_NAME_INVALID”

Assuming you already put in the Common Name (which is your FQDN, e.g. nextcloud.mydomain.com) correctly when generating the certs and it still gave this error, check the alt_names section above, make sure all the DNS.x and IP.x entries cover all your alt_name variants. Once I configured all the stuff under the alt_names section correctly (for me it’s “localhost”, my server’s IP, and the “subdomain” URL I’m using), the error was gone.

Other:

  • Some mentioned that Chrome versions played a role in accepting self-signed certs. But my issues were resolved without dealing with Chrome versions.
  • I’ve seen posts mentioning the chrome://flags/#allow-insecure-localhost flag, but it didn’t apply to my scenario.
  • Some articles say that self-signed certs won’t be deemed secure and valid by browsers/OSs/Chrome, which is not true if the certs are generated and imported correctly.
  • Security hardening – forcing HTTPS, Strict-Transport-Security, and URL redirections. See sample.nextcloud.conf and its comments for details.