UpVent Logo

Desplegando sitios con NGINX

Portada del post
Imágen del autor Fecha de publicación: hace 5 meses por UpVent
Última actualización: hace 5 meses
Compartir:

Introducción.

Desplegar sitios web se ha vuelto una tarea muy sencilla a lo largo de los años, sobre todo con la vasta cantidad de tutoriales que uno puede encontrar mientras navega por internet. Al ser un recurso fácilmente accesible, estos tutoriales se vuelven el instructivo por defecto de los administradores de sistemas y desarrolladores nuevos en el campo de los servidores.

No nos malinterpreten desde el vamos, sabemos que las personas que escriben esos tutoriales lo hacen con la mejor de las intenciones, sin embargo, muchos de estos tutoriales carecen de profundización, tanto en seguridad como en optimización. Por ello, decidimos escribir este pequeño tutorial para los administradores de sistemas y programadores que deseen que sus sitios estáticos en producción sean seguros y rápidos. Además, pueden tomar el conocimiento de este tutorial y aplicarlo a sitios dinámicos y comparar las diferencias en rendimiento y puntajes de Lighthouse u otras herramientas.

 

Prerequisitos.

Este tutorial se hará bajo una instalación de servidor que usa "Ubuntu 20.04 LTS", si no posees un servidor o si aún estás buscando opciones donde alojar tu sitio, te recomendamos usar este servicio. También necesitarás tener instalado NGINX, si no lo tienes instalado puedes leer este tutorial. También necesitarás entender algunos tecnicismos sobre servidores, respuestas y términos de Gnu/Linux. 

 

Una nota más, vamos a asumir que estás importando tu sitio web de un servicio como GitHub, si tu sitio web no se encuentra en algún servicio de Git o si simplemente no usas control de versiones este tutorial aún te será de utilidad, solo necesitarás  omitir los pasos de clonación y protección de algunos directorios. 

 

Configuración

En este tutorial vamos a configura el dominio example.com, antes de poder utilizarlo en la web, necesitarás configurar tus DNS para que apunten a tu servidor, esos pasos están fuera del alcance de este tutorial, por lo que tendrás que revisar la guía de configuración de tu proveedor de servidores.

 

Paso uno: Crear el directorio para nuestro sitio.

En muchas distribuciones de Gnu/Linux, NGINX viene con un "bloque de servidor" y el mismo está preconfigurado para utilizar los archivos bajo el directorio /var/www/html. Este directorio será el directorio por defecto que NGINX mostrará si el cliente conectado no encuentra el sitio que busca o si accede por tu dirección IP. 

 

Paso dos: Proteger la ruta por defecto.

El acceso por dirección IP ya es un problema de buenas a primeras, a menos que poseas un certificado SSL válido para la IP de tu servidor esto puede considerarse un fallo de seguridad. Si posees un formulario de contacto o de otra clase, al ser enviado por un canal no cifrado, los datos del cliente pueden verse comprometidos ante los terceros.

Para evitar accidentes, vamos a proteger el acceso a la ruta por defecto, para ello vamos a editar el bloque de configuración por defecto de NGINX, toma tu editor de texto favorito y abre el archivo localizado en /etc/nginx/sites-available/default, aquí vamos a agregar algunas configuraciones para evitar que los clientes puedan acceder por IP.

Primero tendremos que localizar el bloque llamado "server", si no existe puedes copiar y pegar la configuración de abajo, en caso de existir solo tendrás que modificar para que la directiva de server_name sea un guión bajo y regrese una respuesta 404. El bloque de configuración resultante debería contener las siguientes instrucciones:

server {
listen 80 default_server;
server_name _;
return 404;
}

Si queremos bloquear el acceso desde el puerto 443 podemos hacer lo siguiente:

server {
listen 443 ssl;
server_name example.com

ssl_certificate <ruta-al-archivo.crt>;
ssl_certificate_key <ruta-al-archivo.key>;

 if ($host != "example.com") {
  return 404;
 }
}

Ten en cuenta que tendrás que agregar múltiples if, en caso de que tengas otros sitios con diferentes dominios apuntando al mismo bloque. Ten en cuenta que la configuración de NGINX no es un lenguaje de programación en si y necesitarás usar muchas instrucciones o encontrar algún hack para redirigir múltiples sitios, si quieres saber más sobre la directiva de if puedes leer la documentación de NGINX.

Con estos pasos podrás bloquear todos los intentos de acceder a tu sitio por medio de la IP de tu servidor.

 

Paso tres: Crear un directorio para nuestro nuevo sitio.

Vamos a crear un nuevo directorio bajo la estructura por defecto de NGINX bajo /var/www/. Los sitios web se pondrán en un directorio html/. Para crear estos directorios usaremos la orden mkdir con la bandera -p para crear los directorios faltantes en caso de no existir:

sudo mkdir -p /var/www/example.com/html

Ahora que tenemos el directorio creado, vamos a reasignar los permisos que tiene, de esta forma Linux nos permitirá editar el contenido de los directorios sin la necesidad de escalar privilegios. Para esto podemos usar la variable de entorno $USER con chown para asignar los permisos:

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

Los permisos de nuestro directorio deberían de ser correctos, sin embargo, el valor del umask no han cambiado, por lo que necesitaremos la ayuda de chmod para asignar los permisos correctos:

sudo chmod -R 755 /var/www

Listo, nuestros permisos son correctos, podemos continuar.

 

Paso cuatro: Clonar nuestro sitio estático.

Nota: Si no utilizas un control de versiones, puedes omitir la instrucción de git, sin embargo tendrás que encontrar la manera de subir tus archivos al directorio deseado.

Para clonar nuestra página web desde git podemos ejecutar el siguiente comando.

cd /var/www/example.com/html/ && git clone <url-del-repositorio> .

Es importante mantener el "." al final del comando, pues con esto git evitará crear un directorio extra al momento de clonar nuestro código. Ten en cuenta que NGINX le dará prioridad al archivo llamado index.html, así que te recomendamos llamar así a tu archivo principal para ser el primero en cargar.

 

Paso cinco: Crear un bloque de servidor para nuestro sitio.

Ya tenemos nuestro contenido web para servirlo a nuestros clientes, ahora necesitamos crear un archivo de configuración nuevo para que NGINX pueda hacer su trabajo, para evitar complicarnos demasiado podemos copiar el archivo de configuración por defecto de NGINX:

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com
 

De nuevo, utilizando nuestro editor de texto debemos abrir nuestro nuevo archivo de configuración y cambiar algunas configuraciones, ignorando las líneas con comentarios y tomando en cuenta los cambios que hicimos antes, nuestro archivo llamado example.com debería verse así:

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/html;
        index index.html index.htm index.nginx-debian.html;

        server_name _; 

        location / {
                try_files $uri $uri/ =404;
        }
}

Primero debemos ver a las directiva de listen. Debemos eliminar la directiva default_server de ellas, ya que no utilizaremos ninguna de esas dos páginas como nuestro servidor por defecto, pues ya configuramos  nuestro default_server por defecto para responder con un error 404 en caso de que la gente acceda por IP a nuestro servidor.

Las directivas listen deberían verse así:

listen 80;

listen[::]:80;

 

El paso siguiente será indicarle a NGINX donde se encuentra la raíz de nuestro sitio web, esto se encuentra en la directiva root. Aquí tendremos que apuntar al directorio que creamos para alojar nuestro sitio web, en este caso /var/www/example.com/html, con este cambio la directiva root debería verse así:

root /var/www/example.com/html;

Lo siguiente que tenemos que hacer es modificar la directiva server_name para que NGINX reconozca las peticiones dirigidas a nuestro dominio, además, podemos añadir varios aliases para nuestro dominio, el más clásico es el alias para usar www al inicio de nuestra URL:

server_name example.com www.example.com;
 

Al terminar, nuestro archivo debería verse así:

server {
        listen 80;
        listen [::]:80;

        root /var/www/example.com/html;
        index index.html index.htm index.nginx-debian.html;

        server_name example.com www.example.com;

        location / {
                try_files $uri $uri/ =404;
        }
}

 

Eso es todo lo que necesitamos para nuestra configuración básica, vamos a aplicar un par de protección y optimizaciones antes de mostrarle nuestro sitio al mundo.

 

Paso seis: Proteger el directorio .git y corregir permisos

Al haber clonado nuestro sitio desde un repositorio, git habrá creado un directorio llamado .git, este directorio podría contener información sensible como el correo del autor del commit o en el peor de los casos credenciales como llaves de API u otras cosas. Algunas herramientas como gitjacker pueden extraer repositiorios completos de sitios con directorios no protegidos.

Para proteger nuestro directorio .git debemos añadir un nuevo bloque de configuración al archivo /etc/nginx/nginx.conf al final del archivo:

location ~ /\.git {
  deny all;
}

 

(Opcional) Paso siete: Compilar e instalar mod_pagespeed para mayor velocidad de carga. 

mod_pagespeed es un módulo disponible para Apache y NGINX que mejora la carga de los recursos estáticos de las páginas web haciendo que cumplan con las "best practices" del contenido web. Dichas mejoras son configurables y tenemos una amplia variedad de las mismas, algunos ejemplos de mejoras que mod_pagespeed nos puede ofrecer:

  • Minimizar archivos de JS/CSS
  • Combinar archivos JS/CSS
  • Eliminar comentarios del código
  • Cargar imágenes de forma "lazy"
  • Convertir las imágenes del sitio en WebP

y muchas más. 

Con Apache no hay problema bajando y cargando este módulo desde cero, 

Este paso es totalmente opcional y puede ser omitido sin problemas. Esto es para aquellos administradores de sistemas que gusten sacar un poco de rendimiento extra a su sitio web.

 

Primero necesitamos instalar las dependencias necesarias para compilar nuestros módulos, el siguiente comando debería instalarlas:

sudo apt install dpkg-dev build-essential zlib1g-dev libpcre3 git libpcre3-dev unzip -y

Una vez instaladas nuestras herramientas de compilación, necesitamos ver la versión de NGINX que estamos ejecutando en nuestro servidor, en este caso es la 1.18.0, puedes comprobarla con el siguiente comando:

nginx -v
nginx version: nginx/1.18.0 (Ubuntu)

Antes de descargar y compilar el módulo de pagespeed, necesitaremos descargar el código fuente de NGINX. Asegúrate que el código fuente que estás descargando sea el mismo que la versión de NGINX que tienes instalada. Puedes descargar el código fuente de la siguiente forma:

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

Una vez termine la descarga necesitamos extraer el archivo comprimido con la siguiente orden:

tar -xvzf nginx-1.18.0.tar.gz

Cuando terminemos de descomprimir el código fuente de NGINX, también necesitaremos descargar el código fuente del módulo de pagespeed para NGINX:

git clone https://github.com/apache/incubator-pagespeed-ngx.git

Acabamos de clonar un directorio de git, tenemos que utilizar la última versión estable si queremos asegurarnos de que las cosas funcionen cuando las tengamos en producción, por lo que tendremos que entrar al repositorio y cambiar hacia la rama estable:

cd incubator-pagespeed-ngx
git checkout latest-stable

Una vez cambiada la rama de git, tenemos que revisar con el comando cat un archivo que nos dirá donde podremos descargar un binario "PSOL":

cat PSOL_BINARY_URL
https://dl.google.com/dl/page-speed/psol/1.13.35.2-$BIT_SIZE_NAME.tar.gz

Ahora tenemos que ejecutar el siguiente comando para descargar el binario PSOL:

wget https://dl.google.com/dl/page-speed/psol/1.13.35.2-x64.tar.gz

Repetimos el proceso de extraer el comprimido:

tar -xvzf 1.13.35.2-x64.tar.gz

Y ahora tenemos que regresar al directorio donde guardamos el código fuente de NGINX e instalar todas las dependencias de construcción que necesita con los siguientes comandos:

cd <ruta-al-source-de-NGINX>
apt-get build-dep nginx
apt-get install uuid-dev

Perfecto, ahora tenemos que configurar el módulo ngx_pagespeed con el siguiente comando:

./configure --with-compat --add-dynamic-module=/root/incubator-pagespeed-ngx

La pantalla debería mostrar algo así:

Configuration summary
  + using system PCRE library
  + OpenSSL library is not used
  + using system zlib library

  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/local/nginx/sbin/nginx"
  nginx modules path: "/usr/local/nginx/modules"
  nginx configuration prefix: "/usr/local/nginx/conf"
  nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
  nginx pid file: "/usr/local/nginx/logs/nginx.pid"
  nginx error log file: "/usr/local/nginx/logs/error.log"
  nginx http access log file: "/usr/local/nginx/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"

Ahora tenemos que ejecutar el comando make  para construir el módulo:

make modules

Una vez make termine de hacer su trabajo, tenemos que copiar el módulo generado al directorio de módulos de NGINX:

cp objs/ngx_pagespeed.so /usr/share/nginx/modules/

Llegados a este punto, ngx_pagespeed debería estar instalado en nuestro sistema y ahora estamos listos para acelerar nuestras páginas estáticas.

(Opcional) Paso ocho: Configurar ngx_pagespeed.

Llegó el momento de configurar NGINX para que use pagespeed. Primero necesitamos editar nuestra configuración principal de NGINX en /etc/nginx/nginx.conf añadiendo la siguiente línea al principio del archivo:

load_module modules/ngx_pagespeed.so;

Perfecto, ahora necesitamos crear un directorio para almacenar la cache de nuestros sitios, vamos a crearlo bajo la partición /var/, pues ahí van los archivos que cambian constantemente:

mkdir -p /var/ngx_pagespeed_cache

Ahora asignamos los permisos correctos al directorio:

chown -R www-data:www-data /var/ngx_pagespeed_cache

Por último tenemos que editar nuestro archivo example.conf (el archivo que configuración del sitio que hicimos en el paso cinco) y añadir las configuraciones de PageSpeed al final del mismo:

pagespeed on;
     pagespeed FileCachePath "/var/ngx_pagespeed_cache/";
     pagespeed RewriteLevel OptimizeForBandwidth;

     location ~ ".pagespeed.([a-z].)?[a-z]{2}.[^.]{10}.[^.]+" {
         add_header "" "";
     }

     location ~ "^/pagespeed_static/" { }
     location ~ "^/ngx_pagespeed_beacon$" { }
pagespeed RewriteLevel CoreFilters;

Puedes encontrar más opciones de configuración para tu virtual host aquí.

Paso nueve: Desplegar nuestro sitio.

Hemos llegado al final del tutorial y ahora solo nos falta enlazar nuestros archivos de configuración de NGINX con el servidor para comenzar a servir nuestros sitios, esto podemos lograrlo haciendo enlaces simbólicos al directorio sites-enabled de NGINX:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

Estos archivos ahora están en el directorio de sitios encendidos. Como precaución, NGINX puede ser propenso a errores de memoria, mejor conocidos como "hash bucket memory problem", para solucionar esto debemos editar de nuevo nuestro archivo de configuración de NGINX (/etc/nginx/nginx.conf) y descomentar la siguiente línea (Solo tenemos que eliminar el símbolo de gato #):

server_names_hash_bucket_size 64;

Una vez hayamos guardado el archivo, llegó el momento de reiniciar NGINX para ver nuestro sitio online. Primero necesitamos asegurarnos de que no existan errores de sintáxis en nuestros archivos de NGINX:

sudo nginx -t

Si NGINX no detectó problemas, podemos reinicialo para aplicar nuestros cambios:

sudo systemctl restart nginx

Paso diez: Añadir un certificado de seguridad.

Ya hemos terminado de desplegar nuestro sitio, pero...no todo está perfecto, nos hace falta un certificado SSL. En estos tiempos la mayoría de navegadores modernos muestran una advertencia de seguridad cuando intentamos ingresar a sitios sin un certificado de seguridad, esto podría ser perjudicial para nuestro sitio y su crecimiento. Afortunadamente, un certificado de seguridad es algo que se consigue de forma sencilla estos días. 

Ubuntu viene con una variedad de herramientas que nos permitirán tener un certificado de seguridad con facilidad, necesitaremos instalarlas para comenzar este proceso:

apt update
sudo apt install certbot
apt install python3-certbot-nginx

Una vez instaladas las herramientas, todo se reduce a una sola orden en nuestra consola y listo, tendremos nuestro sitio configurado con un certificado de seguridad:

sudo certbot --nginx -d example.com -d www.example.com

Solo tenemos que reiniciar NGINX y listo.

sudo systemctl restart nginx

Conclusión

Si te gustó esta entrada de blog compártelo con tus amigos si deseas que ellos también conozcan el proceso de despliegue de un sitio estático. 

Te agradeceríamos que compartieras este tutorial en redes sociales o que visites nuestros enlaces a la derecha de este post :) 

¡Nos leemos después!


Otros Recursos

¡Prueba Brave!

¿Te preocupa tu privacidad pero no puedes dejar los navegadores basados en Chromium? Brave te ofrece todas las características de Chromium / Chrome sin sacrificar tu privacidad.

Conocer más...
Conoce los puertos y protocolos de red más comunes.