Fortalecimiento
Fortalecimiento
Un deployment de Chinaski viene bloqueado por defecto: el servicio corre en un sandbox de systemd, los archivos tienen permisos restrictivos, el daemon se enlaza a loopback detrás de un reverse proxy, y el CMS añade headers de seguridad estrictos a cada respuesta. Esta página explica qué son esas protecciones y unas pocas cosas que puedes hacer para mantenerlas intactas.
Sandboxing de systemd
La unidad systemd de producción corre cada instancia como un usuario chinaski dedicado en un sandbox estricto:
- Todo el filesystem es de solo lectura excepto el directorio propio de la instancia; un exploit en la app no puede alcanzar nada más en el host.
- La instancia obtiene un
/tmpprivado, no puede ver los home directories, y no puede tocar la configuración del kernel ni crear archivos privilegiados. - La memoria está limitada a 1 GB (con un techo suave de 768 MB), CPU al 200% y 256 tareas concurrentes, así que un job desbocado no puede dejar sin recursos al host.
- Al apagarse, el servicio se detiene de forma graceful, dándole a las peticiones en vuelo y a un build corriendo tiempo para terminar.
- Los reinicios son automáticos pero estrangulados, y todo el output aterriza en el journal: léelo con
journalctl -u chinaski@<instance>.
Estos límites vienen del unit file; afínalos en hosts más grandes, pero pocos sites necesitan más que los valores incluidos.
Permisos de archivo
El instalador establece permisos restrictivos al momento de instalar y no necesitas cambiarlos:
- El directorio de la aplicación es propiedad del usuario
chinaskiy solo puede leerlo ese usuario y los miembros del grupo. - El archivo de base de datos (
chinaski.db) solo es legible por el usuario y grupochinaski. - El directorio que contiene el archivo env (que contiene tu secret) es solo del dueño (
0700) y el archivo env mismo es0600. - El directorio de backups es solo del dueño (
0700).
Si la propiedad se desvía (por ejemplo, un deploy corrió con el usuario equivocado), el script de deploy reaplica la propiedad correcta al directorio de la aplicación en la próxima corrida.
Mantener el daemon fuera de la red pública
- Enlaza el CMS a una dirección de loopback (
http://127.0.0.1:3001es el ejemplo en la unidad systemd) y deja que el reverse proxy enfrente a internet. El daemon confía en las IPs de cliente reenviadas solo desde conexiones de loopback; enlazarlo a una interfaz pública permitiría a los visitantes falsificar su IP y derrotar los límites de tasa y los bloqueos de login. - Si tu proxy habla con el daemon desde una dirección no loopback (por ejemplo una red bridge de Docker), establece
CHINASKI_TRUSTED_PROXIESa ese rango de IP (direcciones o rangos IPv4 separados por comas) para que la IP real del cliente siga reconocida. Loopback siempre es confiable; nada más lo es, a menos que lo listes. - En modo offline ("EOTW") hypnotoad sirve HTTP plano directamente sin proxy. El CMS entonces lee la dirección real de la conexión e ignora por completo los headers reenviados, así que el rate limiting funciona tal cual. Pero no hay TLS en este modo: no envíes contraseñas por una red no confiable; restringe el acceso con una VPN o reglas de firewall.
Modo airgap
Establece CHINASKI_AIRGAP=1 antes de arrancar el servidor en hosts aislados. Apaga toda petición saliente (build webhooks, form webhooks y la verificación de bot-check), y oculta el widget de verificación incluso si las keys están almacenadas en la base de datos. El CMS sigue funcionando en lo demás.
Headers de respuesta
La aplicación añade headers de seguridad a cada respuesta por su cuenta; no se necesita configuración de proxy para lo básico:
- Elimina el header
Servery establece protección de frames (SAMEORIGIN), protección de sniffing de content-type, una política de referrer estricta y HSTS de un año (se espera que TLS termine en tu reverse proxy). - Las features del navegador que el CMS nunca usa (cámara, micrófono, geolocalización, pago, USB y más) se deshabilitan vía Permissions-Policy.
- Los scripts y estilos inline están protegidos por un nonce por petición en la Content Security Policy. Las submissions y el embedding de forms quedan anclados al origin propio del site.
- Dos relajaciones deliberadas, ambas restringidas a superficies no públicas: las vistas previas de contenido aflojan la política para que las vistas previas de themes rendericen correctamente (requieren una sesión de admin o un secret de token de preview), y las páginas de form públicas permiten ser incrustadas por otros sites ya que ese es su uso diseñado, mientras las form submissions aún solo envían a tu servidor.
Los ejemplos de proxy (Caddy y nginx en deploy/) espejan estos headers como cinturón y tirantes, para que queden establecidos incluso cuando el proxy responde con un error cacheado.
Honeypots de scanners
Los ejemplos de proxy rutean las sondas comunes de scanners (.env, .git/config, wp-login.php, wp-admin, phpmyadmin, xmlrpc.php y compañía) al CMS en lugar del servidor estático. Los hits se loguean y deliberadamente se ralentizan en lugar de responder un 404 silencioso. Si usas los ejemplos de proxy incluidos, esto funciona automáticamente; conserva el bloque de honeypot cuando adaptes la configuración.