Archivo de la categoría: Trabajos Fin de Grado

Instalación de nginx como proxy de apache en centos 6 y virtualmin

En este artículo vamos a ver la instalación paso a paso de un servidor nginx para mejorar las prestaciones de nuestro servidor web apache.

El objetivo es que todas las peticiones las sirva el servidor nginx, de forma que el contenido estático lo servirá directamente mientras que el contenido dinámico (por ejemplo páginas php las solicitará al servidor apache y las servirá como un proxy).

Todo esto lo vamos a hacer sobre nuestro sistema centos 6.5 controlado por un panel virtualmin.

1. Instalación de nginx en centos 6.

Lo mejor para esta instalación es seguir las instrucciones de nginx.org (http://nginx.org/en/linux_packages.html#stable)

Descargamos e instalamos el package ngnix release:
# wget http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
# rpm -Uvh nginx-release-centos-6-0.el6.ngx.noarch.rpm

Ahora podemos instalar ngnix con yum, Primero verificamos que tenemos las últimas versiones estables con:
# yum list nginx

Available Packages
nginx.x86_64 1.4.5-1.el6.ngx

Instalamos:
# yum install nginx

A continuación vamos a instalar mod_rpaf, un módulo de apache que hace que interprete correctamente las direcciones que vienen de un proxy. (Referencia: http://www.ctkn.net/2011/10/install-mod_rpaf-on-centos-5-centos-6/)

Primero instalamos el paquete httpd-devel

# yum install httpd-devel

Ahora descargamos el paquete mod_rpaf

# cd /usr/local/src
# wget http://mirror.trouble-free.net/sources/mod_rpaf-0.6.tar.gz
# tar xzvf mod_rpaf-0.6.tar.gz
# cd mod_rpaf-0.6

Lo compilamos e instalamos con:

# apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c

Ahora hemos de crear el archivo de configuración /etc/httpd/conf.d/mod_rpaf.conf

# vi /etc/httpd/conf.d/mod_rpaf.conf

con el siguiente contenido:

LoadModule rpaf_module modules/mod_rpaf-2.0.so
# mod_rpaf Configuration
RPAFenable On
RPAFsethostname On
RPAFproxy_ips 127.0.0.1 xxx.xxx.xxx.xxx
RPAFheader X-Forwarded-For

Cambiando xxx,xxx,xxx,xxx por la IP de nuestro servidor (si tiene varias las podemos poner todas o por lo menos la que utilice de salida).

El siguiente paso es cambiar los puertos de escucha de apache del 80 al 9080 y del 443 al 9443 por ejemplo. La idea es dejar libres el puerto 80 y el 443 para el nginx y mantener el apache activo en puertos alternativos.

El archivo de configuración es /etc/httpd/conf/httpd.conf y las líneas donde aparecen los puertos son:

Listen 80 ==> Listen 9080
NameVirtualHost xxxxx:80 ==> NameVirtualHost xxxxx:9080
NameVirtualHost xxxxx:443 ==> NameVirtualHost xxxxx:9443

Hay que cambiar todas las líneas que tengan este formato. Además en el archivo /etc/httpd/conf/ssl.conf

Listen 443 ==> Listen 9443

Con esto cambiamos todas las webs que ya tengamos configuradas, ahora es necesario actualizar las plantillas para que cuando creemos nuevas web (servidores virtuales en la terminología de virtualmin) tengamos esto correctamente configurado.

Para ello vamos al interfaz de virtualmin –> System Settings –> Plantillas de Servidor

Y elegimos la plantilla «Default Settings» y vamos a la sección «Sitio web Apache»

En esta ventana tenemos que configurar los puertos de acceso:

Ahora en la seccion de «Rotación de archivos de bitácora» debemos incluir los archivos de log adicionales y un script para que reinicie adeuadamente los servidores después de la rotación. Debe quedar así:

La información que hay que poner es:

Directivas de logrotate para nuevos servidores:

 rotate 5
 weekly
 compress
 postrotate
 [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
 /etc/rc.d/init.d/httpd graceful ; sleep 5
 endscript
 sharedscripts

Additional files to rotate:

/var/log/virtualmin/${DOM}_apache_access_log
/var/log/virtualmin/${DOM}_nginx_error_log

Los archivos de log

Antes de seguir con las instrucciones de configuración vamos a comentar como hacer para que coexistan los archivos de log que generan los servidores web.

Tanto nginx como apache generan un archivo de log de accesos y otro de errores. Si utilizamos como ejemplo un dominio denominado xxxx.com el nombre del archivo de log que asigna virtualmin para apache es /var/log/virtualmin/xxxx.com_access_log y
/var/log/virtualmin/${DOM}_error_log respectivamente, y utiliza este nombre de archivo de acceso para configurar el software de estadísticas gráficas awstat y webalizer.

Sin embargo, puesto que nginx es el servidor web que recibe directamente toas las peticiones del exterior y a apache sólo le llegan algunas, esta configuración no es correcta y el software de estadísticas no tendrá toda la información.

Para resolver esto de forma sencilla, lo que vamos a hacer es crear el servidor virtual con virtualmin y dejarle que lo configure así, y luego editar manualmente el archivo de configuración de apache para que se llame  /var/log/virtualmin/xxxx.com_apache_access_log de forma que configuraremos nginx para que su archivo de log se llame  /var/log/virtualmin/xxxx.com_access_log (que es el que usará el software de estadísticas).

El archivo de error no es relevante para las estadísticas por lo que podemo dejarlo como lo configura virtualmin y el archivo de error de nginx le llamaremos /var/log/virtualmin/xxxx_nginx_error_log

Configuración de nginx

A continuación vamos a presentar los 3 archivos de configuración de nginx que necesitamos para que el sistema funcione. El primero es el archivo de configuración principal /etc/nginx/nginx.conf que ya viene preconfigurado, pero que vamos a modificar para activar la compresión web y algún parámetro adicional. La propuesta es:

user apache;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
 worker_connections 1024;
}

http {
 include /etc/nginx/mime.types;
 default_type application/octet-stream;

 log_format main '$remote_addr - $remote_user [$time_local] "$request" '
 '$status $body_bytes_sent "$http_referer" '
 '"$http_user_agent" "$http_x_forwarded_for"';

 access_log /var/log/nginx/access.log main;

 sendfile on;
 #tcp_nopush on;
 tcp_nodelay on;

 gzip on;
 gzip_http_version 1.1;
 gzip_vary on;
 gzip_comp_level 6;
 gzip_proxied any;
 gzip_min_length 1100;
 gzip_buffers 4 32k;
 gzip_types text/plain text/css application/json application/javascript application/x-javascript text/javascript text/xml application/xml application/rss+xml application/atom+xml application/rdf+xml
 gzip_disable "MSIE [1-6]\.(?!.*SV1)";

 keepalive_timeout 65;

 include /etc/nginx/conf.d/*.conf;
}

El siguiente archivo lo creamos nosotros para especificar las características de la conexión proxy con el servidor apache y lo incluiremos posteriormente desde los archivos específicos de las webs. El archivo es /etc/nginx/proxy.conf y este es su contenido:

proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 4G;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;

Por último, por cada web que tengamos tenemos que crear un archivo de configuración en el directorio /etc/nginx/conf.d

A modo de ejemplo vamos a suponer que nuestro dominio es xxxx.com, que el directorio home es /home/xxxx y que la ip es aaa.bbb.ccc.ddd, además vamos a configurarlo para acceder por https y haremos que los accesos por http se redireccionen de forma automáticas a https. Es bastante fácil a partir de aquí hacer una versión sin https.

El archivo será /etc/nginx/conf.d/xxxx.com.conf y este es su contenido:

server {
 listen aaa.bbb.ccc.ddd:80;
 server_name www.xxxx.com xxxx.com;

 # Strict Transport Security
 add_header Strict-Transport-Security max-age=2592000;

 rewrite ^(.*) https://www.xxxx.com$1 permanent;
}

server {
 # server port and name
 listen aaa.bbb.ccc.ddd:443;
 server_name www.xxxx.com xxxx.com;
 client_max_body_size 4G;
 root /home/xxxx/public_html;

 # ssl certificate files
 ssl on;
 ssl_certificate /home/xxxx/ssl.cert;
 ssl_certificate_key /home/xxxx/ssl.key;

 # add ssl specific settings
 keepalive_timeout 60;

 # limit ciphers
 ssl_ciphers HIGH:!ADH:!MD5;
 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
 ssl_prefer_server_ciphers on;

 access_log /var/log/virtualmin/xxxx.com_access_log;
 error_log /var/log/virtualmin/xxxx.com_nginx_error_log;

 location / {
 proxy_pass http://aaa.bbb.ccc.ddd:9080;
 include /etc/nginx/proxy.conf;
 }

 location = /robots.txt {
 allow all;
 log_not_found off;
 access_log off;
 break;
 }


 location ~* ^.+\.(js|jpeg|jpg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mp3|htm|html|xml)$ {
 expires 30d;
 root /home/xxxx/public_html;
 }

 location ~ /\.ht {
 deny all;
 }
}

Sólo necesitamos reiniciar nginx para tener la web funcionando:

# service nginx restart

Mejoras futuras

Añadir nuevas webs (servidores virtual) es incómodo ya que después de crear la web con el virtualmin hay que hacer bastantes modificaciones de forma manual. Lo ideal sería hacer que todo el proceso sea automático. En estos momentos tengo un Trabajo Fin de Grado en marcha para desarrollar esto.

Otra posibilidad es utilizar varnish como proxy en lugar de nginx (o en colaboración con nginx), aunque el mayor handicap de varnish es la ausencia de soporte para https. También tengo otro TFG sobre este tema.

También es interesante la posibilidad de personalización de los archivos de configuración de nginx para cada web y optimizarlo para las aplicaciones específicas de la web como por ejemplo wordpress o prestashop.

Referencias