Local Root Certificate Notes


by Ramses Soto-Navarro ramses@sotosystems.com, 3/20/2024

Local Root Certificate Notes


Overview

Notes on how to download and install a local Microsoft RootCA authority certificate and test a signed certificate in Linux; this will prevent the dreaded local self-signed certificate prompts; will only work on internal computers/servers within the same local domain where Microsoft AD RootCA servers are available. Here as an example we are using the local certificate installation on a test system called myserver.myexample.com.


Download Local RootCA

Download the local RootCA certificate from your local Microsoft Active Directory server or your RootCA server’s certsrv subdirectory:

https://w2k22srv.myexample.com/certsrv

Login with AD username and password.

    * Download CA certificate
    * Current [MyExampleSubCA2]
    * Base 64
    * Download CA certificate

Converted to pem format. Because it is in Base64, simply rename it from *.cer to *.pem. Next, view the RootCA certificate:

$ cp -a certnew.cer local-myexample-rootca-cert.pem

$ openssl x509 -text -in local-myexample-rootca-cert.pem | less

Add Local RootCA Certificate

Add the local RootCA trust to your Red Hat Linux based OS:

Check to see if there already are any similar trusted Root CA certificates.

# trust list | grep -i myexample

To add the new local RootCA certificate as an authority in Red Hat copy it to the “anchors” subdirectory, then update the RootCA bundle. Verify the new trusted local RootCA:

# cp local-myexample-rootca-cert.pem /etc/pki/ca-trust/source/anchors/

# update-ca-trust

# trust list | grep -i myexample
    label: MyExampleSubCA2

Add the local RootCA trust to your Debian GNU/Linux based OS. First verify that it is saved with the *.crt extension:

# cp local-rootca-cert.myexample.com.crt /usr/local/share/ca-certificates/extra/

# update-ca-certificates -v

...
link local-rootca-cert.myexample.com.pem -> f2ffcc1f.0
...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...

Adding debian:local-rootca-cert.myexample.com.pem
done.

Add Signed Certificate

In create and download the client signed certificate via https://w2k22.myexample.com/certsrv, in Base64 format. Copy the signed certificate and the private key to your local Red Hat Linux OS.

# cp local-privkey-myserver.myexample.com.key /etc/pki/tls/private/
# chown root.root /etc/pki/tls/private/local-privkey-myserver.myexample.com.key
# chmod 0400 /etc/pki/tls/private/local-privkey-.myexample.com.key

# cp local-cert-myexample.com.pem /etc/pki/tls/certs/
# chroot root.root /etc/pki/tls/certs/local-cert-myexample.com.pem
# chmod 0644 /etc/pki/tls/certs/local-cert-myexample.com.pem

Test TLS Connection[ using Ncat

Test SSL/TLS remote connection initiation with ncat on port 12345:

# ncat -lvnp 12345 --ssl --ssl-cert /etc/pki/tls/certs/local-cert-myexample.com.pem 
--ssl-key /etc/pki/tls/private/ocal-privkey-myserver.myexample.com.key

$ openssl s_client -connect myserver.myexample.com:12345

Add local RootCA to Chrome Browser

    * Open chrome://settings/security
    * Manage Certificates
    * Authorities
    * Import
    * X Trust this certificate for identifying website
    * X Trust this certificate for identifying email users
    * X Trust this certificate for identifying software makers
    * OK

Scroll and notice org-MyExampleSubCA2 as one of the authorities

Close and reopen Chrome then try a local MyExample website with a local certificate; it should open without any self-signed prompt as before.


Test TLS SSL listener with socat

Generate temp server key adn certificate then bundle them, or create from already generated certificate and key:

 
# openssl req -new -x509 -keyout /tmp/test.key -out /tmp/test.crt -nodes
# cat /tmp/test.key /tmp/test.crt > /tmp/test.pem

# cat /etc/pki/tls/private/local-privkey-myserver.myexample.com.key  
/etc/pki/tls/certs/local-cert.myexample.com.pem > /tmp/test.pem

Test socat remote web page connection on http port 81:

# echo "Hello World!" > test.html
# socat -v -v TCP-LISTEN:81,crlf,reuseaddr,fork SYSTEM:"echo HTTP/1.0 200; 
echo Content-Type: text/plain; echo; cat test.html"

$ curl http://myserver.myexample.com:81

Test with TLS/SSL https port 82 using curl client

# socat openssl-listen:82,crlf,reuseaddr,fork,verify=0,certificate=/etc/pki/tls/certs/local-cert.myexample.com.pem,
key=/etc/pki/tls/private/local-privkey-myserver.myexample.com.key SYSTEM:"echo HTTP/1.0 200; 
echo Content-Type: text/plain; echo; cat test.html"

$ curl https://myserver.myexample.com:82
Hello World!

NOTE: For diagnostic purpuses, to check with no TLS/SSL security add the “-k” parameter.

Now also try it with a browser. Using chrome browser with the local RootCa installed as mentioned before. I was able to get the “Hello World!” and also it returned with a valid certificate showing.


Add Local RootCA to Firefox

    * Open Firefox to: about:preferences
    * Privacy and Security
    * Certificates
    * View Certificates
    * Authorities
    * Import
    * X Trust this CA to identify websites.
    * X Trust this CA to identify email users.
    * OK
    * OK
    * View Certificates again to verify “MyExampleSubCA2”
    * Test opening a website signed with a local AD RootCA, such as:

Note About Certificate Generating Script

The certificate needs to be created using Subject Alternative Name. Otherwise you’ll get SSL header erros and you’ll have to accept the https connection manually. This script will create a self-signed certificate, but it will also create the private key and the CSR, which is what we need in order to create an official signed certificate. Modify and use the script as follows:

# cat create-self-signed-cert-with-subjectaltname.sh 
#!/bin/bash

# by Ramses Soto-Navarro <ramses@sotosystems.com>, 3/1/2023

# Create a self-signed certificate with subject alternative name
# in order to server URLs with the same domain suffix.
# Also create the private key, public key and CSR.
# Modify the variable below:

# === VARIABLES ===

example MYHOST="myserver"
export DOMAIN="myexample.com"
export EMAIL="ramses@sotosystems.com"
export IP="10.0.0.100"

# === Do not modify below ===

cat > req.cnf <<EOF
[ req ]
prompt = no
default_bits = 4096
distinguished_name = req_distinguished_name
req_extensions = req_ext

[ req_distinguished_name ]
C=US
ST=FL
L=Orlando
O=${DOMAIN}
OU=IT Dept
CN=${DOMAIN}
emailAddress=${EMAIL}

[ req_ext ]
subjectAltName = @alt_names

[alt_names]
DNS.1 = ${DOMAIN}
DNS.2 = *.${DOMAIN}
DNS.3 = ${MYHOST}.${DOMAIN}
IP.1 = ${IP}
EOF

# Create priv key
f_privkey () {
echo -e "n=== Generating private key $DOMAIN.priv.key ==="
openssl genrsa -out $DOMAIN.priv.key 2048

# Verify: openssl rsa -in privateKey.key -check 
}

f_pubkey () {
echo -e "n=== Generating public key $DOMAIN.pub.pem ==="
openssl rsa -in $DOMAIN.priv.key -pubout -out $DOMAIN.pub.pem

# Verify: cat example.pub.pem
}

# Create CSR
f_csr () {
echo -e "n=== Creating CSR $DOMAIN.csr ==="
openssl req 
 -new 
 -key $DOMAIN.priv.key 
 -config req.cnf 
 -out $DOMAIN.csr 

# Verify: openssl req -text -noout -verify -in example.com.csr 
# Verify CSR subjectAltName: openssl req -in example.com.csr -text -noout | grep DNS
}

# Create self-signed cert 
f_cert () {
echo -e "n=== Generating Self-signed Certificate $DOMAIN.crt ==="
openssl x509 
 -signkey $DOMAIN.priv.key 
 -in $DOMAIN.csr 
 -req 
 -days 365 
 -extfile req.cnf 
 -extensions req_ext 
 -out $DOMAIN.crt  

# Verify: openssl x509 -text -noout -in example.com.crt
}

f_privkey
f_pubkey
f_csr
f_cert

To create the CSR and private key simply run the script in an empty directory.