Cuando optimizas tu servidor para intentar sacar el máximo rendimiento, es normal que termines instalando alguna solución de caché además de las que nos ofrecen php o los cms que uses como por ejemplo Varnish. El problema es que por una mala configuración puedes encontrarte con que el log de apache devuelve 127.0.0.1 en lugar de la ip del cliente.
¿Por qué aparece 127.0.0.1 en el log de apache y $_SERVER[ ‘REMOTE_ADDR’ ]?
Como comentaba antes no es algo demasiado complicado de solucionar, ya que es una simple falta de configuración un poco más en profundidad de tu servidor. La respuesta es bastante sencilla, y se centra en el funcionamiento a nivel interno del servicio de caché que estemos utilizando, en este caso Varnish Cache.
Esto ocurre por lo siguiente, Varnish recoge la solicitud del cliente, y hace una petición al servidor de apache desde el servicio local, es decir, desde el servidor interno de varnish para nuestra máquina. Estas solicitudes locales se interpretan como 127.0.0.1 que es el servidor local donde está funcionando varnish, y por tanto apache ve esta ip como ip de la solicitud.
Cómo solucionar el error en los logs 127.0.0.1 con varnish cache 4
Lo que vamos a intentar es conseguir que en el log de apache aparezca la ip del cliente. También vamos a hacer que en php cuando usamos la variable $_SERVER[ ‘REMOTE_ADDR’ ] nos aparezca la ip del cliente remoto y no 127.0.0.1.
Como nos vamos a centrar en la solución para varnish, y no para nginx en este caso, pasará por configurar unos parámetros tanto en el servicio de varnish, como en apache y en php, por lo que vas a necesitar acceso completo al servidor así como permisos de administración.
Vamos a editar el archivo default.vlc de varnish y nos centraremos en la sección que indica vcl_recv {} , por tanto, si tienes la configuración en otro fichero será ese el que tendrás que editar.
Por si acaso siempre es recomendable antes de editar este tipo de archivos hacer una copia de seguridad por ejemplo:
cp /etc/varnish/default.vlc /etc/varnish/default.vlc.bkp
Y ahora ya procedemos a editar el archivo
nano /etc/varnish/default.vcl
Y dentro de vcl_recv{} añadiremos el siguiente código
vcl_recv{ /*Aquí puede haber más código que tengas añadido, simplemente agregas esta porción debajo*/ if (req.restarts == 0) { if (req.http.x-forwarded-for) { set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; } else { set req.http.X-Forwarded-For = client.ip; } } }
Asegúrate de añadir solo la porción de código que hemos resaltado evitando borrar cualquier otra configuración que tengas en la sección vcl_recv.
Con este código lo que hemos conseguido es que cuando un cliente haga una solicitud, los datos del que solicita la página sean redireccionados a través de Varnish hasta el servidor de apache, pero ahora nos falta otro paso.
Tienes que editar el archivo de configuración de tu virtualhost para el dominio en el que quieras que se puedan utilizar las ips que acabamos de redireccionar arriba, ya que si no apache seguirá interpretando la ip de varnish como la del solicitante. Simplemente configuraremos el log para que en lugar de usar la ip de varnish use la ip forwarded en los logs.
Abre tu archivo de configuración de virtualhost
nano /etc/httpd/conf.d/mivirtualhost.conf
Y añadiremos o modificaremos las líneas LogFormat y CustomLog con las del siguiente código (las resaltadas)
<VirtualHost *:8080> ServerAdmin [email protected] DocumentRoot /var/www/www.example.com ServerName www.example.com ErrorLog /var/log/httpd/example.com-error_log LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" varnish CustomLog /var/log/httpd/midominio.com_log varnish </VirtualHost>
- CustomLog: se encarga de indicar donde se tiene que crear el log de este dominio, podemos poner la ruta y archivo que mejor se adapte a nuestra configuración y ahí lo escribirá, asegúrate de que tenga permisos de escritura el servidor de apache, o ponlo en la carpeta logs, o en la del dominio (que no sea visible en la web).
- LogFormat: es el formato que le vamos a dar a cada línea del log, es decir, configurando lo que queremos que nos muestre.
- %{X-Forwarded-For}i : es la ip que nos transfiere varnish del cliente
- %l %u %t \»%r\» %>s %b : fecha en formato día mes año hora
- \»%{Referer}i\» : página de referencia y tipo de solicitud
- \»%{User-Agent}i\ : navegador o agente que se ha utilizado para acceder a la página
A partir de este momento si guardas y reinicias los servicios de varnish y apache empezarás a ver los datos correctamente en el log del dominio, pero aún queda solucionar el 127.0.0.1 en php. Además plantéate deshabilitar el log general de apache si configuras cada dominio con su log personalizado.
Cómo arreglar el 127.0.0.1 en php con Varnish Cache 4
Esto es algo opcional, pero seguro que te sonará el problema de que tienes un foro, o un sistema de gestión de contenido o CMS, y todos los usuarios que se registran, escriben o trabajan con tu web tienen la misma ip 127.0.0.1. Pues este problema es exactamente el mismo que antes, solo que es en php a la hora de recibir los datos del cliente de varnish.
Para solucionarlo en php tendremos que, o bien añadir el código de abajo en la primera línea de todos los archivos php que tengamos (o en el config.php), y esto puede ser una locura, sobretodo si usas WordPress, Joomla o alguno de estos, ya que en alguna actualización te podría dejar de funcionar. En lugar de eso vamos a configurar el servidor php para que siempre lo incluya antes de cargar cualquier script.
Tranquilo, no deberías notar ninguna diferencia en el rendimiento ya que simplemente vamos a cambiar una variable por otra. Tendremos que hacer lo siguiente para que aparezcan bien la ip del cliente en $_SERVER[“REMOTE_ADDR”].
Recuerda seguir los pasos de más arriba antes de estos, sino no te funcionará. Crea el archivo varnish_client_ip.php en la carpeta de configuración de apache por ejemplo
nano /etc/httpd/conf.d/varnish_client_ip.php
y pones dentro el siguiente código
<?php if( isset( $_SERVER[ 'HTTP_X_FORWARDED_FOR' ] ) ) { $HTTP_X_FORWARDED_FOR = explode(',', $_SERVER[ 'HTTP_X_FORWARDED_FOR' ]); $_SERVER[ 'REMOTE_ADDR' ] = $HTTP_X_FORWARDED_FOR[0]; }
No te preocupes por que no haya una etiqueta de cierre de php, así nos aseguramos que no nos de errores como «headers already sent by» o similares.
Lo que hace el código es recoger la variable que nos está enviando Varnish, que tiene el nombre $_SERVER[ ‘HTTP_X_FORWARDED_FOR’ ], revisa que existe y va a reemplazar el contenido de $_SERVER[ ‘REMOTE_ADDR’ ] con la ip del cliente que sacamos del primer valor del arra.
¿Por qué tanto lío? Muy fácil, por que todos los sistemas cms que puedas instalar van a usar $_SERVER[ ‘REMOTE_ADDR’ ], y por tanto tenemos que reajustar el contenido de dicha variable para no tener que modificar el código de cada archivo que la use.
No va a ser suficiente con esto, ya que ahora lo que vas a hacer es decirle al servicio de php que tiene que coger este archivo y ponerlo lo primero cada vez que vaya a ser ejecutado, de esta forma nos aseguramos de que siempre esté ahí y no tener que modificar nuestros scripts. Necesitarás acceso al archivo php.ini y lo editaremos:
nano /etc/php.ini
Y editaremos la directiva auto_prepend_file, añadiremos la ruta al archivo que acabamos de crear
auto_prepend_file = "/etc/httpd/conf.d/varnish_client_ip.php"
Esto lo que hace es cargar este archivo lo primero en cada consulta php, y como en el archivo lo que hemos hecho es sustituir el contenido del remote_addr por el del http_x_forwarded_for que es la ip real, podremos usar esa función para recoger la ip del cliente o usuario y los CMS empezarán a mostrarla correctamente.
Una vez hecho esto debes reiniciar también el servidor apache para que todo se quede en orden.
service httpd restart
Si has seguido alguno de los pasos de forma diferente, o en tu distribución había que modificar algo más te agradecería dejases un comentario con los pasos para ayudar a otros usuarios.
¿Has tenido que llegar hasta aquí? ¿Te ha empezado a mostrar correctamente las ips?