OpenBao – PKI

Pri premýšľaní, na čo všetko by bolo možné Openbao využiť, mi napadla PKI. Niekomu by tak mohla odpadnúť “nutnosť” mať PKI od Microsoftu a ušetriť tak náklady na licencie. V tomto návode si prejdeme celú cestu – od konfigurácie PKI až po finálne použitie certifikátov.

Root CA

Najprv si vytvoríme koreňovú certifikačnú autoritu.

  1. Aktivujeme si PKI Secrets engine. Sem budem Openbao uchovávať Root CA, certifikáty a CRL súbory. Cestu k nemu si zvolíme napr. pki_root.
    export BAO_TOKEN='<token>'
    bao secrets enable -path=pki_root pki

     

  2. Nastavíme si maximálnu platnosť certifikátov, s ktorou môže Root CA certifikáty vydávať. V našom prípade to bude všeobecne odporúčaných 10 rokov (87600 hodín)
    bao secrets tune -max-lease-ttl=87600h pki_root

     

  3. Zadefinujeme si URL adresy, kde klienti nájdu Root CA certifikát a CRL. AIA/CRL sú povinné pre správne TLS validácie v browseroch, CURL alebo HAProxy. Bez nich by niektoré systémy odmietli certifikát ako nekompletný.

    bao write pki_root/config/urls issuing_certificates="https://<bao_VIP>/v1/pki_root/ca" crl_distribution_points="https://<bao_VIP>/v1/pki_root/crl"

     

  4. Vygenerujeme si samotnú internú Root CA, ktorá si vytvorí aj vlastný privátny kľúč. Root CA bude uložená v OpenBao a nikdy neopustí jeho úložisko. Common Name a Organization sa zapíšu do X.509 certifikátu.

    bao write pki_root/root/generate/internal common_name="<Organization> Root CA" organization="<Organization>" ttl=87600h

    Výstup bude podobný tomuto:

    Key              Value
    ---              -----
    certificate      -----BEGIN CERTIFICATE-----
    MIIDwTCCAqmgAwIBAgIUZgX1MnwHy2H0Hnc84APx+hrtx/owDQYJKoZIhvcNAQEL
    ...
    ...
    Zd0na+qksVdPK0nZPaW/J6ERmvEYK5L+i65qKKD+pB620JZP5bs4kaxIGLyRLc2C
    2LrjqGI=
    -----END CERTIFICATE-----
    expiration       2078774369
    issuer_id        50949sn6-7d4e-6661-ca46-ebh7w7aee55d
    issuer_name      n/a
    issuing_ca       -----BEGIN CERTIFICATE-----
    MIIDwTCCAqmgAwIBAgIUZgX1MnwHy2H0Hnc84APx+hrtx/owDQYJKoZIhvcNAQEL
    ...
    ...
    Zd0na+qksVdPK0nZPaW/J6ERmvEYK5L+i65qKKD+pB620JZP5bs4kaxIGLyRLc2C
    2LrjqGI=
    -----END CERTIFICATE-----
    key_id           246ka8d77-cbee-6t72-d1b3-d1089h7d2ef4
    key_name         n/a
    serial_number    66:05:f5:28:7c:07:cb:61:f4:3f:77:3c:e0:91:f1:fa:1a:ed:c7:f2

Intermediate CA

Aj keď Root CA v OpenBao nikdy nie je úplne offline ako v tradičnej PKI, používanie Intermediate CA má stále zásadné bezpečnostné a prevádzkové výhody:

  • minimalizuje riziko kompromitácie root kľúča

  • zabezpečuje, že pri výmene podradenej CA sa nemusí meniť dôvera klientov

  • umožňuje rozdeliť účely PKI

  • umožňuje „soft-offline“ architektúru rootu

Ako nastaviť politiku, aby sa Root CA mohla používať iba na podpisovanie Intermediate CA, si ukážeme v niektorých z ďalších blogov.

Pokračujme teda prípravou Intermediate CA.

  1. Vytvorím si novú PKI inštanciu pre Intermediate CA. Táto inštancia nebude mať vlastný root — bude podpísaná Root CA.

    bao secrets enable -path=pki_int pki

     

  2. Nastavíme si maximálnu životnosť certifikátov vydávaných Intermediate CA. 43800 hodín = 5 rokov

    bao secrets tune -max-lease-ttl=43800h pki_int

     

  3. Aj pre Intermediate CA si nastavíme URL odkazy na certifikát Intermediate CA a jeho CRL.

    bao write pki_int/config/urls issuing_certificates="https://<bao VIP>/v1/pki_int/ca" crl_distribution_points="https://<bao VIP>/v1/pki_int/crl"

     

  4. Týmto krokom vygenerujeme privátny kľúč Intermediate CA a vytvoríme CSR. Privátny kľúč zostáva uzamknutý v PKI engine. CSR sa uloží do súboru “intermediate.csr” aby sme ho v nasledujúcom kroku podpísali pomocou Root CA.

    bao write -field=csr pki_int/intermediate/generate/internal common_name="<Organization> Intermediate CA" organization="<Organization>" ttl=43800h > intermediate.csr

     

  5. Podpíšeme rootovskou CA žiadosť intermediate.csr a vytvorí sa Intermediate certifikát. Výsledkom bude PEM bundle, ktorý bude obsahovať CA chain.

    bao write -field=certificate pki_root/root/sign-intermediate csr=@intermediate.csr format=pem_bundle ttl=43800h > intermediate_bundle.pem

     

  6. Týmto importom dostane Intermediate PKI engine svoj nový podpísaný certifikát. Tým sa z neho stáva plnohodnotná CA autorizovaná rootovskou CA. Od tohto momentu už môže vydávať certifikáty.

    bao write pki_int/intermediate/set-signed certificate=@intermediate_bundle.pem

Rola pre vystavovanie certifikátov – Web-Servers

Rola definuje, aké certifikáty môže Intermediate CA vydávať. Tu nastavujeme povolené domény, TTL, IP SAN, typ kľúča, bitovú dĺžku a CN/SAN. Rola je niečo ako „profile“, ktorý používajú všetky issue operácie.

Vytvorenie role web-servers:

bao write pki_int/roles/web-servers allowed_domains="<domain>" allow_subdomains=true allow_bare_domains=true allow_ip_sans=true require_cn=false max_ttl="8760h" key_type="rsa" key_bits=4096

Vysvetlenie parametrov:

  • allowed_domains=”<domain>” – Certifikáty môžu byť vystavované iba pre doménu napr. company.com
  • allow_subdomains=true – povolí napr. *.company.com, bao.company.com, api.company.com atď.
  • allow_bare_domains=true – povolí aj certifikát pre company.com (bez host časti)
  • allow_ip_sans=true – je možné vystaviť certifikát aj na IP SAN – užitočné pre VIP HAProxy.
  • require_cn=false – Moderné PKI už nepoužíva CN ako hostname, SAN je povinný. Toto necháme zapnuté.
  • max_ttl=”8760h” – Maximálna platnosť vystavených certifiátov je 1 rok (odporúčanie pre web servery).
  • key_type=”rsa”, key_bits=4096 – Bezpečná voľba pre serverové certifikáty → kompatibilná s HAProxy, curl, OpenSSL, …

Overíme, či sa rola vytvorila so správnymi parametrami:

bao read pki_int/roles/web-servers

Vystavenie certifikátu pre HAProxy

Teraz si vytvoríme nový serverový certifikát pre VIP HAProxy s CN + SAN. Výstup bude v JSON, ktorý bude obsahovať certifikát, privátny kľúč a CA chain. Ukladáme ho do JSON súboru preto, aby sme z neho mohli extrahovať jednotlivé časti.

  1. Vytvoríme si certifikát
    bao write -format=json pki_int/issue/web-servers common_name="bao.<domain>" alt_names="bao.<domain>" ip_sans="10.100.1.44" ttl="8760h" > bao_cert.json
  2. Z JSON si vyberieme samotný serverový certifikát. Uložíme ho do pem súboru bao.crt. Tento certifikát bude použitý priamo v HAProxy.

    jq -r .data.certificate bao_cert.json > bao.crt
  3. Extrahujeme privátny kľúč servera. chmod 600 zabezpečí, že kľúč bude čitateľný iba root účtom.

    jq -r .data.private_key bao_cert.json > bao.key
    chmod 600 bao.key
  4. Teraz si uložíme chain certifikát (Intermediate + Root) do jedného súboru. Chain musí ísť za serverovým certifikátom, inak mu prehliadače nebudú dôverovať.

    jq -r '.data.ca_chain[]' bao_cert.json > bao_chain.crt
  5. Zložíme si finálny .pem certifikát pre HAProxy a uložíme ho do /etc/haproxy. HAProxy vyžaduje súbor obsahujúci kľúč, certifikát a chain. Poradie je kritické: key -> cert -> chain.
    sudo mkdir -p /etc/haproxy
    sudo cat bao.key bao.crt bao_chain.crt | sudo tee /etc/haproxy/bao.pem >/dev/null
    sudo chmod 600 /etc/haproxy/bao.pem
  6. Prekopírujeme finálny certifikát na všetky ostatné nody bao clustra
    sudo scp /etc/haproxy/bao.pem <username>@bao02.<domain>:/tmp/bao.pem
    sudo scp /etc/haproxy/bao.pem <username>@bao03.<domain>:/tmp/bao.pem
  7. Na samotných nodoch ho potom presunieme na správne miesto
    sudo mv /tmp/bao.pem /etc/haproxy/bao.pem
    sudo chown root:root /etc/haproxy/bao.pem
    sudo chmod 600 /etc/haproxy/bao.pem

Úprava haproxy.cfg

  1. Urobme si zálohu aktuálneho konfiguračného súboru
    sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak

     

  2. Upravme ho nasledovne:
    global
        maxconn 4096
        log /dev/log local0
        log /dev/log local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin
        stats timeout 30s
        user haproxy
        group haproxy
        daemon
    
        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private
    
        # Mozilla intermediate SSL config
        ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
    
    defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 10s
        timeout client  5s
        timeout server  10s
    
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http
    
    # Interny HTTP frontend (napr. ak interne sluzby pouzivaju 9200)
    frontend openbao_http
        bind *:9200
        mode http
        option httplog
        default_backend openbao_leader
    
    
    # Verejny / VIP frontend - HTTPS 443
    frontend openbao_https
        bind *:443 ssl crt /etc/haproxy/bao.pem
        mode http
        option httplog
    
        # Sem sa moze pridat ACL, ak budeme hostovat viacero sluzieb
        default_backend openbao_leader
    
    backend openbao_leader
        mode http
        balance roundrobin
    
        # HEALTHCHECK - len LEADER odpovie 200
        option httpchk GET /v1/sys/health?standbyok=false
        http-check expect status 200
    
        default-server inter 2s fall 3 rise 3
    
        server bao01 10.100.1.41:8200 check
        server bao02 10.100.1.42:8200 check
        server bao03 10.100.1.43:8200 check
    
    listen stats
        bind *:8404
        mode http
        stats enable
        stats uri /stats
        stats refresh 10s
        stats auth admin:StatsPassw0rd123

     

  3. Teraz stačí už iba reštartovat službu HAProxy na všetkých nodoch.
    sudo systemctl restart haproxy

     

Export Root CA, Intermediate CA a vytvorenie chainu Root+Intermediate

Export Root CA

  1. Zistíme si Issuer_ID pre RootCA
    bao read pki_root/issuer/default

    Príklad výstupu:

    Key                               Value
    ---                               -----
    ca_chain                          [-----BEGIN CERTIFICATE-----
    MIIDwTCCAqmgAwIBAgIUZgX1MnwHy2H0Hnc84APx+hrtx/owDQYJKoZIhvcNAQEL
    ...
    ...
    ...
    Zd0na+qksVdPK0nZPaW/J6ERmvEYK5L+i65qKKD+pB620JZP5bs4kaxIGLyRLc2C
    2LrjqGI=
    -----END CERTIFICATE-----
    ]
    certificate                       -----BEGIN CERTIFICATE-----
    MIIDwTCCAqmgAwIBAgIUZgX1MnwHy2H0Hnc84APx+hrtx/owDQYJKoZIhvcNAQEL
    ...
    ...
    ...
    Zd0na+qksVdPK0nZPaW/J6ERmvEYK5L+i65qKKD+pB620JZP5bs4kaxIGLyRLc2C
    2LrjqGI=
    -----END CERTIFICATE-----
    crl_distribution_points           []
    delta_crl_distribution_points     []
    issuer_id                         94721-fc5-8f3s-6661-ca46-ebc9e6irr88f
    issuer_name                       n/a
    issuing_certificates              []
    key_id                            246kr990-cbee-6f26-g4g87-d1089d794bx4
    leaf_not_after_behavior           err
    manual_chain                      <nil>
    ocsp_servers                      []
    revocation_signature_algorithm    SHA256WithRSA
    revoked                           false
    usage                             crl-signing,issuing-certificates,ocsp-signing,read-only

     

  2. Export certifikátu
    bao read -field=certificate pki_root/issuer/94721-fc5-8f3s-6661-ca46-ebc9e6irr88f > <company>_root_ca.crt

Export Intermediate CA

  1. Takmer identicky zistíme Issuer_ID pre Intermediate CA
    bao read pki_int/issuer/default

    Príklad výstupu:

    Key                               Value
    ---                               -----
    ca_chain                          [-----BEGIN CERTIFICATE-----
    MIIDuTCCAqGgAwIBAgIUKZLFT8hzvWBTVpg8gmy+Vqroz6YwDQYJKoZIhvcNAQEL
    ...
    ...
    ...
    T4lT+y7B1YQfFVMOW01ss8/4jh6T7UJy3Jx1Eo7TVbjnWIvRB1H6bxfXtsvz
    -----END CERTIFICATE-----
     -----BEGIN CERTIFICATE-----
    MIIDwTCCAqmgAwIBAgIUZgX1MnwHy2H0Hnc84APx+hrtx/owDQYJKoZIhvcNAQEL
    ...
    ...
    ...
    Zd0na+qksVdPK0nZPaW/J6ERmvEYK5L+i65qKKD+pB620JZP5bs4kaxIGLyRLc2C
    2LrjqGI=
    -----END CERTIFICATE-----
    ]
    certificate                       -----BEGIN CERTIFICATE-----
    MIIDuTCCAqGgAwIBAgIUKZLFT8hzvWBTVpg8gmy+Vqroz6YwDQYJKoZIhvcNAQEL
    ...
    ...
    ...
    T4lT+y7B1YQfFVMOW01ss8/4jh6T7UJy3Jx1Eo7TVbjnWIvRB1H6bxfXtsvz
    -----END CERTIFICATE-----
    crl_distribution_points           []
    delta_crl_distribution_points     []
    issuer_id                         1fefe5-d7c2-23f6-6410-28706cd93e9c
    issuer_name                       n/a
    issuing_certificates              []
    key_id                            5aa81f43-Af6b-2b2f-0b42-94c34be681b3
    leaf_not_after_behavior           err
    manual_chain                      <nil>
    ocsp_servers                      []
    revocation_signature_algorithm    n/a
    revoked                           false
    usage                             crl-signing,issuing-certificates,ocsp-signing,read-only

     

  2. Export certifikátu
    bao read -field=certificate pki_int/issuer/1fefe5-d7c2-23f6-6410-28706cd93e9c > <company>_int_ca.crt

     

Export celého CA chainu

cat <company>_int_ca.crt <company>_root_ca.crt > <company>_chain_ca.crt

Používanie HTTPS pre BAO_ADDR

Aby sme mohli používať HTTPS v premennej BAO_ADDR potrebujeme urobiť už len 2 kroky.

  1. Nakopírujeme si Intermediate CA certifikát do /etc/openbao
    sudo cp PSguy_int_ca.crt /etc/openbao/
    sudo chmod 644 /etc/openbao/<company>_int_ca.crt

     

  2. Nastavenie BAO_ADDR a BAO_CERT
    export BAO_ADDR="https://bao.<domain>:443"
    export BAO_CACERT="/etc/openbao/<company>_int_ca.crt"

     

  3. Alebo ak chceme toto nastavenie uložiť natrvalo, tak
    echo 'export BAO_ADDR="https://bao.<domain>:443"' >> ~/.bashrc
    echo 'export BAO_CACERT="/etc/openbao/<company>_int_ca.crt"' >> ~/.bashrc

     

Záver

Teraz nám už nič nebráni používať certifikáty. Používanie certifikátov, je z mojich skúseností, pre adminov nočná mora. Preto je najlepšie si ich využívanie vyskúšať v labe a až potom nasadzovať v produkcii.

Súvisiace články:

OpenBao – centrálna správa, uchovávanie a distribúcia citlivých dát

OpenBao – vytvorenie configu a základné nastavenie

OpenBao – politiky, tokeny a reálne použitie

OpenBao – HA cluster

 

Author: Martin

Infrastructure engineer | virtualization & cloud enthusiast | vSphere specialist | blogger | Veeam Vanguard 2021,2022,2023 | VMware vExpert 2017 - 2025 | VMCE | VCP-VCF Architect, VCP-DCV, NV, TKO, VCAP-DCV, CompTIA Security+ | Slovak VMUG Leader | Slovak VUG Leader | husband&father