Setting Up a Local Certificate Authority for Securing Internal Websites

Set up your own local Certificate Authority to issue trusted HTTPS certificates for internal websites and eliminate browser security warnings.

Scenario

You need to secure internal websites running on a private network such as lab environments, development servers, or internal tools but public Certificate Authorities cannot issue certificates for private IPs or internal hostnames. Browsers show HTTPS warnings, and relying on self‑signed certificates becomes messy and untrusted across devices.
To fix this, you set up your own local Certificate Authority (CA) on Ubuntu Server, generate a trusted root certificate, and issue valid HTTPS certificates for internal servers like WEB01. Once the CA’s root certificate is trusted by client machines, all internal sites load securely with no warnings.

Lab Objectives

  • Set up a local Certificate Authority (CA) on Ubuntu Server
  • Generate a root certificate and private key
  • Create and sign certificate requests for internal websites
  • Install the signed certificate on a web server (WEB01)
  • Trust the CA root certificate on client machines to eliminate HTTPS warnings
  • Validate secure HTTPS access to internal sites

Prerequisites

  • A private network (I used VirtualBox with a NAT network).
  • Virtual server for Certificate Authority:
    • CA01 - A standard install of Ubuntu server.
  • Virtual server with test website needed a secure certificate:
    • WEB01 - Apache web server.
  • Virtual server with Windows Admin Center that needed a secure certificate:
    • HYPERV01 - Hyper-V server (I used nested virtualisation).
  • Two client PCs used for testing:
    • Windows 10
    • Ubuntu Desktop

Why a Local Certificate Authority?

Public websites rely on commercial Certificate Authority's (CA) to establish trust and secure traffic. Internal servers often raise browser warnings, even if they serve critical content. That’s where your own CA steps in, enabling encrypted, trusted connections without ongoing costs.

Set Up the Certificate Authority

  • On the Ubuntu Server CA01 install the easy-rsa toolkit.
sudo apt install easy-rsa
  • Create a dedicated directory for your CA’s assets, link CA files from their default location and set secure permissions to the directory (only root has full permissions).
mkdir ca01
ln -s /usr/share/easy-rsa/* ca01
chmod 700 ca01
  • Change to directory and initialise the Public Key Infrastructure (PKI) with init-pki.
cd ca01
./easyrsa init-pki
  • Create a copy of the example vars file. The vars file in Easy-RSA is essentially a configuration file that defines default values used when generating certificates. Then customise the certificate details and save the file.
cp vars.example vars
vim vars

The following settings were un-commented and customised in the vars file:

  • set_var EASYRSA_REQ_COUNTRY – Country code (e.g 'GB')
  • set_var EASYRSA_REQ_PROVINCE – State or province
  • set_var EASYRSA_REQ_CITY – City or locality
  • set_var EASYRSA_REQ_ORG – Organisation name
  • set_var EASYRSA_REQ_EMAIL – Contact email
  • set_var EASYRSA_REQ_OU – Organisational unit
Since this CA is used internally, the values in the vars file, like country, organisation, and email, don’t need to be accurate; they’re only visible to devices within your network and won’t affect functionality.
  • Build the certificate authority and set the secure passphrase which will be required when signing certificate requests.
./easyrsa buildca

You will need to set the common name using a FQDN like ca01.system.lab

The CA is now ready to issue certificates using it's private key which is stored in pki/private directory.

Trust the CA on Client Machines

Adding the CA’s public certificate (stored in pki directory) to a computer tells it to trust any website or server that uses a certificate signed by that CA. This makes the browser stop showing security warnings and allows secure HTTPS connections.

Windows Server (HYPERV01)

  • Copy the public certificate from the CA server using SCP to the Documents folder.
scp rajinder@ca01:/home/rajinder/ca01/pki/ca.crt Documents

The certificate can be installed by double clicking on it and choosing the install certificate option, with store location of Local Machine and in the Trusted Root Certification Authorities store.

Ubuntu Server (WEB01)

  • Copy the public certificate from the CA server using SCP to the current directory .
scp rajinder@ca01:/home/rajinder/ca01/pki/ca.crt .
  • In Firefox:
    • Open Preferences > Privacy & Security > Certificates > View Certificates
    • Import under Authorities, and select Trust this CA for websites.

Create and Sign Certificate Requests

A Certificate Signing Request (CSR) is a file a server creates when it wants a trusted certificate from a Certificate Authority (CA). It contains the server’s public key and identity details, such as its hostname, organisation, and location. The CSR is digitally signed using the server’s private key, proving ownership of the key pair.

This request is sent to the CA, which verifies the information and uses its own private key to sign the CSR, issuing a certificate that clients and browsers can trust because the already trust the CA.

On the our internal CA server, we’ll generate CSRs and sign them for each internal server.

Create temp directory for storing certificates for signing requests

mkdir tmp_csr
cd tmp_csr

Create private key and CSR for WEB01

openssl genrsa -out web01.key
openssl req -new -key web01.key -out web01.req

The most important setting is the common name, it must match the URL of the website that the certificate is for, in this case: web01.system.lab

Create private key and CSR for HYPERV01

openssl genrsa -out hyperv01.key
openssl req -new -key hyperv.key -out hyperv01.req

The most important setting is the common name, it must match the URL of the website that the certificate is for, in this case: hyperv01.system.lab

Import and sign the Certificates

./easyrsa import-req tmp_csr/web01.req web01
./easyrsa sign-req server web01

./easyrsa import-req tmp_csr/hyperv01.req hyperv01
./easyrsa sign-req server hyperv01

The resulting signed certificates are stored in the issued directory.

Install Certificates on Servers

Signed certificates need to be installed on the requesting servers so they can prove their identity to clients, without them, browsers won’t trust the server, and secure HTTPS connections won’t be established.

For the Apache web server WEB01:

Create a local certs directory and copy both the private key and the signed certificate via SCP.

sudo mkdir /etc/apache2/certs
scp rajinder@ca01:/home/rajinder/ca01/tmp_csr/web01.key /etc/apache2/certs/
scp rajinder@ca01:/home/rajinder/ca01/pki/issued/web01.crt /etc/apache2/certs/
  • Update Apache’s config /etc/apache2/sites-enabled/000-default.conf to:
    • Use port 443 (change from port 80 to 443 in <VirtualHost *:80>)
    • Enable SSL SSLEngine on
    • Point to the certificate and key files.
SSLCertificateFile /etc/apache2/certs/web01.crt
SSLCertificateKeyFile /etc/apache2/certs/web01.key
  • Turn on SSL and Restart Apache
sudo a2enmod ssl
sudo systemctl restart apache2

Now when we test on both clients, https://web01.system.lab is showing as secure and encrypted, this is because the browser trusts the internal CA server ca01 using it's public certificate. The CA has a trust relationship with WEB01 and so let's the browser know that it's safe to proceed.

For the Hyper-V server HYPERV01:

First the signed certificate we generated earlier needs to be converted into a PFX format. This conversion is required because Windows servers prefer certificates in this format, which bundles both the private key and the signed certificate into a single file for easier import and management.

  • Convert signed certificate to create the PFX file on CA01 server.
cd ca01
openssl pkcs12 -inkey tmp_csr/hyperv01.key -in pki/issued/hyperv01.crt -export -out pki/issued/hyperv01.pfx
  • On HYPERV01 get the .pfx file using SCP.
scp rajinder@ca01:/home/rajinder/ca01/pki/issued/hyperv01.pfx .
  • Import the PFX certificate using PowerShell and store it under LocalMachine\My
$password = ConvertTo-SecureString "YourPassword" -AsPlainText -Force Import-PfxCertificate -FilePath "hyperv01.pfx" -CertStoreLocation Cert:\LocalMachine\My" -Password $password

PowerShell will provide the thumbprint of the certificate in the output of the above command, which we'll use to install the certificate in Windows Admin Center.

  • Update Windows Admin Center by running the install file for WAC and enter the thumbprint above, the install will then install the certificate.

Now when we test on both clients, https://hyperv01.system.lab is showing as secure and encrypted, this is because the browser trusts the internal CA server ca01 using it's public certificate. The CA has a trust relationship with HYPERV01 and so let's the browser know that it's safe to proceed.

Conclusion

This lab successfully walked through the complete process of setting up a local Certificate Authority to secure internal websites with trusted HTTPS encryption. By generating your own CA, distributing its public certificate to client machines, and issuing signed certificates to internal servers, you can build a private trust system that mirrors the security of the public web, without relying on external vendors.

Lab Video