first draft
ci.vdhsn.com/push Build is passing Details

ca-cert
Adam Veldhousen 1 year ago
parent 9beca1b180
commit ae186ff197
Signed by: adam
GPG Key ID: 6DB29003C6DD1E4B

@ -7,95 +7,122 @@ tags:
draft: false
---
Even though there are plenty of free SSL certificate options, you may need to manage your own SSL certs for various reasons.
Even though there are plenty of options available for obtaining an SSL certificate, you may want to issue your certificates
and check their validity using your own CA. This is useful for internal domains or doing mTLS for services in your networks.
Below is how to create a CA certificate and issue certs signed with it, as well as some validation steps to make sure you did everything right.
Below is how to create a CA certificate and issue certs with it, and how to verify that a certificate was issued with
the CA you generated.
All examples here use the [openssl](https://www.openssl.org/docs/man1.1.1/man1/) cli tool.
All examples here use the [OpenSSL command-line tool](https://www.openssl.org/docs/man1.1.1/man1/).
## Creating the Certificate Authority Certificate and Keys
## Creating the Certificate Authority's Certificate and Keys
First generate the private key and Root CA certificate that we will use to issue certs.
1. Generate a private key for the CA:
```sh
$ openssl genrsa 4096 > ca-key.pem
```sh {linenos=false}
openssl genrsa 4096 > ca-key.pem
```
2. Generate the X509 certificate for the CA:
```sh
$ openssl req -new -x509 -nodes -days 3650 -sha256 \
-subj "/C=US/ST=CO/O=My Org, Inc./OU=Engineering/CN=ca.example.internal" \
2. Generate the X509 CA certificate. Note that if you exclude `-subj` you will get an interactive prompt instead:
```sh {linenos=false}
openssl req -new -x509 -nodes -days 3650 -sha256 \
-subj "/C=US/O=My Org, Inc./OU=R&D/CN=MyOrgCA" \
-key ca-key.pem \
-out ca-cert.pem
```
If you want to pass more options to `-subj` the following are the available attribute strings - from [RFC4514 Page 6](https://www.rfc-editor.org/rfc/rfc4514):
```text {linenos=false}
String X.500 AttributeType
------ --------------------------------------------
CN commonName (2.5.4.3)
L localityName (2.5.4.7)
ST stateOrProvinceName (2.5.4.8)
O organizationName (2.5.4.10)
OU organizationalUnitName (2.5.4.11)
C countryName (2.5.4.6)
STREET streetAddress (2.5.4.9)
DC domainComponent (0.9.2342.19200300.100.1.25)
UID userId (0.9.2342.19200300.100.1.1)
```
At this point you can view the CA certificate in a pretty format:
```sh {linenos=false}
$ openssl x509 -in mydomain.com.crt -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
25:28:31:d4:81:a4:1e:74:36:9c:50:e2:3e:dd:d0:a5:be:c9:d3:25
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, O = "My Org, Inc.", OU = R&D, CN = MyOrgCA
Validity
Not Before: Jan 29 02:06:59 2023 GMT
Not After : Jan 26 02:06:59 2033 GMT
Subject: C = US, O = "My Org, Inc.", OU = R&D, CN = MyOrgCA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
...
```
## Creating the Server's Certificate and Keys
Now that we have our Root CA certificate we can issue certs for our servers to use. To do this you must first generate a
certificate request, and then sign it with your Root CA cert to generate the final certificate.
1. Generate the private key and certificate request:
```sh
$ openssl req -newkey rsa:4096 -nodes -days 3650 -sha256 \ # -newkey if you need a new private key
-subj "/CN=mysite.example.internal" \ # exclude this and you will get interactive prompts
```sh {linenos=false}
openssl req -newkey rsa:4096 -nodes -sha256 \
-subj "/CN=mysite.myorg.internal" \
-keyout server-key.pem \
-out server-req.pem
```
# if you already have a private key
$ openssl req -new -nodes -days 3650 -sha256 \
-subj "/CN=mysite.example.internal" \
-key server-key.pem \
-out server-req.pem
# if you want to add SANs
$ openssl req -new -nodes -days 3650 -sha256 \
If you want to add Subject Alternative Names (SANs) to make your cert valid for multiple DNS names, you can use the encantation below:
```sh {linenos=false}
openssl req -newkey rsa:4096 -nodes -days 3650 -sha256 \
-subj "/CN=mydomain.com" \
-reqexts SAN \
-config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:test.example.internal,DNS:www.example.internal")) \ # to add SANs
-config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:site1.myorg.internal,DNS:site2.myorg.internal")) \
-key server-key.pem \
-out server-req.pem
```
2. Generate the X509 certificate for the server:
> `-days` expiration can be no longer than 398 days (13 months) (thanks [Apple](https://support.apple.com/en-us/HT211025))
> https://www.globalsign.com/en/blog/maximum-ssltls-certificate-validity-now-one-year
> `-set_serial` is like an ID number for each cert. It must be a positive integer and unique to each cert signed by the CA.
> `date +%s` prints the current number of seconds since the Epoch (00:00:00 UTC, January 1, 1970). See [RFC 5280](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.2 "https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.2") for details
When setting `-days`, the validity time can be no longer than *398 days (13 months)* or you might see errors. This is for security reasons,
read up on the history behind it [here at global sign](https://www.globalsign.com/en/blog/maximum-ssltls-certificate-validity-now-one-year).
The flag `-set_serial` is like an ID number for each cert issued by your CA. It must be a positive integer and unique to each cert issued.
Below I'm just using `date +%s` to get a unix timestamp for a simple serial number.
For further reading see [RFC 5280](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.2).
```sh
$ openssl x509 -req -days 398 -set_serial $(date +%s) -sha256 \
```sh {linenos=false}
openssl x509 -req -days 398 -set_serial $(date +%s) -sha256 \
-in server-req.pem \
-out server-cert.pem \
-CA ca-cert.pem \
-CAkey ca-key.pem
# if you want to add SANs
$ openssl x509 -req -days 398 -set_serial $(date +%s) -sha256 \
-extfile <(printf "subjectAltName=DNS:my.domain.com") \
# Or once again, if you need to specify SANs
openssl x509 -req -days 398 -set_serial $(date +%s) -sha256 \
-extfile <(printf "subjectAltName=DNS:site1.myorg.internal,DNS:site2.myorg.internal") \
-in server-req.pem \
-out server-cert.pem \
-CA ca-cert.pem \
-CAkey ca-key.pem
```
## Verifying the Certificates
1. Verify the server certificate:
```sh
$ openssl verify -CAfile ca-cert.pem \
ca-cert.pem \
server-cert.pem
```
2. Verify the client certificate:
```sh
$ openssl verify -CAfile ca-cert.pem \
ca-cert.pem \
client-cert.pem
```
## Verifying the Certificate
## Verify the certificate's content
1. To verify the server certificate:
```sh
openssl x509 -in mydomain.com.crt -text -noout
```sh {linenos=false}
$ openssl verify -CAfile ca-cert.pem server-cert.pem
```

Loading…
Cancel
Save