2021-12-01 / Bartłomiej Kurek
EasyRSA: zarządzanie certyfikatami SSL

Czym jest EasyRSA?

EasyRSA to skrypt shell umożliwiający prowadzenie własnego podmiotu zarządzającego certyfikatami SSL 1.
Taki podmiot może przydać nam się we własnej infrastrukturze deweloperskiej lub produkcyjnej (np. przy zabezpieczaniu połączeń wewnętrznych, gdy nie dysponujemy certyfikatem wydanym przez urząd zewnętrzny).

Własnych certyfikatów możemy używać m.in. do:
- certyfikacji serwerów
- certyfikacji i autentykacji klientów (np. w OpenVPN)
- szyfrowania/podpisywania dokumentów

Zakres użycia samodzielnie tworzonych certyfikatów

Należy mieć na uwadze, że podpisane przez nas samodzielnie certyfikaty nie nadają się do użytku zewnętrznego, kiedy chcemy aby nasz certyfikat był walidowany przez popularne programy poza naszą infrastrukturą (takie jak np. przeglądarki internetowe klientów).
Systemy operacyjne mają zainstalowane certyfikaty znanych i autoryzowanych urzędów i tylko
certyfikaty wystawione/podpisane przez takie urzędy będą domyślnie poprawnie weryfikowane na urządzeniach naszych klientów/użytkowników. Wprawdzie nasi klienci/użytkownicy mogliby mieć zainstalowany nasz certyfikat, ale jest to praktyka mocno niewskazana.
W takich przypadkach potrzebujemy certyfikatów wystawionych przez zewnętrzne podmioty certyfikacyjne (czy to w opcji płatnej, czy darmowej).
Darmowe certyfikaty SSL dostarcza np. letsencrypt.org.
Certyfikaty Let's Encrypt ograniczone są do certyfikacji serwerów, wystawiane są na konkretne domeny (również na subdomeny /wildcard certificates/).

EasyRSA: instalacja i konfiguracja

Narzędzie to jest tak naprawdę bardzo wygodną nakładką na skomplikowane komendy pakietu OpenSSL.
Kod i dokumentację EasyRSA 3 znajdziemy w repozytorium OpenVPN na platformie GitHub: easy-rsa doc.
W systemach Linux możemy zainstalować to narzędzie z poziomu menedżera pakietów.

Poniżej zajmiemy się przybliżeniem podstawowego użycia tego narzędzia celem:
- stworzenia własnego urzędu certyfikacji
- wystawienia certyfikatu serwera/aplikacji
- wystawienia certyfikatu klienta

Uźyjemy również kilku podstawowych komend openssl.

Instalacja (Debian)

W systemie Debian i pochodnych (Ubuntu, Mint, ...) pakiet instalujemy komendą:

sudo apt install easy-rsa

Tworzenie katalogu CA (certificate authority), wstępna konfiguracja

easy-rsa dostarcza komendę make-cadir, której używamy do automatycznego stworzenia nowego katalogu naszego urzędu.

~ $ make-cadir CA

Powstały katalog zawiera skrypt easyrsa i pliki konfiguracyjne naszego nowego urzędu:

~ $ tree CA/
CA/
├── easyrsa -> /usr/share/easy-rsa/easyrsa
├── openssl-easyrsa.cnf
├── vars
└── x509-types -> /usr/share/easy-rsa/x509-types
  • easyrsa to link symboliczny do skryptu shell zainstalowanego globalnie w systemie
  • openssl-easyrsa.cnf to plik konfiguracyjny openssl
  • vars to plik, w którym definiujemy zmienne domyślne właściwe naszemu urzędowi
  • x509-types to katalog z domyślnymi konfiguracjami dla generowanych certyfikatów (server, client, email, code-signing, ...)

Edytujemy plik vars i ustawiamy żądane wartości. Domyślnie wszystkie zmienne są zakomentowane, zatem odnajdujemy fragment:

#set_var EASYRSA_REQ_COUNTRY    "US"
#set_var EASYRSA_REQ_PROVINCE   "California"
#set_var EASYRSA_REQ_CITY       "San Francisco"
#set_var EASYRSA_REQ_ORG        "Copyleft Certificate Co"
#set_var EASYRSA_REQ_EMAIL      "me@example.net"
#set_var EASYRSA_REQ_OU         "My Organizational Unit"

a następnie ustawiamy właściwe wartości i odkomentowujemy zmienne. Użyję przykładowych danych:

set_var EASYRSA_REQ_COUNTRY    "PL"
set_var EASYRSA_REQ_PROVINCE   "Internet"
set_var EASYRSA_REQ_CITY       "MyCity"
set_var EASYRSA_REQ_ORG        "CodeASAP"
set_var EASYRSA_REQ_EMAIL      "me@localhost"
set_var EASYRSA_REQ_OU         "Development"

Dostępnych zmiennych jest oczywiście więcej.
Domyślnie m.in.:
- rozmiarem klucza jest 2048 bitów (EASYRSA_KEY_SIZE),
- klucz urzędu jest ważny przez 10 lat (EASYRSA_CA_EXPIRE)
- generowane certyfikaty mają ważność 825 dni (EASYRSA_CERT_EXPIRE)

Możemy ustawić te wartości według uznania. Obecnie używa się najczęściej kluczy o rozmiarze 2048 lub 4096 bitów.

Pomoc dla komendy easyrsa

Użycie komendy easyrsa bez argumentów lub easyrsa --help wyświetli nam pomoc programu.
EasyRSA to skrypt shell, zatem wykonujemy go przez "sh easyrsa" lub "./easyrsa".
Poniżej skrócony listing pomocy programu.

  init-pki
  build-ca [ cmd-opts ]
  gen-dh
  gen-req <filename_base> [ cmd-opts ]
  sign-req <type> <filename_base>
  build-client-full <filename_base> [ cmd-opts ]
  build-server-full <filename_base> [ cmd-opts ]
  revoke <filename_base> [cmd-opts]
  renew <filename_base> [cmd-opts]
  build-serverClient-full <filename_base> [ cmd-opts ]
  gen-crl
  update-db
  show-req <filename_base> [ cmd-opts ]
  show-cert <filename_base> [ cmd-opts ]
  show-ca [ cmd-opts ]
  import-req <request_file_path> <short_basename>
  export-p7 <filename_base> [ cmd-opts ]
  export-p8 <filename_base> [ cmd-opts ]
  export-p12 <filename_base> [ cmd-opts ]
  set-rsa-pass <filename_base> [ cmd-opts ]
  set-ec-pass <filename_base> [ cmd-opts ]
  upgrade <type>

Inicjalizacja, generowanie certyfikatu urzędu (root CA)

Przed stworzeniem głównego certyfikatu naszego urzędu musimy zainicjalizować katalog, w którym certyfikaty i klucze prywatne będą przechowywane.

~/CA $ ./easyrsa init-pki

init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: ~/CA/pki

Następnie budujemy certyfikat naszego urzędu. Program zapyta nas dwukrotnie o hasło (min. 4 znaki), następnie o nazwę dla naszego urzędu, a pozostałe wartości pobierze z wcześniej omawianego pliku "vars".

~/CA $ ./easyrsa build-ca
Using SSL: openssl OpenSSL 1.1.1l  24 Aug 2021

Enter New CA Key Passphrase: 
Re-Enter New CA Key Passphrase: 
Generating RSA private key, 2048 bit long modulus (2 primes)
................................................................+++++
e is 65537 (0x010001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:DevCA

CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
~/CA/pki/ca.crt

Katalog pki zawiera teraz certyfikat naszego urzędu:

~/CA $ file pki/ca.crt 
pki/ca.crt: PEM certificate

a w pliku pki/private/ca.key znajduje się klucz prywatny.

~/CA $ file pki/private/ca.key 
pki/private/ca.key: PEM RSA private key

EasyRSA dba o uprawnienia do tych poufnych danych. Katalog pki oraz wszystkie zawarte w nim podkatalogi i pliki są dostępnie jedynie dla właściciela.
Pamiętać należy o tym, aby te dane były zawsze zabezpieczone przed dostępem osób niepowołanych.

Wyświetlenie danych certyfikatu

Dane naszego certyfikatu w pliku pki/ca.crt są w formacie *.pem.
Aby je wyświetlić, możemy posłużyć się komendą "easyrsa show-ca".

~/CA $ ./easyrsa show-ca
Using SSL: openssl OpenSSL 1.1.1l  24 Aug 2021

Showing  details for 'ca'.
This file is stored at:
/home/me/CA/pki/ca.crt

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            6c:55:05:af:2e:5b:4e:0f:3f:48:3d:88:48:fb:59:ca:7a:fd:b2:a1
        Signature Algorithm: sha256WithRSAEncryption
        Issuer:
            commonName                = DevCA
        Validity
            Not Before: Dec  1 19:50:37 2021 GMT
            Not After : Nov 29 19:50:37 2031 GMT
        Subject:
            commonName                = DevCA
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                15:39:EE:09:C9:39:D8:93:84:01:A3:E9:0F:77:12:C2:41:EE:A0:3F
            X509v3 Authority Key Identifier: 
                keyid:15:39:EE:09:C9:39:D8:93:84:01:A3:E9:0F:77:12:C2:41:EE:A0:3F
                DirName:/CN=DevCA
                serial:6C:55:05:AF:2E:5B:4E:0F:3F:48:3D:88:48:FB:59:CA:7A:FD:B2:A1

            X509v3 Basic Constraints: 
                CA:TRUE
            X509v3 Key Usage: 
                Certificate Sign, CRL Sign

Widzimy, że wystawcą certyfikatu Issuer/commonName oraz nazwą urzędu (Subject/commonName) jest DevCA, które podałem przy tworzeniu urzędu (krok "build-ca" wyżej).
W Basic Constraints widzimy, że jest to certyfikat urzędu, a w Key Usage widzimy ograniczenie jego użycia do:
- podpisywania innych certyfikatów
- podpisywania listy certyfikatów unieważnionych (CRL - Certificate Revocation List) przez nasz urząd 2.

Klucz prywatny urzędu

Klucz prywatny urzędu znajduje się w pki/private/ca.key i jest zaszyfrowany, chroniony hasłem, które podaliśmy przy tworzeniu naszego CA.

~/CA $ head -3 pki/private/ca.key 
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,564FB4D5011DCB07F456A3E113F47361

Generowanie certyfikatów

Tworzenie certyfikatu serwera

Kiedy chcemy użyć szyfrowanych połączeń w serwerze webowym, serwerze bazy danych lub innym oprogramowaniu - dostarczamy w konfiguracji certyfikat oraz klucz.
Nie posługujemy się w tym celu certyfikatem urzędu, a generujemy osobną parę certyfikat/klucz dla danego serwera. W poniższym przykładzie generuję certyfikat i klucz
dla "my-server". Program pyta o hasło do klucza dla "my-server", a następnie przechodzi do etapu podpisania certyfikatu serwera kluczem naszego urzędu. Musimy zatem podać równeż hasło klucza prywatnego urzędu.

~/CA $ ./easyrsa build-server-full my-server
Using SSL: openssl OpenSSL 1.1.1l  24 Aug 2021
Generating a RSA private key
............................+++++
writing new private key to '/home/me/CA/pki/easy-rsa-3848149.ZvOUce/tmp.bxCfZZ'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
Using configuration from /home/me/CA/pki/easy-rsa-3848149.ZvOUce/tmp.YtvbGZ
Enter pass phrase for /home/me/CA/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'my-server'
Certificate is to be certified until Mar  5 20:30:43 2024 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

Wygenerowane certyfikaty nieurzędowe (tutaj dla "my-server") znajdują się w pki/issued, a klucze prywatne w pki/private.
Certyfikat:

~/CA $ ls -l pki/issued/my-server.crt 
-rw------- 1 me me 4594 Dec  1 21:30 pki/issued/my-server.crt

Klucz prywatny:

~/CA $ ls -l pki/private/my-server.key 
-rw------- 1 me me 1854 Dec  1 21:30 pki/private/my-server.key

Klucz prywatny jest również zaszyfrowany.

~/CA $ head -1 pki/private/my-server.key 
-----BEGIN ENCRYPTED PRIVATE KEY-----

Wyświetlenie certyfikatu serwera

~/CA $ ./easyrsa show-cert my-server
Using SSL: openssl OpenSSL 1.1.1l  24 Aug 2021

Showing cert details for 'my-server'.
This file is stored at:
/home/me/CA/pki/issued/my-server.crt

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            fd:0e:2d:26:d9:a6:d9:4a:62:3a:98:97:7b:9f:b2:93
        Signature Algorithm: sha256WithRSAEncryption
        Issuer:
            commonName                = DevCA
        Validity
            Not Before: Dec  1 20:30:43 2021 GMT
            Not After : Mar  5 20:30:43 2024 GMT
        Subject:
            commonName                = my-server
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Subject Key Identifier: 
                A6:61:50:C4:2A:48:A4:52:E1:6A:65:02:EC:59:0E:28:15:9D:40:D7
            X509v3 Authority Key Identifier: 
                keyid:15:39:EE:09:C9:39:D8:93:84:01:A3:E9:0F:77:12:C2:41:EE:A0:3F
                DirName:/CN=DevCA
                serial:6C:55:05:AF:2E:5B:4E:0F:3F:48:3D:88:48:FB:59:CA:7A:FD:B2:A1

            X509v3 Extended Key Usage: 
                TLS Web Server Authentication
            X509v3 Key Usage: 
                Digital Signature, Key Encipherment
            X509v3 Subject Alternative Name: 
                DNS:my-server

W Issuer/commonName widzimy, że certyfikat został wydany przez urząd "DevCA" dla podmiotu my-server (Subject/commonName).
W Basic Constraints widzimy CA:FALSE, a zatem ten certyfikat nie może być używany w zakresie urzędu certyfikacyjnego (podpisywania innych certyfikatów).
Extended Key Usage informuje nas, że jest to certyfikat służący do poświadczenia tożsamości serwera w sesjach bezpiecznej transmisji danych (TLS).

Certyfikaty klientów

Zdarza się, że ze względów bezpieczeństwa chcemy wykorzystać autentykację za pomocą certyfikatu. Przykładem może być dostęp do serwera VPN przy użyciu certyfikatu zamiast pary użytkonik/hasło. W najprostszym przypadku (na własny użytek) certyfikaty te generujemy podobnie do certyfikatów serwera. Służy do tego komenda easyrsa build-client-full.
Wygenerowana zostanie para certyfikat/klucz, pola w certyfikacie (Key Usage, Extended Key Usage) będą zawierały wpisy właściwe dla certyfikatu klienta, służącego do autentykacji.

CSR (certificate signing request)

Realizacja próśb certyfikacji

W powyższych scenariuszach tworzyliśmy pary certyfikat/klucz samodzielnie. Mieliśmy zatem dostęp do kluczy prywatnych, których mogliśmy bezośrednio użyć.
W urzędach certyfikacyjnych wykorzystuje się jednak często CSR (certificate signing request 3). W takim przypadku "aplikant" (nasz klient) samodzielnie generuje prośbę o certyfikację (podpis), która nie zawiera klucza prywatnego. Dzięki temu urząd zajmuje się jedynie poświadczeniem tożsamości aplikanta, ale nie otrzymuje samego klucza prywatnego. Aplikant dostarcza prośbę o podpis, która zawiera klucz publiczny, ale jest podpisana kluczem prywatnym aplikanta.

Przykład

Dla przykładu przyjmijmy, że w naszym zespole deweloperskim pojawia się nowa osoba, która ma posiadać własny certyfikat. Osoba ta generuje na swoim komputerze prośbę o podpis (CSR), przykładowo:

/tmp/JohnDoe $ openssl req -out john_doe.csr -new -newkey rsa:2048 -nodes -keyout john_doe_private.key
Generating a RSA private key
....................................+++++.
writing new private key to 'john_doe_private.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:XX
State or Province Name (full name) [Some-State]:Internet
Locality Name (eg, city) []:Nowhere
Organization Name (eg, company) [Internet Widgits Pty Ltd]:MyCompany
Organizational Unit Name (eg, section) []:Development
Common Name (e.g. server FQDN or YOUR name) []:John Doe
Email Address []:john.doe@example.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

a nasz urząd (DevCA) otrzymuje tę prośbę (tylko plik john_doe.csr). Umieszczamy zatem plik john_doe.csr w pki/reqs. Zwracam tutaj uwagę, że easyrsa spodziewa się próśb o podpis w plikach z rozszerzeniem "req".

~/CA $ cp -v /tmp/JohnDoe/john_doe.csr pki/reqs/john_doe.req
'/tmp/JohnDoe/john_doe.csr' -> 'pki/reqs/john_doe.req'

Teraz nasz urząd może podpisać tę prośbę podając zakres użycia tego certyfikatu (client, server, email, ...). W przykładzie podpiszę tę prośbę generując certyfikat typu "client", który służy do poświadczenia klienta (np. przy logowaniu do usług).

~/CA $ ./easyrsa sign-req client john_doe
Using SSL: openssl OpenSSL 1.1.1l  24 Aug 2021


You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.

Request subject, to be signed as a client certificate for 825 days:

subject=
    countryName               = XX
    stateOrProvinceName       = Internet
    localityName              = Nowhere
    organizationName          = MyCompany
    organizationalUnitName    = Development
    commonName                = John Doe
    emailAddress              = john.doe@example.com


Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes
Using configuration from /home/me/CA/pki/easy-rsa-3903649.J4x6ao/tmp.w7LC9e
Enter pass phrase for /home/me/CA/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'XX'
stateOrProvinceName   :ASN.1 12:'Internet'
localityName          :ASN.1 12:'Nowhere'
organizationName      :ASN.1 12:'MyCompany'
organizationalUnitName:ASN.1 12:'Development'
commonName            :ASN.1 12:'John Doe'
emailAddress          :IA5STRING:'john.doe@example.com'
Certificate is to be certified until Mar  5 21:22:14 2024 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

Certificate created at: /home/me/CA/pki/issued/john_doe.crt

W pliku pki/issued/john_doe.crt mamy podpisany przez nas certyfikat, który przekazujemy aplikantowi.
Certyfikat ten będzie możliwy do wykorzystania jedynie z kluczem prywatnym aplikanta, którego sam urząd certyfikacyjny nie posiada.

Ważność wystawionego certyfikatu wynosi 825 dni, a certyfikat ograniczony jest do użycia w roli klienta (easyrsa sign-req client NAME).
Możemy wyświetlić ten certyfikat:

~/CA $ ./easyrsa show-cert john_doe
Using SSL: openssl OpenSSL 1.1.1l  24 Aug 2021

Showing cert details for 'john_doe'.
This file is stored at:
/home/me/CA/pki/issued/john_doe.crt

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            62:48:b8:a4:36:81:ce:87:46:72:98:06:73:b3:c7:51
        Signature Algorithm: sha256WithRSAEncryption
        Issuer:
            commonName                = DevCA
        Validity
            Not Before: Dec  1 21:22:14 2021 GMT
            Not After : Mar  5 21:22:14 2024 GMT
        Subject:
            countryName               = XX
            stateOrProvinceName       = Internet
            localityName              = Nowhere
            organizationName          = MyCompany
            organizationalUnitName    = Development
            commonName                = John Doe
            emailAddress              = john.doe@example.com
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Subject Key Identifier: 
                66:C6:10:CE:BE:43:B8:7F:11:FE:AC:93:95:2E:E4:A0:D9:6F:5A:94
            X509v3 Authority Key Identifier: 
                keyid:15:39:EE:09:C9:39:D8:93:84:01:A3:E9:0F:77:12:C2:41:EE:A0:3F
                DirName:/CN=DevCA
                serial:6C:55:05:AF:2E:5B:4E:0F:3F:48:3D:88:48:FB:59:CA:7A:FD:B2:A1

            X509v3 Extended Key Usage: 
                TLS Web Client Authentication
            X509v3 Key Usage: 
                Digital Signature

W Extended Key Usage widzimy TLS Web Client Authentication.

Generowanie CSR w EasyRSA

EasyRSA pozwala również w łatwy sposób generować CSR, kiedy to my ubiegamy się o podpis w zewnętrznym urzędzie certyfikacyjnym.
Służy do tego "easyrsa gen-req MY-NAME, gdzie w miejsce MY-NAME wstawiamy własną nazwę (nazwisko, domenę, nazwę serwera, organizacji, itp.).

Odnawianie certyfikatów (scenariusz)

W celu odnowienia certyfikatu używamy komendy "easyrsa renew nazwa_certyfikatu".
W pliku vars EasyRSA pozwala skonfigurować liczbę dni pozostałych do końca ważności certyfikatu, w których takie odnowienie można zrealizować.
Jest to zmienna EASYRSA_CERT_RENEW. Domyślnie jest to okres 30 dni (do wygaśnięcia certyfikatu).

Prześledźmy scenariusz:

Użytkownik Bob generuje prośbę o podpis

Generuję CSR w katalogu "/tmp", aby pokazać, że odbywa się to poza urzędem.

/tmp $ openssl req -out bob.req -new -newkey rsa:2048 -nodes -keyout bob.key

Urząd otrzymuje plik bob.req

W naszym przypadku, po prostu kopiuję "otrzymany" certyfikat do pokatalogu "pki/reqs" w katalogu urzędu (CA).

~/CA $ cp -v /tmp/bob.req pki/reqs/
'/tmp/bob.req' -> 'pki/reqs/bob.req'

Urząd wystawia certyfikat z datą ważności 15 dni

W tym celu ustawiamy zmienną środowiskową (export EASYRSA_CERT_EXPIRE=15), lub podajemy ją przy wywołaniu easyrsa.
Dla odmiany, tym razem wystawiam certyfikat dla roli "server".

~/CA $ EASYRSA_CERT_EXPIRE=15 ./easyrsa sign-req server bob
Using SSL: openssl OpenSSL 1.1.1l  24 Aug 2021


You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.

Request subject, to be signed as a server certificate for 15 days:

subject=
    countryName               = XX
    stateOrProvinceName       = XX
    localityName              = XX
    organizationName          = XX
    organizationalUnitName    = XX
    commonName                = Bob
    emailAddress              = bob@example.com


Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes
Using configuration from /home/me/CA/pki/easy-rsa-3963525.lAt1AE/tmp.GFiGbh
Enter pass phrase for /home/me/CA/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'XX'
stateOrProvinceName   :ASN.1 12:'XX'
localityName          :ASN.1 12:'XX'
organizationName      :ASN.1 12:'XX'
organizationalUnitName:ASN.1 12:'XX'
commonName            :ASN.1 12:'Bob'
emailAddress          :IA5STRING:'bob@example.com'
Certificate is to be certified until Dec 16 22:17:47 2021 GMT (15 days)

Widzimy, że easyrsa informuje nas o okresie ważności dla certyfikatu zanim potwierdzimy jego generowanie wpisujac "yes".
Certyfikat został wygenerowany z datą ważności 15 dni.

Odnawiamy certyfikat

~/CA $ ./easyrsa renew bob
Using SSL: openssl OpenSSL 1.1.1l  24 Aug 2021


Please confirm you wish to renew the certificate with the following subject:

subject=
    countryName               = XX
    stateOrProvinceName       = XX
    localityName              = XX
    organizationName          = XX
    organizationalUnitName    = XX
    commonName                = Bob
    emailAddress              = bob@example.com

X509v3 Subject Alternative Name:
    DNS:Bob


Type the word 'yes' to continue, or any other input to abort.
  Continue with renew: yes
Generating a RSA private key
..................................+++++
writing new private key to '/home/me/CA/pki/easy-rsa-3966184.8CFoSa/tmp.XBnK5B'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
Using configuration from /home/me/CA/pki/easy-rsa-3966184.8CFoSa/tmp.p9Ji87
Enter pass phrase for /home/me/CA/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'bob'
Certificate is to be certified until Dec 17 22:20:32 2021 GMT (16 days)

Write out database with 1 new entries
Data Base Updated

UWAGA: Tak naprawdę odnowienie certyfikatu polega na jego unieważnieniu i wygenerowaniu nowego. Dlatego widzimy powyżej, że podczas "odnowienia" generowany był klucz prywatny.
"Renew" jest terminem przyjętym w świecie urzędów certyfikacyjnych, jednak jest to nieco mylące.
W rzeczywistym scenariuszu użytkownik Bob przesłałby do urzędu nowy CSR, a urząd zrealizowałby tę prośbę generując nowy certyfikat (i - zależnie od polityki - unieważniając poprzedni).
Tak dzieje się też w Let's Encrypt. Kiedy "odnawiamy" certyfikaty serwera w Let's Encrypt, to tak naprawdę "stary" certyfikat jest unieważniany i otrzymujemy nowy.

Unieważnianie certyfikatów

Możemy chcieć unieważnić dany certyfikat z różnych przyczyn, przykładowo:
- klucz prywatny powiązany z danym certyfikatem został przejęty lub został gdzieś ujawniony (np. w repozytorium kodu)
- osoba/organizacja przestaje być z nami powiązana (pracownik zmienia pracę, organizacja przestaje być naszym klientem) i chcemy odebrać dostęp, który
umożliwiał certyfikat
- "odnawiamy" certyfikat
- klucz urzędu wyciekł

W procesie unieważniania certyfikatów mamy do czynienia z tzw. "listą certyfikatów unieważnionych" (CRL - certificate revocation list 2).
Zacznijmy od prześledzenia unieważnienia certyfikatu "bob".

~/CA $ ./easyrsa revoke bob
Using SSL: openssl OpenSSL 1.1.1l  24 Aug 2021


Please confirm you wish to revoke the certificate with the following subject:

subject=
    commonName                = bob

X509v3 Subject Alternative Name:
    DNS:Bob


Type the word 'yes' to continue, or any other input to abort.
  Continue with revocation: yes
Using configuration from /home/me/CA/pki/easy-rsa-3980995.kS96kq/tmp.7DvIgE
Enter pass phrase for /home/me/CA/pki/private/ca.key:
Revoking Certificate A68D8C53A78F1B7E05F9898151629321.
Data Base Updated

IMPORTANT!!!

Revocation was successful. You must run gen-crl and upload a CRL to your
infrastructure in order to prevent the revoked cert from being accepted.

Certyfikat został unieważniony (musieliśmy podać hasło do klucza urzędu). Zwróćmy też uwagę na linię: "Revoking Certificate A68D8C53A78F1B7E05F9898151629321", przyda nam się do testu za chwilę.
EasyRSA informuje nas, że musimy wykonać komendę gen-crl, a następnie umieścić w naszej infrastrukturze otrzymaną listę odwołanych certyfikatów.
Dzięki temu - programy doknujące autentykacji (walidacji certyfikatu) będą pobierać i sprawdzać za każdym razem tę listę pod kątem certyfikatów unieważnionych.

Generujemy CRL i weryfikujemy certyfikat

~/CA $ ./easyrsa gen-crl
Using SSL: openssl OpenSSL 1.1.1l  24 Aug 2021
Using configuration from /home/me/CA/pki/easy-rsa-3984944.g7M5XD/tmp.GoLvJ8
Enter pass phrase for /home/me/CA/pki/private/ca.key:

An updated CRL has been created.
CRL file: /home/me/CA/pki/crl.pem

Dla zwięzłości - użyjemy teraz zwykłej komendy openssl do zweryfikowania certyfikatu "bob". Skoro został unieważniony, to nie może już być zweryfikowany jako poprawny.
Oczywiście musimy posiadać plik certyfikatu "bob". W rzeczywistości Bob posiadałby taki plik, a my możemy wyciągnąć jego kopię z pki/revoked/certs_by_serial/A68D8C53A78F1B7E05F9898151629321.crt.
Ciąg A68... to numer seryjny unieważnionego certyfikatu. Plik ten zawiera certyfikat "bob" i właśnie tego pliku użyję do weryfikacji względem wygenerowanej listy CRL.
Do samej weryfikacji potrzebujemy jeszcze pliku *.pem zawierającego zarówno certyfikat naszego urzędu, jak i listę CRL. Wpisuję zatem oba pliki (pki/ca.crt oraz pki/crl.pem do pliku chain.pem):

~/CA $ cat pki/ca.crt pki/crl.pem > chain.pem

Następnie wykorzystuję openssl do weryfikacji certyfikatu bob.

~/CA $ cp -v pki/revoked/certs_by_serial/A68D8C53A78F1B7E05F9898151629321.crt bob.crt
'pki/revoked/certs_by_serial/A68D8C53A78F1B7E05F9898151629321.crt' -> 'bob.crt'

~/CA $ openssl verify -crl_check -CAfile chain.pem bob.crt 
CN = bob
error 23 at 0 depth lookup: certificate revoked
error bob.crt: verification failed

Wszystko się zgadza - certyfikat został unieważniony.
Taki plik CRL powinniśmy umieścić w naszej infrastrukturze, aby inne programy dokonujące weryfikacji (serwer www, radius, postgres, itd) miały do niego dostęp.

Na koniec - dla pełnego obrazu - zweryfikujmy certyfikat, który nie został unieważniony.

~/CA $ openssl verify -crl_check -CAfile chain.pem pki/issued/john_doe.crt 
pki/issued/john_doe.crt: OK

Tutaj również wszystko się zgadza - certyfikat "john_doe" jest nadal ważny.

Podsumowanie

Przy odrobinie wiedzy o certyfikatach możemy zapewnić bezpieczeństwo danych i ich transmisji, czy autentykację we własnej infrastrukturze.
Pakiet EasyRSA jest częścią projektu OpenVPN i znacznie ułatwia pracę z OpenSSL w zakresie zarządzania certyfikatami.
Oczywiście użyjemy tego tam, gdzie jest to niezbędne, ale projekty bywają różne:
czasem pracujemy z danymi osobowymi, czasem zarządzamy użytkownikami, niekiedy wymagamy cyfrowych podpisów wiadomości (np. w niektórych kolejkach zadań w systemach rozproszonych).
Czasami też chcemy po prostu, aby nasze środowiska deweloperskie były jak najbardziej zbliżone do środowiska produkcyjnego, w którym certyfikaty SSL są obecne, a sama praca w środowisku deweloperskim wykorzystującym te same mechanizmy, co środowisko produkcyjne, pozwala wypracować lepsze standardy deweloperskie i wcześniej przewidywać procesy wdrożeniowe.
Przy odrobinie wprawy możemy to osiągnąć niskim nakładem pracy.