Configuraciones básicas de NGINX contra backend Apache
En esta sección se describen 3 configuraciones básicas de NGINX para atacar a un backend Apache.
- La primera se encarga de servir todos los ficheros estáticos excepto los ficheros de extensión .php.
- La segunda utiliza la directiva try_files (a partir de nginx 0.7) para verificar si existe el fichero. Si existe, lo sirve directamente y si no, en lugar de devolver un 404, lo pasa al backend (por si la URL es en realidad un "rewrite" de algo que se genera dinámicamente).
- La tercera hace un intento de fallback doble (primero try_files del document_root, si no, fallback a un try_files de una ruta NFS y si no, fallback al Apache). Este tipo de configuraciones se utiliza en CMSs como EZ Publish.
- Finalmente, se muestra la configuración a realizar en Apache para mostrar la IP real del visitante en lugar de la IP de nginx (127.0.0.1).
Las 3 configuraciones hacen uso de un nginx.conf y proxy.conf común, que se muestra a continuación:
# cat /etc/nginx/nginx.conf user www-data; worker_processes 2; worker_rlimit_nofile 65535; error_log /var/log/nginx/error.log; pid /var/run/nginx.pid; events { worker_connections 10240; use epoll; } http { include /etc/nginx/mime.types; access_log /var/log/nginx/access.log; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 10; tcp_nodelay on; gzip on; gzip_comp_level 2; gzip_proxied any; gzip_types text/plain text/css application/x-javascript ç text/xml application/xml application/xml+rss text/javascript; gzip_disable msie6; include /etc/nginx/sites-enabled/*; include /etc/nginx/conf.d/*.conf; }
# cat /etc/nginx/proxy.conf # Standard proxy settings 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 10m; client_body_buffer_size 128k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 16k; proxy_buffers 32 64k; proxy_busy_buffers_size 128k;
Configuración NGINX básica con proxypass
Ejemplo de configuración básica para entorno "LAMP": NGINX intentará servir todo el contenido del document_root excepto los ficheros de extensión .php:
# cat /etc/nginx/sites-enabled/default server { listen 80; server_name dominio.com; access_log /var/log/nginx/dominio.access.log; root /var/www/dominio/; index index.php index.html; # Scripts en PHP: location ~ "\.php$" { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include /etc/nginx/fastcgi_params; } }
Configuración NGINX proxy inverso Apache try_files
La siguiente configuración permite que NGINX v0.7.0 o superior atienda las peticiones HTTP y sirva directamente los contenidos estaticos. Para los contenidos no estáticos o los ficheros que no se encuentren, se realiza un proxy-pass contra Apache:
$ cat /etc/nginx/sites-enabled/000-dominio.com.conf server { listen 80; server_name www.dominio.com dominio.com; access_log /var/log/nginx/dominio.com.access.log; error_log /var/log/nginx/dominio.com.error.log; root /var/www/; index index.php index.html; error_page 403 404 503 = http://www.dominio.com/404.html; # URIs que queremos servir directamente, contenido estático: location ~ ^/(web_html1|web_html2|web_html3)($|/$|/.*) { root /var/www/webs_html/; index index.html index.htm; break; } # Servir los contenidos estáticos sólo si están presentes: location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls| exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|htm|html| swf|flv|xml|wml|xhtml)$ { try_files $request_uri $request_uri/ @backend; } # Si no se encontraron esos contenidos estáticos, pasarlos al backend Apache: location @backend { proxy_pass http://127.0.0.1:81; include /etc/nginx/proxy.conf; } # Resto de la web que no sea contenido estatico o no exista, pasarlo al backend Apache: location / { proxy_pass http://127.0.0.1:81; include /etc/nginx/proxy.conf; } }
Configuración NGINX doble fallback try-files + NFS + apache
server { listen 80; server_name servidor.dominio.com; access_log /var/log/nginx/wwwuser01.access.log; error_log /var/log/nginx/wwwuser01.error.log; root /var/www/website/; index index.php index.html; include /etc/nginx/phpmyadmin.conf; location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls| exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|htm|html| swf|flv|xml|wml|xhtml)$ { root /var/www/website/; try_files $request_uri $request_uri/ @backend_NFS; } location @backend_NFS { root /nfs_import/; try_files $request_uri $request_uri/ @backend_APACHE; } location @backend_APACHE { proxy_pass http://127.0.0.1:81; include /etc/nginx/proxy.conf; } # Resto de la web que no sea contenido estatico o no exista: location / { proxy_pass http://127.0.0.1:81; include /etc/nginx/proxy.conf; } }
Configuración a realizar en Apache
Instalar Apache en el puerto 81 y realizar una configuración con este formato de logs:
$ grep -i Listen /etc/apache2/ports.conf Listen 81 $ cat /etc/apache2/sites-enabled/dominio.com.conf NameVirtualHost * <VirtualHost *> DocumentRoot "/var/www" ServerName www.dominio.com; ServerAlias dominio.com; (...) # Lineas largas partidas para lectura - unirlas LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" proxy:%h" proxy SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" proxied CustomLog /var/log/apache2/www.dominio.com-access.log combined env=!proxied CustomLog /var/log/apache2/www.dominio.com-access.log proxy env=proxied ErrorLog /var/log/apache2/www.dominio.com-error.log </VirtualHost>
Gracias a estas líneas de configuración, Apache mostrará la IP real de origen así como un campo original con la IP del proxy:
A.B.C.D - - [30/Mar/2010:11:38:04 +0200] "GET /destacados/home/a.jpg HTTP/1.0" 200 1013 "-" "Mozilla/5.0 (X11; U; Linux x86_64; es-ES; rv:1.9.2) Gecko/20100301 Ubuntu/9.10 (karmic) Firefox/3.6" proxy:127.0.0.1
Otra opción (no necesaria ni recomendada, ya que es suficiente con las directivas de log anteriormente descritas) es instalar mod_rpaf para que Apache logue la cabecera X-Forwarded-For en lugar de !Remote_IP:
# apt-get install libapache2-mod-rpaf # cat /etc/apache2/mods-enabled/rpaf.conf <IfModule mod_rpaf.c> RPAFenable On RPAFsethostname On RPAFproxy_ips 127.0.0.1 </IfModule>
Por otra parte, nginx logará todas las peticiones, incluídas aquellas de las que hace ProxyPass, con lo cual podemos sacar estadísticas awstats directamente de los logs de NGINX.