# ¿Conexión ADSL lenta? Mejora la velocidad de tu conexión a Internet (Capítulo III de III)

> Índice:
>
> 19/07/2009 - [Capítulo I - Revisar y mejorar la instalación telefónica de nuestra casa](/conexion-adsl-lenta-mejora-la-velocidad-de-tu-conexion-a-internet-capitulo-1 "Capítulo I")  
> 21/07/2009 - [Capítulo II - Parámetros y configuraciones de ADSL, cómo configurar el router para sacar el mayor partido a tu ADSL](/conexion-adsl-lenta-mejora-la-velocidad-de-tu-conexion-a-internet-capitulo-2 "Capítulo II")  
> 28/07/2009 - [Capítulo III - Cuando no hay pan, buenas son migas. Si tu conexión es lenta, te interesará saber cómo cachear contenidos para acelerar la conexión a Internet](/conexion-adsl-lenta-mejora-la-velocidad-de-tu-conexion-a-internet-capitulo-3 "Capítulo III")

Para terminar, en esta última entrega hablaremos sobre como intentar hacer un uso eficiente del ancho de banda. La idea general es, teniendo una conexión a internet lenta, tratar de hacer el menor número de peticiones hacia ella y utilizar contenido cacheado para ahorrar ancho de banda.

Para racionar el uso de ancho de banda entre cualquier protocolo, tal y como mencionaba en el anterior capítulo, puede conseguirse usando [QoS](http://es.wikipedia.org/wiki/QoS "Calidad de Servicio en la Wikipedia"). En este capítulo vamos a centrarnos en mejorar la navegación Web especialmente, ya que es uno de los principales usos que le daremos a nuestra conexión.

Para conocer como mejorar la navegación debemos conocer como funciona nuestro navegador (en resumidas cuentas):

1. Tecleamos una dirección web en la barra de direcciones.
2. El navegador tiene que utilizar el protocolo DNS ([Domain Name System](http://es.wikipedia.org/wiki/Domain_Name_System "DNS en la Wikipedia")) para resolver que ordenador es el que maneja ese dominio.
3. Tras conocer la IP del ordenador, se conecta a él y hace una petición HTTP ([Hyper Text Transfer Protocol](http://es.wikipedia.org/wiki/Http "HTTP en la Wikipedia")) para obtener el contenido de la página.
4. Si la página posee imágenes o enlaces, deberá solicitarlas al mismo servidor (o a otro externo) volviendo al punto 2. Si se trata del mismo servidor generalmente no necesita volver a resolver la IP.

[![Ejemplo peticion DNS y HTTP](https://reprogramador.es/images/2009/07/dns.webp)](https://reprogramador.es/images/2009/07/dns.webp)

En una página web típica como podría ser la web de [Marca](http://www.marca.com "Marca.com"), puede haber más de 120 imágenes estáticas repartidas entre varios servidores de contenidos (estaticos[01,02,03,04,05].marca.com), enlaces de publicidad, vídeos, etc...

Esto implica que el navegador tendrá que resolver cada uno de los dominios que alojan los contenidos y tendrá que ir conectándose a cada uno para solicitar los datos y finalmente componer la página web final.

Si hacemos cuentas, una resolución DNS suele tardar alrededor de unos 100 milisegundos (dependiendo de la carga de la red y del servidor), si la web hace referencia a unos 30 dominios distintos, sólo en resoluciones DNS se perderán 3 segundos. Después tiene que conectarse a cada servidor y hacer más de 120 peticiones, añadiendo al propio retraso de la transferencia de las imágenes un pequeño retraso en el manejo del protocolo HTTP.

En definitiva, la web no carga rápidamente. Muchos navegadores son muy competentes y para solucionar esto hacen lo que se llama *cacheo de contenidos*, es decir, almacenan durante algún tiempo los dominios ya resueltos y el contenido estático para no tener que volver a solicitarlo al servidor.

El protocolo HTTP implementa una serie de controles para marcar la caducidad de los contenidos, el problema es que en muchos casos las páginas web son dinámicas y usan trucos anti-cache para asegurarse de que el contenido que recibe el cliente sea fresco, a costa de consumir un mayor ancho de banda y ralentizar la carga.

Lo que voy a explicar a continuación es cómo montar un servidor DNS local y un proxy caché web. El servidor DNS local nos permitirá hacer cache de las resoluciones DNS durante más tiempo, además, si tenemos una red con varios equipos ahorraremos peticiones desde éstos.

[![Proxy Cache Web HTTP](https://reprogramador.es/images/2009/07/Proxy_HTTP.webp)](https://reprogramador.es/images/2009/07/Proxy_HTTP.webp)

En mi caso tengo montado un equipo en red actuando como servidor de ficheros, proxy web, cache DNS, etc... usando [debian GNU/Linux](http://www.debian.org "debian"). No es estrictamente necesario tener un equipo destinado exclusivamente como servidor, aunque si te gusta experimentar seguramente podrás conseguir un ordenador entre 400 y 800 Mhz que cumpla con la tarea. Existen más programas que los utilizados en este post, inclusive para Windows, así que si no te convence alguno siempre puedes utilizar otro que se ajuste más a tus necesidades.

Como caché de DNS voy a utilizar [dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html "dnsmasq WebSite"), que es un pequeño servidor DNS ligero que implementa caché de DNS por defecto y está en los repositorios de debian:

```
apt-get install dnsmasq dig
```

Ni siquiera es necesario modificar la configuración por defecto, a menos que queramos que escuche en una interfaz determinada. Además nos da una serie de configuraciones interesantes:

```
vi /etc/dnsmasq.conf

address=/doubleclick.net/127.0.0.1
address=/router/192.168.1.1
```

Podemos bloquear ciertos dominios que sabemos que sólo aportan publicidad para que el navegador no consiga conectarse a ellos, también podemos asignar un nombre de dominio a nuestro router o, si tenemos un dominio propio, hacer que los equipos de dentro de la red resuelvan la IP local del servidor en lugar de la de Internet.

Modificamos el archivo */etc/resolv.conf* para utilizar nuestro servidor DNS:

```
nameserver 127.0.0.1
```

Y probamos que funcione:

```
jdf@debian:/tmp$ date
 Tue Jul 28 12:21:16 CEST 2009
 jdf@debian:/tmp$ dig terra.es

; <<>> DiG 9.5.1-P2 <<>> terra.es
 ;; global options:  printcmd
 ;; Got answer:
 ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51021
 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
 ;terra.es.            IN    A

;; ANSWER SECTION:
 terra.es.        24419    IN    A    213.4.130.210

;; Query time: 72 msec
 ;; SERVER: 127.0.0.1#53(127.0.0.1)
 ;; WHEN: Tue Jul 28 12:21:25 2009
 ;; MSG SIZE  rcvd: 42

jdf@debian:/tmp$ date
 Tue Jul 28 12:22:18 CEST 2009
 jdf@debian:/tmp$ dig terra.es

; <<>> DiG 9.5.1-P2 <<>> terra.es
 ;; global options:  printcmd
 ;; Got answer:
 ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 84
 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
 ;terra.es.            IN    A

;; ANSWER SECTION:
 terra.es.        24363    IN    A    213.4.130.210

 ;; Query time: 4 msec
 ;; SERVER: 127.0.0.1#53(127.0.0.1)
 ;; WHEN: Tue Jul 28 12:22:21 2009
 ;; MSG SIZE  rcvd: 42

jdf@debian:/tmp$
```

Indiscutiblemente, mucho mejor con el cache DNS. 🙂

El proxy caché web que vamos a utilizar es [squid](http://www.squid-cache.org/ "squid proxy cache"). También está disponible en los repositorios de debian  e incluso hay versiones portadas a Windows. Se trata de un proxy HTTP altamente configurable y muy utilizado a nivel empresarial.

squid es muy flexible, nos permite hacer un proxy HTTP que no haga cache (sólo para controlar que páginas se visitan y generar estadísticas de uso) o incluso un servidor proxy caché transparente (que cachea todo el contenido de forma transparente para el usuario final, almacenando el contenido incluso durante más tiempo que el indicado por el servidor).

En nuestro caso queremos cachear todo el contenido estático de la web, en general, la mayor parte de las páginas no suelen modificar las imágenes que ya tienen sino que añaden imágenes nuevas o las sustituyen. Existen páginas web que generan contenido dinámico (misma imagen renombrada cada vez que se pide, por ejemplo) evitando que podamos cachearlo. Un ejemplo perfecto de web incacheable es [Youtube](http://www.youtube.com "Youtube") 🙁.

Instalamos el servidor squid y una utilidad para ver como está procesando las peticiones:

```
apt-get install squid squidview
```

Y procedemos a configurarlo:

```
vi /etc/squid/squid.conf
```

> # Primero configuramos el puerto donde va a escuchar el servidor y le indicamos que queremos utilizar un proxy transparente
>
> http\_port 8080 transparent  
> icp\_port 3130
>
> # Las ACL (Access lists, Listas de Acceso) definen grupos de IPs a las que se le aplicarán determinados permisos, es crucial tener bien definida la siguiente:
>
> acl all src 0.0.0.0-0.0.0.0/0.0.0.0
>
> # Definimos los nuevos periodos de refresco segun el dominio o el tipo de contenido, probablemente no es la mejor configuración, la modifiqué de otra que encontré en la web en su momento.
>
> # Por defecto el contenido se cacheará durante una semana, ampliable hasta un mes segun el caso
>
> # los modificadores añadidos al final significan lo siguiente:
>
> # override-lastmod -> Ignorar la fecha de última modificación,se utilizará la indicada en la configuración
>
> # override-expire -> Ignorar la fecha de caducidad indicada por el servidor
>
> # ignore-private -> Ignorar las etiquetas que indican que el contenido es privado, se cacheará de todas formas
>
> # reload-into-ims -> Las peticiones que fuerzan la recarga de la página (Control + F5 en Internet Explorer ó Control + Shift + R en Mozilla Firefox) se convierten en peticiones If-Modified-Since, es decir, sólo actualizará si el contenido se ha modificado desde la última vez.
>
> # ignore-reload -> Se ignoran las peticiones de recarga forzada de la página
>
> refresh\_pattern windowsupdate.com/.*.(cab|exe) 4320 100% 43200  
> refresh\_pattern download.microsoft.com/.*.(cab|exe) 4320 100% 43200  
> refresh\_pattern ^http://.*.cnn.com 360 50% 4320 override-lastmod  
> refresh\_pattern ^http://news.bbc.co.uk 360 50% 4320 override-lastmod  
> refresh\_pattern microsoft 1080 150% 10080 override-lastmod  
> refresh\_pattern msn.com 4320 150% 10080 override-lastmod  
> refresh\_pattern ^http://.*.doubleclick.net 10080 300% 40320 override-lastmod override-expire ignore-private reload-into-ims ignore-reload  
> refresh\_pattern ^http://.*.google-analytics.com 10080 300% 40320 override-lastmod override-expire ignore-private reload-into-ims ignore-reload  
> refresh\_pattern ^http://.*FIDO 360 1000% 480  
> refresh\_pattern .r[0-9][0-0]$ 10080 150% 40320  
> refresh\_pattern ^http://.*.gif$ 1440 50% 20160 ignore-no-cache override-lastmod ignore-private reload-into-ims ignore-reload  
> refresh\_pattern ^http://.*.asis$ 1440 50% 20160  
> refresh\_pattern -i .pdf$ 10080 90% 43200  
> refresh\_pattern -i .art$ 10080 150% 43200  
> refresh\_pattern -i .avi$ 10080 150% 40320  
> refresh\_pattern -i .mov$ 10080 150% 40320  
> refresh\_pattern -i .wav$ 10080 150% 40320  
> refresh\_pattern -i .mp3$ 10080 150% 40320  
> refresh\_pattern -i .qtm$ 10080 150% 40320  
> refresh\_pattern -i .mid$ 10080 150% 40320  
> refresh\_pattern -i .viv$ 10080 150% 40320  
> refresh\_pattern -i .mpg$ 10080 150% 40320  
> refresh\_pattern -i .flv$ 10080 150% 40320 ignore-no-cache override-expire ignore-private reload-into-ims ignore-reload  
> refresh\_pattern -i .swf$ 10080 150% 40320 override-lastmod ignore-no-cache override-expire reload-into-ims ignore-reload  
> refresh\_pattern -i .jpg$ 10080 150% 40320 override-lastmod ignore-no-cache ignore-private reload-into-ims ignore-reload  
> refresh\_pattern -i .rar$ 10080 150% 40320  
> refresh\_pattern -i .ram$ 10080 150% 40320  
> refresh\_pattern -i .gif$ 10080 300% 40320 override-lastmod ignore-no-cache ignore-private reload-into-ims ignore-reload  
> refresh\_pattern -i .txt$ 1440 100% 20160  override-lastmod ignore-no-cache ignore-private reload-into-ims ignore-reload  
> refresh\_pattern -i .zip$ 2880 200% 40320  
> refresh\_pattern -i .arj$ 2880 200% 40320  
> refresh\_pattern -i .exe$ 2880 200% 40320  
> refresh\_pattern -i .tgz$ 10080 200% 40320  
> refresh\_pattern -i .gz$ 10080 200% 40320  
> refresh\_pattern -i .tgz$ 10080 200% 40320  
> refresh\_pattern -i .tar$ 10080 200% 40320  
> refresh\_pattern -i .Z$ 10080 200% 40320  
> refresh\_pattern -i .png$ 10080 150% 40320 override-lastmod ignore-no-cache ignore-private reload-into-ims ignore-reload
>
> # Estos son los patrones de refresco por defecto segun el protocolo utilizado, es muy importante dejar el último con un retraso de 0, sino puede suceder que las páginas web dinámicas no se actualicen correctamente
>
> refresh\_pattern ^ftp:// 1440 50% 10080  
> refresh\_pattern ^gopher:// 1440 10% 1440  
> refresh\_pattern . 0 20% 4320
>
> # Recordamos las páginas web que dieron error al intentar solicitarlas
>
> negative\_ttl 1 minutes  
> positive\_dns\_ttl 15 hours  
> negative\_dns\_ttl 1 minutes  
> half\_closed\_clients off
>
> # Definimos ciertas listas de acceso para dominios que queremos intentar cachear
>
> acl youtube dstdomain .youtube.com  
> acl youtubeip dst 64.15.112.0/24  
> acl youtubeip2 dst 74.125.15.0/24  
> acl googlevideo dstdomain .googlevideo.com  
> acl imageshack dstdomain .imageshack.us  
> acl router dst 192.168.1.1
>
> # Permitimos cachear estas listas de acceso
>
> cache allow youtubeip  
> cache allow youtubeip2  
> cache allow youtube  
> cache allow googlevideo  
> cache allow imageshack
>
> # Evitamos cachear la web del router, por ejemplo
>
> no\_cache deny router
>
> # Modifico la cabecera User-Agent para que parezca que todos los equipos de la red utilizan Linux
>
> header\_access User-Agent deny all  
> header\_replace User-Agent Mozilla/5.0 (X11; U; Linux x86\_64; es-ES; rv:1.9.0.11) Gecko/2009060309 Ubuntu/9.04 (jaunty) Firefox/3.0.12
>
> # Podemos indicarle a squid que cachee los contenidos en base al tipo de objeto MIME, estas configuraciones pueden guardarse en un archivo externo, como es el caso:
>
> acl CACHEMIME rep\_mime\_type -i "/etc/squid/cache\_mime.lst"
>
> # De las configuraciones que utilizamos antes, algunas violan el protocolo HTTP, así que es posible que tengamos problemas de fresco con determinadas páginas web. Para subsanarlo creamos un archivo con una lista de dominios que no queremos cachear. En mi caso me he topado con que as.com y elpais.com dan problemas con el caché.
>
> acl NOCACHE dstdomain "/etc/squid/nocache.lst"
>
> cache allow CACHEMIME  
> no\_cache deny NOCACHE
>
> # Aquellas páginas web que sean dinámicas (esten en cgi-bin o tengan parámetros) no se cachean nunca
>
> hierarchy\_stoplist cgi-bin ?  
> acl QUERY urlpath\_regex cgi-bin \?  
> no\_cache deny QUERY
>
> # Le indicamos que muestren los mensajes de error en Español
>
> error\_directory /usr/share/squid/errors/Spanish
>
> # Bloqueamos algunas cabeceras HTTP para que no se note que estamos utilizando un proxy:
>
> header\_access X-Cache deny all  
> header\_access X-Cache-Lookup deny all  
> header\_access X-Cache-Hit deny all  
> header\_access Via deny all  
> header\_access X-Forwarded-For deny all
>
> # Usamos 128 Mb de memoria
>
> cache\_mem 128 MB  
> cache\_swap\_low 90  
> cache\_swap\_high 95
>
> # No se cachearan contenidos mayores de 64 Mb
>
> maximum\_object\_size 65535 KB
>
> # La caché en disco podrá ocupar hasta 15 Gb
>
> cache\_dir ufs /var/spool/squid 15000 16 256
>
> # Sólo queremos el log de acceso
>
> cache\_access\_log /var/log/squid/access.log  
> cache\_log none  
> cache\_store\_log none

El resto de configuración del squid puede dejarse por defecto, más que nada quería centrarme en aquellos parámetros menos comunes.

Para poder ver si funciona el proxy, debemos configurarlo en los navegadores en las opciones de conexión, o si tenemos el servidor haciendo NAT entre el router y el resto de la red, redirigir las peticiones al puerto HTTP 80 hacia el puerto de nuestro proxy.

Desde consola usando [squidview](http://www.rillion.net/squidview/ "SquidView") podemos ver la efectividad de las peticiones:

```
 168.1.2          www.softonic.com/<br />
 168.1.2     m  www.softonic.com/linux<br />
 168.1.2     R  www.softonic.com/specials_leaderboard/home/910
```

Recomiendo consultar la página web oficial para entender los datos que se muestran por pantalla.

Si queremos generar estadísticas diarias de la efectividad del proxy recomiendo utilizar [calamaris](http://calamaris.cord.de/ "Calamaris Squid Log Analyzer") (también disponible en el repositorio de debian) que genera un informe muy detallado con el ratio de efectividad del proxy, porcentaje de ahorro de ancho de banda, dominios más consultados, etc...

Aquí podeis ver la sección de resumen del informe que genera:

[![Calamaris Report](https://reprogramador.es/images/2009/07/Squid.webp)](https://reprogramador.es/images/2009/07/Squid.webp)

Si probamos a navegar a través del proxy notaremos que tiene mucha más fluidez y menos latencia. Las páginas cargan casi instantáneamente y el contenido dinámico se actualiza bien. Esto se debe a que la mayor parte del tráfico de la página, especialmente todo el contenido estático (imágenes, flash, etc...), nos lo sirve nuestro servidor proxy sin tener que conectar al servidor real; sólo es necesario actualizar el código html de la página, que es realmente lo que varía.

Y bueno, hasta aquí pretendía llegar, si has conseguido leer los tres capítulo te felicito, me temo que han sido bastante extensos (espero que no fuesen espesos ;)).

Si tienes cualquier duda no dudes en preguntar. Espero que estos consejos le sean útiles a alguien (aparte de mí mismo, claro xD), si es así agradecería que me dejases un comentario. 🙂

*P.D.-* Por petición popular, en unos días liberaré el código fuente completo del script que almacena datos estadísticos del router de Ya.com. Puede ser adaptado para funcionar con cualquier router, puliré un poco el código fuente y será publicado bajo licencia GPL. Con él puedes intentar diagnosticar cual es el origen de tus problemas basandote en los horarios, así como poder reclamarle a tu operadora cualquier tipo de incidencia con datos reales. No lo publico directamente aquí porque creo que el capítulo ha sido suficientemente extenso.
