Create a Self Signed CA and Cert with ECDSA
Create a Self Signed CA and Cert with ECDSA for Your Homelab
Ever wanted to secure your homelab with your own Certificate Authority (CA)? In this guide, I’ll walk you through creating a modern, ECDSA-based self-signed CA and using it to issue certificates for your home network. This approach lets you generate as many trusted certificates as you need for your devices and services, all under your own local domain (e.g., mypc.mynet
).
Why a Self-Signed CA?
A self-signed CA gives you full control over your network’s trust model. Instead of relying on public CAs, you can issue and manage certificates for every server, device, or service in your homelab. This is especially useful for internal services, dashboards, and devices that don’t need public exposure.
Step 1: Initialize the CA Directory Structure
First, let’s set up a dedicated directory for your CA. This is your CA’s workspace, where all keys, certificates, and supporting files will live. You can place this directory anywhere, but for a global setup, /etc/ssl/myca
is a good choice.
myca/ ├── ca.cnf ├── server.cnf ├── index.txt ├── serial ├── ca/ ├── certs/ ├── crl/ ├── newcerts/ ├── server/
Here’s what each part is for:
- ca.cnf – Main CA configuration file
- server.cnf – Config for server certificates
- index.txt – OpenSSL’s certificate database
- serial – Tracks certificate serial numbers
- ca/ – Stores CA private key and certificate
- certs/ – Issued certificates
- crl/ – Certificate Revocation Lists
- newcerts/ – Newly issued certificates
- server/ – Server keys and CSRs
To create the structure, run:
mkdir -p certs crl newcerts ca server
touch index.txt
echo '01' > ./serial
The index.txt
file is OpenSSL’s database for tracking issued certificates. The serial
file starts at 01
and increments with each new certificate.
Important: Set the following environment variable so OpenSSL knows where your config and files are:
export SSL_CONF_DIR=$(pwd)
Step 2: Create the CA Configuration File (ca.cnf
)
OpenSSL uses configuration files to define how certificates are created. Here’s a sample ca.cnf
tailored for ECDSA and your homelab:
[ req ]
default_bits = 256
prompt = no
default_md = sha256
distinguished_name = dn
x509_extensions = v3_ca
[ dn ]
C = US
ST = Utah
O = Ferronescotia
OU = homelab
CN = ca.mynet
emailAddress = your.email@example.com
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, keyCertSign, cRLSign
[ ca ]
default_ca = mynet_ca
[ mynet_ca ]
dir = $ENV::SSL_CONF_DIR
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/index.txt
serial = $dir/serial
RANDFILE = $dir/.rand
private_key = $dir/ca/ca.key
certificate = $dir/ca/ca.crt
default_days = 8440
default_md = sha256
policy = policy_only_name
[ policy_only_name ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = match
emailAddress = match
commonName = supplied
This config sets up your CA to use ECDSA, SHA-256, and a policy that requires most fields to match the CA’s distinguished name, except for the Common Name (CN).
Step 3: Generate the CA Private Key and Certificate
ECDSA is a modern, efficient cryptographic algorithm. We’ll use the prime256v1
curve, which is widely supported.
To see available curves:
openssl ecparam -list_curves
Generate the CA’s private key:
openssl ecparam -genkey -name prime256v1 -out ca/ca.key
Now, create the CA certificate:
openssl req -new -x509 -key ca/ca.key -out ca/ca.crt -config ca.cnf
Tip: This certificate is your root of trust. You’ll need to add it to your devices’ trust stores for them to trust certificates you issue.
Step 4: Issue Server Certificates from Your CA
You can now issue certificates for any device or service in your homelab. Each certificate will have a unique Common Name (CN), such as myserver.mynet
.
Set the CN for your server certificate:
export SERVER_CN="myserver.mynet"
Create a server.cnf
file in your CA directory:
##
# Configuration to create certificates from a self signed ca with ecdsa.
##
.include $ENV::SSL_CONF_DIR/ca.cnf
[ req ]
x509_extensions = v3_req
req_extensions = v3_req
[ v3_req ]
subjectKeyIdentifier = hash
basicConstraints = CA:false
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alt_names
[ dn ]
CN = $ENV::SERVER_CN
[ alt_names ]
DNS.1 = $dn::CN
[SAN]
subjectAltName = DNS:$dn::CN
Generate the server’s private key:
openssl ecparam -genkey -name prime256v1 -out server/$SERVER_CN.key
Create a Certificate Signing Request (CSR). A CSR is a file that contains your public key and identifying information, which the CA uses to issue a certificate.
openssl req -new -nodes -config server.cnf -key server/$SERVER_CN.key -out server/$SERVER_CN.csr
Sign the CSR with your CA to generate the server certificate:
openssl ca -config server.cnf -in server/$SERVER_CN.csr -out server/$SERVER_CN.crt
Repeat this process for as many devices or services as you need—just change the SERVER_CN
each time.
Step 5: Trust Your CA in Ubuntu
To make your CA trusted by Ubuntu, add it to the system’s certificate store:
sudo mkdir -p /usr/share/ca-certificates/mynet
sudo cp ca/ca.crt /usr/share/ca-certificates/mynet/mynet.crt
sudo dpkg-reconfigure ca-certificates
sudo update-ca-certificates
Note: During dpkg-reconfigure
, use the space bar to select your new CA in the dialog.
Step 6: Trust the CA in Chrome and Firefox
Browsers like Chrome and Firefox use their own certificate stores. To add your CA:
sudo apt install libnss3-tools
certfile="ca/ca.crt"
certname="ca.mynet"
certDB="${HOME}/.pki/nssdb/cert9.db"
certdir="$(dirname ${certDB})"
certutil -A -n "${certname}" -t "TCu,Cu,Tu" -i ${certfile} -d sql:${certdir}
This command uses certutil
to add your CA to the NSS database, which Chrome and some other apps use for certificate trust.
Bonus: Using Your Certs with Cockpit
If you use Cockpit for server management, you can install your new certificate like this:
sudo cp server/server.crt /etc/cockpit/ws-certs.d/10-mynet.cert
sudo cp server/server.key /etc/cockpit/ws-certs.d/10-mynet.key
sudo systemctl restart cockpit
sudo /usr/lib/cockpit/cockpit-certificate-ensure --check
Wrapping Up
Congratulations! You’ve set up a modern, ECDSA-based self-signed CA for your homelab. Now you can issue as many certificates as you need, and once your CA is trusted, all those certificates will be trusted too. This setup is scalable, secure, and perfect for a home network with lots of devices and services.
Happy homelabbing!
Comments
Post a Comment