Principios de configuración =========================== .. _nginx-install: Instalación ----------- Para versiones recientes de *Debian* (sobre todo a partir de *Bookworm*) basta con:: # apt install nginx pero la regla es, en realidad, una simplificación que merece una explicación: :program:`nginx` hasta su versión *1.9.11* tenía un sistema de módulos que obligaba a añadirlos monolíticamente al ejecutable, es decir, que no se podían cargar dinámicamente a través de la configuración, sino que en la compilación se añadían al núcleo del programa. Por esa razón, los empaquetadores de *Debian* crearon tres sabores dependiendo de cuáles fueran los módulos que se habían incluido en la compilación: :deb:`nginx-light`, que incluía el menor número de módulos. :deb:`nginx-full`, que incluía un mayor número de módulos, además de algunos módulos de terceros. :deb:`nginx` a secas, era simplemente un metapaquete que forzaba la instalación de esta versión *completa*. :deb:`nginx-extras`, que incluía más módulos aún, tanto propios como de terceros. De este modo, dependiendo de si necesitábamos más o menos módulos para la configuración del servidor, instalábamos uno u otro. Desgraciadamente, si requeríamos un módulo no incluído en estos tres sabores, debíamos compilar toda la aplicación\ [#]_. Al añadir :program:`nginx` la posibilidad de cargar módulos de forma dinámica, Stretch_ (que incluyó la versión *1.10.3*), produjo ejecutables con la posibilidad de cargar dinámicamente módulos. Sin embargo, se mantuvieron los tres sabores enumerados, cada uno de cuyos ejecutables contenía un número distinto de módulos compilados estáticamente\ [#]_. La única diferencia respecto a la versiones anteriores es que *Debian* incluyó paquetes con módulos adicionales que podían instalarse y cargarse dinámicamente con cualquiera de los tres sabores\ [#]_. Además, cada sabor podía añadir dependencias a paquetes de módulos dinámicos. Bullseye_ mantuvo esta situación con dos diferencias: * La primera fue añadir un nuevo sabor: :deb:`nginx-core` que era un sabor casi equivalente a :deb:`nginx-full`, pero sin incluir estáticamente ningún módulo de terceros. * La segunda, que :deb:`nginx` dejó de ser un metapaquete que instalaba forzosamente :deb:`nginx-full` y pasó a ser uno que instalaba cualquiera de los cuatro. Y, finalmente, apareció *Bookworm*, que unificó los ejecutables en uno solo. A partir de esta versión, el paquete :deb:`nginx` es el que contiene el ejecutable del servidor (esto es, :file:`/usr/sbin/nginx`) con un número mínimo de módulos compilados estáticamente, y los cuatro sabores ya mencionados son metapaquetes que instalan éste y añaden dependencias a paquetes de módulos dinámicos, por lo que la única diferencia entre ellos es la cantidad de paquetes de módulos instalados automáticamente. .. warning:: Si trabaja con una versión anterior a *Bookworm* es posible que le salga más a cuenta instalar :deb:`nginx-light`, porque apenas hay aspectos recogidos en esta guía que no se puedan resolver con esta versión. Para *Bookworm* y posteriores instale :deb:`nginx` por la misma razón y añada módulos dinámicos según convenga. Ficheros de configuración ------------------------- La configuración de :program:`nginx` está incluida toda dentro de :file:`/etc/nginx`. Los ficheros y directorios relevantes son los siguientes: .. code-block:: none /etc/nginx +--- conf.d/ +--- modules-available/ +--- modules-enabled/ +--- nginx.conf +--- sites-available/ +--- default +--- sites-enabled/ +--- default -> ../sites-available/default +--- snippets/ +--- fastcgi-php.conf +--- snakeoil.conf cuyo significado podemos desglosar así: :file:`nginx.conf` Es, en sí, el fichero de configuración. el resto de configuración existente en este directorio se aplica, bien porque este fichero la carga directamente, bien porque un fichero cargado por él, la carga a su vez. :file:`conf.d` Contiene ficheros con trozos de configuración que :file:`nginx.conf` siempre carga si su extensión es :file:`*.conf`. :file:`snippets` Es un directorio destinado a contener también ficheros con trozos de configuración, pero a diferencia de los contenidos en el directorio anterior, sólo se aplicarán si son expresamente citados dentro de otros ficheros de configuración. *Debian* trae dos configuraciones ya definidas que podemos aprovechar: * :file:`fastcgi-php.conf` para la configuración de |PHP|. * :file:`snakeoil.conf` que incluye las líneas necesarias para usar el certificado autofirmado del servidor. Para aplicar una configuración incluida en este directorio debe utilizar en la línea en que queramos que se aplique la directiva ``include``: .. code-block:: nginx include snippets/snakeoil.conf; :file:`sites-available` Un mismo servidor web puede alojar distintos sitios *web* mediante el mecanismo de :ref:`dominios virtuales `. Este directorio está destinado a albergar la definición de todos los *dominios virtuales*. Ya se verá más adelante esto con mayor profundidad. :file:`sites-enabled` Contiene los *dominios virtuales* habilitados. Los que no se encuentren aquí, no forman parte de la configuración y por tanto es como si no se hubieran definido. Para habilitar dominios basta, simplemente, con hacer enlaces simbólicos que apuntes a las definiciones incluidas en :file:`sites-available`. :file:`modules-available` Para cargar dinámicante un módulo la documentación de :program:`nginx` indica que debe incluirse en la configuración una línea así: .. code-block:: nginx load_module modules/nonbre_del_modulo.so Para simplificarlo, *Debian* incluye un fichero de configuración para cada módulo con su línea ``load_module`` correspondiente, con lo que cargar el fichero de configuración, implica cargar el módulo. Como *Debian* prefiere alojar para sus paquetes estos ficheros en :file:`/usr/share/nginx/modules-available/`, en este directorio sólo cabría crear ficheros de configuración para módulos que hubiéramos compilado nosotros mismos. :file:`modules-enabled` Son enlaces simbólicos a los módulos que realmente se cargan al arrancar :program:`nginx`. Cada vez que se instala en el sistema un paquete correspondiente a un módulo, *Debian* crea el enlace simbólico que apunta al fichero de configuración correspondiente en :file:`/usr/share/nginx/modules-available`. Por supuesto, si algún módulo no lo usamos, podemos aligerar :program:`nginx` eliminando el enlace (y reiniciando el servidor, claro). En la práctica: * :file:`nginx.conf` se modifica si se desea alterar alguna directiva citada en él. * Se escribe algún fichero :file:`conf.d`, si se desea añadir configuración predeterminada a la labor |HTTP| de :program:`nginx`\ [#]_. * Nuestra tarea se basa fundamentalmente en crear sitios cuya configuración se creará en un fichero dentro de :file:`sites-available` que luego se enlazará desde :file:`sites-enabled`. * Si algún trozo de configuración es recurrente en varios sitios, o bien deseamos apartarla para tenerla mejor controlada y organizada, podemos crear un *snippet* para ella e incluir tal *snippet* con la directiva ``include`` en el fichero de configuración del sitio correspondiente. .. _nginx-install-modules: Módulos adicionales ------------------- Como hemos instalado *nginx-light* puede ocurrir que en algún momento necesitemos un módulo empaquetado que no instala automáticamente este sabor. Supongamos que tal módulo es *libnginx-mod-http-auth-pam*. En ese caso:: # apt-get install libnginx-mod-http-auth-pam El script de *postinstalación* se encarga de todo, así que nos podemos limitar a comprobar que en :file:`/etc/nginx/modules-enabled` se ha creado el enlace adecuado:: # ls -F /etc/nginx/modules-enabled/*pam* 50-mod-http-auth-pam.conf@ .. note:: Por supuesto podemos deshabilitar módulos innecesarios eliminado los enlaces simbólicos correspondientes en ese directorio. .. _nginx-basico: Configuración básica -------------------- Para ilustrar la configuración, tomemos una muy básica que sirve contenido estático y analicémosla. En principio, editemos :file:`/etc/nginx/sites-available/default` y dejémoslo con este contenido: .. code-block:: nginx server { listen 80; server_name _; root /srv/www; try_files $uri $uri/ =404; } .. _nginx-server: .. _nginx-listen: .. _nginx-root: .. _nginx-try_files: Cada directiva `server `_ nos permite configurar un *dominio virtual* y es lo que hemos hecho. Por ahora: * sólo nos preocuparemos de definir una que escucha por el puerto **80** (`listen `_) * en el que no preocupa cuál sea el nombre (la cabecera ``Host``, de ahí el valor de `server_name `_) * en que todos los ficheros compartidos a través del servidor se sitúan bajo :file:`/srv/www`\ [#]_, merced a la directiva `root `_ * la directiva `try_files `_ le indica al servidor qué recursos debe intentar devolver al realizarse una petición. En la configuración propuesta, primero se intenta devolver el propio recurso; si éste no es un fichero, debe comprobarse si es un directorio y en tal caso tratarlo como tal; y, si tampoco es un directorio, devolver un error **404**. Una alternativa podría haber sido: .. code-block:: nginx try_files $uri $uri/ / en este caso, cuando el recurso no se encontró como fichero ni como directorio, no se genera un error, sino que se devuelve la página principal. Por tanto en esta configuración, jamás se devolverá al cliente un error de recurso inexistente. .. note:: Si miramos dónde se inserta este fichero dentro de :file:`nginx.conf`, comprobaremos que lo hace en un bloque ``http``. O sea que un bloque ``server`` se inserta dentro de un bloque ``http``. Esto es importante tenerlo en cuenta porque la configuración de :program:`nginx` se estructura en contextos: el global, el ``http``, el ``server``, etc.` que se anidan unos dentro de otros. Cuando consultemos la documentación oficial, podremos comprobar que para cada directiva se define en qué contextos es válida. Para rematar la configuración, debemos probarla. Para ello, podemos escribir una página principal simple en :file:`/srv/www/index.html`: .. code-block:: html Página principal

Página principal

Y, por último, usar un navegador para acceder a la página usando, por ejemplo, la propia *IP* de la máquina en la que hayamos instalado el servidor. Sobre esta configuración básica podemos añadir algunas modificaciones: * La directiva ``listen`` puede incluir explicitamente la interfaz en la que queremos que escuche. Por ejemplo: .. code-block:: nginx listen localhost:80; ya que cuando se indica únicamente el puerto se sobreentiende que escuchará en todas las disponibles. * Esta misma directiva puede usarse repetidamente para escuchar en múltiples puertos o múltiples interfaces, de modo que: .. code-block:: nginx listen 80; listen 8080; hará que el servidor escuche tanto en el puerto **80** como en el **8080**\ [#]_. * Si en el navegador hemos usado esta dirección (cambiése la *ip* por la que toque):: http://192.168.1.11 .. _nginx-index: para pedir la página, deberíamos ser conscientes de lo que ha ocurrido. No hemos incluido ruta alguna para especificar el recurso, así que :program:`nginx` no encuentra el "no recurso" (por llamarlo de alguna forma). Siguiendo la directiva ``try_files`` añade una barra y entonces prueba a pedir el directorio raíz e, inexplicablemente, se devuelve el recurso :file:`/index.html`. Obviamente el suceso tiene explicación. Cuando :program:`nginx` se encuentra con que se le pide un directorio, revisa una directiva llamada `index `_ para saber cuáles son los fichero que se consideran de índice y que se mostrarán. El valor predeterminado de esta directiva es: .. code-block:: nginx index index.html; así que esa es la razón por la que se sirve la página simple que preparamos. La directiva, por supuesto, admite que le cambiemos el valor o incluso que pongamos varios para que :program:`nginx` pruebe su existencia ordenadamente. Por ejemplo: .. code-block:: nginx index index.html index.htm; probaría si existen :file:`index.html` y, si no es así, prueba :file:`index.htm`. Ahora bien, ¿qué ocurre si no existen tales ficheros de índice? En ese caso, :program:`nginx` mostrará el contenido del directorio, pero sólo si se añade la directiva `autoindex `_: .. code-block:: nginx autoindex on; autoindex_exact_size off; # Muestra unidades k, m, M, etc. y no bytes siempre que por defecto tiene valor *off*. .. Quizás podría ponerse un formato más aparente con xml y el módulo http://nginx.org/en/docs/http/ngx_http_xslt_module.html. Estudiarlo y añadir un epígrafe si es así. La configuración, además, admite algunos añadidos interesantes: .. _nginx-logs: * :program:`nginx` registra los accesos y los accesos fallidos dentro de los ficheros :file:`access.log` y :file:`error.log` del directorio :file:`/var/log/nginx`, ya que así de define dentro :file:`nginx.conf` mediante las directivas `access_log `_ y `error_log `_. A este respecto es importante tener claras dos cosas: - Es común definir distintos ficheros de registro para distintos dominios virtuales, así que podríamos incluir dentro del bloque ``server`` estas dos directivas con ficheros alternativos. - Si en un mismo contexto se definen varios ``access_log`` (o ``error_log``), se escribirán registros en los ficheros que definen todas las directivas. Sin embargo, cuando en un contexto inferior se define la directiva, ésta sobreescribe las definiciones que pudieran haberse hecho en un contexto superior. - Estos ficheros se escriben directamente y no pasan por el gestor de registros (:program:`systemd` o :program:`rsyslog`, según el caso). Para propiciar que :program:`nginx` use el gestor, vea más adelante :ref:`cómo `. * :program:`nginx` tiene unas páginas predefinidas para informar al cliente de los errores (**403**, **404**, **502**, etc.). Podemos, no obtante, crear páginas personalizadas y hacer que :program:`nginx` las envíe al cliente en vez de las predefinidas: .. code-block:: nginx error_page 404 /errors/404.html; error_page 500 502 503 504 /errors/50X.html; .. rubric:: Notas al pie .. [#] Este es el inconveniente de que los módulos se compilen estáticamente. .. [#] Por ejemplo, `ngx_http_referer` no estaba incluido en el ejecutable de *nginx-light*, pero sí en los de *nginx-full* y *nginx-extra*. .. [#] Por ejemplo, :deb:`libnginx-mod-http-dav-ext` contiene el módulo `ngx_http_dav_module `_, que da suporte a :program:`nginx` para las extensiones de *WebDav*, :ref:`ya comentadas `. .. [#] :program:`nginx` puede actuar como *proxy* de correo o *proxy* para conexiones TCP crudas. Para estos casos, no sirve escribir dentro de este fichero y se debe tocar directamente :file:`nginx.conf`. .. [#] Lo cierto es que *Debian* sigue pretendiendo que el contenido del servidor siga estando bajo :file:`/var/www`. Nosotros, en cambio, preferimos seguir las directrices del `FHS `_, ya citado al comienzo de este material. .. [#] Ya veremos que esto es útil cuando queramos versiones seguras e inseguras del mismo sitio: .. code-block:: nginx listen 80; listen 443 ssl; aunque esto requiere más configuración. .. |SSL| replace:: :abbr:`SSL (Security Socket Layer)` .. |PHP| replace:: :abbr:`PHP (PHP Hypertext Preprocesor)`