SSL Certificate For LAN Only Access (iOS 13)

Hello @chench0,
I have a tested solution which you can execute on Linux or MacOS. Instead of just creating a self signed certificate I decided to create CA first then the certificate, that way you can create and sign multiple certificates for your domain.
Secondly I also have a configuration to create a wildcard certificate. Modify as you please (DNS.1, DNS.2 in config file within the script).

Create Certificates

  1. Create a file called caCertGenerator.sh
  2. Copy the content given (see below)
  3. Replace the variables at the beginning of the script (
  4. Make it executable: chmod +x caCertGenerator.sh
  5. Run it ./caCertGenerator.sh

File: caCertGenerator.sh

#!/bin/bash

# Variables to replace ##############
CA_NAME=rootCA
# home.local
# example: www.example.com, BASE_DOMAIN=com, DOMAIN=example
BASE_DOMAIN=local
DOMAIN=home
TLS_DOMAIN=${DOMAIN}.${BASE_DOMAIN}
countryName="DE"
organizationName="Home GmbH"
emailAddress= "webmaster@${TLS_DOMAIN}"
organizationalUnitName="IT Department"
stateOrProvinceName="Bayern"
localityName="Schweinfurt"
postalCode="97422"
streetAddress="Weingartenweg 15"
organizationName="Home GmbH"
# End Variables to replace ##########

# Create folders
mkdir -p ca
mkdir -p domain
##############################
# Create configuration files
##############################

createRootCaConf() {
cat <<-EOF
[ req ]
default_bits        = 2048                   # RSA key size
encrypt_key         = yes                    # Protect private key | default = yes
default_md          = sha256                 # MD to use
utf8                = yes                    # Input is UTF-8
string_mask         = utf8only               # Emit UTF-8 strings
prompt              = no                     # Don't prompt for DN
distinguished_name  = req_distinguished_name # DN section

[req_distinguished_name]
countryName            = "${countryName}"            # C=
stateOrProvinceName    = "${stateOrProvinceName}"    # ST=
localityName           = "${localityName}"           # L=
organizationName       = "${organizationName}"       # O=
organizationalUnitName = "${organizationalUnitName}" # OU=
commonName             = "${TLS_DOMAIN}"             # CN=
emailAddress           = "webmaster@${TLS_DOMAIN}"   # CN/emailAddress=
EOF
}

# Includes commented variables, for easy customisation
createTlsConf() {
cat <<-EOF
[ req ]
default_bits        = 2048                   # RSA key size
# default_keyfile   = key.pem
# encrypt_key       = yes                    # Protect private key | default = yes
default_md          = sha256                 # MD to use
# utf8              = yes                    # Input is UTF-8
# string_mask       = utf8only               # Emit UTF-8 strings
prompt              = no                     # Don't prompt for DN

distinguished_name  = req_distinguished_name
req_extensions      = req_ext                # Desired extensions
# attributes        = req_attributes

[req_distinguished_name]
0.domainComponent       = "${BASE_DOMAIN}"
1.domainComponent       = "${DOMAIN}"
countryName             = "${countryName}"            # C=
stateOrProvinceName     = "${stateOrProvinceName}"    # ST=
localityName            = "${localityName}"           # L=
postalCode              = "${postalCode}"             # L/postalcode=
streetAddress           = "${streetAddress}"          # L/street=
organizationName        = "${organizationName}"       # O=
organizationalUnitName  = "${organizationalUnitName}" # OU=
commonName              = "${TLS_DOMAIN}"             # CN=
emailAddress            = "webmaster@${TLS_DOMAIN}"   # CN/emailAddress=
# 0.commonName          = "example.com"               # CN=
# 1.commonName          = "www.example.com"           # CN=
# 2.commonName          = "www2.example.com"          # CN=
# 3.commonName          = "www3.example.com"          # CN=

[ req_ext ]
# authorityKeyIdentifier = keyid
basicConstraints         = CA:FALSE
keyUsage                 = digitalSignature, keyEncipherment
extendedKeyUsage         = serverAuth,clientAuth
# keyUsage               = digitalSignature,serverAuth,clientAuth,keyEncipherment, dataEncipherment, nonRepudiation
# extendedKeyUsage       = codeSigning
subjectAltName           = @alt_names

[ req_attributes ]
unstructuredName         = "Home GmbH"

[ alt_names ]
DNS.1 =   ${TLS_DOMAIN}
DNS.2 = *.${TLS_DOMAIN}
EOF
}

# This has dublicate variables, but need to be created to include
# authorityKeyIdentifier. The other variables are there as they will be
# replaced otherwise
createExtConf() {
cat <<-EOF
authorityKeyIdentifier = keyid
basicConstraints       = CA:FALSE
keyUsage               = digitalSignature, keyEncipherment
extendedKeyUsage       = serverAuth,clientAuth
subjectAltName         = @alt_names

[ alt_names ]
DNS.1 =   ${TLS_DOMAIN} # Specific domain
DNS.2 = *.${TLS_DOMAIN} # Wildcard certificate, for any subdomain
EOF
}


createRootCaConf > ./ca/${CA_NAME}.csr.cnf

createTlsConf > ./domain/${TLS_DOMAIN}.csr.cnf
createExtConf > ./domain/${TLS_DOMAIN}.ext.cnf

##############
# Signing CA #
##############

# will ask for a password
openssl genrsa -aes256 -out ca/${CA_NAME}.key 2048
# Verify above
# openssl rsa  -noout -text -in private-key.pem                                                 

# will ask for a password
# Variation with config file
openssl req -x509 -new -key ca/${CA_NAME}.key -sha256 -days 730 -out ca/${CA_NAME}.pem -config ca/${CA_NAME}.csr.cnf
# Verify above
# openssl x509 -noout -text -in rootCA.pem      

##############
# Site TLS   #
##############

# Create rsa key without encryption (-aes256 is missing :) )
openssl genrsa -out domain/${TLS_DOMAIN}.key 2048
# Create Signing request (.csr)
openssl req -new -key domain/${TLS_DOMAIN}.key -out domain/${TLS_DOMAIN}.csr -config domain/${TLS_DOMAIN}.csr.cnf
# Sign the certificate with your root CA
openssl x509 -days 365 -sha256 -req -in domain/${TLS_DOMAIN}.csr -CA ca/${CA_NAME}.pem -CAkey ca/${CA_NAME}.key -CAcreateserial -extfile domain/${TLS_DOMAIN}.ext.cnf -out domain/${TLS_DOMAIN}.crt

Copy certificates

Copy the *.crt and *.key (under the domain folder created from the script) and put
them inside bwdata/ssl/self/<domainName>
Correct the path on bwdata/config.yml on ssl_certificate_path and ssl_key_path.

Import

Import on iOS link

End

Hope this helps :slight_smile:

1 Like