Skip to content

Instantly share code, notes, and snippets.

@LiamPerson
Created June 16, 2025 12:56
Show Gist options
  • Select an option

  • Save LiamPerson/0ab38a79fa617d2fcbb1e6626ca7c543 to your computer and use it in GitHub Desktop.

Select an option

Save LiamPerson/0ab38a79fa617d2fcbb1e6626ca7c543 to your computer and use it in GitHub Desktop.
How to be your own Certificate Authority

How to be your own Certificate Authority

Being your own boss!

High-level

All we need to do is create a root key (Certificate Authority key) and a descendent key (what you will use on your server). Both are just keys, nothing special. Then we need to create a root certificate, we do this by signing it with the root key. Then we need to create a descendent certificate. This is signed by both the root, and the descendent key.

Core concepts

We will use 'CSR's which are 'Certificate Signing Request's. These are just a "can I please have a certificate" files which have information such as "who's asking?"

Instructions

Creating the root / Certificate Authority

# Create the key
openssl ecparam -out certificate_authority.key -name prime256v1 -genkey

# Create the request for a certificate (CSR)
# IMPORTANT: You can write whatever here but it MUST NOT BE what you will have as your server. If you are registering example.com, your certificate authority cannot be example.com
openssl req -new -sha256 -key certificate_authority.key -out certificate_authority.csr

# Sign your own certificate request with your root key
openssl ecparam -out certificate_authority.key -name prime256v1 -genkey

Creating the certificate for your server

# Again, create a key
openssl ecparam -out descendant.key -name prime256v1 -genkey

# Request for a certificate
openssl req -new -sha256 -key descendant.key -out descendant.csr

# Sign the server certificate with the server key AND the certificate authority.
# This creates a certificate that is valid for 365 days
# IMPORTANT: Ensure the name you have here matches the hostname you want for this to apply. If you want a certificate for the URL 192.168.1.1, 192.168.1.1 must be the name! If you want it for example.com, example.com must be the name!
openssl x509 -req -in descendant.csr -CA  certificate_authority.crt -CAkey certificate_authority.key -CAcreateserial -out descendant.crt -days 365 -sha256

Why do this?

If you ever want to reverse-proxy out of a server into another server, you will want to be encrypted. This allows you to SSLProxy without man-in-the-middle attacks.

My setup in Apache2 for doing this:

SSLProxyEngine on
SSLProxyVerify require
SSLProxyCACertificateFile /location/to/my/certificate_authority.crt
SSLProxyCheckPeerCN on
SSLProxyCheckPeerName on
SSLProxyCheckPeerExpire on

# Redirect all HTTPS traffic to internal port
ProxyPreserveHost off
ProxyPass / https://12.34.56.78:8443/
ProxyPassReverse / https://12.34.56.78:8443/

Resources

https://learn.microsoft.com/en-us/azure/application-gateway/self-signed-certificates

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment