Configurar VPS desde cero V: servidor web nginx

En este post, continuación de la serie de como configurar nuestro servidor vps desde cero, procederemos a instalar el servidor web. Me he decidido por nginx en vez de apache por su mejor aprovechamiento de los recursos. Aunque como contrapartida, su configuración es mas compleja.

En muchas pagina podremos encontrar ficheros .htaccess usados por Apache con diversas configuraciones, pero es mas raro encontrar la configuración equivalente para nginx. Seguramente tendremos que buscar en otras paginas para saber como configurarlo.

Ademas, una vez metidos en harina, creo que es interesante añadir tres mejoras para optimizar el rendimiento el servidor web: el soporte para el protocolo http2, la compresión brotli y el modulo pagespeed.

Índice
  1. ¿Qué es el protocolo http2?
  2. ¿Qué es la compresión brotli?
  3. El módulo pagespeed
  4. ¿Porque compilar nginx desde el código fuente?
  5. Preparativos antes de compilar el código fuente de nginx
    1. Obteniendo los parámetros de configuración de nginx
    2. Añadir soporte http2 a nginx
    3. Añadiendo la compresión Brotli
    4. Añadiendo el modulo pagespeed
  6. Compilando e instalando nginx
  7. Posibles errores en la compilación
    1. HTTP image filter module requires the GD library
    2. GeoIP module requires the GeoIP library
    3. SSL modules require the OpenSSL library
    4. HTTP rewrite module requires the PCRE library
    5. HTTP XSLT module requires the libxml2/libxslt
  8. Modificación del fichero de configuración de la web
  9. Comprobando http2 y Brotli

¿Qué es el protocolo http2?

El protocolo http2 es una actualización de la version 1.1 del protocolo http, que es el que te permite estar viendo ahora mismo esta web.

Entre sus mejoras, podemos destacar las siguientes:

  • HTTP/2 es binario, en lugar de textual.
  • Está totalmente multiplexado, enviando múltiples peticiones en paralelo a través de una única conexión TCP.
  • Utiliza compresión de cabecera HPACK para reducir la sobrecarga.
  • Permite a los servidores "empujar" las respuestas proactivamente a las cachés de los clientes en lugar de esperar una nueva solicitud para cada recurso.
  • Utiliza la nueva extensión ALPN que permite conexiones cifradas más rápidas, ya que el protocolo de aplicación se determina durante la conexión inicial.
  • Reduce los tiempos adicionales de ida y vuelta (RTT), haciendo que su sitio web se cargue más rápido sin necesidad de optimización.
  • Domain sharding y la concatenación de activos ya no son necesarios con HTTP/2.

El protocolo http2 incluye mas mejoras aparte de las citadas, si quieres informarte sobre ellas, puedes consultar el RFC: HTTP/2 RFC7540

¿Qué es la compresión brotli?

Es un método alternativo a la tradicional compresión gzip, que permite servir los recursos de las paginas comprimidos al navegador, con lo que se aumenta la velocidad (esto es relativo, ya que la compresión solo se nota en ficheros de texto: html, css, js, etc; en los recursos binarios apenas se gana nada con la compresión).

Brotli permite un mayor grado de compresión con un menor consumo de cpu. Según la web de certsimple, la mejora de brotli sobre gzip es:

  • Los ficheros de Javascript comprimidos con Brotli son un 14% más pequeños que gzip.
  • Los ficheros HTML son un 21% más pequeños que gzip.
  • Los ficheros CSS son un 17% más pequeños que gzip.

Ademas, la compresión brotli esta soportada en la mayoría de los navegadores:

Brotli, soporte de los navegadores
Soporte de los navegadores a la compresión brotli

El módulo pagespeed

El modulo pagespeed desarrollado por Google permite realizar optimizaciones en los ficheros de recursos (javascript, css, html e imágenes) para aumentar la velocidad de carga sin necesidad de modificar nada del código existente.

¿Porque compilar nginx desde el código fuente?

Dado que los repositorios de debian, la version de nginx no incluye ni http2, ni la compresión brotli por defecto, deberemos descargar sus fuentes y compilar de nuevo nginx incluyendo el código fuente de ambas características, asi como de pagespeed.

Si hubiera un repositorio que lo incluyese, seria mucho mas fácil, tan solo con un apt-get install nginx_con_http2_y_brotli nos serviría. Ademas, al depender de un repositorio, se actualizaría al hacer un apt-get update.

Pero las cosas no pueden ser sencillas. Así que nos tocara pegarnos con el código fuente, compilar y comprobar que todo funciona perfectamente. Un detalle a tener en cuenta es que al ser compilado, no se actualizara el nginx, por lo que si deseamos hacerlo, deberemos repetir los pasos y compilarlo de nuevo.

Preparativos antes de compilar el código fuente de nginx

Obteniendo los parámetros de configuración de nginx

Como actualmente ya tengo instalada una version de nginx de los repositorios en el servidor vps, y quiero añadir el soporte http2 y la compresión brotli, tengo que compilar el código fuente de nginx.

Un paso muy importante a la hora de compilar es especificar los parámetros de configuración por defecto con que deseamos hacerlo, lo primero que necesito es obtenerlos de la actual version de nginx instalada. De esta manera obtendré una version con los mismos módulos que la actual y evito tener problemas por faltar alguna característica del nginx actual.

nginx  -V

Nos devolverá esta respuesta, donde podremos encontrar los parámetros de configuración por defecto que necesitamos. Buscamos la cadena --prefix= y todo lo que muestra, son parámetros que anotaremos para mas adelante:

nginx version: nginx/1.6.2
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt=-Wl,-z,relro --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module 

Añadir soporte http2 a nginx

Para añadir el soporte de http2, debemos incluir el parametro --with-http_v2_module a la hora de hacer el ./configure en el código de nginx:

 --with-http_v2_module

Añadiendo la compresión Brotli

Comenzamos instalando las librerías y programas necesarios para poder compilar el código fuente de brotli:

apt-get install build-essential zlib1g-dev libpcre3-dev libssl-dev libxslt1-dev libxml2-dev libgd2-xpm-dev libgeoip-dev libgoogle-perftools-dev libperl-dev git

Clonamos el código fuente del repositorio de Brotli:

cd /usr/local/src
git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli
git submodule update --init --recursive

Añadiendo el modulo pagespeed

Comenzamos siguiendo las instrucciones de instalación de pagespeed descargando los paquetes necesarios para poder compilar el código fuente:

sudo apt-get install build-essential zlib1g-dev libpcre3 libpcre3-dev unzip uuid-dev

A continuación debemos comprobar cual es la ultima version de pagespeed actualmente y sustituirla en estas instrucciones:

NPS_VERSION=1.13.35.2-stable
cd
wget https://github.com/apache/incubator-pagespeed-ngx/archive/v${NPS_VERSION}.zip
unzip v${NPS_VERSION}.zip
nps_dir=$(find . -name "*pagespeed-ngx-${NPS_VERSION}" -type d)
cd "$nps_dir"
NPS_RELEASE_NUMBER=${NPS_VERSION/beta/}
NPS_RELEASE_NUMBER=${NPS_VERSION/stable/}
psol_url=https://dl.google.com/dl/page-speed/psol/${NPS_RELEASE_NUMBER}.tar.gz
[ -e scripts/format_binary_url.sh ] && psol_url=$(scripts/format_binary_url.sh PSOL_BINARY_URL)
wget ${psol_url}
tar -xzvf $(basename ${psol_url})  # extracts to psol/

Debemos cambiar la version en negrita (1.13.35.2-stable) por la que actualmente nos muestre en las notas de la version.

Compilando e instalando nginx

Lo primero que necesitamos es descargar el código fuente de OpenSSL, porque para activar ALPN, la version de OpenSSL debe ser mayor o igual a 1.0.2.

Primero, debemos buscar cual es la ultima version del código de OpenSSL publicada. Comprobamos en la pagina de versiones publicadas de OpenSSL la ultima y copiamos el hash. Cuando escribo estas lineas, la ultima version es la OpenSSL es la 1.1.1c y el hash es 97ace46e11dba4c4c2b7cb67140b6ec152cfaaf4.

Creamos el directorio para OpenSSL y descargamos el código fuente:

cd /usr/local/src
git clone https://github.com/openssl/openssl.git
cd openssl
git checkout 97ace46e11dba4c4c2b7cb67140b6ec152cfaaf4

Para que a la hora de compilar nginx compile las fuentes de OpenSSL 1.1.1c, debemos añadir este parametro al ./configure

--with-openssl=/usr/local/src/openssl

Y continuamos descargando la ultima version de nginx disponible, cuando escribo estas lineas es la 1.17.0

wget http://nginx.org/download/nginx-1.17.0.tar.gz

Descomprimimos el fichero tar.gz:

tar -xzvf nginx-1.17.0.tar.gz

PAra incluir el protocolo http2, debemos incluir el parametro:

--with-http_v2_module

Para incluir la compresión brotli, debemos añadir el parámetro:

--add-module=/usr/local/src/ngx_brotli --sbin-path=/usr/sbin/nginx

Para incluir el modulo pagespeed, debemos añadir el siguiente parámetro a la linea de compilación de nginx:

--add-module=../incubator-pagespeed-ngx-1.13.35.2-stable

Con lo que al final procedemos a compilar nginx, comenzando por hacer un ./configure con los parametros por defecto y los correspondientes a http2, brotli, openssl y pagespeed:

cd nginx-1.17.0
./configure --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-http_v2_module --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module --with-openssl=/usr/local/src/openssl --add-module=../incubator-pagespeed-ngx-1.13.35.2-stable --add-module=/usr/local/src/ngx_brotli --sbin-path=/usr/sbin/nginx

Nos preguntara si queremos instalar los binarios precompilados de PSOL, responderemos que si:

You have set --with-debug for building nginx, but precompiled Debug binaries for
PSOL, which ngx_pagespeed depends on, aren't available.  If you're trying to
debug PSOL you need to build it from source.  If you just want to run nginx with
debug-level logging you can use the Release binaries.

Use the available Release binaries? [Y/n] Y

Cuando acabe de realizar el ./configure, nos mostrara una pantalla similar a esta:

Compilar nginx: ./configure
Compilar nginx: ./configure

procedemos a compilar e instalar nginx:

make
make install

Nos mostrar algo similar a esta pantalla:

Compilando nginx: make
Compilando nginx: make

Comprobamos que nginx se ha actualizado correctamente, hacemos un nginx -V:

nginx -V

Nos mostrara un mensaje similar a este:

nginx version: nginx/1.17.0
built by gcc 4.9.2 (Debian 4.9.2-10+deb8u2) 
built with OpenSSL 1.1.1c  28 May 2019
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-http_v2_module --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module --with-openssl=/usr/local/src/openssl --add-module=../incubator-pagespeed-ngx-1.13.35.2-stable --add-module=/usr/local/src/ngx_brotli --sbin-path=/usr/sbin/nginx

Podemos comprobar que se ha compilado correctamente con la ultima version de OpenSSL, con el protocolo http2 (--with-http_v2_module), brotli (--add-module=/usr/local/src/ngx_brotli) y pagespeed (--add-module=../incubator-pagespeed-ngx-1.13.35.2-stable)

Posibles errores en la compilación

A continuación se muestran una serie de errores que nos pueden surgir por faltar alguna libreria en nuestro sistema y como resolverlos.

HTTP image filter module requires the GD library

Si nos muestra el mensaje de error:

./configure: error: the HTTP image filter module requires the GD library.
You can either do not enable the module or install the libraries.

Debemos instalar el paquete libgd-dev

apt-get install libgd-dev

GeoIP module requires the GeoIP library

Si nos muestra el mensaje de error:

./configure: error: the GeoIP module requires the GeoIP library.
You can either do not enable the module or install the library.

Debemos instalar el paquete libgeoip-dev

apt-get install libgeoip-dev

SSL modules require the OpenSSL library

Si nos muestra el mensaje de error:

./configure: error: SSL modules require the OpenSSL library.
You can either do not enable the module or install the library.

Debemos instalar el paquete libssl-dev

apt-get install libssl-dev

HTTP rewrite module requires the PCRE library

Si nos muestra el mensaje de error:

./configure: error: the HTTP rewrite module requires the PCRE library.
You can either do not enable the module or install the library.

Debemos instalar el paquete libpcre++-dev

apt-get install libpcre++-dev

HTTP XSLT module requires the libxml2/libxslt

Si nos muestra el mensaje de error:

./configure: error: the HTTP XSLT module requires the libxml2/libxslt
You can either do not enable the module or install the library.

Debemos instalar el paquete libxslt1-dev

apt-get install libxslt1-dev

Modificación del fichero de configuración de la web

Ahora debemos modificar el fichero de configuración de nuestra web en /etc/nginx/sites-enabled/miweb. Necesitaremos modificar uno o varios ficheros, dependiendo del numero de web que aloja nuestro vps.

nano /etc/nginx/sites-enables/miweb

Y activamos http2:

listen *:443 ssl http2;

Y también activamos la compresión brotli:

brotli on;
brotli_comp_level 6;
brotli_min_length 256;

brotli_types
   application/javascript
   application/json
   application/xml
   image/svg+xml
   text/css
   text/plain;

En esta tabla se puede comprobar las funciones que realiza cada parametro:

ParámetroValorFunción que realiza
brotlionActivación de la compresión brotli.
brotli_comp_level6Nivel de compresión de 1 a 11. A mayor nivel, mas compresión, pero tardara mas en generar el fichero comprimido.
brotli_min_length256Longitud minima del fichero a comprimir. Cualquier fichero menor de 256 bytes no sera comprimido.
brotli_typesapplication/javascript
application/json
application/xml
image/svg+xml
text/css
text/plain
Tipo de ficheros a comprimir. Todos los ficheros de estos tipos mime comprimidos si cumplen el criterio anterior.

Comprobaremos que la configuración es correcta:

nginx -t

Es posible que nos muestre este mensaje de error:

nginx: [emerg] "try_files" directive FileCachePath must be set, even for standby in /etc/nginx/nginx.conf:88

Esto es debido porque debemos indicar el directorio que usara pagespeed, asi que haremos los siguiente:

mkdir -p /var/ngx_pagespeed

Y añadir el parametro FileCachePath en cada fichero de configuración de cada web:

pagespeed FileCachePath /var/ngx_pagespeed_cache;

Si todo ha salido bien y el nginx -t no nos muestra ningun aviso de error en la configuración, debemos reiniciar nginx para que se actualice y cargue la nueva configuración de los sitios web:

/etc/init.d/nginx restart

Comprobando http2 y Brotli

Una vez hemos instalado nginx, debemos comprobar que funcionan correctamente tanto el protocolo http2 y la compresión brotli.

Para comprobar el funcionamiento del protocolo http2, podemos ir al sitio http2 test, donde con solo introducir la url de nuestro dominio donde hemos activado http2, nos indicara si esta activo o no.

Test http/2
Test para comprobar si nuestro sitio web soporta http2

Podemos comprobar también en la misma pagina si esta activa la compresión brotli:

Test de compresión brotli
Test para comprobar si tenemos activa en nuestra web la compresión brotli

Ya tenemos funcionando nuestro nginx con http2, pagespeed y brotli!!

¡Haz clic para puntuar esta entrada!
(Votos: 1 Promedio: 5)

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir