Context
After setting up a self-hosted nextcloud server on Ubuntu 22.10 over a tor domain, I created a self-signed SLL certificate using the script below:
Code
This script first
- generates the certificate authority (CA) and SSL certificates, and then it adds the CA private key to:
"/usr/local/share/ca-certificates/$ca_public_key_filename"
and reloads the trusted ca certificates with:
sudo update-ca-certificates
- It also adds the SSL prublic and private key and the full chain certificate into Nextcloud.
- The
fullchain.pem
consists of the SSL certificate, followed by the CA certificate.
#!/usr/bin/env bash# Here is the list of certificates and their description:# First you create your own certificate authority.CA_PRIVATE_KEY_FILENAME="ca-key.pem"CA_PUBLIC_KEY_FILENAME="ca.pem"# Same file as ca.pem except different file extension and content.CA_PUBLIC_CERT_FILENAME="ca.crt"# Then you create a SSL certificate.SSL_PRIVATE_KEY_FILENAME="cert-key.pem"# Then create a sign-request (for your own CA to sign your own SSL certificate)CA_SIGN_SSL_CERT_REQUEST_FILENAME="cert.csr"SIGNED_DOMAINS_FILENAME="extfile.cnf"# Then create the signed public SSL cert.SSL_PUBLIC_KEY_FILENAME="cert.pem"# Then merge the CA and SLL cert into one.MERGED_CA_SSL_CERT_FILENAME="fullchain.pem"setup_tor_ssl() { local onion_address="$1" # Create domains accepted by certificate. local domains #domains="DNS:$onion_address,IP:127.0.0.1" #domains="DNS:localhost,IP:$onion_address" # IP onion does not work #domains="DNS:*.$onion_address" # Does not work. #domains="DNS:$onion_address" # Does not work. domains="DNS:localhost,DNS:$onion_address" # Works for localhost echo "domains=$domains.end_without_space" delete_target_files # Generate and apply certificate. generate_ca_cert "$CA_PRIVATE_KEY_FILENAME" "$CA_PUBLIC_KEY_FILENAME" generate_ssl_certificate "$CA_PUBLIC_KEY_FILENAME" "$CA_PRIVATE_KEY_FILENAME" "$CA_SIGN_SSL_CERT_REQUEST_FILENAME" "$SIGNED_DOMAINS_FILENAME" "$SSL_PUBLIC_KEY_FILENAME" "$SSL_PRIVATE_KEY_FILENAME" "$domains" verify_certificates "$CA_PUBLIC_KEY_FILENAME" "$SSL_PUBLIC_KEY_FILENAME" merge_ca_and_ssl_certs "$SSL_PUBLIC_KEY_FILENAME" "$CA_PUBLIC_KEY_FILENAME" "$MERGED_CA_SSL_CERT_FILENAME" install_the_ca_cert_as_a_trusted_root_ca "$CA_PUBLIC_KEY_FILENAME" "$CA_PUBLIC_CERT_FILENAME" add_certs_to_nextcloud "$SSL_PUBLIC_KEY_FILENAME" "$SSL_PRIVATE_KEY_FILENAME" "$MERGED_CA_SSL_CERT_FILENAME"}generate_ca_cert() { local ca_private_key_filename="$1" local ca_public_key_filename="$2" # Generate RSA openssl genrsa -aes256 -out "$ca_private_key_filename" 4096 # Generate a public CA Cert openssl req -new -x509 -sha256 -days 365 -key "$ca_private_key_filename" -out "$ca_public_key_filename"}generate_ssl_certificate() { local ca_public_key_filename="$1" local ca_private_key_filename="$2" local ca_sign_ssl_cert_request_filename="$3" local signed_domains_filename="$4" local ssl_public_key_filename="$5" local ssl_private_key_filename="$6" local domains="$7" # Example supported domains: # DNS:your-dns.record,IP:257.10.10.1 # Create a RSA key openssl genrsa -out "$ssl_private_key_filename" 4096 # Create a Certificate Signing Request (CSR) openssl req -new -sha256 -subj "/CN=yourcn" -key "$ssl_private_key_filename" -out "$ca_sign_ssl_cert_request_filename" # Create a `extfile` with all the alternative names echo "subjectAltName=$domains" >>"$signed_domains_filename" # optional #echo extendedKeyUsage = serverAuth >> "$ca_sign_ssl_cert_request_filename" # Create the public SSL certificate. openssl x509 -req -sha256 -days 365 -in "$ca_sign_ssl_cert_request_filename" -CA "$ca_public_key_filename" -CAkey "$ca_private_key_filename" -out "$ssl_public_key_filename" -extfile "$signed_domains_filename" -CAcreateserial}verify_certificates() { local ca_public_key_filename="$1" local ssl_public_key_filename="$2" openssl verify -CAfile "$ca_public_key_filename" -verbose "$ssl_public_key_filename"}merge_ca_and_ssl_certs() { local ssl_public_key_filename="$1" local ca_public_key_filename="$2" local merged_ca_ssl_cert_filename="$3" cat "$ssl_public_key_filename" >"$merged_ca_ssl_cert_filename" cat "$ca_public_key_filename" >>"$merged_ca_ssl_cert_filename"}install_the_ca_cert_as_a_trusted_root_ca() { local ca_public_key_filename="$1" local ca_public_cert_filename="$2" # The file in the ca-certificates dir must be of extension .crt: openssl x509 -outform der -in "$ca_public_key_filename" -out "$ca_public_cert_filename" # First remove any old cert if it existed. sudo rm "/usr/local/share/ca-certificates/$ca_public_cert_filename" sudo update-ca-certificates # TODO: Verify target directory exists. # On Debian & Derivatives: #- Move the CA certificate (`"$ca_private_key_filename"`) into `/usr/local/share/ca-certificates/ca.crt`. sudo cp "$ca_public_cert_filename" "/usr/local/share/ca-certificates/$ca_public_cert_filename" # TODO: Verify target file exists. # TODO: Verify target file MD5sum. # Update the Cert Store with: sudo update-ca-certificates}add_certs_to_nextcloud() { local ssl_public_key_filename="$1" local ssl_private_key_filename="$2" local merged_ca_ssl_cert_filename="$3" # First copy the files into nextcloud. # Source: https://github.com/nextcloud-snap/nextcloud-snap/issues/256 # (see nextcloud.enable-https custom -h command). #sudo cp ca.pem /var/snap/nextcloud/current/ca.pem sudo cp "$ssl_public_key_filename" /var/snap/nextcloud/current/"$ssl_public_key_filename" sudo cp "$ssl_private_key_filename" /var/snap/nextcloud/current/"$ssl_private_key_filename" sudo cp "$merged_ca_ssl_cert_filename" /var/snap/nextcloud/current/"$merged_ca_ssl_cert_filename" # CLI sudo /snap/bin/nextcloud.enable-https custom Says: sudo /snap/bin/nextcloud.enable-https custom "/var/snap/nextcloud/current/$ssl_public_key_filename" "/var/snap/nextcloud/current/$ssl_private_key_filename" "/var/snap/nextcloud/current/$merged_ca_ssl_cert_filename"}delete_target_files() { rm "$CA_PRIVATE_KEY_FILENAME" rm "$CA_PUBLIC_CERT_FILENAME" rm "$CA_PUBLIC_KEY_FILENAME" rm "$SSL_PRIVATE_KEY_FILENAME" rm "$CA_SIGN_SSL_CERT_REQUEST_FILENAME" rm "$SIGNED_DOMAINS_FILENAME" rm "$SSL_PUBLIC_KEY_FILENAME" rm "$MERGED_CA_SSL_CERT_FILENAME" sudo rm "/usr/local/share/ca-certificates/$CA_PUBLIC_KEY_FILENAME" sudo rm "/usr/local/share/ca-certificates/$CA_PUBLIC_CERT_FILENAME" sudo rm "/var/snap/nextcloud/current/$SSL_PUBLIC_KEY_FILENAME" sudo rm "/var/snap/nextcloud/current/$SSL_PRIVATE_KEY_FILENAME" sudo rm "/var/snap/nextcloud/current/$MERGED_CA_SSL_CERT_FILENAME"}
Output
The output of this script can be read as:
$src/main.sh -hdomains=DNS:some_onion.onion,IP:127.0.0.1.end_without_spacerm: cannot remove 'ca.pem': No such file or directoryrm: cannot remove 'cert.csr': No such file or directoryrm: cannot remove 'extfile.cnf': No such file or directoryrm: cannot remove 'cert.pem': No such file or directoryrm: cannot remove 'fullchain.pem': No such file or directoryrm: cannot remove '/usr/local/share/ca-certificates/ca.pem': No such file or directoryGenerating RSA private key, 4096 bit long modulus (2 primes)................................................................................................................................................................................++++...................................................................................................................................................................................................................................++++e is 65537 (0x010001)Enter pass phrase for ca-key.pem:Verifying - Enter pass phrase for ca-key.pem:Enter pass phrase for ca-key.pem:You are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [AU]:soState or Province Name (full name) [Some-State]:state3Locality Name (eg, city) []:locality3Organization Name (eg, company) [Internet Widgits Pty Ltd]:org3Organizational Unit Name (eg, section) []:orgunit3Common Name (e.g. server FQDN or YOUR name) []:cn3Email Address []:email3@email.comGenerating RSA private key, 4096 bit long modulus (2 primes)...................................................................++++.............................................++++e is 65537 (0x010001)Signature oksubject=CN = yourcnGetting CA Private KeyEnter pass phrase for ca-key.pem:cert.pem: OKUpdating certificates in /etc/ssl/certs...0 added, 0 removed; done.Running hooks in /etc/ca-certificates/update.d...Processing triggers for ca-certificates-java (20220719) ...done.Updating Mono key storeMono Certificate Store Sync - version 6.8.0.105Populate Mono certificate store from a concatenated list of certificates.Copyright 2002, 2003 Motus Technologies. Copyright 2004-2008 Novell. BSD licensed.Importing into legacy system store:I already trust 124, your new list has 124Import process completed.Importing into BTLS system store:I already trust 124, your new list has 124Import process completed.Donedone.Installing custom certificate... doneRestarting apache... done
Error Message
After running the script successfully, I can manually import the ca.crt
into brave at: brave://settings/certificates This ensures https works for https://localhost:81 . However, when I open the tor browser in brave, and visit the some_onion.onion
it returns:
This site can’t provide a secure connectionsome_onion.onion sent an invalid response.ERR_SSL_PROTOCOL_ERROR
Question
How can I ensure the certificate is trusted on both the some_onion.onion
link, as well as on localhost?
Doubt
- I am unsure whether:
echo "subjectAltName=DNS:some_onion_link.onion"
is permitted. for an SSL certificate. I wonder why the tor version of Brave does not show why the certificate is not trusted.