Solution
As implied by Ben Tasker, It seems the issue was that https over Tor requires port 443, which was not opened by the written code. So the solution was to ensure the /etc/tor/torrc
file was modified such that it contained:
HiddenServiceDir /var/lib/tor/nextcloud/
HiddenServicePort 443 127.0.0.1:443
Followed by:
sudo reload tor
(And activating the tor service with:)
sudo tor
and to visit the onion at: https://some_onion.onion:443
Code
The full script for supporting https over tor is:
#!/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"
}
Afterwards you still have to manually load your certificate into your respective browser in settings>search:certificates>...