Be you own Root Certification Authority. Create a Root Certificate and use it to sign any needed End-Entity Certificates.
The .internal top-level domain is reserved for private-use applications.
These scripts show how we might create certificates for *.home.internal:
$ ./RootCertificate.sh $ ./Certificate.sh $ ls -1 HOME* HOME_INTERNAL.crt HOME_INTERNAL.key HOME_INTERNAL.pfx HOME_INTERNAL_CHAIN.pem HOME_INTERNAL_CHAIN_WITH_KEY.pem HOME_INTERNAL_ROOT.crt HOME_INTERNAL_ROOT.key
RootCertificate.sh creates a Root Certificate:
#!/bin/bash
# Create the Root Certification Authority's Root Certificate
CERTNAME="HOME_INTERNAL_ROOT"
COMMON_NAME="HOME.INTERNAL ROOT"
## --
openssl=/usr/local/opt/openssl/bin/openssl # homebrew on macOS
OPENSSL_CONF="$CERTNAME.cfg"
export COMMON_NAME OPENSSL_CONF
## --
cat >$OPENSSL_CONF << 'EOF'
[ req ]
default_bits = 4095
default_md = sha256
prompt = no
encrypt_key = no
utf8 = yes
string_mask = utf8only
distinguished_name = req_distinguished_name
req_extensions = v3_req
x509_extensions = v3_req
[ req_distinguished_name ]
commonName = ${ENV::COMMON_NAME}
[ v3_req ]
basicConstraints = critical, CA:true, pathlen:0
authorityKeyIdentifier = keyid:always, issuer
keyUsage = digitalSignature, cRLSign, keyCertSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
EOF
$openssl req -new -x509 -days 3650 -keyout "$CERTNAME.key" -out "$CERTNAME.crt"
rm "$OPENSSL_CONF"
download:
RootCertificate.shCertificate.sh creates a End-Entity Certificate signed by the Root Certificate:
#!/bin/bash
set -e
# Create End-Entity Certificate signed by the Root Certificate
DAYS=365
CERTNAME="HOME_INTERNAL"
COMMON_NAME="home.internal"
SUBJECT_ALT_NAME="DNS:home.internal,DNS:*.home.internal,DNS:localhost"
PFX_PASSWORd="changeit"
ROOT_CERTNAME="HOME_INTERNAL_ROOT" # CERTNAME from RootCertificate.sh
## --
openssl=/usr/local/opt/openssl/bin/openssl # homebrew on macOS
OPENSSL_CONF="$CERTNAME.cfg"
export COMMON_NAME SUBJECT_ALT_NAME OPENSSL_CONF
## --
cat >$OPENSSL_CONF << 'EOF'
[ req ]
default_bits = 2048
default_md = sha256
prompt = no
encrypt_key = no
utf8 = yes
string_mask = utf8only
distinguished_name = req_distinguished_name
req_extensions = v3_req
x509_extensions = v3_req
[ req_distinguished_name ]
commonName = ${ENV::COMMON_NAME}
[ v3_req ]
subjectAltName = ${ENV::SUBJECT_ALT_NAME}
basicConstraints = CA:false
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectKeyIdentifier = hash
EOF
# generate a private key and a certificate signing request
$openssl req -new -keyout "$CERTNAME.key" -out "$CERTNAME.csr"
# Sign the certificate with root CA cert
$openssl x509 -req -days $DAYS \
-CAkey $ROOT_CERTNAME.key -CA $ROOT_CERTNAME.crt \
-extfile $OPENSSL_CONF -extensions v3_req \
-in "$CERTNAME.csr" -out "$CERTNAME.crt"
rm "$OPENSSL_CONF"
rm "$CERTNAME.csr"
#$openssl x509 -outform der -in "$CERTNAME.crt" -out "$CERTNAME.der"
$openssl verify -CAfile $ROOT_CERTNAME.crt $CERTNAME.crt
# generate a pfx file
cat "$CERTNAME.key" "$CERTNAME.crt" |\
$openssl pkcs12 -export -out "$CERTNAME.pfx" -name "$COMMON_NAME" -password "pass:$PFX_PASSWORd"
cat $CERTNAME.key $CERTNAME.crt > ${CERTNAME}_CHAIN_WITH_KEY.pem
cat $CERTNAME.crt > ${CERTNAME}_CHAIN.pem
download:
Certificate.shTLS Analysis
SSLyze can analyze the SSL/TLS configuration of a server, e.g.docker run --rm -it -v/tmp/HOME_INTERNAL_ROOT.crt:/tmp/cert.crt nablac0d3/sslyze --certinfo_ca_file /tmp/cert.crt myhost.home.internal
home.arpa
The Special-Use Domain'home.arpa' (RFC 8375)
has been added in the ICANN domains section of the Public Suffix List,
and browsers like Google Chrome does not allow
wildcard certs for public/ICANN registry controlled domains. Before this, '*.home.arpa' worked, but now
'*.subdomain.home.arpa' would be necessary.