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.



<Volver a Página de NGINX>