Hamish Burke | 2025-06-30
TLS/SSL Certificates
When a client wants to access a server, the server will present their digital certificate to prove it authentic and the desired destination.
Contains
- Users name
- Company or department
- IP address or serial num of device
- Copy of public key from a certificate holder
- Duration of time the certificates valid for
- Domain certificate is authorised to represent
Handshake process
ClientHello
: Client initiates connections: Gives CipherSuite and other detailsServerHello
: Selects encryption method, and sends TLS certificate to client- Key Exchange: Client encrypts PMS with servers public key
- Both client and server use the PMS to generate a session key, which is used for symmetrically encrypting/decrypting data during the session
Creating a TLS Certificate
Using OpenSSL
Making a selfsigned certificate to as CA
openssl req -x509 -newkey rsa:4096 -days 365 -keyout ca-key.pem -out ca-cert.pem
-x509
outputs a self-signed certificate instead of a certificate request.- x509 is a standard format for a public key certificate
- Can also provide details in the cmd, so it doesn't need to be added interactively
openssl req -x509 -newkey rsa:4096 -days 365 -keyout ca-key.pem -out ca-cert.pem -subj "/C=FR/ST=Occitanie/L=Toulouse/O=Tech School/OU=Education/CN=*.techschool.guru/emailAddress=techschool.guru@gmail.como"
/C=NZ
is country/ST=Bay of Plenty
is state/O=School
is organisation/OU=Eduaction
is orignation unit/CN=*.techschool.guru
is for common or domain name/emailAddress=emaail@gmail.com
- can add
-nodes
to make it not encrypt private key (fully headless)
openssl x509 -in ca-cert.pem -noout -text
- Views the certificate in text format (in the x509 format)
- noout makes it not also output the original base64 as well
- text makes it readable
Make servers privates key and CSR (certificate signing request)
openssl req -newkey rsa:4096 -keyout server-key.pem -out server-req.pem -subj "/C=NZ/ST=Wellington/L=Wellington/O=PC Book/OU=Computer/CN=*.pcbook.com/emailAddress=pcbook@gmail.com"
- If want to use existing private key
openssl req -key server.key -out server-req.pem
Sign the server certificate request
- `openssl x509 -req -in server-req.pem -days 60 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile server-ext.cnf
-req
means we are going to pass it a CSRCAkey
is the private key of the CA (so normally we couldn't run this, only can cus this is self signed)CAcreateserial
: associates a unique serial number to this certificate (gets added to certificate, and creates aca-cert.srl
)- By default, it is valid for 30 days. Can add
-days 60
to change it -extfile server-ext.cnf
can be added, to specify alternative names the certificate should sign- ext file can contain different emails, ip's and urls you want signed (format here)
Verify a certificate
- Needs certificate for CA and server
openssl verify -CAfile ca-cert.pem server-cert.pem
Using ACME.sh
https://github.com/acmesh-official/acme.sh
-
Use ACME Protocol
-
Works on linux
-
Works on windows (cygwin with curl, openssl and crontab included)
When installing, it adds acme.sh
to path, then adds a crontab to run acme.sh everyday
cat /var/spool/cron/burkehami
28 9 * * * "/home/burkehami/.acme.sh"/acme.sh --cron --home "/home/burkehami/.acme.sh" > /dev/null
On windows can created a scheduled task in Task Scheduler:
schtasks /create /tn "acme-renew" /tr "\"C:\Program Files\Git\bin\bash.exe\" -c '~/.acme.sh/acme.sh --cron'" /sc daily /st 09:00
ACME.sh options
--csr <file> Specifies the input csr.
--notify-level <0|1|2|3> Set the notification level: Default value is 2.
0: disabled, no notification will be sent.
1: send notifications only when there is an error.
2: send notifications when a cert is successfully renewed, or there is an
error.
--openssl-bin <file> Specifies a custom openssl bin location.
-se, --stop-renew-on-error
Only valid for '--renew-all' command. Stop if one cert has error in renewal.
--days <ndays>
Specifies the days to renew the cert when using '--issue' command. The default value is 60 days.
--reloadcmd <command>
Command to execute after issue/renew to reload the server.
--register-account Register account key. (if wanting to use smth like digicert with this)
--force (will force rotation of keys)
--install-cert -d <domain> \
--key-file /etc/ssl/private/domain.priv.key \
--fullchain-file /etc/ssl/certs/domain.cert \ (this is all public certs up to root)
--reloadcmd "systemctl reload nginx"
This will save all specifies paths, and will rerun this every time certs are renewed (even with crontab). Saves paths to ~/.acme.sh/domain/domain.conf
- how do you make acme.sh see your certs?
- All cert are created in ~/.acme.sh
- Where do certs normally get saved/installed on a regular server?