Me he decidido a probar el servidor nginx.
Desde siempre he sido usuario del servidor web apache, tanto en servidores Linux (Debian y CentOS) como en Windows instalado con una distribución de Xampp. Estos días he necesitado realizar una prueba de configuración de un certificado let’s encrypt en un servidor y que todo fuera redirigido por https , incluido puertos que venían de docker como 8081. Así que me he decidido a probar el servidor nginx y la verdad es que estoy muy contento.
Necesitaba configurar el servidor y que además actuara como proxy inverso para servir páginas hacia otros servidores y además con certificado https.
Una vez instalado, los mayores problemas que pueden surgir vienen determinados por conflictos de puertos. Es decir, que si no nos hemos dado cuenta tengamos el puerto 80 ,que es el que por defecto utilizan los servidores web , ya cogido por apache .
Podemos comprobarlo con la instrucción netstat –tcp -lpn de esta forma nos indica que software está ocupando que puertos en cada momento. Por ejemplo, si tenemos nginx activo debería aparecer una línea como esta en el puerto 80:
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 51871/nginx.conf
y si además tenemos activo ssl tendríamos
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 51871/nginx.conf
Esto tenemos que tenerlo en cuenta para no tener conflictos entre nginx y apache.
Instrucciones básicas
- Con nginx -V podemos obtener todos los datos sobre la instalación que tenemos, obtendremos una salida como esta, se nos indica la versión del software, los módulos habilitados y mucho más parámetros de configuración que tengamos en nuestro servidor.
nginx version: nginx/1.16.0
built by gcc 4.9.2 (Debian 4.9.2-10+deb8u2)
built with OpenSSL 1.0.1t 3 May 2016
TLS SNI support enabled
configure arguments: –prefix=/etc/nginx –sbin-path=/usr/sbin/nginx –modules-path=/usr/lib/nginx/modules –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –http-log-path=/var/log/nginx/access.log –pid-path=/var/run/nginx.pid –lock-path=/var/run/nginx.lock –http-client-body-temp-path=/var/cache/nginx/client_temp –http-proxy-temp-path=/var/cache/nginx/proxy_temp –http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp –http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp –http-scgi-temp-path=/var/cache/nginx/scgi_temp –user=nginx –group=nginx –with-compat –with-file-aio –with-threads –with-http_addition_module –with-http_auth_request_module –with-http_dav_module –with-http_flv_module –with-http_gunzip_module –with-http_gzip_static_module –with-http_mp4_module –with-http_random_index_module –with-http_realip_module –with-http_secure_link_module –with-http_slice_module –with-http_ssl_module –with-http_stub_status_module –with-http_sub_module –with-http_v2_module –with-mail –with-mail_ssl_module –with-stream –with-stream_realip_module –with-stream_ssl_module –with-stream_ssl_preread_module –with-cc-opt=’-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC’ –with-ld-opt=’-fPIE -pie -Wl,-z,relro -Wl,-z,now -Wl,–as-needed -pie’
- Si queremos comprobar el estado de nuestro servidor nginx podemos realizarlo con la instrucción systemctl status nginx, que nos mostrará una salida asi:
● nginx.service – nginx – high performance web server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled)
Active: active (running) since mié 2020-09-30 12:17:03 CEST; 22h ago
Docs: http://nginx.org/en/docs/
Process: 51311 ExecStop=/bin/kill -s TERM $MAINPID (code=exited, status=0/SUCCESS)
Process: 51870 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)
Main PID: 51871 (nginx)
CGroup: /system.slice/nginx.service
├─51871 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
└─51872 nginx: worker process
- Para parar , arrancar y reiniciar el servicio nginx , las instrucciones son como en el resto de servicios :
- /etc/init.d/nginx start
- /etc/init.d/nginx stop
- /etc/init.d/nginx restart
Configuración básica del servidor nginx
En mi caso la configuración básica se sitúa en el archivo /etc/nginx/conf.d/default.conf. Aunque se puede configurar como en apache con sites, y tener sitios activos o inactivos y habilitarlos o deshabilitarlos.
La configuración siempre inicia con la palabra server, sería algo asi:
server {
listen 80 default_server;
server_name nombre del dominio;
}
Si queremos habilitar ssl tenemos que incluir que se escuche también en el puerto 443 con la sentencias:
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
Y posteriormente añadir las rutas a los certificados ssl con
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
ssl_certificate /etc/letsencrypt/live/linuxowindows.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/linuxowindows.com/privkey.pem;
Posteriormente añadir lo que en nginx se llaman locations, o localizaciones de las diferentes rutas.
En este caso location / hará referencia a la raíz del dominio, si el dominio es linuxowindows.com , la sentencia location / hará referencia al dominio linuxowindows.com
location / {
}
Y ahí incluiremos la ruta donde se encuentren nuestras páginas en el sistema de ficheros local, o si queremos habilitar un proxy inverso o si queremos modificar algún tipo de cabecera para evitar crossdomain,…
Por ejemplo en mi caso debía habilitar las cabeceras X-Forwarded ,… para que se redirigiera todo lo que viniera del puerto 8081 a este por defecto y que saliera por el dominio principal, pues tuve que añadir dentro del location lo siguiente:
proxy_pass http://localhost:8081;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
Si quisiera configurar un proxy inverso para que una carpeta o ruta determinada de mi dominio saliera se encaminara y se mostrará hacia otro servidor o otra ruta, de nuevo lo podemos hacer con locations. Configuraremos así:
location /ruta_nueva/ {
proxy_pass http://<direccion_IP_servidor_remoto>:5000/ruta_nueva_que_queremos_llamar/;
}
De esta manera las peticiones realizadas a nuestro dominio www.linuxowindows.com/ruta_nueva/ serían una llamada al servidor remoto que queramos y a la ruta determinada que queramos. Mucho más sencillo que en apache, donde había que configurar el proxy pass y el proxy pass reverse dos directivas dentro de un virtualhost.
En definitiva, que funciona muy bien.