Saltar a contenido

37. NGINX

Instalación y configuración de nginx. En el último apartado, como alternativa, nginx proxy manager que incluye un gestor web de los proxy

37.1 Instalación nginx en Linux

Para nginx en ubuntu

sudo apt update
sudo apt install nginx
Para usar las últimas distribuciones:
deb https://nginx.org/packages/ubuntu/ focal nginx
deb-src https://nginx.org/packages/ubuntu/ focal nginx

Y para iniciar el servicio:

sudo systemctl start nginx

37.2 Directorios

  • Configuración por defecto: /etc/nginx/nginx.conf
    • Directorio de configuración de servidores "sites" : /etc/nginx/sites-available
    • Directorio de configuración de servidor activos : /etc/nginx/sites-enabled
  • Share: /usr/share/nginx
  • Páginas web: /var/www/html/

37.3 NGINX.CONF

Información procedente de : Configuración web server

En "sites-availables" se crean los ficheros de configuración. En "sites-enabled" se crean enlaces directos a sites-available

37.3.1 Servidores virtuales

Bajo la directiva http :

user nginx;  # Nombre del usuario con el que se ejecuta Nginx

http {
    server { }
    server { }
    server { }
}
O mejor en ficheros separados e incluyendo :
# /etc/nginx/nginx.conf
user nginx;

http {
    # Para cargar otros ficheros
    include /etc/nginx/conf.d/*.conf;
    ##
    # Virtual Host Configs
    ##
    include /etc/nginx/sites-enabled/*;
}

37.3.2 Configuración básica

  • listen : para que escuche a uno o varios clientes.
  • La IPv4 0.0.0.0 se usa para que escucha a todo el mundo.
  • La IPv6 :: es el equivalente (todo ceros) en IPv6.
  • server_name: si nuestro servidor tiene nombre DNS.
  • root: el directorio del que se sirven ficheros para este servidor.
server {
    # listen 0.0.0.0:80;  # Escucha a todos los clientes en IPv4
    listen 80;            # Igual que la línea anterior
    listen [::]:80;       # Escucha en IPv6
    server_name _;        # Si no tenemos DNS se usa _
    root /var/www/html;   # Directorio habitual
}

37.3.3 Multiples servidores virtuales

Debe cumplir: * Respondan a diferentes nombre * Escuchen en puertos diferentes

┌───────────────────────────────────────────┐ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Virtual │ │ Virtual │ │ Virtual │ │ │ │ Server │ │ Server │ │ Server │ │ │ └────▲────┘ └────▲────┘ └────▲────┘ │ │ │ │ │ │ │ └─────────────┴─────────────┘ │ │ NGINX │ └─────────────────────▲─────────────────────┘ │ ┌───┴───┐ │Port 80│ └───────┘ ▲ │ Clients

Ejemplo:

server {
    listen 80;
    listen [::]:80;
    server_name primero.com;
    root /var/www/primero;
}

server {
    listen 80;
    listen [::]:80;
    server_name segundo.com;
    root /var/www/segundo;
}

server {
    listen 8080;
    listen [::]:8080;
    server_name segundo.com;
    root /var/www/segundo_test;
}
Para probar, las tres tendrán la misma ip

Directiva Server name Permite que un servidor virtual responda a uno o varios nombres de dominio:
server { server_name minombre.com www.minombre.com *.otronombre.com; } NOTA: Con el asterisco se añaden patrones de dominios.

default_server se utiliza para señalar el servidor por defecto donde se dirigen las peticiones que no se pueden asignar a otro servidor

server {
    listen 8080 default_server;
    location / {
        root /home/asuarez/Proy/mdoc/site
    }
    #...
}

Logs Por servidor

server {
    access_log /var/log/nginx/myserver_access.log;
    error_log /var/log/nginx/myserver_error.log;
}
indices

Nombre por defecto del index.html

server {
    index index.html inicio.html;
}

Location Configuraciones distintas para cada ruta:

server {
    location /ruta_1/ {
       # Configuración para http://server/ruta_1/*
    }
    location /ruta_2/ {
       # Configuración para http://server/ruta_2/*
    }
}

Redirecciones Es fácil redireccionar a otra URI devolviendo un código 301 junto al location de la redirección.

Para redireccionar del servidor www.domain.com al nombre desnudo domain.com:

  • Usa la variable $scheme para devolver al mismo protocolo de origen (http o https).
  • Usa $request_uri para que el path, query y fragment sean los mismos*

server {
    listen 80;
    server_name www.domain.com;
    return 301 $scheme://domain.com$request_uri;
}
Y el resultado:
$ nc <host> 80
GET /page.html#fragment HTTP/1.0
Host: www.domain.com

HTTP/1.0 301 Moved Permanently
Location: http://domain.com/page.html#fragment
Para redirigir a clientes de HTTP a HTTPS:

Se mantiene el $host y la $request_uri de la petición, pero se fuerza manualmente al esquema https.

server {
    listen 80;
    server_name domain.com;
    return 301 https://$host$request_uri;
}

37.3.4 Restringir acceso a páginas con "Nasic Authentication"

Dos pasos: crear un fichero de claves para la web y configurar nginx.

Para crear el fichero de claves utilizamos el comando htpasswd de apache2-utils (instalar si no está ya instalado)

sudo mkdir /etc/apache2
sudo htpasswd -c /etc/apache2/.htpasswd user1
El comando pregunta por la password del "user1"

Y cambiamos la configuración del servidor (virtual):

Para una sección de la web

location /api {
    auth_basic           "Administrator’s Area";
    auth_basic_user_file /etc/apache2/.htpasswd; 
}
O para toda la web excepto una parte, ejemplo para /public

server {
    ...
    auth_basic           "Administrator’s Area";
    auth_basic_user_file conf/htpasswd;

    location /public/ {
        auth_basic off;
    }
}
([Página de ayuda de nginx][https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/]) y sobre el Framework basic auth

37.4 HTTPS

PRERREQUISITO: Debes disponer de un nombre de un servidor en internet y de un dominio apuntando a su IP, O bien en una red privada disponer de un servidor DNS y una autoridad de certificados CA.

Para tener HTTPS es necesario disponer de un certificado, que se puede obtener de dos maneras:

  • Creando tú mismo un certificado autofirmado (self-signed).
  • Obteniéndolo de una CA (Certification Authority) como Let’s Encrypt.

37.4.1 Certificados autofirmados

Se necesitan dos ficheros:

  • DOMINIO.key: clave pública
  • DOMINIO.crt: info adicional y metadatos. Ej: entidad que expide el certificado, fecha de expiración, etc. Para generarlos (sustituye DOMINIO por tu nombre de dominio, como example-com.key y example-com.crt):

$ cd  # Vamos al home
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout DOMINIO.key -out DOMINIO.crt
# ...rellena los campos que te pide
$ mv DOMINIO.key /etc/ssl/private/DOMINIO.key
$ mv DOMINIO.crt /etc/ssl/certs/DOMINIO.crt
Por último, configurar nginx:
server {
    listen 443 ssl;
    ssl_certificate /etc/ssl/certs/DOMINIO.crt;
    ssl_certificate_key /etc/ssl/private/DOMINIO.key;

    # Resto de configuraciones
}

37.4.2 Certificados let`s encrypt

Let’s Encrypt es una CA que ofrece certificados gratuitos.

No necesitas tener una cuenta en Let’s Encrypt. Necesitas tener un nombre de dominio en una máquina con IP pública en internet. La herramienta para crear certificados de esta CA se llama certbot.

Instalamos los paquetes necesarios:

$ sudo apt install certbot python3-certbot-nginx
Debe estar configurado el nombre de dominio correctamente

server {
    server_name DOMINIO;  # ej: example.com
}

Y modificar la configuración con:

$ sudo certbot --nginx -d DOMINIO
# ... sigue las instrucciones
Renovación de certificado

$ sudo certbot renew  # Renueva todos los certificados
Instala un temporizador que comprueba la renovación periódicamente. Se verifica :
$ sudo systemctl status certbot.service
# Debe estar *active*

37.5 nginx como proxy inverso

Ver esta página y el ejemplo de configuración de nginx como proxy inverso

La documentación de nginx para proxy

37.6 nginx autenticación PAM

Usamos el módulo de autenticacion PAM. Para ello tenemos que instalar:

 apt -y install nginx-extras
 ```

1. Para autenticar cuando se accede al directorio **/test** , añadimos al fichero de configuración  del servidor:

```json
location /test {
    auth_pam "Secure area";
    auth_pam_service_name "nginx";
}
2. En el directorio /etc/pam.d añadimos el fichero nginx

auth required pam_unix.so
account required pam_unix.so
3. Para autenticar con las cuentas de linux ejecutamos:

groupadd shadow
usermod -a -G shadow www-data
chown root:shadow /etc/shadow
chmod g+r /etc/shadow

Se autoriza a nginx el acceso al archivo shadow . nginx se usa con el usuario www-data (en la instalación)

  1. Reiniciar servicio:
    sudo systemctl restar nginx

37.7 Comandos utiles

  • netstat -lnp . Lista puertos y servicios asociados
  • netcat: nc localhost 80 : abre una sesión telnet

37.8 Nginx Proxy Manager

Esta herramienta open source sirve para configurar de forma fácil el servidor proxy inverso con nginx.

Para instalar usaremos docker y docer-compose.
Creamos el fichero:

version: "3"
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      # These ports are in format <host-port>:<container-port>
      - '80:80' # Public HTTP Port
      - '443:443' # Public HTTPS Port
      - '81:81' # Admin Web Port
      # Add any other Stream port you want to expose
      # - '21:21' # FTP

    # Uncomment the next line if you uncomment anything in the section
    # environment:
      # Uncomment this if you want to change the location of 
      # the SQLite DB file within the container
      # DB_SQLITE_FILE: "/data/database.sqlite"

      # Uncomment this if IPv6 is not enabled on your host
      # DISABLE_IPV6: 'true'

    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
y levantamos el servicio
docker-compose up -d