# Clientes ACMEUsar clientes ACME estándar con la CA interna — qué es igual que Let's Encrypt, qué es distinto.

## Qué se mantiene igual que Let's Encrypt

Si alguna vez has obtenido un certificado Let's Encrypt, ya
puedes usar la CA interna. El protocolo es idéntico — ACME RFC
8555. Los clientes que ya conoces funcionan sin modificación.

Igual:

- Retos HTTP-01 y DNS-01.
- Registro de cuenta y gestión de clave.
- Duración por defecto de 90 días.
- Renovación automática a los 60 días.
- Certificados wildcard vía DNS-01.

## Qué es distinto

Dos pequeñas diferencias, ambas pasos de configuración únicos:

1. **La URL del directorio ACME** apunta a la CA interna, no a
   `https://acme-v02.api.letsencrypt.org/directory`.
2. **El certificado raíz** de la CA interna debe ser confiado
   por el cliente que hace la solicitud. Esto se gestiona
   normalmente vía configuración (Ansible, Puppet, MDM) al
   aprovisionar el host.

Esa es toda la diferencia. Todo lo demás es el mismo flujo
Let's Encrypt que ya conoces.

## Apuntar tu cliente a la CA interna

El endpoint ACME interno se publica en una URL interna estable
(típicamente `https://acme.example.internal/acme/acme/directory`,
pero la ruta exacta depende de tu despliegue). A continuación
recetas para clientes comunes.

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

Para renovación, el flag `--server` se persiste en
`renewal/*.conf`, así que el cron periódico `certbot renew` lo
recoge automáticamente.

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

En tu `Caddyfile`:

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

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

Caddy obtiene y renueva el certificado automáticamente.

### Traefik

En tu configuración dinámica:

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

Referenciar `certResolver: internal` desde las definiciones de
router.

## Instalar el certificado raíz en los clientes

Para que los certificados emitidos por la CA sean confiados sin
advertencias, la raíz de la CA debe estar en el store de
confianza del sistema de cada host que vaya a ver los
certificados.

### Linux (familia Debian/Devuan)

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

### Linux (familia 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
```

Para navegadores que mantienen sus propios stores de confianza
(Firefox), la raíz debe importarse adicionalmente vía Ajustes →
Privacidad → Certificados → Autoridades.

Esta instalación normalmente se gestiona por gestión de
configuración. Hacerlo a mano está bien para un caso puntual
pero no escala a una flota.

## Certificados wildcard

Los wildcards se emiten vía reto DNS-01 — el cliente prueba el
control de un dominio creando un registro TXT. Esto funciona
para dominios solo internos porque la CA interna puede validar
registros TXT en cualquier servidor DNS que controles.

Ejemplo con `acme.sh` usando el proveedor BIND nsupdate:

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

Necesitarás que el proveedor nsupdate esté configurado contra tu
DNS interno — ver la documentación `acme.sh` para las variables
de entorno específicas.

## Renovación

La renovación funciona igual que con Let's Encrypt: el cliente
comprueba la validez restante y renueva cuando está por debajo
del umbral (60 días para un cert de 90 días).

Para la mayoría de despliegues, el cron de renovación existente
(`certbot renew`, `acme.sh --cron`, la renovación automática de
Caddy) funciona tal cual.

Si ves fallos de renovación:

1. **¿Sigue siendo alcanzable la URL del directorio?** Un cambio
   de red puede haber roto la ruta del cliente a la CA.
2. **¿Ha expirado o rotado el certificado raíz?** Las raíces
   típicamente son válidas 10 años; los intermedios por periodos
   más cortos. Una rotación que no propagó a todos los clientes
   se manifestará como fallos de renovación.
3. **¿Sigue siendo apropiado el tipo de reto?** Un servicio que
   antes era alcanzable para HTTP-01 puede ahora estar detrás de
   un load balancer que rompe la respuesta del reto.

## Límites y políticas

La CA interna aplica políticas por cuenta — qué dominios cada
cuenta puede solicitar certificados, qué duración máxima se
permite, qué tipos de reto se aceptan.

Si una solicitud que funcionaba ayer falla de repente con un
error `policy denied`, la política ha cambiado (o tu vinculación
de cuenta). Contacta con tu operador de CA. El servicio
[Operación](/es/services/support/) es la vía de escalado si tu
operador de CA somos nosotros.
