# Clienți ACMEFolosirea clienților ACME standard cu CA-ul intern — ce e la fel ca la Let's Encrypt, ce e diferit.

## Ce rămâne la fel ca la Let's Encrypt

Dacă ai obținut vreodată un certificat Let's Encrypt, deja știi să folosești CA-ul intern. Protocolul este identic — ACME RFC 8555. Clienții pe care îi cunoști deja funcționează fără modificare.

La fel:

- Challenges HTTP-01 și DNS-01.
- Înregistrarea contului și administrarea cheilor.
- Durata implicită de 90 de zile pentru certificat.
- Reînnoirea automată la 60 de zile.
- Certificate wildcard prin DNS-01.

## Ce este diferit

Două mici diferențe, ambele pași de setup unici:

1. **URL-ul de directory ACME** indică spre CA-ul intern, nu spre `https://acme-v02.api.letsencrypt.org/directory`.
2. **Certificatul root** al CA-ului intern trebuie să fie acceptat ca de încredere de către clientul solicitant. Asta se configurează de obicei prin configuration management (Ansible, Puppet, MDM) la provisioningul hostului.

Asta e toată diferența. Restul este același workflow Let's Encrypt pe care îl cunoști.

## Îndreaptă clientul către CA-ul intern

Endpointul ACME intern este publicat la un URL intern stabil (de regulă `https://acme.example.internal/acme/acme/directory`, dar calea exactă depinde de deployment). Urmează rețete pentru clienții uzuali.

### `certbot`

```sh
certbot --server https://acme.example.internal/acme/acme/directory \
        --email ops@example.internal \
        --no-eff-email \
        --agree-tos \
        certonly --standalone -d service.example.internal
```

La reînnoire, flag-ul `--server` este persistat în `renewal/*.conf`, astfel încât cronul periodic de `certbot renew` îl preia automat.

### `acme.sh`

```sh
acme.sh --register-account \
        --server https://acme.example.internal/acme/acme/directory \
        -m ops@example.internal

acme.sh --issue \
        --server https://acme.example.internal/acme/acme/directory \
        --standalone \
        -d service.example.internal
```

### `lego`

```sh
lego --server=https://acme.example.internal/acme/acme/directory \
     --email=ops@example.internal \
     --domains=service.example.internal \
     --http run
```

### Caddy

În `Caddyfile`-ul tău:

```caddy
{
  acme_ca https://acme.example.internal/acme/acme/directory
  email ops@example.internal
}

service.example.internal {
  reverse_proxy localhost:8080
}
```

Caddy obține și reînnoiește certificatul automat.

### Traefik

În configurația ta dinamică:

```yaml
certificatesResolvers:
  internal:
    acme:
      caServer: "https://acme.example.internal/acme/acme/directory"
      email: ops@example.internal
      storage: /etc/traefik/acme.json
      httpChallenge:
        entryPoint: web
```

Referenția `certResolver: internal` în definițiile de router.

## Instalează certificatul root pe clienți

Ca certificatele emise de CA să fie de încredere fără avertizare, root-ul CA trebuie să stea în trust store-ul de sistem al fiecărui host care vede certificatele.

### Linux (familie Debian/Devuan)

```sh
sudo cp internal-ca-root.crt /usr/local/share/ca-certificates/internal-ca-root.crt
sudo update-ca-certificates
```

### Linux (familie RHEL)

```sh
sudo cp internal-ca-root.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust extract
```

### OpenBSD / FreeBSD

```sh
# OpenBSD
sudo install -m 0644 internal-ca-root.crt /etc/ssl/internal-ca-root.crt
sudo cat /etc/ssl/cert.pem internal-ca-root.crt > /etc/ssl/cert.pem.new
sudo mv /etc/ssl/cert.pem.new /etc/ssl/cert.pem
```

### macOS

```sh
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain internal-ca-root.crt
```

### Windows

```cmd
certutil.exe -addstore -f "ROOT" internal-ca-root.crt
```

Pentru browserele care își țin propriile trust stores (Firefox), root-ul trebuie importat în plus prin Setări → Confidențialitate → Certificate → Autorități de certificare.

Această instalare se face de obicei prin configuration management. Manual e OK pentru un caz singular, dar nu scalează pentru o flotă.

## Certificate wildcard

Wildcard-urile se emit prin challenge DNS-01 — clientul demonstrează controlul asupra unui domeniu prin crearea unui record TXT. Asta funcționează pentru domenii pur interne, pentru că CA-ul intern poate valida record-uri TXT pe orice server DNS pe care îl controlezi.

Exemplu cu `acme.sh` și providerul BIND nsupdate:

```sh
acme.sh --issue \
        --server https://acme.example.internal/acme/acme/directory \
        --dns dns_nsupdate \
        -d '*.example.internal' \
        -d 'example.internal'
```

Providerul nsupdate trebuie configurat împotriva DNS-ului tău intern — vezi documentația `acme.sh` pentru variabilele de mediu specifice.

## Reînnoire

Reînnoirea funcționează la fel ca la Let's Encrypt: clientul verifică valabilitatea rămasă și reînnoiește când e sub prag (60 de zile pentru un certificat de 90).

Pentru cele mai multe deployments, cronul de reînnoire existent pur și simplu funcționează (`certbot renew`, `acme.sh --cron`, reînnoirea automată Caddy).

La erori de reînnoire:

1. **URL-ul de directory mai e accesibil?** O modificare de rețea poate fi rupt calea de la client la CA.
2. **Certificatul root a expirat sau a fost rotat?** Root-urile sunt de regulă valabile 10 ani; intermediate-urile mai scurt. O rotație care nu a fost propagată la toți clienții se manifestă ca eroare de reînnoire.
3. **Tipul de challenge mai este adecvat?** Un serviciu care era accesibil pentru HTTP-01 poate sta acum în spatele unui load balancer care strică răspunsul la challenge.

## Limite și policies

CA-ul intern aplică policies per-account — ce domenii poate solicita fiecare cont, ce valabilitate maximă este permisă, ce tipuri de challenge sunt acceptate.

Dacă o cerere care funcționa ieri eșuează brusc cu eroare `policy denied`, policy-ul s-a schimbat (sau binding-ul tău de account). Adresează-te operatorului tău de CA. Serviciul de [Operare](/ro/services/support/) este calea de escaladare, dacă operatorul tău de CA suntem noi.
