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
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 { }
}
# /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;
}
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;
}
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;
}
$ 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
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
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;
}
server {
...
auth_basic "Administrator’s Area";
auth_basic_user_file conf/htpasswd;
location /public/ {
auth_basic off;
}
}
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
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
server {
server_name DOMINIO; # ej: example.com
}
Y modificar la configuración con:
$ sudo certbot --nginx -d DOMINIO
# ... sigue las instrucciones
$ sudo certbot renew # Renueva todos los certificados
$ 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";
}
auth required pam_unix.so
account required pam_unix.so
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)
- 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
docker-compose up -d