Cómo instalar y configurar el servidor web Caddy con PHP en Fedora 34 / CentOS 8

Caddy es un servidor web de código abierto escrito en lenguaje Go. Ofrece soporte HTTP/3, TLS v1.3, configuración SSL automática con Let’s Encrypt, proxy inverso, y admite múltiples plugins para ampliar su funcionalidad. Tiene la ventaja de que toda su configuración se sirve desde un único archivo, independientemente del número de sitios que necesites alojar.

Este tutorial cubrirá la instalación y configuración de Caddy y PHP en servidores basados en Fedora 34 y CentOS 8. Cubriremos cómo alojar sitios individuales y múltiples y cómo utilizar el proxy inverso junto con algunas otras características de seguridad.

Requisitos previos

  • Servidor basado en Fedora 34 o CentOS 8
  • Un usuario no root con privilegios sudo
  • Un nombre de dominio que apunte a la dirección IP del servidor
  • SELinux está desactivado.
    $ sudo setenforce 0
    
  • Asegúrate de que todo está actualizado.
    $ sudo dnf update
    

Paso 1 – Configurar el Cortafuegos

El primer paso es configurar el Cortafuegos para abrir los puertos HTTP y HTTPS. Fedora y CentOS vienen con el cortafuegos Firewalld preinstalado.

Comprueba si el cortafuegos se está ejecutando.

$ sudo firewall-cmd --state

Deberías obtener la siguiente salida.

running

Comprueba los servicios/puertos permitidos actualmente.

$ sudo firewall-cmd --permanent --list-services

Debería aparecer lo siguiente

dhcpv6-client mdns ssh

Permite los puertos HTTP y HTTPS.

$ sudo firewall-cmd --permanent --add-service=http
$ sudo firewall-cmd --permanent --add-service=https

Vuelve a comprobar el estado del cortafuegos.

$ sudo firewall-cmd --permanent --list-services

Deberías ver una salida similar.

dhcpv6-client http https mdns ssh

Recarga el Cortafuegos.

$ sudo systemctl reload firewalld

Paso 2 – Instalar Caddy

El primer paso es instalar el servidor. Los pasos de instalación son los mismos tanto para Fedora 34 como para CentOS 8.

$ sudo dnf install 'dnf-command(copr)'
$ sudo dnf copr enable @caddy/caddy
$ sudo dnf install caddy

Puedes verificar la instalación mediante el siguiente comando.

$ caddy version
v2.4.3 h1:Y1FaV2N4WO3rBqxSYA8UZsZTQdN+PwcoOcAiZTM8C0I=

Paso 3 – Conceptos básicos de configuración de Caddy

Caddy utiliza JSON como formato principal para almacenar o escribir la configuración. Es la forma más flexible de escribir la configuración y soporta todas las características de Caddy. Pero si no sabes cómo escribir archivos JSON, Caddy ofrece una forma más sencilla en forma de Caddyfile.

El paquete Fedora / CentOS incluye un Caddyfile en /etc/caddy/Caddyfile. Debería tener el siguiente aspecto (ignorando los comentarios)

:80 {
        root * /usr/share/caddy
        file_server
}

Habilita e inicia el demonio Caddy.

$ sudo systemctl enable --now caddy

Puedes abrir la URL http://youripaddress para comprobarlo. Deberías ver la siguiente página de bienvenida.

Página de bienvenida a Caddy

Caddy ofrece muchas funciones y configuraciones, así que sólo nos ocuparemos de las importantes para servir nuestro sitio web. La configuración por defecto sirve a través de HTTP, que se especifica como :80. La directiva root indica a Caddy que busque los archivos a servir en el directorio /usr/share/caddy.

La directiva file_server indica a Caddy que actúe como servidor de archivos, lo que significa que sólo servirá archivos estáticos a través de la dirección por defecto.

Configurar Caddy para un sitio web HTML básico

Vamos a crear un archivo de configuración básico de Caddy para servir un sitio web estático.

Crea un directorio para alojar tu sitio web y almacenar tus archivos de registro.

$ sudo mkdir -p /var/www/example.com/html
$ sudo mkdir /var/log/caddy

Establece la propiedad del directorio a Caddy.

$ sudo chown caddy:caddy /var/www/example.com/html -R
$ sudo chown caddy:caddy /var/log/caddy

Crea un archivo HTML de prueba y ábrelo para editarlo.

$ sudo nano /var/www/example.com/html/index.html

Añade el siguiente código.

<!DOCTYPE html>
<html>
<head>
<title>Hello from Caddy!</title>
</head>
<body>
<h1>Hello, from Caddy!</h1>
</body>
</html>

Pulsa Ctrl + X para cerrar el editor y pulsa Y cuando se te pida guardar el archivo.

Abre el archivo Caddy para editarlo.

$ sudo nano /etc/caddy/Caddyfile

Sustituye el código existente por el siguiente.

example.com {
    root * /var/www/example.com/html
    file_server
    encode gzip

    log {
        output file /var/log/caddy/example.access.log
    }

    @static {
        file
        path *.ico *.css *.js *.gif *.jpg *.jpeg *.png *.svg *.woff *.pdf *.webp
    }
    header @static Cache-Control max-age=5184000

    tls [email protected]
}

Pulsa Ctrl + X para cerrar el editor y pulsa Y cuando se te pida guardar el archivo.

Repasemos todas las directivas del archivo. La directiva encode gzip indica a Caddy que comprima los archivos utilizando la compresión Gzip.

La directiva log envía el registro de acceso del sitio al archivo /var/log/caddy/example.access.log. Por defecto, Caddy rota los archivos de registro cuando alcanzan los 100 MB. Los archivos rotados se eliminan después de 90 días o cuando hay más de 10 registros rotados. Puedes cambiar los parámetros por defecto de la siguiente manera.

log {
    output file /var/log/caddy/example.access.log {
        roll_size 10MB
        roll_keep 5
        roll_keep_for 240h
    }
}

En el código anterior, los archivos de registro rotados se limitan a 10 MB y se eliminan al cabo de 10 días (240 horas) o cuando hay más de 5 registros rotados.

Caddy generará e instalará el certificado SSL automáticamente sin ninguna intervención. La directiva tls nos permite proporcionar opciones adicionales para configurar HTTPS, como la dirección de correo electrónico utilizada para obtener informes de Let’s Encrypt.

La directiva header habilita Cache-control en todos los archivos estáticos (imágenes/archivos javascript/CSS). Puedes añadir más extensiones de archivo o copiar el código para establecer una duración diferente para distintos formatos de archivo. Tendrás que cambiar el valor static por otro distinto, ya que se trata de una referencia con nombre.

Una vez terminado, puedes validar tu configuración utilizando el siguiente comando.

$ caddy validate --adapter caddyfile --config /etc/caddy/Caddyfile

Tenemos que utilizar la opción --adapter caddyfile porque, por defecto, el comando sólo valida configuraciones JSON.

Si te aparece la siguiente advertencia, puedes solucionarla fácilmente con un solo comando.

WARN    input is not formatted with 'caddy fmt' {"adapter": "caddyfile", "file": "/etc/caddy/Caddyfile", "line": 2}

Ejecuta el siguiente comando para solucionar el error.

$ caddy fmt --overwrite /etc/caddy/Caddyfile

El comando anterior formatea y sobrescribe el archivo Caddyfile.

Reinicia Caddy para activar la configuración. Tendrás que reiniciar el servidor cada vez que realices un cambio en la configuración.

$ sudo systemctl restart caddy

Abre en tu navegador, y deberías ver la siguiente página, lo que significa que la configuración está funcionando.

Caddy FrontPage

Configurar varios sitios en Caddy

Puedes configurar varios sitios en un único archivo caddy. Para ello, crea bloques separados para cada sitio de la siguiente manera.

example1.com {
	root * /var/www/example1.com/html
	...
}

example2.com {
	root * /var/www/example2.com/html
	...
}

Este método está bien para un par de sitios, pero uno solo puede hacerse bastante grande y difícil de mantener si alojas varios sitios.

Crea el directorio `/etc/caddy/caddyconf.

$ sudo mkdir /etc/caddy/caddyconf

Ahora puedes importar los archivos de configuración del directorio en tu /etc/caddty/caddyfile en la parte superior del archivo.

import caddyconf/*.conf

El último paso es crear archivos de configuración individuales para cada sitio.

Configurar sitios PHP

Hasta ahora, sólo hemos hablado de servir sitios estáticos utilizando Caddy. Puedes utilizar Caddy con la misma facilidad para servir también sitios PHP dinámicos. Para habilitar el soporte PHP, añade el siguiente código dentro del bloque de tu sitio.

example1.com {
	root * /var/www/example1.com/html
	...
	php_fastcgi unix//run/php-fpm/www.sock
}

También necesitarás instalar PHP.

$ sudo dnf install php-fpm php-cli php-gd

Puedes instalar cualquier módulo PHP adicional que necesites. También necesitarás configurar el archivo /etc/php-fpm.d/www.conf. Abre el archivo para editarlo.

$ sudo nano /etc/php-fpm.d/www.conf

Necesitamos establecer el usuario/grupo Unix de los procesos PHP a caddy. Busca las líneas user=apache y group=apache en el archivo y cámbialas a nginx.

...
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
; RPM: apache user chosen to provide access to the same directories as httpd
user = caddy
; RPM: Keep a group allowed to write in log dir.
group = caddy
...

Busca la línea listen.acl_users = apache,nginx y cambia su valor por el siguiente.

...
listen.acl_users = apache,nginx,caddy
...

Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te solicite.

Inicia el proceso PHP-fpm.

$ sudo systemctl start php-fpm

Para probar tu configuración PHP, crea un archivo test.php en la carpeta html.

$ sudo nano /var/www/example.com/html/test.php

Añade el siguiente contenido y guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te solicite.

<?php phpinfo();

Ejecuta http://example.com/test.php en tu navegador web, y deberías ver lo siguiente.

Página de prueba PHP de Caddy

Configurar el Proxy Inverso

Caddy también puede utilizarse como servidor proxy inverso. Para configurarlo, utiliza el siguiente código.

example1.com {
	...
	reverse_proxy localhost:8000 {
		header_up Host {http.reverse_proxy.header.X-Forwarded-Host}
	}
}

Paso 4 – Opciones globales de Caddy

El Caddyfile te permite establecer algunas opciones que serán aplicables globalmente, es decir, que se aplicarán a todos tus sitios. Es beneficioso definir opciones globales para no tener que volver a declararlas en cada bloque del servidor.

Debes incluir las opciones globales al principio de tu Caddyfile. Hay muchas opciones que puedes configurar globalmente. Sólo repasaremos algunas importantes. Para el resto, debes consultar la documentación de Caddy.

Aquí tienes algunas opciones por defecto que puedes utilizar en tu Caddyfile.

{	
	#TLS Options
	email [email protected]

	servers	:443 {
		protocol {
			experimental_http3
		}
		max_header_size 5mb
	}
	
	servers :80 {
		protocol {
			allow_h2c
		}
		max_header_size 5mb
	}
}

En el código anterior email especifica el ID de correo electrónico utilizado para registrar el certificado SSL con la autoridad Let’s Encrypt. El grapado OCSP mejora el rendimiento de los sitios HTTPS proporcionando información sobre la revocación de certificados a los navegadores de forma automática. La opción max_header_size especifica el tamaño de las cabeceras de solicitud HTTP del cliente que se analizarán.

También hemos activado el protocolo HTTP/3 para los sitios HTTPS y la compatibilidad con HTTP/2 para los sitios HTTP. Se trata de funciones experimentales y probablemente se eliminarán con el tiempo, así que ten cuidado antes de activarlas.

Paso 5 – Mejorar la seguridad

Activar la autenticación HTTP

Puedes activar la autenticación HTTP simple para determinados directorios. Primero, tienes que crear credenciales de autenticación para ello.

Caddy sólo acepta contraseñas hash en la configuración. Por tanto, primero tienes que crear una contraseña con hash. Ejecuta el siguiente comando para hacerlo.

$ caddy hash-password
Enter password:
Confirm password:
JDJhJDEwJEVCNmdaNEg2Ti5iejRMYkF3MFZhZ3VtV3E1SzBWZEZ5Q3VWc0tzOEJwZE9TaFlZdEVkZDhX

Una vez que tengas lista la contraseña, introduce el siguiente código en tu Caddyfile.

basicauth /secret/* {
	John JDJhJDEwJEVCNmdaNEg2Ti5iejRMYkF3MFZhZ3VtV3E1SzBWZEZ5Q3VWc0tzOEJwZE9TaFlZdEVkZDhX
}

El comando anterior protegerá el directorio /secret con las credenciales que acabas de crear.

Endurecer la seguridad del sitio y activar HSTS

Hay otras configuraciones de seguridad que puedes añadir para proteger tus sitios. Para ello, crearemos otro archivo /etc/caddy/caddy_security.conf.

$ sudo nano /etc/caddy/caddy_security.conf

Añádele el siguiente código.

header {
    Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    X-Xss-Protection "1; mode=block"
    X-Content-Type-Options "nosniff"
    X-Frame-Options "DENY"
    Permissions-Policy "interest-cohort=()"
    Content-Security-Policy "upgrade-insecure-requests"
    Referrer-Policy "strict-origin-when-cross-origin"
    Cache-Control "public, max-age=15, must-revalidate"
    Feature-Policy "accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'self'; camera 'none'; encrypted-media 'none'; fullscreen 'self'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; payment 'none'; picture-in-picture *; speaker 'none'; sync-xhr 'none'; usb 'none'; vr 'none'"
}

El código anterior habilita/implementa lo siguiente.

  1. Activa el soporte HSTS para el sitio y todos sus subdominios.
  2. Activa el filtrado XSS.
  3. Evita el Esnifado de Contenido/MIME.
  4. Impide que tu sitio se cargue dentro de un IFRAME.
  5. Impide que tu sitio se incluya en las pruebas de rastreo FLOC.
  6. Añade una política de seguridad de Contenidos sobre cómo tratan los agentes de usuario las URL inseguras.
  7. Implementa una política de remitente para que sólo se envíe el remitente en las solicitudes de origen cruzado si el protocolo dice lo mismo.
  8. La Política de Funciones proporciona un mecanismo para activar y desactivar determinadas funciones del navegador.

A continuación, importa el archivo en cualquiera de los bloques de sitio que desees.

example.com {
	...
	import /etc/caddy/caddy_security.conf
}

Reinicia el servidor para aplicar el cambio.

Conclusión

Con esto concluye el tutorial sobre la instalación y configuración del servidor web Caddy en servidores basados en Fedora 34 / CentOS 8. Si tienes alguna pregunta, publícala en los comentarios a continuación.

Scroll al inicio