I installed a Snapshot OpenWrt image on a Pi 4.
I am accessing the OpenWrt LuCI Web admin page from a Windows PC running Chrome v87
OpenWrt didn't come with LuCI so I installed it along with nginx ssl version: opkg install luci-ssl-nginx
It creates self signed certs in /etc/nginx/conf.d
When I browse to... https://openwrt.lan/cgi-bin/luci/ I get the log-in page for my OpenWrt router and I can log in and it all works fine.
So it looks like I have secure communication between my browser and the router Luci home page? Despite reading ?official documentation about Nginx webserver and How to get rid of LuCI HTTPS certificate warnings I am totally confused as to what I am supposed to do to get rid of that address bar warning.
Here is my current understanding:
Self-signed certificates are auto generated during the install of nginx. Does the Chrome error message above mean that these certs are not adequate to stop the browser error? Because they only seem to have a Common Name (OpenWrt) which is not enough if your Chrome version is > v.58? Instead I need to follow the steps in How to get rid of LuCI HTTPS certificate warnings and...
Create /etc/ssl/myconfig.conf that contains a Subject Alternative Name extension containing a domain name or IP address (DNS.1 and IP.1)
Then go here: cd /etc/ssl and generate a new pair of keys
Isn't this more a thing of Chrome bein a pain in the behind about self-signed certificates? I vaguely remember something about Google wanting to be holier than thou again.
A trusted root certificate needs to be in CA format, not just a certificate. In other words create a self-signed CA (certificate with CA flag set), then use it to sign the server certificate. Export the public part of the CA to your browser machine. You don't have to export the server certificate. The public part of the server certificate is automatically transferred during each https negotiation.
It's a significant risk to install a trusted root CA on your machine because if someone is able to steal the private key, they can create signed certificates to set up a fake version of any website you may visit.
Chrome is extremely strict about this. I'm surprised it's letting you access the page at all.
https does not protect a server from malicious users. Don't expose LuCI to the Internet even in https mode.
I am using Windows OS and Google Chrome to run a webpage hosted in Nginx on OpenWrt.
This solution may not be the only way or even the best way of doing this. It allows you to run websites on your local lan using https and not get annoying https browser errors.
Here is what I did:
This script, genCA.sh, creates a root CA pem and key file.
When you run it you just need to specify any name you like, e.g: $./genCA.sh mylanCA
You add the PEM file to Chrome > Manage Certificates > Trusted Root Certification Authorities Then restart Chrome.... chrome://restart
This script has to be run ONCE only.
#!/bin/bash
# Directories
cur=$(pwd)
tmp=$(mktemp -d)
scriptName=$(basename "$0")
# Certificate Variables
OUTPATH="./"
VERBOSE=0
DURATION=3650 # 10 years
C="US"
ST="California"
L="Ureka"
O="Paradise Inc"
OU="The Beach"
safeExit() {
if [ -d "$tmp" ]; then
if [ $VERBOSE -eq 1 ]; then
echo "Removing temporary directory '${tmp}'"
fi
rm -rf "$tmp"
fi
trap - INT TERM EXIT
exit
}
# Help Screen
help() {
echo -n "${scriptName} [OPTIONS] --name=mylanCA
Generate a CA using OpenSSL which you can use to make your own self-signed Certs
Options:
-n|--name Name to give your own Certificate Authority
-h|--help Display this help and exit
"
}
# Script starts here...
# Process Arguments
while [ "$1" != "" ]; do
PARAM=$(echo "$1" | awk -F= '{print $1}')
VALUE=$(echo "$1" | awk -F= '{print $2}')
case $PARAM in
-h|--help) help; safeExit ;;
-n|--name) NAME=$VALUE ;;
*) echo "ERROR: unknown parameter \"$PARAM\""; help; exit 1 ;;
esac
shift
done
# Prompt for variables that were not provided in arguments
checkVariables() {
# Country
if [ -z "$NAME" ]; then
echo -n "Name to give your own Certificate Authority:"
read -r NAME
fi
}
# Build TLS Certificate
build() {
# Sanitise domain name for file name
FILENAME=${NAME/\*\./}
# Generate CA key & crt
openssl genrsa -out "${FILENAME}_CA.key" 2048
openssl req -x509 -new -nodes -key "${FILENAME}_CA.key" -sha256 -days "${DURATION}" -out "${OUTPATH}${FILENAME}_CA.pem" -subj "/C=$C/ST=$ST/L=$L/O=$O/OU=$OU/CN=$NAME/emailAddress=info@${FILENAME}.com"
}
checkVariables
build
safeExit
Next step:
This script, gen-self-signed.sh, creates the cert/key pair that are signed by the CA created above. You add them to your server block .conf file on Nginx on OpenWrt.
Before you run it you need to update the info at the top of the script between the two #============== lines, with details specific to your needs.
Then save the file and run the script, takes no parameters.
Reload Nginx should be enough, may need to restart?
#!/bin/bash
#==================================================================
# When creating a new cert/key pair for your site you only need to
# change the details below and make sure CA_PEM and CA_KEY are in the
# same directory as this script and that CA_PEM is added to your browser.
# Then add the newly created .key/.crt pair to your webserver.
CN="mysite.lan"
NAMES="mysite.lan,www.mysite.lan,fun.mysite.lan"
IP="192.168.1.254"
C="US"
ST="New York"
L="Manhatton"
O="Studio 54"
OU="Fun Times"
DURATION=3650 # 10 years
# Your CA details
CA_PEM="mylanCA_CA.pem"
CA_KEY="mylanCA_CA.key"
#==================================================================
j=0
SAN=""
getaltnames(){
for i in $(echo $NAMES | sed "s/,/ /g")
do
if [[ ! -z "$i" ]]; then
j=$((j+1))
if [ "$j" -gt 1 ]; then
SAN="${SAN}"$'\n'
fi
SAN="${SAN}DNS.${j} = ${i}"
fi
done <<< "${CN},${SAN}"
}
buildCsrCnf() {
cat << EOF > "${CN}.csr.cnf"
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
[dn]
C=${C}
ST=${ST}
L=${L}
O=${O}
OU=${OU}
CN=${CN}
emailAddress=info@${CN}
EOF
}
buildExtCnf() {
cat << EOF > "${CN}.v3.ext"
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
${SAN}
IP.1=${IP}
EOF
}
# Build TLS Certificate
build() {
# Put list of sub domains (NAMES) into SAN variable (${SAN})
getaltnames
# CSR Configuration
buildCsrCnf
# Create v3.ext configuration file
buildExtCnf
# Server key
openssl req -new -sha256 -nodes -out "${CN}.csr" -newkey rsa:2048 -keyout "${CN}.key" -config <( cat "${CN}.csr.cnf" )
# Server certificate
openssl x509 -req -in "${CN}.csr" -CA "${CA_PEM}" -CAkey "${CA_KEY}" -CAcreateserial -out "${CN}.crt" -days "${DURATION}" -sha256 -extfile "${CN}.v3.ext"
}
# Script starts here
build
Here is my new server block in /etc/nginx/mysite.lan.conf: