Docs/ Infraestructura/ Dominios personalizados

Dominios personalizados

Asocie sus propios nombres de dominio a una aplicación. sh0 los enruta a través de Caddy y obtiene el certificado HTTPS en la primera visita.

Agregar un dominio

Un dominio se asocia a una sola aplicación. La ruta se envía a Caddy en cuanto se agrega el dominio; sh0 no espera al DNS.

  1. Abra la aplicación en el panel.
  2. Vaya a la pestaña Dominios y SSL.
  3. Haga clic en Agregar dominio y escriba el nombre en Nombre de dominio, por ejemplo api.example.com.
  4. Confirme con Agregar dominio. La pestaña muestra entonces el registro DNS que debe crear (tipo A, valor: la IP de su servidor).

Desde la CLI, sh0 domains <app> add|list|remove hace lo mismo. remove acepta el nombre o el ID del dominio y pide confirmación salvo con --yes:

Terminal
$ sh0 domains my-api add api.example.com
[ok] Added domain api.example.com to my-api

$ sh0 domains my-api remove api.example.com --yes
[ok] Removed api.example.com from my-api

Configuración DNS

En su proveedor DNS, apunte el nombre a la dirección IP pública del servidor sh0 con un registro A. El panel muestra esa IP en Configuración DNS, con un botón para copiarla.

DNS
api.example.com.   A   <your server IP>

Para un subdominio, un CNAME hacia otro nombre que ya resuelve al servidor funciona igual: lo importante es que la solicitud llegue a esta máquina por los puertos 80 y 443.

Warning
Para un dominio que usted administra, sh0 no consulta el DNS. El indicador DNS de la lista no es una verificación: la única señal fiable es que el Estado SSL pase a Activo.

Certificados HTTPS

Caddy, el proxy inverso que gestiona sh0, obtiene los certificados mediante ACME (Let's Encrypt, con ZeroSSL como respaldo). No hay nada que configurar, pero conviene conocer su funcionamiento:

  • Bajo demanda. El certificado se solicita en el primer handshake HTTPS para ese nombre, no al agregar el dominio. Mientras nadie abra https://api.example.com, el estado sigue en Pendiente.
  • Solo para los nombres que sh0 enruta. Antes de emitir, Caddy pregunta a sh0 si alguna ruta lleva ese nombre; cualquier otro nombre presentado en un handshake TLS se rechaza, de modo que nadie puede hacer que su servidor solicite certificados para nombres arbitrarios.
  • De HTTP a HTTPS. Caddy redirige las solicitudes HTTP a HTTPS.
  • Renovación. Caddy renueva los certificados por sí mismo antes de que caduquen.

La pestaña Dominios y SSL vuelve a leer el estado cada 10 segundos mientras haya un dominio pendiente. Por la API, un dominio pendiente incluye un campo ssl_pending_reason con el motivo, por ejemplo: «No TLS handshake for this name has reached this server yet: certificates are issued on demand at the first visit. Check that DNS points here, then open the site once over HTTPS.»

Detrás de una CDN (proxy de Cloudflare)

Cuando una CDN termina el TLS delante de su servidor (Cloudflare con la nube naranja, por ejemplo), la solicitud de validación HTTP-01 se detiene en la CDN y el certificado puede no emitirse nunca. Hay tres salidas:

  • Solo DNS (nube gris): lo más sencillo; Caddy atiende entonces directamente a los visitantes.
  • La validación DNS-01, dominio por dominio: Caddy demuestra la titularidad escribiendo un registro TXT mediante la API de Cloudflare en lugar de responder por HTTP.
  • Un certificado propio, como un certificado de origen de Cloudflare, subido como se describe más abajo.

DNS-01 requiere un Caddy compilado con el módulo de Cloudflare (sudo sh0 install-dns-caddy y luego reiniciar sh0) y un token de API de Cloudflare con Zone:DNS:Edit en la configuración del panel. Se activa dominio por dominio, solo por la API: el panel todavía no tiene un control para ello. En un servidor sin el módulo, la llamada se rechaza (respuesta real):

Terminal
$ sudo sh0 install-dns-caddy        # then restart sh0
$ curl -X PUT https://panel.example.com/api/v1/apps/<app-id>/domains/<domain-id>/tls-challenge \
    -H "Authorization: Bearer $SH0_TOKEN" -H "Content-Type: application/json" \
    -d '{"challenge":"dns-01"}'
{"error":{"code":"VALIDATION_ERROR","message":"This server's Caddy carries no DNS provider module, so DNS-01 cannot be used. Run `sh0 install-dns-caddy` and restart sh0; until then this domain would keep HTTP-01 and the setting would be a lie."}}

sh0 también rechaza DNS-01 cuando no hay token configurado y cuando el dominio está fuera de la zona que controla el token: allí el desafío nunca podría responderse. "challenge":"http-01" vuelve al modo predeterminado.

Certificados propios

Para usar un certificado de su propia autoridad en lugar de ACME, utilice la sección Certificados SSL de la misma pestaña:

  1. O bien Generar CSR (la clave privada se crea y se guarda en el servidor) y enviar el CSR a su autoridad, o bien Subir certificado con el certificado y su clave privada en formato PEM, más la cadena intermedia si su autoridad la proporciona.
  2. Una vez subido el certificado firmado, cambie el dominio a Usar SSL personalizado.
  3. Usar SSL automático vuelve a los certificados automáticos. Eliminar un certificado también devuelve al modo automático los dominios que lo usaban. La renovación de un certificado propio corre por su cuenta.

Reglas y límites

  • Sin comodines. *.example.com se rechaza («Domain labels must contain only alphanumeric characters and hyphens»). Agregue cada subdominio de forma explícita.
  • Un worker no puede tener dominio. Una aplicación de tipo worker no expone ningún puerto HTTP; cámbiela primero a tipo web.
  • Un solo propietario por nombre. Se rechaza un nombre ya asociado a una instancia de almacenamiento de archivos.
  • Normalización. Los nombres se recortan y se pasan a minúsculas antes de guardarse; cada etiqueta tiene de 1 a 63 caracteres: letras, dígitos y guiones.
  • Permisos. Agregar o quitar un dominio, o cambiar su validación, requiere el rol developer en el proyecto de la aplicación.

Solución de problemas

Si el Estado SSL sigue en Pendiente:

  • Lea ssl_pending_reason en GET /api/v1/apps/<id>/domains: indica la causa que ve sh0.
  • Compruebe que el nombre resuelve a la IP pública del servidor (dig +short).
  • Compruebe que los puertos 80 y 443 están abiertos en todos los cortafuegos delante del servidor, incluido el de su proveedor.
  • Abra el sitio una vez por HTTPS: sin un primer handshake no se solicita ningún certificado.
  • Detrás de una CDN, use una de las tres salidas anteriores.
Terminal
$ dig +short api.example.com
$ curl -I http://api.example.com