SSL sertifikatų (CRT failų) galiojimo laikas yra trumpesnis nei sertifikato paslaugos užsakymo periodas, todėl juos būtina periodiškai atnaujinti ir perrašyti serveryje. Sertifikato atnaujinimo (angl. reissue) procesą galima automatizuoti naudojant mūsų API.

Ši API prieiga veikia tik jau išduoto sertifikato atnaujinimui. Pirmąjį kartą CSR turi būti pateiktas klientų savitarnos sistemoje. Po pirmojo CRT išdavimo galite susisiekti su mumis ir gauti API prieigą vėlesniems atnaujinimams.

API užklausa (request)

Visoms API užklausoms privalomi identifikacijos parametrai. Nurodžius neteisingą ar neegzistuojančią parametro reikšmę, serveris grąžins HTTP 404 Not Found klaidą.

  • id=<id> — paslaugos ID mūsų sistemoje (matomas savitarnos sistemos paslaugos valdymo puslapio adrese).
  • vendorid=<id> — užsakymo ID leidėjo sistemoje (rodomas savitarnos sistemos paslaugos valdymo puslapyje).
  • cn=<domain> — pagrindinis domenas (rodomas savitarnos sistemos paslaugos valdymo puslapyje).

Komandos (action) ir jų parametrai

  • GET action=status (numatytoji komanda) – grąžina dabartinius sertifikato duomenis. Leidžiama ne dažniau kaip 1 užklausa per 10 sekundžių.
  • GET action=validate – inicijuoja pakartotinį domeno patikrinimą (pvz., sunčia el. laišką). Leidžiama ne dažniau kaip 1 užklausa per 5 minutes.
  • POST action=csr (formatas application/x-www-form-urlencoded) – įkelia naują CSR sertifikato atnaujinimui. Komanda priimama tik jau išduotiems sertifikatams ("status": "active") – negalima įkelti naujo CSR, jei neužbaigtas anksčiau įkelto CSR patikrinimas. Šiai komandai būtini POST parametrai:
    • csr – užklausa PEM formatu.
    • dcv_method: email, dns, http arba https.
    • approveremail – kai dcv_method=email, būtina nurodyti patikrinimo el. pašto adresą, pvz., admin@kriptografija.lt.

Ši API prieiga skirta kuo paprastesniam CRT failų atnaujinimo automatizavimui, todėl turi ne visas komandas. Pavyzdžiui, įkėlus CSR nebegalima keisti DCV metodo, nes automatizacijos skriptas to nedarytų. Šiuos per API neprieinamus veiksmus galima atlikti prisijungus prie klientų savitarnos sistemos.

Pavyzdžiai:

curl -s "https://<host>?id=12345&vendorid=1234567890&cn=kriptografija.lt"
curl -s "https://<host>?id=12345&vendorid=1234567890&cn=kriptografija.lt&action=validate"
curl -s -X POST "https://<host>?id=12345&vendorid=1234567890&cn=kriptografija.lt&action=csr" \
  --data-urlencode "csr=$(cat request.csr)" \
  --data-urlencode "dcv_method=email" \
  --data-urlencode "approveremail=admin@kriptografija.lt"

API atsakymas (response)

Atsakymas pateikiamas application/json;charset=utf-8 formatu.

status atsakymas

Atsakymo pavyzdys įkėlus CSR domenui kriptografija.lt nurodžius patikrinimo būdą https:

{
  "status": "active",
  "cn": "kriptografija.lt",
  "crt_from": "2026-08-01",
  "crt_till": "2027-08-01",
  "service_from": "2026-07-15",
  "service_till": "2028-07-15",
  "dcv_method": "https",
  "validation": {
    "method": "https",
    "filename": "09BBA5094D9F8BA68BD35D24F7E5511F.txt",
    "path": "/.well-known/pki-validation/09BBA5094D9F8BA68BD35D24F7E5511F.txt",
    "content": "98D245A3509D89B3945E4058B2483B6EA193B241D79087A2106EBF4BFB79434C\r\nsectigo.com\r\nt0429980001787904444"
  },
  "sans": {
    "www.kriptografija.lt": {
      "method": "https",
      "filename": "09BBA5094D9F8BA68BD35D24F7E5511F.txt",
      "path": "/.well-known/pki-validation/09BBA5094D9F8BA68BD35D24F7E5511F.txt",
      "content": "98D245A3509D89B3945E4058B2483B6EA193B241D79087A2106EBF4BFB79434C\r\nsectigo.com\r\nt0429980001787904444"
    }
  },
  "csr": "-----BEGIN CERTIFICATE REQUEST-----...",
  "crt": "-----BEGIN CERTIFICATE-----...",
  "ca": "-----BEGIN CERTIFICATE-----..."
}

validation reikšmė ir jos struktūra priklauso nuo pasirinkto DCV metodo. Visuose pavyzdžiuose naudojame dažniausiai naudojamą https metodą. sans reikšmė turi tą pačią validation struktūrą kiekvienam į sertifikatą įrašomam SAN adresui – jie visi turi būti patikrinti.

validation ir sans reikšmės pateikiamos tik tuomet, kai vyksta įkelto CSR patikrinimas. Kol naujas CSR neįkeltas (sertifikatas tiesiog galioja), šių reikšmių atsakyme nėra – DCV duomenų reikia ieškoti tik įvykdžius action=csr komandą. Duomenys atsiranda ne akimirksniu, todėl automatizacijos skripte status užklausą verta pakartoti kelis kartus.

Jei ankstesnio atnaujinimo DCV įrašas (failas serveryje arba DNS įrašas) tebegalioja, sertifikatas gali būti išduotas iškart. Tuomet validation duomenų atsakyme irgi nebus, tačiau crt reikšmėje jau bus naujas sertifikatas – automatizacijos skriptas šiuos atvejus turi atskirti palygindamas gautą crt su serveryje įdiegtuoju.

status reikšmės:

  • active – sertifikatas jau išduotas. Atsakyme pateikiami crt ir ca duomenys.
  • processing – vyksta domeno patikrinimas, sertifikatas neišduotas.

validate atsakymas

{
  "success": true,
  "message": "success"
}

csr atsakymas

Atsakyme visų pirma nurodoma, ar atnaujinimo užklausa priimta. Sėkmės atveju kartu pateikiami ir įprasti status atsakymo duomenys:

{
  "accepted": true,
  "message": "Reissue request accepted",
  "status": "processing",
  "cn": "example.com",
  "...": "..."
}

Jei CSR netinka, accepted reikšmė yra false, o priežastis nurodoma message laukelyje:

{
  "accepted": false,
  "message": "CSR does not match the domain"
}

Prieš tęsdami domeno patikrinimą, būtinai patikrinkite accepted reikšmę – neužtenka to, kad užklausa grąžino HTTP 200. Jei POST užklausa neteisinga, CSR netikrinamas ir iš karto grąžinamas klaidos atsakymas 422 {"error": "Missing required field(s): ..."}.

Įkėlus naują CSR, pagal senąjį CSR išduotas CRT lieka galioti iki galiojimo pabaigos, tačiau mūsų sistema jo neberodo.

Automatizavimas

Su įvairiomis serverių valdymo programomis galime susikurti automatizavimo skriptą/receptą, kuris periodiškai tikrins serveryje įdiegtų CRT failų galiojimo laikus ir per API užsakys jų atnaujinimus.

Bash skriptas

Čia pateikiame pavyzdį panaudojant vieną Bash skriptą, kuris patikrina sertifikato galiojimo datą ir, jei reikia, inicijuoja naujo CRT išdavimą bei atlieka įdiegimą. Pavyzdyje reikalingi tik openssl, curl ir jq paketai. mail paketas naudojamas pranešimams administratoriui siųsti – jei jo serveryje nėra, pranešimai lieka tik skripto registre (log). Realioje situacijoje pranešimams turėtų būti naudojamas patikimesnis kanalas.

Pateiktas skriptas naudoja seniau išsaugotą privatų raktą. Dauguma kibernetinio saugumo tvarkų numato privačių raktų rotavimą – tai išlieka serverio administratoriaus atsakomybė. Patikimas raktų rotavimas gali būti įgyvendinamas tik koreguojant žiniatinklio serverio konfigūraciją, nes vienu metu turi būti saugomas ir senasis, ir naujasis privatus raktas, nerekomenduojame tiesiog perrašyti senojo rakto failą ir prarasti senąjį raktą. Todėl raktų rotavimą administratorius turi automatizuoti numatydamas žiniatinklio serverio konfigūracijos failo koregavimą arba bent jau rankiniu būdu kaskart kai keičiasi sertifikato paslaugos ID.

#!/bin/bash

# Nutraukiame vykdymą, jei naudojamas neapibrėžtas kintamasis
set -u

# ==========================================
# A. Nustatymai – reikia pakeisti
# ==========================================

# Sertifikato paslaugos nustatymai – pakeisti po kiekvieno sertifikato užsakymo
ID="12345"
VENDORID="1234567890"
DOMAIN="kriptografija.lt"

# Serverio nustatymai - įvesti kiekvienam vhost pajungiant pirmą kartą
ADMIN_EMAIL="admin@kriptografija.lt" # Administratoriaus el. paštas perspėjimams
WEB_ROOT="/var/www/html" # Kelis vartotojus turinčiuose serveriuose dažniausiai /home/user/$DOMAIN/public
CRT_FILE="/etc/ssl/certs/${DOMAIN}.crt"
CA_FILE="/etc/ssl/certs/${DOMAIN}-ca.crt"
KEY_FILE="/etc/ssl/private/${DOMAIN}.key"
CSR_FILE="/etc/ssl/csr/${DOMAIN}.csr"
JSON_FILE="/etc/ssl/kriptografija.lt/${DOMAIN}.json"

# API nustatymai - įvesti pajungiant pirmą kartą
HOST="kriptografija.lt/api/ssl.php" # Hipotetinis, tikrą suteikia pagalbos tarnyba
MIN_DAYS=20
MAX_WAIT=10800 # Maksimalus DCV laukimo laikas: 3 valandos (10800 sekundžių)

# ==========================================
# 0. Skripto aplinkos sukūrimas
# ==========================================

API_URL="https://$HOST?id=$ID&vendorid=$VENDORID&cn=$DOMAIN"
START_TIME=$(date +%s)
API_ERROR="" # Paskutinės nepavykusios API užklausos priežastis

# Pranešimas administratoriui. Jei „mail“ paketo serveryje nėra,
# žinutė lieka tik skripto registre (log faile) – skriptas dėl to nenutrūksta.
notify() {
    local subject="$1"
    local body="$2"

    echo "$body"

    if command -v mail > /dev/null 2>&1; then
        echo "$body" | mail -s "$subject" "$ADMIN_EMAIL"
    else
        echo "Įspėjimas: komanda 'mail' nerasta, pranešimas '$subject' neišsiųstas." >&2
    fi
}

# Visos API užklausos. Atsakymą įrašo į $API_BODY; jei nepavyko prisijungti
# arba grąžintas ne HTTP 200, parodo priežastį ir grąžina klaidos kodą.
api_call() {
    local response http_code curl_error error_file
    error_file=$(mktemp)

    response=$(curl --silent --show-error --max-time 30 --write-out '\n%{http_code}' "$@" 2> "$error_file")
    http_code=$(printf '%s\n' "$response" | tail -n 1)
    API_BODY=$(printf '%s\n' "$response" | sed '$d')
    curl_error=$(cat "$error_file")
    rm -f "$error_file"

    # HTTP kodas 000 reiškia, kad prisijungti prie serverio išvis nepavyko (DNS, TLS, ugniasienė)
    if [ "$http_code" != "200" ]; then
        API_ERROR="HTTP $http_code: ${curl_error:-${API_BODY:-tuščias atsakymas}}"
        echo "API klaida – $API_ERROR" >&2
        return 1
    fi
}

# Tikriname, ar skriptas paleistas su root teisėmis
if [ "$EUID" -ne 0 ]; then
    echo "Klaida: Šį skriptą būtina paleisti su 'root' teisėmis (naudokite sudo), kad būtų išvengta 'Permission denied' klaidų."
    exit 1
fi

# Užtikriname, kad SSL katalogai egzistuoja
mkdir -p /etc/ssl/certs
mkdir -p /etc/ssl/private
mkdir -p /etc/ssl/csr
mkdir -p /etc/ssl/kriptografija.lt

# ==========================================
# 1. Sertifikato galiojimo patikrinimas
# ==========================================

# Patikriname, ar failas egzistuoja ir ar sėkmingai nuskaitoma data
if [ -f "$CRT_FILE" ]; then
    EXP_DATE=$(openssl x509 -enddate -noout -in "$CRT_FILE" 2>/dev/null | cut -d= -f2)

    if [ -n "$EXP_DATE" ]; then
        EXP_SEC=$(date -d "$EXP_DATE" +%s)
        NOW_SEC=$(date +%s)
        DAYS_LEFT=$(( (EXP_SEC - NOW_SEC) / 86400 ))
    else
        DAYS_LEFT=-1
    fi
else
    DAYS_LEFT=-1
fi

if [ "$DAYS_LEFT" -ge 0 ] && [ "$DAYS_LEFT" -gt "$MIN_DAYS" ]; then
    echo "Sertifikatas dar galioja $DAYS_LEFT d. Atnaujinimas nereikalingas."
    exit 0
elif [ "$DAYS_LEFT" -lt 0 ]; then
    echo "Sertifikato failas nerastas arba negaliojantis. Pradedamas naujas išdavimas."
else
    echo "Sertifikatas galioja tik $DAYS_LEFT d. Pradedamas atnaujinimas."
fi

# ==========================================
# 2. Paslaugos galiojimo patikrinimas iš API
# ==========================================

# Jei API neatsakė, toliau nebetęsiame – kitaip klaida keliautų per visą skriptą
if ! api_call "$API_URL"; then
    notify "Klaida: SSL API neatsako domenui $DOMAIN" "Nepavyko gauti sertifikato būsenos iš API domenui $DOMAIN ($API_ERROR). Patikrinkite HOST, ID, VENDORID ir CN reikšmes bei serverio interneto ryšį."
    exit 1
fi

STATUS_JSON="$API_BODY"
API_STATUS=$(echo "$STATUS_JSON" | jq -r '.status // empty')

if [ -z "$API_STATUS" ]; then
    notify "Klaida: netinkamas SSL API atsakymas domenui $DOMAIN" "API atsakyme nėra 'status' reikšmės. Gautas atsakymas: $STATUS_JSON"
    exit 1
fi

SERVICE_TILL=$(echo "$STATUS_JSON" | jq -r '.service_till')

if [ "$SERVICE_TILL" != "null" ] && [ -n "$SERVICE_TILL" ]; then
    SERVICE_TILL_SEC=$(date -d "$SERVICE_TILL" +%s)
    NOW_SEC=$(date +%s)
    SERVICE_DAYS_LEFT=$(( (SERVICE_TILL_SEC - NOW_SEC) / 86400 ))

    if [ "$SERVICE_DAYS_LEFT" -lt 20 ]; then
        notify "Dėmesio: Baigiasi SSL paslauga domenui $DOMAIN" "Domeno $DOMAIN sertifikato paslauga baigsis už $SERVICE_DAYS_LEFT d. ($SERVICE_TILL). Būtina užsakyti naują paslaugą. Atnaujinimas nutrauktas."
        exit 1
    else
        echo "Sertifikato paslauga dar galioja $SERVICE_DAYS_LEFT d. Tęsiame..."
    fi
fi

# ==========================================
# 3. CSR generavimas ir siuntimas
# ==========================================

if [ "$API_STATUS" == "processing" ]; then
    echo "Sertifikato būsena yra 'processing'. CSR jau pateiktas ankstesnio vykdymo metu."
else
    # Jei privataus rakto nėra arba jis tuščias (pvz., liko po nepavykusio vykdymo), sukuriame naują
    if [ ! -s "$KEY_FILE" ]; then
        echo "Privatus raktas nerastas arba tuščias. Generuojamas naujas: $KEY_FILE"
        openssl genrsa -out "$KEY_FILE" 2048 || exit 1
        chmod 600 "$KEY_FILE"
    fi

    # Netinkamo rakto neperrašome – jis gali būti naudojamas kitur; apie tai pranešame administratoriui
    if ! openssl rsa -in "$KEY_FILE" -noout -check > /dev/null 2>&1; then
        notify "Klaida: netinkamas privatus raktas domenui $DOMAIN" "Privatus raktas $KEY_FILE netinkamas arba apsaugotas slaptažodžiu, todėl CSR sugeneruoti nepavyks."
        exit 1
    fi

    echo "Generuojamas naujas CSR failas: $CSR_FILE"
    openssl req -new -sha256 -key "$KEY_FILE" -out "$CSR_FILE" -subj "/CN=$DOMAIN" || exit 1

    # Įsitikiname, kad CSR tikrai sugeneruotas – tuščią CSR API priimtų, bet atnaujinimas neprasidėtų
    if ! openssl req -in "$CSR_FILE" -noout -verify > /dev/null 2>&1; then
        notify "Klaida: netinkamas CSR domenui $DOMAIN" "Sugeneruotas CSR failas $CSR_FILE yra tuščias arba netinkamas."
        exit 1
    fi

    # Siunčiame CSR į API – tik po to tiekėjo sistemoje atsiranda DCV duomenys
    echo "Siunčiame CSR į API."
    if ! api_call -X POST "${API_URL}&action=csr" \
        --data-urlencode "csr=$(cat "$CSR_FILE")" \
        --data-urlencode "dcv_method=https"; then
        notify "Klaida: nepavyko įkelti CSR domenui $DOMAIN" "Nepavyko įkelti CSR domenui $DOMAIN. $API_ERROR"
        exit 1
    fi

    STATUS_JSON="$API_BODY"
    echo "$STATUS_JSON" > "$JSON_FILE"

    # Tiekėjo sistema CSR priima ne visada, todėl tikriname „accepted“ reikšmę,
    # o ne vien HTTP kodą – kitaip veltui lauktume DCV duomenų
    CSR_ACCEPTED=$(echo "$STATUS_JSON" | jq -r '.accepted // false')
    CSR_MESSAGE=$(echo "$STATUS_JSON" | jq -r '.message // empty')

    if [ "$CSR_ACCEPTED" != "true" ]; then
        notify "Klaida: CSR nepriimtas domenui $DOMAIN" "API atmetė CSR domenui $DOMAIN: ${CSR_MESSAGE:-priežastis nenurodyta}. Atsakymas išsaugotas: $JSON_FILE"
        exit 1
    fi

    echo "CSR priimtas: ${CSR_MESSAGE:-atsakyme pranešimo nėra}"
fi

# ==========================================
# 4. DCV failų kūrimas ir patvirtinimo inicijavimas
# ==========================================

# DCV duomenys atsakyme atsiranda tik tada, kai vyksta įkelto CSR patikrinimas, ir ne iš karto
# po CSR įkėlimo, todėl „status“ užklausą kartojame (API leidžia 1 užklausą per 10 sekundžių).
DCV_LIST=""
SKIP_DCV=0 # 1 – DCV nebereikia, nes sertifikatas jau išduotas

for ATTEMPT in 1 2 3; do
    sleep 10

    if ! api_call "$API_URL"; then
        notify "Klaida: SSL API neatsako domenui $DOMAIN" "Nepavyko gauti DCV duomenų iš API domenui $DOMAIN ($API_ERROR)."
        exit 1
    fi

    STATUS_JSON="$API_BODY"
    echo "$STATUS_JSON" > "$JSON_FILE"

    # Išrenkame pagrindinio domeno („validation“) ir visų SAN adresų („sans“) DCV failus.
    # Turinį perduodame base64 formatu, nes jame yra eilučių lūžių (CRLF).
    DCV_LIST=$(echo "$STATUS_JSON" | jq -r '
        [.validation] + [.sans[]?]
        | .[]
        | select(.path != null and .content != null)
        | "\(.path)\t\(.content | @base64)"' | sort -u)

    if [ -n "$DCV_LIST" ]; then
        break
    fi

    echo "DCV duomenų dar nėra ($ATTEMPT bandymas iš 3). Laukiame..."
done

# Jei ankstesnio atnaujinimo DCV įrašas dar galioja, sertifikatas išduodamas iškart –
# tuomet DCV duomenų atsakyme nebus, bet „crt“ reikšmėje jau bus naujas sertifikatas.
if [ -z "$DCV_LIST" ]; then
    INSTALLED_FINGERPRINT=$(openssl x509 -in "$CRT_FILE" -noout -fingerprint -sha256 2>/dev/null)
    NEW_FINGERPRINT=$(echo "$STATUS_JSON" | jq -r '.crt // empty' | openssl x509 -noout -fingerprint -sha256 2>/dev/null)

    if [ -n "$NEW_FINGERPRINT" ] && [ "$NEW_FINGERPRINT" != "$INSTALLED_FINGERPRINT" ]; then
        echo "DCV duomenų nėra, tačiau API pateiktas CRT skiriasi nuo įdiegtojo – sertifikatas jau išduotas. Pereiname prie diegimo."
        SKIP_DCV=1
    else
        notify "Klaida: negauti DCV duomenys domenui $DOMAIN" "API atsakyme nėra 'validation' duomenų, o pateiktas CRT nesiskiria nuo įdiegtojo domenui $DOMAIN. Patikrinkite, ar CSR įkeltas ir ar naudojamas 'https' DCV metodas (atsakymas išsaugotas: $JSON_FILE)."
        exit 1
    fi
fi

if [ "$SKIP_DCV" -eq 0 ]; then
    while IFS=$'\t' read -r DCV_PATH DCV_B64; do
        mkdir -p "${WEB_ROOT}$(dirname "$DCV_PATH")"
        # Naudojame tee, jei skriptas kažkokiu būdu paleistas su dalinėmis sudo teisėmis
        echo "$DCV_B64" | base64 -d | tee "${WEB_ROOT}${DCV_PATH}" > /dev/null
        echo "Sukūrėme naują DCV failą: ${WEB_ROOT}${DCV_PATH}"
    done <<< "$DCV_LIST"

    if [ "$API_STATUS" == "processing" ]; then
        api_call "${API_URL}&action=validate" > /dev/null
        echo "Inicijavome DCV procesą iš naujo."
    fi
fi

# ==========================================
# 5. Laukiame sertifikato išdavimo
# ==========================================

while true; do
    if api_call "$API_URL"; then
        STATUS_JSON="$API_BODY"
        STATUS=$(echo "$STATUS_JSON" | jq -r '.status // empty')
    else
        # Laikina API klaida neturi nutraukti laukimo – bandysime dar kartą
        STATUS=""
    fi

    if [ "$STATUS" == "active" ]; then
        echo "Išsaugomi nauji CRT ir CA failai..."

        echo "$STATUS_JSON" | jq -r '.crt' > "${CRT_FILE}.new"
        echo "$STATUS_JSON" | jq -r '.ca' > "$CA_FILE"

        # Įsitikiname, kad gautas CRT atitinka mūsų privatų raktą, ir tik tada keičiame veikiantį failą
        CRT_MOD=$(openssl x509 -noout -modulus -in "${CRT_FILE}.new" 2>/dev/null | openssl md5)
        KEY_MOD=$(openssl rsa -noout -modulus -in "$KEY_FILE" 2>/dev/null | openssl md5)

        if [ -z "$CRT_MOD" ] || [ "$CRT_MOD" != "$KEY_MOD" ]; then
            rm -f "${CRT_FILE}.new"
            notify "Klaida: SSL atnaujinimas domenui $DOMAIN" "Gautas CRT neatitinka privataus rakto $KEY_FILE. Senas sertifikatas paliekamas nepakeistas."
            exit 1
        fi

        # Sujungiame CRT ir CA į vieną failą Nginx serveriui
        cat "$CA_FILE" >> "${CRT_FILE}.new"
        mv "${CRT_FILE}.new" "$CRT_FILE"

        # Perkrauname žiniatinklio serverį – reikia pakeisti į naudojamo paketo komandą
        nginx -t && systemctl reload nginx
        echo "Sertifikatas sėkmingai atnaujintas ir įdiegtas."
        break
    else
        CURRENT_TIME=$(date +%s)
        ELAPSED=$(( CURRENT_TIME - START_TIME ))
        ELAPSED_MIN=$(( ELAPSED / 60 ))

        if [ "$ELAPSED" -gt "$MAX_WAIT" ]; then
            notify "Kritinė klaida: SSL atnaujinimas strigo" "Domeno $DOMAIN patvirtinimas (DCV) užtruko ilgiau nei 3 valandas. Sertifikato atnaujinimas nutrauktas."
            exit 1
        fi

        echo "Sertifikatas dar neišduotas, praėjo $ELAPSED_MIN min. Laukiame..."
        sleep 60
    fi
done

Skriptas DCV failus sukuria pagrindiniam domenui (validation) ir visiems SAN adresams (sans) – jei SAN adresai serveryje naudoja atskirus dokumentų katalogus, tą patį failą reikia nukopijuoti į kiekvieną iš jų.

Skripte CSR generuojamas nurodant tik CN – atnaujinant DV sertifikatą to pakanka. SAN adresai imami iš užsakymo, o ne iš CSR (žr. CSR generavimas), įmonės ir adreso duomenys DV sertifikatuose nenaudojami, o OU laukelis viešuose SSL sertifikatuose nuo 2022 m. rugsėjo 1 d. apskritai neleidžiamas. Svarbu tik tai, kad CN sutaptų su užsakymo cn reikšme (wildcard sertifikatams – *.kriptografija.lt), raktas būtų bent 2048 bitų, o parašas – SHA-256.

Atnaujinant OV arba EV sertifikatą tomis pačiomis komandomis, į -subj reikšmę papildomai įrašykite patikrintus įmonės duomenis, pvz.: -subj "/CN=$DOMAIN/O=UAB Pavyzdys/C=LT/ST=Vilnius/L=Vilnius".

Prieš pirmą paleidimą įsitikinkite, kad HOST reikšmėje nurodytas tikrasis mūsų pagalbos tarnybos suteiktas adresas – pavyzdyje pateiktas adresas yra hipotetinis. Užklausą patogu pasitikrinti rankiniu būdu:

curl -sS "https://<host>?id=12345&vendorid=1234567890&cn=kriptografija.lt"

Jei skriptas praneša HTTP 000, serveris API iš viso nepasiekė – patikrinkite adresą, DNS ir ugniasienę. HTTP 404 reiškia neteisingas id, vendorid arba cn reikšmes.

Išsaugome šį skriptą serveryje, pvz.: /usr/local/bin/ssl-renew-kriptografija.lt.sh. Suteikiame šiam failui vykdymo teises:

chmod +x /usr/local/bin/ssl-renew-kriptografija.lt.sh

Paleidžiame šį skriptą prisijungę prie serverio per SSH ir patikriname, ar viskas veikia:

/usr/local/bin/ssl-renew-kriptografija.lt.sh

CRON komanda

Kad šis skriptas būtų paleidžiamas automatiškai kasnakt, o mes galėtume pasitikrinti jo istoriją, sukuriame cron komandą atsidarę redaktorių (crontab -e) skripto paleidimui kadien 2:00 ir jo atsakymo išsaugojimui į registrą:

0 2 * * * /usr/local/bin/ssl-renew-kriptografija.lt.sh >> /var/log/ssl-renew-kriptografija.lt.log 2>&1

Kiti DCV metodai

Po CSR įkėlimo lengviausia domeno patikrinimą automatizuoti dcv_method nustačius http arba https – tame pačiame serveryje, kuris naudos sertifikatą, sukuriame txt failą.

Tačiau HTTP/HTTPS metodas turi apribojimų:

  • visada tikrinami 2 adresai – ir su, ir be www. Jei nėra galimybės naudoti abiejų adresų, DCV nepavyks.
  • naudojamas tik 80 (HTTP) arba 443 (HTTPS) prievadas (angl. port). Jei adresai nepasiekiami nė vienu iš šių prievadų (pvz., sertifikatas naudojamas tik IMAP serveryje), DCV nepavyks.
  • nepalaiko wildcard domenų, pvz., *.kriptografija.lt.

Visais šiais atvejais, kai neveikia HTTP/HTTPS metodas, geriausia alternatyva yra dns metodas. Tam reikės su skriptu pasiekti DNS serverį arba jo API – įgyvendinimas skiriasi priklausomai nuo naudojamo DNS serverio. Individualiomis sąlygomis galime pasiūlyti automatizaciją per API su Dom.lt DNS serveriais.

Praktikoje kol kas nesame bandę automatizuoti domeno patikrinimo email metodu. Teoriškai galėtume susikurti el. pašto dėžutės automatizaciją, kuri paspaustų iš Sectigo gaunamas nuorodas. Tačiau prieš paspaudžiant el. paštu gautą nuorodą reikia įsitikinti, kad šis laiškas atėjo būtent mūsų prašyto sertifikato patikrinimui. Sectigo laiške nurodo užsakymo numerį, pvz.: We have received a request to issue an SSL certificate for order #1234567890. Tai yra į API kliento skriptą įvedamas VENDORID, tad juos galime susivesti ir el. pašto dėžutės automatizacijoje. Tačiau tokia el. pašto automatizacija tiek su IMAP algoritmais, tiek su el. pašto klientų DI agentais yra sudėtingesnė ir mažiau patikima, todėl kol kas visose situacijose naudojame HTTP/HTTPS arba DNS DCV metodus.

Nespauskite patvirtinimo nuorodos visuose iš Sectigo ir DigiCert gaunamuose laiškuose jų nepatikrinę – taip galite suteikti savo domeno SSL sertifikatą tretiesiems asmenims.

Kai iki sertifikato galiojimo pabaigos (crt_till) lieka mažiau kaip 14 dienų, o iki paslaugos galiojimo pabaigos (service_till) yra likę daugiau kaip 20 dienų, vėl įkelkite CSR ir kartokite visą ciklą.

Jei iki paslaugos galiojimo pabaigos (service_till) liko mažiau kaip 20 dienų, nutraukite atnaujinimą ir rankiniu būdu įsigykite naują sertifikatą (rekomenduojame 3 metams). Įsigiję naują sertifikatą nepamirškite savo automatizacijos skripte atnaujinti id ir vendorid.