# ACME clientsΧρήση standard ACME clients με την εσωτερική CA — τι είναι ίδιο με Let's Encrypt, τι διαφέρει.

## Τι μένει ίδιο όπως στο Let's Encrypt

Αν έχεις ποτέ λάβει πιστοποιητικό Let's Encrypt, μπορείς ήδη να
χρησιμοποιήσεις την εσωτερική CA. Το πρωτόκολλο είναι ίδιο —
ACME RFC 8555. Οι clients που ήδη γνωρίζεις λειτουργούν χωρίς
τροποποίηση.

Ίδια:

- HTTP-01 και DNS-01 challenges.
- Εγγραφή λογαριασμού και διαχείριση κλειδιού.
- Προεπιλεγμένη διάρκεια 90 ημερών.
- Αυτόματη ανανέωση στις 60 ημέρες.
- Wildcard πιστοποιητικά μέσω DNS-01.

## Τι διαφέρει

Δύο μικρές διαφορές, και οι δύο εφάπαξ βήματα setup:

1. **Το ACME directory URL** δείχνει στην εσωτερική CA, όχι στο
   `https://acme-v02.api.letsencrypt.org/directory`.
2. **Το root πιστοποιητικό** της εσωτερικής CA πρέπει να είναι
   αξιόπιστο για τον client που κάνει το αίτημα. Αυτό
   κανονίζεται μέσω configuration management (Ansible, Puppet,
   MDM) στο provisioning των hosts.

Αυτή είναι όλη η διαφορά. Όλα τα άλλα είναι το ίδιο workflow
Let's Encrypt που ήδη γνωρίζεις.

## Στρέφοντας τον client σου στην εσωτερική CA

Το εσωτερικό ACME endpoint δημοσιεύεται σε μια σταθερή εσωτερική
URL (τυπικά `https://acme.example.internal/acme/acme/directory`,
αλλά η ακριβής διαδρομή εξαρτάται από το deployment σου).
Παρακάτω είναι συνταγές για κοινούς clients.

### `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
```

Για ανανέωση, το flag `--server` διατηρείται στο
`renewal/*.conf`, οπότε το περιοδικό `certbot renew` cron το
παίρνει αυτόματα.

### `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

Στο `Caddyfile` σου:

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

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

Το Caddy θα λάβει και θα ανανεώσει το πιστοποιητικό αυτόματα.

### Traefik

Στη δυναμική σου διαμόρφωση:

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

Αναφορά `certResolver: internal` από τους ορισμούς router.

## Εγκατάσταση του root πιστοποιητικού στους clients

Για να γίνονται αποδεκτά τα πιστοποιητικά που εκδίδει η CA χωρίς
προειδοποιήσεις, το root της CA πρέπει να βρίσκεται στο trust
store συστήματος κάθε host που θα δει τα πιστοποιητικά.

### Linux (οικογένεια Debian/Devuan)

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

### Linux (οικογένεια 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
```

Για browsers που διατηρούν τα δικά τους trust stores (Firefox), το
root πρέπει επιπλέον να εισαχθεί μέσω Ρυθμίσεις → Απόρρητο →
Πιστοποιητικά → Αρχές.

Αυτή η εγκατάσταση κανονικά γίνεται μέσω configuration
management. Με το χέρι είναι ok για μια εφάπαξ περίπτωση, αλλά
δεν κλιμακώνεται σε στόλο.

## Wildcard πιστοποιητικά

Τα wildcards εκδίδονται μέσω challenge DNS-01 — ο client αποδεικνύει
τον έλεγχο ενός domain δημιουργώντας μια εγγραφή TXT. Αυτό
λειτουργεί για εσωτερικά μόνο domains επειδή η εσωτερική CA
μπορεί να επικυρώσει εγγραφές TXT σε οποιοδήποτε DNS server
ελέγχεις.

Παράδειγμα με `acme.sh` χρησιμοποιώντας τον BIND nsupdate
provider:

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

Θα χρειαστείς τον nsupdate provider διαμορφωμένο ενάντια στο
εσωτερικό σου DNS — δες την τεκμηρίωση `acme.sh` για τις
συγκεκριμένες μεταβλητές περιβάλλοντος.

## Ανανέωση

Η ανανέωση δουλεύει όπως με το Let's Encrypt: ο client ελέγχει
την υπολειπόμενη εγκυρότητα και ανανεώνει όταν είναι κάτω από το
κατώφλι (60 ημέρες για cert 90 ημερών).

Για τα περισσότερα deployments, ο υπάρχων renewal cron
(`certbot renew`, `acme.sh --cron`, αυτόματη ανανέωση Caddy)
λειτουργεί απλά.

Αν δεις αποτυχίες ανανέωσης:

1. **Είναι το directory URL ακόμη προσβάσιμο;** Μια αλλαγή
   δικτύου μπορεί να έσπασε τη διαδρομή από τον client στη CA.
2. **Έληξε ή περιστράφηκε το root πιστοποιητικό;** Τα roots
   είναι τυπικά έγκυρα για 10 χρόνια· τα intermediates για
   μικρότερες περιόδους. Μια rotation που δεν διαδόθηκε σε όλους
   τους clients θα εκδηλωθεί ως αποτυχίες ανανέωσης.
3. **Είναι ο τύπος challenge ακόμη κατάλληλος;** Μια υπηρεσία που
   ήταν προσβάσιμη για HTTP-01 μπορεί τώρα να βρίσκεται πίσω
   από load balancer που σπάει την απάντηση challenge.

## Όρια και πολιτικές

Η εσωτερική CA επιβάλλει πολιτικές ανά λογαριασμό — ποια domains
κάθε λογαριασμός μπορεί να αιτηθεί πιστοποιητικά, ποια μέγιστη
διάρκεια επιτρέπεται, ποιοι τύποι challenge γίνονται αποδεκτοί.

Αν ένα αίτημα που λειτουργούσε χθες αποτύχει ξαφνικά με σφάλμα
`policy denied`, η πολιτική έχει αλλάξει (ή το account binding
σου). Επικοινώνησε με τον CA operator σου. Η υπηρεσία
[Λειτουργία](/el/services/support/) είναι η διαδρομή κλιμάκωσης
αν ο CA operator σου είμαστε εμείς.
