Proyecto: Creación de un Proxy Transparente en Linux Miguel Ángel Esteban Proyecto: Creación de un Proxy Transparente en Linux Miguel Ángel Esteban This project can be followed at: https://www.penflip.com/marianitu/proyecto ©2014 Miguel Ángel Esteban Contents 1 Pasos Iniciales Objetivo . . . . . . . . . . . . Software Utilizado . . . . . . . Instalación de Debian 7 . . . . Instalación de Webmin . . . . Administración mediante SSH . . . . . . 5 5 6 9 10 12 2 Configuración de la Red El archivo /etc/network/interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Reiniciando los servicios de red . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Videotutorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 16 17 17 3 DHCP DHCP Server . . . . . . . . . . . . . . . . . . . . . . Hacer que DHCP escuche sólo a través de una interfaz Asignando rangos de IP’s a los clientes . . . . . . . . . Reservas IP . . . . . . . . . . . . . . . . . . . . . . . Videotutorial: DHCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 18 19 19 22 24 4 Servicio DNS Para qué sirve el servicio DNS? . . . Instalación del servicio DNS . . . . . Configurando el servicio DNS . . . . El archivo named.conf . . . . . . . . Caché DNS, Reenviadores y opciones Zonas DNS . . . . . . . . . . . . . Videotutorial: DNS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . generales. . . . . . . . . . . . . 5 Squid: Montando un Proxy Introducción: ¿Por qué un Proxy? . . Squid: Instalación . . . . . . . . . . . Editando Squid.conf . . . . . . . . . . Selección de Puertos . . . . . . . . . Nombrando roles . . . . . . . . . . . Creando una Lista de Acceso . . . . . Política hasta en Squid: LRU, LFUDA, . . . . . . . . . . . . . . . . . . . . . . . . GDSF 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 25 25 26 26 26 29 33 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 34 36 36 38 38 41 44 4 Navegando por los logs de Squid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Videtutorial: Squid + IPtables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 IPTables Introducción . . . . . . . . . . . . Tipos de peticiones . . . . . . . . Nuestro listado de reglas . . . . . Ejecutar nuestras reglas de iptables Videotutorial: Squid+Iptables . . . Documentación Adicional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . al arrancar el equipo . . . . . . . . . . . . . . . . . . . . . . . . 7 OpenDNS: Filtrado por DNS Introducción . . . . . . . . . . . . . . . Hacer que BIND utilice OpenDNS . . . Hacer que Squid utilice OpenDNS . . . Configurar los filtros de OpenDNS . . . Configurando ddclient . . . . . . . . . . Video Tutorial: Un paseo por OpenDNS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 46 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 47 47 49 52 53 53 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 54 54 55 55 56 56 1 Pasos Iniciales Objetivo La idea de este proyecto es la creación de un Servidor Proxy Transparente basado en Debian Linux y configurado a bajo nivel, es decir, sin ayuda ni asistente alguno. Dicho proxy nos proporcionará las ventajas siguientes: Filtrado: Al pasar todo el tráfico web a través del Proxy, nosotros podremos decidir qué tráfico servir y qué tráfico no servir. • Velocidad: Nuestro proxy proporcionará una caché, que hará que no sea necesario descargar más de una vez el mismo recurso de la red. • Simplicidad: Al navegar a través de un proxy, normalmente es necesario configurar nuestro navegador con parámetros de IP y puerto del servidor proxy. Esto no es necesario cuando el proxy es transparente, como en nuestro caso. Nuestros usuarios estarán navegando a través de nuestro proxy sin darse cuenta. • Para poder tener un proxy caché, deberemos colocar una máquina que corte el tráfico hacia internet, dando paso únicamente al que se necesite. Esa máquina contará con dos interfaces de red, una conectada a Internet o a un Router ADSL y la otra conectada a un Switch, donde se conectarán los equipos cliente. Más o menos tendremos una topología como la de la figura siguiente: 5 6 Software Utilizado Nuestro servidor deberá tener instaladas una serie de herramientas que proporcionen los servicios deseados. Éstas serán: Debian Linux: El Sistema Operativo bajo el que correrá todo nuestro servidor. Se hablará con más detalle en breve. • DHCP: Mediante DHCP conseguiremos que los equipos clientes obtengan su configuración de red, es decir… dirección IP, Puerta de Enlace, Servidores DNS… Será nuestra propio servidor el que realice esta tarea y, para ello, utilizaremos el paquete isc-dhcp-server. Podremos definir rangos de IP, y también podremos realizar reservas IP, reservando una IP concreta a la dirección MAC de un adaptador de red. También podemos utilizar el paquete isc-dhcp-relay en un entorno de enroutado múltiple. En el caso de este proyecto no se dará el caso, aunque se mencionará brevemente su (sencillo) funcionamiento. • DNS: Para el tema DNS utilizaremos el paquete de Software Bind9. El servicio DNS permitirá que nuestro servidor pueda resolver Nombres a los clientes de la red. Se creará una Zona DNS llamada casa.local. y nuestro servidor proxy será reconocido dentro de la red interna como • 7 trasto.casa.local. Por otra parte las peticiones DNS desconocidas serán redireccionadas a unos forwarders externos (los DNS de Google o los de OpenDNS). Otra de las funciones que nos aportará Bind9 es la posibilida de cachear peticiones DNS, de manera que su resolución en el futuro será mucho más rápida. • Servidor Proxy: Es el Software central en nuestro cometido. Utilizaremos Squid, incluído también dentro de los paquetes de Debian Linux. Squid será el software que descargará los elementos web de Internet y se los servirá a nuestros clientes. Así se podrán cachear dichos elementos y servirlos a los clientes de manera más eficiente. Otra de las carácterísticas fundamentales de Squid es el uso de Listas de Control de Acceso (o ACL) que nos permitirá tener un control preciso sobre a qué, cómo, cuándo, dónde podrán acceder nuestros clientes a los recursos web. Obsérvese que no se dice quién… eso es debido a que una de las limitaciones de usar un proxy de manera transparente es que no permite autentificación de usuario. • Firewall: Nuestro sistema también contará con un CortaFuegos, que en nuestro caso será iptables. IPTables no sólo filtra paquetes, sino que además permite realizar traducción de direcciones de la red (NAT). Será mediante esa traducción con la que nuestro servidor interpretará las peticiones web que reciba (puerto 80) y las redirigirá al puerto que tengamos configurado en nuestro servidor Proxy (puerto 8080 en nuestro caso). Mediante NAT también podemos hacer que nuestro servidor actúe de la misma manera que un router ADSL, aunque teniendo mayor control sobre qué queremos (o no) que entre o salga del/hacia el exterior. Para poder hacer esto deberemos crear una serie de reglas mediante las cuales construiremos unas tablas NAT que serán las que definiran el comportamiento de nuestro servidor como enroutador. Debian Debian es una distribución GNU/Linux creada por el proyecto debian en 1993. Su desarrollo no está supeditado a necesidades empresariales ya que ha sido creado por sus propios usuarios. Está disponible en Internet y se puede explotar comercialmente tanto por particulares como empresas siempre y cuando se respeten los términos de su licencia. Se ha elegido Debian por estar habituado a su uso a lo largo de los años (primera instalación en Junio de 1998) y por ser una distribución Linux en la que se prioriza la seguridad del sistema antes que la incorporación de las últimas versiones de los programas. Existen tres ramas de Debian en función del uso que le queramos dar. 8 • Estable: Cuenta con el apoyo del Equipo de Seguridad de Debian y es la recomendada para su uso en producción. La versión actual es La 7.0 Wheezy. Es la que usaremos en este proyecto. ¿Toy History? Sí, los nombres clave de las diferentes versiones de Debian son personajes de la película Toy History. • Inestable: Es la rama en la que tiene lugar el desarrollo de Debian, donde aparecerán y las últimas versiones de los paquetes y donde fácilmente nos podremos encontrar con un sistema roto debido a lo poco que se ha probado el sistema. El nombre clave que se le da a esta rama es Sid. sí, el niño inestable que en Toy History se dedicaba a romperlo todo. • En Pruebas: También conocida como Testing. En esta versión se encuentran paquetes que han estado previamente en la versión Inestable, pero que contienen muchos menos fallos. Esta versión es muy utilizada como sistema de escritorio para aquellos que buscan tener el software más actualizado, aunque se pierde en estabilidad. De la versión Testing es de la que aparecerá más tarde la futura versión estable, de hecho hay un punto en el que dicha versión se Congela, es decir, no se le añade ninguna funcionalidad más, y se lanza como nueva versión estable. 9 Instalación de Debian 7 Nuestra instalación de Debian se realizará sobre una máquina virtual generada con Virtual Box. A dicha máquina virtual se la dotará de dos intefaces de red, una interna y otra externa con salida a Internet. La interfaz externa será de tipo Puente o Bridged y apuntará a la Interfaz Ethernet o la Interfaz Wifi del equipo sobre el que virtualicemos. Ello dependerá de la situación en la que nos encontremos a la hora de realizar la presentación. La idea con ello es que se pueda obtener acceso a internet a través de dicha interfaz, ya se a través de un router ADSL, otro Proxy o bien un Punto de Acceso Wifi generado desde un teléfono con conectividad 3G. La Interfaz Interna será del tipo Red Interna, introduciendo en el campo Nombre la palabra intnet. Intnet es el nombre del Switch virtual al que estará conectado dicho interfaz de red. Toda máquina virtual a la que dotemos de una interfaz interna de nombre intnet estará conectada al mismo Switch virtual. 10 Dentro del esquema que vimos al principio del capítulo correspondería a esto: Instalación de Webmin Webmin es una herramienta de administración web que permite hacer toda clase de configuraciones sobre una máquina Linux a través de un navegador Web. Su uso es muy sencillo e intuitivo. Aunque nosotros no lo usaremos en nuestro proyecto, ya que todo lo configuraremos a bajo nivel en modo texto, sí que lo instalaremos para que cualquier usuario con los permisos suficientes pueda 11 administrar el sistema sin necesidad de conocer todos los archivos de configuración. Lo primero que hemos de saber es que Webmin no viene incluído dentro de Debian. No hay problema, ya que se puede descargar desde la página Web de Webmin para su posterior instalación. Advertencia En el momento de la confección de éste documento (07/05/2014) la última versión de Webmin era la 1.680. Podría ser que los pasos y/o enlaces actuales no correspondan a los que lees. No obstante la página de Webmin (http://www.webmin.com/deb.html) aparecen los pasos necesarios para hacer hacer una instalación con la versión actual. Descarga e Instalación Lo primero que deberíamos hacer es instalar el paquete de webmin mediante el gestor de descargas wget. Caso de no tenerlo (poco probable porque Debian lo instala por defecto), deberías instalarlo con el comando sudo aptitude install wget. El comando para descargar el paquete de webmin sería el siguiente wget http://prdownloads.sourceforge.net/webadmin/webmin_1.680_all.deb Una vez finalizado el proceso de descarga, se deberían instalar toda una serie de paquetes de los cuales depende webmin y sin los cuales no puede funcionar. Es probable que ya los tengamos instalados, pero no estaría de más ejecutar el comando siguiente para asegurarnos. sudo apt-get install perl libnet-ssleay-perl openssl libauthen-pam-perl libpam-runtime libio-pty-perl apt-show-versions python Hecho esto instalaríamos el paquete webmin que descargamos previamente. Al no instalar desde repositorios utilizaremos el comando dpkg. sudo dpkg –install webmin_1.680_all.deb Una vez realizados estos pasos, podremos gestionar nuestra Debian desde la siguiente URL: https://IPServer:10000, donde IPServer será en nuestro caso 172.20.0.1 si accedemos desde una máquina de la red Interna. 12 Administración mediante SSH Cuando tenemos un servidor, lo más normal es acceder a él remotamente. Al tratarse de un entorno en modo texto lo habitual era usar Telnet para esos menesteres, pero al ser un protocolo inseguro, cada vez más se está utilizando más SSH para este fin. Acceder es muy sencillo. Si intentamos desde un sistema Linux/Mac simplemente abriremos una terminal y ejecutaremos este comando ssh -l maec 172.20.0.1 Donde maec será el usuario con el que queremos iniciar sesión y 172.20.0.1 la dirección IP o nombre DNS de nuestro servidor Linux. Si el sistema no nos reconoce el comando, deberíamos instalar el cliente SSH mediante el comando siguiente: sudo aptitude install openssh-client 13 Una vez dentro se nos pedirá la contraseña y podremos trabajar con el equipo como si estuviésemos sentados ante él. Desde una máquina Windows la manera de acceder varía ligeramente, ya que necesitaremos una aplicación cliente que permita conectar con nuestro servidor SSH. La más popular es Putty, y puede ser descargada desde http://www.chiark.greenend.org.uk/ ~sgtatham/putty/download.html Su funcionamiento es extremandamente sencillo. Al abrir se nos pedira los datos (dirección, puerto y protocolo) del servidor al que queramos conectarnos. En el caso de la captura siguiente sería 172.20.0.1 (dirección), SSH (protocolo) y 22 (puerto). 14 Donde una vez se haya establecido la conexión, nos aparecerá una sesión en modo texto contra el servidor 15 2 Configuración de la Red El archivo /etc/network/interfaces Ya tenemos instalado Debian Linux 7 con dos adaptadores de red: • • eth0: Salida a Internet eth1: Red Interna Por defecto nos quedará eth0 configurado por DHCP y eth1 sin configurar. La idea es cambiar la configuración de manera que eth1 tendrá la IP estática 172.20.0.1 perteneciente a la red 172.20.0.0/24. Para poder configurar esto deberemos editar el archivo /etc/network/interfaces, con un editor de textos como nano, vim, etc… Para editar el archivo con nano habá que ejecutar el comando siguiente: sudo nano /etc/network/interfaces Debiendo dejar el contenido del archivo tal y como sigue: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # This file describes the network interfaces available on your system # and how to activate them. For more information , see interfaces (5). # The loopback network interface auto lo iface lo inet loopback # Xarxa Externa auto eth0 iface eth0 inet dhcp # Xarxa Interna auto eth1 iface eth1 inet static address 172.20.0.1 netmask 255.255.255.0 network 172.20.0.0 broadcast 172.20.0.255 16 17 A continuación paso a explicar para qué sirve cada una de estas opciones. • • • • • • auto eth1: Hace que la interfaz eth1 se inicialice automáticamente al arrancar el equipo o al reiniciar los servicios de red (sudo service networking restart). iface eth1 inet static: Indica que la interfaz eth1 tendrá una dirección estática. Si en vez de static pusiéramos dhcp, no deberíamos poner indicar más configuraciones en el adaptador ya que la dirección IP se intentaría obtener automáticamente por DHCP. address 172.20.0.1: Asigna la dirección IP 172.20.0.1 al adaptador de res que hayamos inicializado previamente (en este caso eth1). netmask 255.255.255.0: Asigna una máscara de 24 bits a la red eth1. network 172.20.0.0: Indica la dirección de red. broadcast 172.20.0.255: Indica la dirección de difusión de la red. Adicionalmente podríamos introducir la línea gateway 172.20.0.1, que haría que la puerta de enlace del adaptador sea 172.20.0.1, aunque en el caso de este proyecto no se hará uso de ésta opción. Reiniciando los servicios de red Una vez hayamos editado los archivos de configuración, deberemos reiniciar el servicio de red para que el sistema adopte los cambios mediante el comando siguiente: sudo service networking restart Si lo hemos hecho todo bien, ahora nuestra máquina debería ser capaz de responder pings tanto desde la red conectada a eth1 como a la conectada a eth0. Videotutorial A continuación unos videos en los que se muestra de manera práctica cómo hacer todo lo visto a los capítulos anteriores. Instalación de Debian: https://www.youtube.com/watch?v=lH_ZoWQNDQY Configuración Red y de Sudo: https://www.youtube.com/watch?v=cCD_sGMC5BE 3 DHCP Lo primero que deberíamos hacer es conseguir que nuestras máquinas de la Red Interna obtengan Dirección IP, Puerta de Enlace y Servidores DNS. De esa manera simplificaremos la configuración de las máquinas cliente haciendo que todas estén integradas en la red y perfectamente configuradas para acceder a Internet. La idea es que todas las máquinas tengan definida como puerta de enlace la dirección IP en la que tendremos instalado nuestro proxy. Para poder disponer disponer de este servicio, usaremos el paquete isc-dhcp-server , correspondiente lal servicio DHCP del ISC (Internet System Consortium). Como no se encuentra instalado por defecto en nuestro sistema, deberemos instalarlo mediante el comando siguiente. sudo aptitude install isc-dhcp-server Dicho servicio se configurará editando el archivo /etc/dhcp/dhcpd.conf, aunque para que los cambios tengan efecto, se deberá reiniciar el servicio dhcp mediante el siguiente comando: sudo service isc-dhcp-server restart Donde… sudo: Ejecuta el comando siguiente como administrador service: Comando que indica que queremos hacer algo con un servicio (encenderlo, apagarlo, reiniciarlo…) isc-dhcp-server: Nombre del servicio que queremos apagar, encender, reiniciar, etc… en este caso se trata del servidor DHCP. restart: Acción que queremos realizar sobre el servicvio previamente indicado. Con restart reiniciaremos el servicio para que los cambios tengan efecto. Podemos apagar (stop), encender (start), etc … Vamos a ver cómo se configuran los diferentes archivos para que nuestro servicio DHCP esté activo. DHCP Server Ya tenemos en marcha nuestro servidor DHCP. Ahora deberemos configurarlo convenientemente para que todo configure como debiera. 18 19 Lo que buscamos en nuestro caso es que se asignen direcciones IP automáticamente sólo a través de la interfaz eth1, es decir, la de la red interna a través de la cual accederán nuestros equipos cliente. A todos los equipos cliente que soliciten dirección IP por DHCP se les pasará la siguiente información: Red: 172.20.0.0 Máscara de Red: 255.255.255.0 (/24) Dirección IP: Entre 172.20.0.10 y 172.20.0.100 Puerta de Enlace: 172.20.0.1 Servidor DNS: 172.20.0.1 Para conseguir todo esto deberemos editar algunos archivos y reiniciar el servicio DHCP. Veamos cómo se hace todo esto. Hacer que DHCP escuche sólo a través de una interfaz Lo primero que hará es hacer que nuestro servidor DHCP sólo escuche peticiones a través de la interfaz de red interna, es decir, eth1. Para ello será necesario editar el archivo /etc/default/isc-dhcp-server con un editor de textos cualquiera, por ejemplo nano sudo nano /etc/default/isc-dhcp-server dentro de dicho archivo deberíamos localizar una cadena con el siguiente contenido: 1 INTERFACES ="" Que deberemos editar dejándola como: 1 INTERFACES =" eth1" Finalmente reiniciaremos el servicio de DHCP para que los cambios surjan efecto. Deberemos ejecutar el comando siguiente: sudo service isc-dhcp-server restart A partir de ahora nuestro servidor DHCP sólo atenderá peticiones recibidas a través de la interfaz eth1. Ahora vamos a configurar nuestro servidor para que sepe interfaz enviar a través de ella. Asignando rangos de IP’s a los clientes A continuación configuraremos nuestro servidor DHCP para que vaya asignando los parámetros de red a las máquinas que se conecten a la red local. Todos los parámetros necesarios para llegar a tal fin han de ser introducidos en el archivo /etc/dhcp/dhcpd.conf. Por defecto se nos proporciona un archivo de configuración por defecto, pero yo optaré por crear mi propio archivo de configuración desde cero. 20 cd /etc/dhcp sudo mv dhcpd.conf dhcpd.porsi sudo touch dhcpd.conf Con esto tendremos un archivo de configuración vacío y una copia de seguridad por si hemos metido la pata. Vamos a realizar la configuración en sí. Recordenos qué es lo que queremos que haga nuestro servidor DHCP: Red: 172.20.0.0 Máscara de Red: 255.255.255.0 (/24) Dirección IP: Entre 172.20.0.10 y 172.20.0.100 Puerta de Enlace: 172.20.0.1 Servidor DNS: 172.20.0.1 Para conseguir esto, deberemos editar /etc/dhcp/dhcpd.conf con cualquier editor de textos como nano, vim, emacs… Una vez dentro escribiré las siguientes instrucciones. 1 2 3 4 5 6 7 subnet 172.20.0.0 netmask 255.255.255.0{ range 172.20.0.10 172.20.0.100; option routers 172.20.0.1; option domain -name - servers 172.20.0.1; option domain -name "casa. local "; default -lease -time 68000; } Vamos a explicar para qué sirve cada uno de estos “comanditos” subnet 172.20.0.0 netmask 255.255.255.0 { … }: Define una subred 172.20.0.0/24 con máscara 255.255.255.0 y, obviamente, 172.20.0.255 como dirección de difusión. Los parámetros de esa red los definiremos en la zona marcada con puntos suspensivos. Obsérvese que cada parámetro finaliza en un punto y coma (;). • range 172.20.0.10 172.20.0.100;: Indica en qué rango se irán asignando IP a los equipos clientes que se vayan conectando. Tal y como aparece el diálogo, se asignarán dinámicamente las direcciones comprendidas entre la 10 y la 100, pudiendo dedicarse el resto de direcciones (de la 1 a la 9 y de la 101 a la 254) a direcciones estáticas. • option routers 172.20.0.1;: Con esta linea se indicará cual será la puerta de enlace o Gateway asignado a cada uno de los clientes que nos realicen peticiones dhcp. A nosotros interesa que las máquinas cliente naveguen a través nuestro, es por eso que pondremos la dirección de la máquina Linux como Gateway por defecto. -option donamain-name-servers 172.20.0.1;: En esta línea se indica qué máquina deberán utilizar los equipos cliente como DNS para resolver nombres. Como montaremos un servidor DNS en nuestro mismo equipo, nos pondremos nosotros mismos como servidores DNS. -option domain-name “casa.local”;: Sirve para indicar un nombre de domio que el cliente utilizará a la hora de resolver nombres por DNS. -default-lease-time 68000;: Se trata del tiempo en segundos que por defecto tardará el servidor en volver a ofrecer una IP asignada previamente a otro cliente. • 21 Una vez introducida esta información reinciaremos el servidor DHCP (sudo service isc-dhcp-server restart) y encenderemos una máquina cliente con el TCP/IP configurado por defecto para ver si es capaz de pillar dirección IP. Vamos a hacerlo con un Windows 8. Este Windows 8 ha sido creado con VirtualBox para acceder a mismo Switch virtual que creamos para nuestra máquina Debian Linux. Tal y como podemos ver en la siguiente figura, se ha dejado toda la configuración por defecto para que busque algún servidor DHCP en la red. 22 Sin embargo si hacemos un ipconfig, veremos que tiene toda la información de red asignada correctamente. Reservas IP Uno de los problemas que nos podemos encontrar con DHCP es que la IP aisignada a un equipo puede variar de una sesión a otra. Este hecho puede ser problemático en entornos donde queremos que ciertas máquinas conserven siempre la misma dirección IP. Para evitar esto exite la caracteristica de reserva IP, que permite que el servidor DHCP se reserve determinadas direcciones IP para asignarselas a determinados ordenadores de la red. Dichos ordenadores serán identificados por el servidor DHCP a través de la dirección MAC del adaptador de red que instalado el equipo, de manera que adaptaremos cada una de esas direcciones IP a cada una de las direcciones MAC. En el caso de nuestra red, vamos a hacer que la dirección IP 172.20.0.254 a la máquina con Windows 8. Siendo una máquina Windows, podremos obtener la MAC del adaptador de red a través del comando ipconfig/all (en linux sería con sudo ifconfig -a, aunque al tratarse de una máquina virtual, también podremos ver la dirección MAC de su adaptador de red a través de la configuración del mismo adaptador dento de VirtualBox. 23 En este caso la dirección MAC del adaptador sería 08:00:27:D5:05:0F, de manera que lo que queremos es que la IP 172.20.0.254 quere reservada al adaptador con MAC 08:00:27:D5:05:0F. La manera para conseguir esto desde nuestro servidor sería la siguiente. Editamos el archivo /etc/dhcp/dhcpd.conf como administrador… sudo nano /etc/dhcp/dhcpd.conf … y colocaremos en la parte final del mismo las siguientes instrucciones: 1 host windows8 { 2 hardware ethernet 08:00:27: D5 :05:0F; 3 fixed - address 172.20.0.254; 4 } Esto lo que hará es que un host, al que llamaremos windows8, de MAC 08:00:27:D5:05:0F, tenga asignada la IP fija 172.20.0.254. Reiniciamos el servicio DHCP (sudo service isc-dhcp-server restart) y probamos a agregar nuestro windows 8 a ver qué IP obtiene esta vez. 24 Como podemos ver, funciona. Ya tenemos resuelto el tema de los parámetros IP, ahora falta tener en marcha la resolución de nombres, pero eso tocará en el capítulo siguiente. Videotutorial: DHCP El siguiente vídeo muestra a grandes rasgos el funcionamiento de DHCP tal y como se ha visto a lo largo de este documento: https://www.youtube.com/watch?v=GPofOPI_Z98 4 Servicio DNS Para qué sirve el servicio DNS? El objetivo de DNS es la resolución de nombres, es decir, hacer corresponder un nombre fácil de recordar con una dirección IP. En el caso de nuestro proyecto, la máquina que hará de proxy tendrá como dirección IP 172.20.0.1. Sin embargo, como recordar esta dirección va a ser complicado para la mayoría de los usuarios, utilizaremos un servicio DNS que permitirá resolver el nombre trasto.casa.local hacia dicha dirección. De esa manera los usuarios que quieran acceder al proxy podrán hacerlo atacando únicamente a trasto.casa.local. Por ejemplo: En el caso de webmin había que acceder a https://172.20.0.1:10000. Pues bien, tan pronto como configuremos nuestro servicio DNS podremos acceder a él desde cualquie punto de la red simplemente con https://trasto.casa.local:10000. Instalación del servicio DNS Para instalar el servicio DNS sería necesario instalar toda una serie de paquetes que por defecto no vienen instalados en el sistema. El comando para hacer esto sería el siguiente: sudo aptitude install bind9 bind9-doc dnsutils Ahora deberíamos editar el archivo /etc/resolv.conf para que realice las peticiones DNS a través de nuestro propio ordenador (127.0.0.1). Concretamente deberíamos dejarlo como en la captura siguiente: 1 domain casa. local 2 search casa. local 3 nameserver 127.0.0.1 Con esto ya tendríamos todo lo necesario para tener un sistema DNS en marcha. Ahora sólo faltaría configurarlo. 25 26 Configurando el servicio DNS El servicio DNS es gestionado por un ejecutable llamado named cuyo comportamiento podemos configurar editando el archivo /etc/bind/named.conf. Cada vez que realicemos alguna modificación en ese archivo, o en alguno que dependa de él, deberemos reiniciar el servicio DNS para que dichos cambios tengan efecto. Reiniciar el servicio DNS Para reiniciar el servcicio DNS realizaremos el siguiente comando: sudo service bind9 restart De esta manera todos los cambios que hayamos realizado sobre los archivos de configuración de BIND tendrán efecto. El archivo named.conf Como dijimos antes, named.conf es el archivo donde podemos indicar todas las configuraciones a nivel DNS. Sin embargo, lejos de introducir todas las instrucciones allí dentro, realizaremos una serie de includes para poder hacer referencia a archivos externos. De hecho viene así por defecto. Miremos el contenido de este archivo 1 2 3 4 5 6 7 8 9 10 11 // // // // // // // This is the primary configuration file for the BIND DNS server named. Please read /usr/share /doc/ bind9/ README . Debian .gz for information on the structure of BIND configuration files in Debian , * BEFORE * you customize this configuration file. If you are just adding zones , please do that in /etc/bind/named.conf.local include "/ etc/bind/ named .conf. options "; include "/ etc/bind/ named .conf. local "; include "/ etc/bind/ named .conf.default - zones "; Como podemos ver, se hace referencia a tres archivos: - named.conf.options: Caché, reenviadores y opciones - named.conf.local: Definición de zonas DNS locales - named.conf.default-zones: Definición de zonas por defecto (servidores raíz, localhost, etc…) De estos tres archivos tocaremos los dos primeros, veremos cómo y para qué. Caché DNS, Reenviadores y opciones generales. Como ya sabemos, el servicio DNS se encarga de traducir nombres (p.e. pepelotas.net) a su correspondiente dirección IP. Este proceso, aunque en apariencia rápido, puede demorar un poco. Es 27 por ello por lo que conviene disponer de una cache DNS que nos evite tener que resolver direcciones que ya fueron resueltas en anteriores ocasiones. Una cache DNS guarda localmente los resultados de esa búsqueda para utilización futura, evitando la repetición de búsquedas y aumentando drásticamente la velocidad de las mismas. La configuración generada durante la instalación es perfectamente funcional, no requiere modificaciones. Sin embargo, vamos personalizar la instalación en 2 aspectos principales: vamos a definir a cuáles servidores consultará el nuestro para pedir ayuda en la resolución de nombres, si no es posible hacer esto localmente (forwarders) y vamos a fortalecer algunos aspectos de seguridad. Como forwarders podemos optar por varias hipótesis: podemos utilizar los servidores DNS de nuestro proveedor de acceso a Internet. Nosotros optaremos por una opción muchísimo mejor: los servidores de OpenDNS (http://www.opendns.com/) OpenDNS no sólo provee resoluciones más rápidas, sino también diversos servicios adicionales de seguridad, como filtros de direcciones maliciosos y otros más. Lo único que deberemos saber es que los servidores DNS de OpenDNS (y por tanto, nuestros reenviadores) serán 208.67.222.222 y 208.67.220.220. En el futuro podremos documentarnos a través de su página web para poder configurar todos los filtros y características extra que nos aporta. Para configurar estos parámetros deberíamos editar nuestro archivo named.conf.options procurando que nos quede de la siguiente manera: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 options { directory "/ var/ cache /bind "; // If there is a firewall between you and nameservers $ // to talk to , you may need to fix the firewall to all$ // ports to talk. See http :// www.kb.cert.org/vuls/id/$ // // // // If your ISP provided one or more IP addresses for s$ nameservers , you probably want to use them as forwa$ Uncomment the following block , and insert the addre$ the all -0's placeholder . forwarders { 208.67.222.222; 208.67.220.220; }; Por seguridad sólo serán recibidas conexiones por el puerto 53 a través de la interfaz local o la destinada a la red interna (listen-on port 53 { 127.0.0.1; 172.20.0.1; };). Así mismo, sólo serán contestadas las peticiones de resolución que partan del propio puesto o de la red interna (allow-query { 127.0.0.1; 172.20.0.0/24; };). El resto de peticiones DNS será denegadas. De esta manera, nuestro named.conf.options continuará como sigue: 1 2 3 4 listen -on port 53 { 127.0.0.1; 172.20.0.1; }; allow - query { 127.0.0.1; 172.20.0.0/24; }; allow - recursion { 127.0.0.1; 172.20.0.0/24; }; allow - transfer { none; }; Una vez realizados estos cambios, deberemos comprobar que el fichero está correcto. Esto se hace a través del este comando 28 sudo named-checkconf Si no hay mensaje de error, es que la cosa está bien. Ahora sólo faltará comprobar que, efectivamente, se resuelven las peticiones DNS. Verificando la configuración Antes de verificar nada, recordemos que debremos reiniciar el servicio DNS para que los cambios surtan efecto Para verificar la configuración, el servidor debe buscar la dirección IP de cualquier sitio en internet. El servidor DNS deberá mostrar nuestra dirección (127.0.0.1) y las direcciones IP del sitio buscado, se mostrarán de forma correcta tras ejecutar el comando nslookup: El proceso inverso, es decir, buscar un nombre a partir de una dirección IP, también debería funcionar: 29 El comando de control rndc rndc es un comando de control que permite, entre otras cosas, borrar la caché DNS de nuestro servidor. Puede ejecutarse en general o sólo contra una zona DNS concreta. Por otra parte permite también cargar archivos de zona nuevos sin necesidad de reiniciar el servidor DNS. No entraremos en detalle en su funcionamiento, ya que este se encuentra en las páginas man de Linux (man rndc). Sin embargo comentaré algunos ejemplos. (sudo) rndc reconfig Carga los archivos de configuración sólamente para las nuevas zonas. (sudo) rndc flush: Borra la caché del servidor. Zonas DNS Ya hemos solucionado la resolución de nombres usando servidores de apoyo (reenviadores). Ahora deberías configurar nuestro servidor DNS para que sea capaz de resolver nombres e IP dentro de la red local. La idea es que el servidor sea reconocido dentro de la red como trasto (o trasto.casa.local) y que dicha petición sea resuelta como 172.20.0.1, que es la IP de mi servidor. De la misma manera podré hacer que cualquier nombre que me invente resuelva hacia cualquier IP, siempre y cuando así lo indiquemos en los archivos de configuración correspondientes. Para poder hacer esto deberemos crear zonas DNS en las que definiremos los diferentes nombres y sus correspondencias IP. 30 Deberemos definir como mínimo un archivo de resolución de nombres (traduce nombres en IP) y por otra otro de resolución inversa (traduce IP en nombres). El archivo named.conf.local Lo primero que deberíamos hacer es editar el archivo /etc/bind/named.conf.local. Dentro de dicho archivo será donde definiremos las diferentes zonas DNS, las cuales se especificarán en archivos externos independientes para cada zona. Veamos cómo lo he dejado en el caso de este proyecto 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // // Do any local configuration here // // Consider adding the 1918 zones here , if they are not used in your // organization // include "/ etc/bind/ zones . rfc1918 "; zone "casa. local" { type master ; file "/ etc/bind/db.casa. local "; }; zone "0.20.172. in -addr.arpa" { type master ; file "/ etc/bind/db .0.20.172"; }; Vemos en este archivo cómo hay definidas dos zonas (cada una comienza por zone). casa.local: zona de resolución de nombres desde la que iré colocando entrada DNS correspon dientes a nombres concretos que serán resueltas por las IP que le diga. Nombres se encontrarán dentro del dominio casa.local, de manera que si defino un equipo llamado “trasto”, este será considerado como trasto.casa.local. En mi configuración he indicado que dicha zona estará configurada dentro del archivo /etc/bind/db.casa.local. • 0.20.172.in-addr.arpa: Zona de resolución inversa en la que iré enumerando las diferentes IP dentro del rango 172.20.0.x y el nombre al que corresponderán. Aquí le diré que “1” (es decir, 172.20.0.1) corresponde a trasto.casa.local. En mi configuración he indicado que dicha zona estará configurada dentro del archivo /etc/bind/db.0.20.172. • Comprobemos y analicemos el contenido de los archivos que he generado y qué es lo que representa dentro del ecosistema del servidor. El archivo db.casa.local Localizado en /etc/bind/db.casa.local, setrata, tal y como hemos comentado anteriormente, de una zona de resolución de nombres. Veamos el contenido de éste archivo y qué significa cada una de sus opciones 31 1 2 3 4 5 ; ; BIND zone file for casa. local ; $TTL 3D La variable $TTL indica el tiempo que la zona DNS puede ser cacheada. En mi caso he puesto 3D, que indicaría que el tiempo de cacheo será de 6 días. En caso de poner 0, esta zona no se será cacheada. 1 @ IN SOA ns.casa. local. root.casa.local. ( Es la entrara SOA o Start of Autority. Define los valores por defecto de la zona DNS . ns.casa.local. será el FQDN del servidor que tiene autoridad en la zona, mientras root.casa.local. es el e-mail del administrador de esta zona (en éste caso sería [email protected], ya que en sólo se permite escribir la @ al inicio del a entrada SOA). 1 2 3 4 5 2010111102 8H 2H 4W 1D ) En las líneas anteriores se definen los parámetros correspondientes al Serial Number, refresh, retry, expire y negative de nuestra zona DNS. Muchas de estas opciones sólo son útiles cuando replicamos zonas. No obstante las explicaremos brevemente: Serial Number: De valor 2010111102, es un valor numérico. Se trata del número de serie del archivo y es útil para cuando la zona se replica en otros servidores para saber si los datos han cambiado y si debe hacerse la réplica. Refresh: Le hemos puesto 8H (8 Horas). Es utilizado cuando la zona se replica. Indica al servidor esclavo con qué intervalo comprobar la validez de su zona. Retry: Le tengo puesto el valor 2H (2 horas). Se utiliza cuando la zona se replica. Si es imposible para el servidor esclavo contactar con elservidor maestro, indica cuánto esperar antes de volverlo a intentar. Expire: Lo tenemos con el valor 4W (4 semanas). Se utiliza cuando la zona se replica. Si es imposible para el servidor esclavo contactar con el servidor maestro, indica con cuánto tiempo los registros sin refrescar pierden su vlidez y deben dejarse de usar. Negative: Lo tenemos con 1D (1 día). Indica cuánto tiempo se deberán mantener cada una de las respuestas negativas en la caché DNS de nuestro servidor. 1 2 NS MX ns 10 mail ; Inet address of name server ; Primary mail exchanger NS: Registro que indica cuál será el servidor de nombres de nuestra zona. En nuestro caso hemos indicado que será ns (más tarde le diremos a BIND dónde apunta). MX: Desde esta entrada declaramos un servidor de Mail en nuestra zona DNS, el nombre de éste será mail(.casa.local.) y tendrá una preferencia de 10 respecto a otros. Esta preferencia (o pref) es un valor entre 0 y 65535, teniendo una valor interior mayor preferencia). A continuación unos cuantos registros A. Estps Registros A alimentan a nuestro servidor DNS de nombres y su correspondientes concordancias IP. 32 1 2 3 4 ns mail trasto windows8 A A A A 172.20.0.1 172.20.0.1 172.20.0.1 172.20.0.254 Con estas tres entradas haremos que tanto los nombres ns, mail como trasto apunten a la dirección IP 172.20.0.1, que es la de nuestro servidor. Finalmente asignaremos el nombre windows8 a la IP 172.20.0.254, la cual se asignará por reserva DHCP a la máquina con dirección MAC 08:00:27:D5:05 :0F, tal y como se vió en el capítulo correspondiente. Ahora definiremos unos cuantos Registros CNAME. Los registros CNAME, también conocidos como Canonical Name no son más que alias a otros nombres DNS ya definidos previamente, de manera que en lugar de indicar a qué IP apuntan, deberemos indicarles los nombres a los que corresponden. 1 proxy 2 jefe CNAME CNAME trasto windows8 Con estas dos entradas hacemos que al acceder a proxy.casa.local se nos lleve a trasto.casa.local, de la misma manera que cuando accedamos a jefe.casa.local aparezcamos en windows.casa.local. El resultado del archivo sería éste: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; ; BIND zone file for casa. local ; $TTL @ 3D IN SOA ns.casa. local. root.casa.local. ( 2010111102 8H 2H 4W 1D ) ns mail NS MX A A ns 10 mail 172.20.0.1 172.20.0.1 trasto windows8 proxy jefe A A CNAME CNAME 172.20.0.1 172.20.0.254 trasto windows8 ; ; Inet address of name server ; Primary mail exchanger Y daría como resultado será que obtengamos respuesta al hacer ping a cualquiera de éstos nombres desde cualquier máquina de la red 172.20.0.0/24 que haya obtenido su dirección IP por DHCP. El archivo db.0.20.172 Este será nuestro archivo de resolución inversa. Desde él haremos justamente lo contrario que hicimos en el archivo anterior: Haremos que las direcciones IP correspondan con sus nombres. El aspecto resultante del archivo que vamos a generar será el siguiente: 33 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; ; BIND zone file for 172.20.0. xxx ; $TTL @ 3D IN SOA ns.casa. local. 2010111101 8H 2H 4W 1D ) ; ; ; ; ; root.casa.local. ( serial refresh retry expire minimum ; 1 254 NS PTR PTR ns.casa. local . trasto .casa. local. windows8 .casa. local . Dicho archivo contiene una estructura similar al anterior, teniendo que diferenciar las dos últimas líneas que son las siguientes: 1 1 2 254 PTR PTR trasto .casa. local. windows8 .casa. local . Vemos que ambas líneas de ambas entradas PTR comienzan por un número (1 o 254). Estos números será con los los que se deberá complementar el nombre de la zona inversa. De esta manera si la zona inversa es 0.20.172 y el núnero de la entrada es el 1, estaremos definiendo una entrada para la dirección IP 172.20.0.1. Siguiendo esta lógica veremos que estamos asignando trasto.casa.local. 172.20.0.254 a windows8.casa.local. a 172.20.0.1 y Videotutorial: DNS He grabado un vídeo donde se explica a grandes rasgos cómo se configura el servicio DNS dentro de mi máquina Debian. Se puede visualizar haciendo clic en el enlace siguiiente: https://www. youtube.com/watch?v=Qg6WP9-vsUM 5 Squid: Montando un Proxy Introducción: ¿Por qué un Proxy? Ya hemos coneseguido conectividad entre los diferentes equipos de nuestra red interna. Ahora necesitamos hacer que éstos equipos puedan acceder a los recursos de la red externa (Internet), pero este acceso debe ser optimizado y limitado al máximo para así ganar en eficiencia y seguridad. Recordemos que tenemos controlado el tráfico de nuestra red interna, pero Internet contiene potencialmente diferentes amenazas que pueden hacer saltar por los aires todo el trabajo que hemos hecho. Precisamente por este motivo es por el que usaremos un servidor proxy. Un Proxy no es más que un programa que interceptará las peticiones de nuestros clientes webs, se encargará de llevarlas a cabo y una vez completada será capaz de enviar el resultado al mismo cliente del que recibió la petición. De esta manera nuestro servidor proxy intervendrá de intermediario y como tal podrá controlar qué se le entrega y qué no al cliente. 34 35 Otra función que tiene el Proxy es la de caché. El sistema de caché del servidor proxy hace que éste se guarde una copia de todos los contenidos que entrega a los clientes, de manera que si otro cliente pide un contenido repetido, éste ya no volverá a ser descargado por el servidor, siendo entregado al cliente a partir de la copia previamente almacenada. El software que utilizaremos para montar nuestro Proxy será Squid. Se trata de un programa muy flexible que hará de intermediario entre la nuestra red externa (Internet) y nuestra red interna, haciendo que los clientes tengan un acceso controlado a Internet. 36 Squid: Instalación La instalación de Squid es extremadamente sencilla. Tan sólo deberemos de ejecutar el siguiente comando desde la terminal de nuestra Debian. sudo aptitude instal squid3 Hecho esto, se nos generará un archivo de configuración y un servicio. El servicio de squid se puede iniciar/reiniciar/parar mediante los comandos: sudo service squid3 start sudo service squid3 stop sudo service squid3 restart Por otra parte podremos configurar el comportamiento de nuestro squid a través del archivo /etc/squid3/squid.conf. Dicho archivo podrá ser modificado mediante nuestro editor de textos favorito. Vamos a crear un archivo de configuración vacío, construyendo poco a poco las diferentes opciones con las que funcionará nuestro esquid. Editando Squid.conf Lo primero que haremos será desplizar nuestro archivo original a una copia de seguridad. sudo mv /etc/squid3/squid.conf /etc/squid3/squid.porsi Hecho esto procederemos a crear un archivo squid.conf vacío (sudo touch /etc/squid3/squid.conf) y editarlo. El resultado una vez seguidos los pasos de este manual será el siguiente. 1 2 3 4 5 6 7 8 9 10 11 12 # Puerto principal de Squid , tal y como esta escuchara por el puerto 8080 de # manera transparente http_port 172.20.0.1:8080 transparent # La linea siguiente permite abrir un puerto especifico para el trafico SSL. # Generamos un certificado en nuestra maquina que sera enviado al # cliente cada vez que acceder a una pagian segura . El usuario recibira # advertencias de seguridad a cada pagina , de manera que no es la # solucion mas comoda . Como aun y asi , el trafico SSL no puede ser # filtrado , se ha optado por una herramienta externa como OpenDNS ### https_port 172.20.0.1:8081 transparent cert =/ home/maec/proxy.casa.local.cert key =/ home/maec/proxy .casa. local .key 13 14 # Parametros Cache 37 15 # Documentados en: http :// funnybutnot . wordpress .com /2011/12/09/ setting -up -a-squid -caching -proxy/ 16 17 cache_mem 1024 MB 18 cache_dir aufs /var/spool / squid3 1024 16 256 19 maximum_object_size 5120 MB 20 cache_store_log /var/log/ squid3 / store .log 21 coredump_dir /var/ spool / squid3 22 refresh_pattern ^ftp: 1440 20% 10080 23 refresh_pattern ^ gopher : 1440 0% 1440 24 refresh_pattern -i (/cgi -bin /|\?) 0 0% 0 25 refresh_pattern . 0 20% 4320 26 quick_abort_min -1 QB 27 read_ahead_gap 1 MB 28 positive_dns_ttl 30 second 29 negative_dns_ttl 1 second 30 minimum_expiry_time 600 seconds 31 chunked_request_body_max_size 4096 KB # compatible solo con squid 3.0 32 33 # Declaracion de variables para la lista de acceso 34 35 # La siguiente linea es requerida en Squid2 36 ## acl all src 0.0.0.0/0 37 acl manager proto cache_object 38 acl localhost src 127.0.0.1/32 39 acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 40 acl entraip src "/ etc/ squid / entraip " 41 acl nodomini url_regex "/ etc/ squid/ nodomini " 42 acl noextensions url_regex "/ etc/ squid/ noextensions " 43 acl nomac arp "/ etc/ squid / nomac " 44 acl horarioficina time M T W H F 08:00 -14:00 45 http_access allow manager localhost 46 http_access deny manager 47 http_access deny to_localhost 48 http_access allow localhost 49 50 # Lista de acceso . Se iran procesando las lineas una por una. Una vez se 51 # cumpla la condicion de una , ya no se procesaran las demas 52 53 http_access allow localhost 54 http_access deny nodomini 55 http_access deny noextensions 56 reply_body_max_size 100 MB all 57 http_access deny nomac 58 http_access allow entraip horarioficina 59 60 # Finalmente cerramos el paso a toda peticion que no cumpla ninguna de las 61 # condiciones anteriores 62 http_access deny all Ahora analizaremos paso a paso cómo está estructurado éste archivo de configuración y qué efecto tiene cada una de sus opciones dentro del comportamiento general de Squid. 38 Selección de Puertos Lo primero que indicaremos en nuestro archivo de configuración es qué puertos escuchará nuestro servidor Proxy basado en Squid. En principio está configurado para escuchar al puerto 3128. En realidad no es necesario utilizar este puerto, podemos indicar cualquier otro. Esto se conseguiría introduciendo la línea siguiente en mi Squid.conf 1 http_port 3128 Aunque como lo queremos es crear un Proxy Transparente, comentaremos la línea con un corchete para que no tenga efecto o, directamente, la borraremos. 1 # http_port 3128 En lugar de esto, introduciremos una nueva línea en la que indicaremos el puerto en el que escuchará Squid de manera transparente. 1 http_port 172.20.0.1:8080 transparent Como vemos he indicado la IP desde la que escucha el servidor proxy (sin esto me daba problemas) y el puerto 8080 (puede ser cualquier otro) separado por el carácter dos puntos(:). Tras el puerto colocaremos un espacio y la sentencia transparent, que indicará que se accederá de manera transparente, es decir, sin configurar ni puertos ni IP de proxy en las preferencias LAN de cada navegador web. Nombrando roles En este apartado nos fijaremos en esta sección del archivo squid.conf 1 2 3 4 5 6 7 8 9 #acl all src 0.0.0.0/0 acl manager proto cache_object acl localhost src 127.0.0.1/32 acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 acl entraip src "/ etc/ squid3 / entraip " acl nodomini url_regex "/ etc/ squid3 / nodomini " acl noextensions url_regex "etc/ squid3 / noextensions " acl nomac arp "/ etc/ squid3 / nomac " acl horarioficina time M T W H F 09:00 -14:00 Desde cada una de estas líneas acl definiremos diferentes roles, a cada uno de los cuales le asignaremos un nombre. Estos roles son grupos de elementos consistentes en direcciones IP, direcciones URL, extensiones de archivo, horas del día, días de la semana, direcciones MAC, etc… La idea es que una vez hayamos definido roles, permitiremos o rechazaremos su acceso web en función de quién/qué/desde dónde… acceda, aunque eso lo veremos en el capítulo siguiente. Analicemos el código anterior línea por línea. 1 #acl all src 0.0.0.0/0 39 Ésta opción está comentada ya que Squid 3.x no la necesita (de hecho da error si la usamos). Lo que haría sería crear un rol llamado all que engloba a todas las direcciones IP o, lo que es lo mismo, la red 0.0.0.0 con máscara /0. 1 acl manager proto cache_object Variable de uso interno de Squid. Nosotros no la utilizaremos después, simplemente la dejaremos tal y como está. 1 acl localhost src 127.0.0.1/32 Todas las peticiones procedentes de 127.0.0.1/32, es decir, de 127.0.0.1 y nadie más serán conocidas como localhost. 1 acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 Se conocerá como tolocalhost_ a toda aquella petición destinada a cualquier dirección que comience por 127. (127.0.0.0/8) o que sea 0.0.0.0/32. Nuevamente, nosotros no utilizaremos este nombre en nuestra lista de acceso y, por tanto, es de uso interno del propio squid. 1 acl entraip src "/ etc/ squid3 / entraip " Aquí vemos un ejemplo de uso de archivos externos. Consisten en archivos donde almacenaremos direcciones IP, extensiones, etc… de las que se alimentarán nuestras líneas ACL. Eso simplifica enórmemente la gestión de nuestras políticas de filtado, ya que en lugar de navegar/editar directamente el archivo squid.conf podremos acceder a nuestros listados de IP, direcciones, etc… editando directamente estos archivos. En este caso vamos a definir una lista de direcciones IP de procedencia a las cuales llamaremos entraip. Éstas direcciones estarán contenidas dentro del archivo /etc/squid/entraip, cuyo contenido será, por ejemplo: 1 172.20.0.254 2 172.20.0.11 De esta manera se asignarían las direcciones 172.20.0.254 y 172.20.0.11 a la acl entraip. El efecto de ésto sería lo mismo que introducir la siguiente línea… 1 acl entraip src 172.20.0.254 172.20.0.11 …pero con la ventaja de poder introducir directamente direcciones IP en el archivo externo o bien generarlas a partir de un script, aplicación, etc… Vamos a la siguiente línea 1 acl nodomini url_regex "/ etc/ squid3 / nodomini " Aquí generamos un nuevo rol de nombre nodomini que contendrá todas aquellas URL que contengan las cadenas indicadas dentro del archivo /etc/squid3/nodomini. Echemos una ojeada al archivo nodomini 40 1 2 3 4 . vayagif .com . minijuegos .com . cuantocabron .com . ascodevida .com Como vemos, contiene una serie de servidores web y éstos comienzan por punto. Este detalle del punto es muy importante para que le archivo funcione correctamente. Siguiente línea 1 acl noextensions url_regex "/ etc/ squid3 / noextensions " En esta línea defineremos un rol llamado noextensions con una serie de extensiones de archivo pertenecientes a las URL de las páginas por las que se navega. Estas extensiones se obtendrán del archivo /etc/squi3/noextensions 1 2 3 4 5 .exe$ .avi$ .mpg$ .mpeg$ .mp3$ Aquí vemos las extensiones de archivo con su sintaxis correcta, con punto al principio y símbolo $ al final. Esto nos resultará útil para evitar que los usuarios tengan acceso a determinados tipos de archivos al navegar por Internet. Vamos por otra línea 1 acl nomac arp "/ etc/ squid3 / nomac " Hemos estado asignando nombres a direcciones IP. Desgraciadamente en los entornos DHCP es imposible tener identificado a los equipos por su IP, ya que esta cambia a no ser que se haga una reserva. Es por ello que en ocasiones conviene tener localizados los equipos por la dirección MAC de su adaptador de red. Esta línea lo que hace es precisamente eso, definir un rol de nombre nomac con una serie de direcciones MAC contenidas dentro del archivo /etc/squid3/nomac. Veamos su contenido 1 08:00:27: C4:D7:4A Como vemos sólo hay una dirección MAC, aunque podremos añadir más, una debajo de la otra.. Vamos por la línea final 1 acl horarioficina time M T W H F 09:00 -14:00 Mediante este comando vamos a crear un rol de tipo fecha/hora donde se nos indique tanto unos días de la seamana como una franja horaria. El nombre de este rol será horarioficina. Como se puede ver, aparece una serie de letras en mayúscula (M T W…). Estas letras son días de la semana, donde la correspodencia sería: M (Lunes), T (Martes),W (Miércoles), H (Jueves), F (Viernes), A (Sábado), S (Domingo) 41 Por otra parte la cadena 09:00-14:00 correspondería a la franja horaria entre las 9 de la mañana y las 2 de la tarde. Resumiendo: El rol horario oficina correspondería al tiempo transcurrido de Lunes a Viernes de 9h a 14h. Creando una Lista de Acceso Ya tenemos creados diferentes roles, ahora deberemos autorizar o denegar accesos en función de si se cumplen esos roles o no. En Squid se sigue un sistema de listas de acceso, comú a otros muchos sistemas informáticos en red. Su funcionamiento consiste en una serie de condiciones que se van comprobando de manera secuencial. Cada una de estas condiciones tiene asociada una acción que se ejecutará cuando ésta se cumpla. La idea de estas listas es que se irá comprobando las condiciones una a una, hasta que se encuentre una que se cumpla, momento en el que se ejecutará la acción correspondiente y se ignorará el resto de las condiciones siguientes. En nuestro Squid tenemos generada la siguiente lista de acceso. 1 2 3 4 5 6 7 http_access allow localhost http_access deny nodomini http_access deny noextensions reply_body_max_size 100 MB all http_access deny nomac http_access allow entraip horarioficina http_access deny all Vamos a analizar una a una las líneas de esta lista de acceso. 1 http_access allow localhost Comprueba que se cumpla el rol localhost (origen de la petición = 127.0.0.1/32), y si es así permite el acceso al recurso web ignorando el resto de condiciones aunque se cumplan. 1 http_access deny nodomini Comprueba que se cumpla el rol nodomini (listado de dominios de páginas de productividad cero) y caso de ser así, denegaría el acceso al recurso, ignorando el resto de condiciones. 1 http_access deny noextensions Comprueba que la extensión del archivo al que se está accediendo sea una de las que aparecen en el listado del archivo noextensions, es decir, comprueba que se cumpla el rol noextensions. Caso de confirmarse dicha condición, se denegaría el acceso al recurso y se ignorarían el resto de las condiciones. 1 reply_body_max_size 100 MB all 42 Sobre el rol all (cualquier IP, rol definido por el sistema en Squid 3.x) se comprueba que el recurso accedido exceda los 100Mb de tamaño. Caso de cumplirse la condición, se denegaría el acceso y se ignorarían el resto de las condiciones. 1 http_access deny nomac Comprueba el contenido de las direcciones MAC del rol nomac, caso de cumplirse (coincidendia de dirección MAC del equipo) se denegaría el acceso y se ignorarían el resto de condiciones. 1 http_access allow entraip horarioficina Comprueba si la petición cumple las directivas entraip Y horarioficina (es decir, ambas a la vez). Caso de ser así permite el acceso al recurso web y se ignorarían el resto de condiciones. 1 http_access deny all Cierra el paso al recurso web a todas las peticiones. Es la regla final que se aplica a las peticiones que no cumplen ninguna de las condiciones anteriores. Squid 2.7 Por defecto, y a no ser que le indiquemos lo contrario indicando que queremos instalar squid3 en lugar de squid a secas, se nos instalará la versión 2.7 de Squid. Usar Squid 2 supone tener que renunciar a algunas directivas sólo disponible para la versión 3, así como tener que modificar otras para que funcionen correctamente. El principal cambio radica en que el rol all, que en Squid 3 ya viene definido por defecto, pero que ha de ser creado manualmente en Squid 2.7. Esto nos llevaría a crear una línea acl más. 1 acl all src 0.0.0.0/0 Por lo demás también hay algunos cambios a nivel de las líneas de gestión de caché. De entre las directivas usadas en el proyecto se tendría que cambiar esta directiva de Squid 3. 1 reply_body_max_size 100 MB all Por esta otra de Squid 2, de idéntico efecto. Variando un poco la cifra, ya que como todo el mundo sabe la conversión entre unidades de almacenamiento se hace en escalas de 1024. 1 reply_body_max_size 100000000 deny all Squid.conf definitivo Finalmente, y tras hacer modificaciones a localización y tamaños de caché, etc… el squid.conf final es este: 1 2 3 4 5 # Puerto principal de Squid , tal y como esta escuchara por el puerto 8080 de # manera transparente http_port 172.20.0.1:8080 transparent # La linea siguiente permite abrir un puerto especifico para el trafico SSL. 43 6 7 8 9 10 11 12 # Generamos un # cliente cada # advertencias # solucion mas # filtrado , se certificado en nuestra maquina que sera enviado al vez que acceder a una pagian segura . El usuario recibira de seguridad a cada pagina , de manera que no es la comoda . Como aun y asi , el trafico SSL no puede ser ha optado por una herramienta externa como OpenDNS ### https_port 172.20.0.1:8081 transparent cert =/ home/maec/proxy.casa.local.cert key =/ home/maec/proxy .casa. local .key 13 14 # Parametros Cache 15 # Documentados en: http :// funnybutnot . wordpress .com /2011/12/09/ setting -up -a-squid -caching -proxy/ 16 17 cache_mem 1024 MB 18 cache_dir aufs /var/spool / squid3 1024 16 256 19 maximum_object_size 5120 MB 20 cache_store_log /var/log/ squid3 / store .log 21 coredump_dir /var/ spool / squid3 22 refresh_pattern ^ftp: 1440 20% 10080 23 refresh_pattern ^ gopher : 1440 0% 1440 24 refresh_pattern -i (/cgi -bin /|\?) 0 0% 0 25 refresh_pattern . 0 20% 4320 26 quick_abort_min -1 QB 27 read_ahead_gap 1 MB 28 positive_dns_ttl 30 second 29 negative_dns_ttl 1 second 30 minimum_expiry_time 600 seconds 31 chunked_request_body_max_size 4096 KB # compatible solo con squid 3.0 32 33 # Declaracion de variables para la lista de acceso 34 35 # La siguiente linea es requerida en Squid2 36 ## acl all src 0.0.0.0/0 37 acl manager proto cache_object 38 acl localhost src 127.0.0.1/32 39 acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 40 acl entraip src "/ etc/ squid / entraip " 41 acl nodomini url_regex "/ etc/ squid/ nodomini " 42 acl noextensions url_regex "/ etc/ squid/ noextensions " 43 acl nomac arp "/ etc/ squid / nomac " 44 acl horarioficina time M T W H F 08:00 -14:00 45 http_access allow manager localhost 46 http_access deny manager 47 http_access deny to_localhost 48 http_access allow localhost 49 50 # Lista de acceso . Se iran procesando las lineas una por una. Una vez se 51 # cumpla la condicion de una , ya no se procesaran las demas 52 53 http_access allow localhost 54 http_access deny nodomini 55 http_access deny noextensions 56 reply_body_max_size 100 MB all 57 http_access deny nomac 58 http_access allow entraip horarioficina 59 60 # Finalmente cerramos el paso a toda peticion que no cumpla ninguna de las 44 61 # condiciones anteriores 62 http_access deny all Política hasta en Squid: LRU, LFUDA, GDSF Introducción Como bien sabemos, una de las principales características de Squid es que permite guardar en caché objetos de las páginas web visitadas. De esta manera si un usuario accede a una página previamente visitada por otro, se encontrará con que Squid no se descargará nuevamente los objetos redundantes de Internet, sino que los obtendrá directamente de la caché, haciendo que para el cliente la carga de la página resulte más ágil y el ancho de banda gastado inferior. Esta memoria caché está acotada por un parámetro que deberemos definir en nuestro archivo squid.conf. En el ejemplo anterior pusimos lo siguiente: 1 cache_dir aufs /var/spool / squid3 1024 16 256 Esta directiva nos crea un espacio de caché en disco de 1024Mb subdividido en directorios donde habrán 16 directorios en el primer nivel y 256 cada uno de los segundos niveles. Esto está bien, pero llegará un momento en que el espacio de la caché de disco se acabará. Justo en ese preciso instante es donde el sistema deberá decidir qué objetos de la caché desea eliminar para dar paso a los nuevos objetos entrantes. Ahí es donde entrarán en funcionamiento las Políticas de Reemplazo en la caché web. Clases y usos En Squid tenemos 4 políticas de reemplazo: LRU, heap LFUDA, heap GDSF y heap LRU, siendo la primera la que se aplicará por defecto si no se indica lo contrario. Dichas políticas podrán ser activadas mediante una directiva que deberá aparecer justo antes del elemento caché que queramos cambiar. La directiva en cuestión se llama cache_replacement_policy. De esta manera, para alterar el comportamiento del ejemplo anterior utilizando una política de reemplazo heap GDSF deberíamos modificar nuestro squid.conf de la siguiente manera. 1 cache_replacement_policy heap GDSF 2 cache_dir aufs /var/spool / squid3 1024 16 256 Repasemos el efecto de las diferents políticas de reemplazo en nuestra caché Squid. LRU Acrónimo de Least Recently Used, que traduce como Menos Recientemente Utilizado. En este algoritmo los objetos que fueron accedidos hace mucho tiempo, son eliminados primero, manteniendo siempre en el caché a los objetos más recientemente solicitados. 45 heap LFUDA Least Frequently Used with Dynamic Aging, que se traduce como Menos Frecuentemente Utilizado con Envejecimiento Dinámico. Se trata de un algoritmo que tiene en cuenta dos factores: 1- Frecuencia de uso: A uso menos frecuente de un objeto web, más posibilidades de que este sea eliminado de la caché. 2- Tamaño: A objeto de mayor tamaño, menos posibilidades de que este sea eliminado de la caché. Se trata de una modalidad en la que prima la cantidad de bytes de tráfico ahorrados a los clientes sobre la cantidad de hits sobre cache. heap GDSF Acrónimo de GreedyDual Size Frequency. Se trata de un algoritmo de reemplazamiento que prima importancia sobre el HIT rate (cantidad de objetos cargados directamente de la caché). Suele preferir almacenar gran cantidad de objetos pequeños en caché que pocos y grandes, haciendo que el % de posibilidades de que el objeto deseado esté en la caché sea mayor. Navegando por los logs de Squid Como buen programa Linux que es, Squid guarda registros de todas las acciones en /var/log/squid. El archivo que nos interesa más es access.log Este archivo se puede monitorizar en tiempo real, dándonos como resultado interesante información. De hecho, si instalamos el programa de coloreado de sintaxis ccsze (sudo aptitude install ccsze), podemos obtener unos listados bastante visuales con este comando. tail -f /var/log/squid3/access.log | ccze -CA 46 Columnas de access.log El contenido del log se nos muestra en un total de 10 columnas que describiré a continuación 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Hora: Muestra la hora y día en en los que se ha realizado la petición. Duracion: Muestra el tiempo transcurrido por la petición Dirección del cliente: Dirección IP del cliente que ha realizado la petición Código de resultado: Esta columna se compone de los elementos separados por una barra (elemento1/elemento2). El primer elemento nos muestra el resultado de la solicitud de cache a Squid. Normalmente un resultado de tipo HIT muestra un elemento que no ha sido descargado de Internet ya que estaba previamente almacenado en la cache, mientras que los resultados de tipo MISS suelen hacer referencia a elementos que por distintos motivos han tenido que ser descargados de Internet. Tenemos más información sobre estos códigos en http: //www.linofee.org/~jel/proxy/Squid/accesslog.shtml. El segundo elemento nos muestra el código de error que ha dado la petición, por ejemplo, un código 200 nos muestra un OK, mientras que un 404 nos estaría dando un NOT FOUND (no encontrado). bytes: Tamaño del objeto descargado de la red, tener en cuenta que no sólo es el tamaño del objeto en sí, sino que también se tienen en cuenta sus encabezados. Método: Método utilizado en la petición (GET, PUT, POST, DELETE, HEAD…) URL: Dirección URL sobre la que se ha realizado la petición rfc931: Deshabilitado por defecto Hierarchy code: Codigo de SQUID que nos indica cómo fue tratado el cache Type: Tipo de objeto al que se ha accedido. Videtutorial: Squid + IPtables Se ha realizado un pequeño vídeo donde se ve a grandes rasgos coómo configurar e instalar Squid, así como la manera de hacer que funcione en modo no transparente: http://youtu.be/FFxCdQZaVAs En la parte final del video también podemos ver cómo se configura el tema de IPTables, aunque eso lo veremos en el tema siguiente. 6 IPTables Introducción IPtables, qué es IPTables? IPtables antes que nada es un Firewall, un cortafuegos, que es capaz de cortar las peticiones no deseadas para mayor seguridad del sistema con el que se está trabajando. Pero no sólo eso, IPTables también puede trabajar de manera que nuestra máquina Linux actue como un Router, es decir, que sepa gestionar eficientemente peticiones que en principio no son para él. Se trata de una herramienta extremadamente compleja y potente que utilizaremos durante este proyecto y que iremos documentando en la medida que la vayamos necesitando. De cara a nosotros, IPTables no es más que un comando Linux que iremos ejecutando tantas veces como reglas queramos definir. Si queremos cortar los pings a nuestra máquina, deberemos ejecutar iptables, si además quedemos permitirlo al resto de máquinas, deberemos volverlo a ejecutar, etc… Sea como fuere, hemos de tener en cuenta que al hablar de iptables siempre se aplicará aquella directiva más específica. Por ejemplo, si con una directiva corto todo el tráfico de entrada a la interfaz eth1 pero luego con otra lo abro por el puerto 80, al llegar algo por este puerto será aceptado aunque haya otra directiva más general que en teoría corte el paso. Es por ello que lo más conveniente en la mayoría de casos es crear un script con todas las reglas deseadas y colocarlo en algún lugar donde se ejecute solo. Tipos de peticiones Filtrado Las reglas de filtrado de iptables se pueden clasificar en tres tipos según la manera como vayan a ser procesadas por nuestro sistema. En general podemos clasificar las reglas en tres grandes tipos. INPUT: Se utiliza para filtrar paquetes que entran y que van a ser procesado por la própia máquina desde la que se ejecuta el firewall. Ejemplo: Solicitud de página web a Apache • OUTPUT: Se utiliza para filtrar paquetes que salen de la máquina y que acaban de ser procesadors por la máquina. Ejemplo: Respuesta a la solicitud de una página web a Apache. • 47 48 • FORWARD: Peticiones que no van a la propia máquina. Ejemplos: - iptables -P INPUT DROP: Deniega (DROP) todas las peticiones de entrada - iptables -A INPUT -i eth1 -s 192.168.0.1 -p TCP –dport 80 -j ACCEPT: Acepta todas aquellas peticiones que entren por la interfaz eth1 procedente de 192.168.0.1 y que vayan a ser procesadas por el puerto 80 (www/Apache). Reglas NAT Las reglas NAT son aquellas que son capaces de cambiar el origen o destino de un paquete que pase a través de nuestra red. Estas se dividen en dos tipos. PREROUTING (DNAT): Se trata de un tipo de enmascaramiento que permite modificar el destino de una trama. Este tipo de regla se aplicará según los paquetes entran (de ahí el término prerouting). Nosotros lo utlizaremos para hacer que todas las tramas destinadas al puerto 80 (www) vayan destinadas al puerto 8080 (squid) • POSTROUTING (SNAT): Se trata de un tipo de enmascaramiento que permite modificar el origen de una trama justo antes de ser enviada. El tema de que este proceso se llame “Post” (a posteriori) es un detalle importante, ya que significa que cualquier otro servicio de la máquina Linux (encaminamiento, filtrado de paquetes) verá el paquete sin cambiar debido a que el cambio en las cabeceras se efectuará cuando el paquete salga. • Ejemplo: 1 iptables -t nat -A PREROUTING -i eth1 -p tcp -s 172.20.0.0/24 --dport 80 -j DNAT --to 172.20.0.1:8080 Significado: _“Haz que toda trama que entre por eth1 procedente de cualquier IP perteneciente a 172.20.0.0/24 y cuyo destino fuera el puerto 80 cambie de destino y vaya al puerto 8080 de la IP 172.20.0.1” Desglosemos la regla opción a opción: 49 Características de la regla -t nat: Los parámetros del comando serán aplicados a la tabla NAT -A: “Append”, es decir, añade lo que se indique en esta regla al conjunto de reglas de la tabla que estamos modificando (en este caso la tabla NAT). PREROUTING: Se realizará un proceso de Prerouting. Esto implicará que el destino de la trama procesada será modificado. Luego veremos cómo. Condiciones: Sólo se procesarán tramas que cumplan todas estas condiciones… -i eth1: Se procesarán las tramas que entren (-i significa “input”, “entrada”) por la interfaz eth1, que en nuestro caso es la red interna. Las tramas procedentes de otras interfaces no serán procesadas por esta regla -p tcp: Se aplicará la regla a tramas de protocolo TCP -s 172.20.0.0/24 –dport 80: Serán procesadas aquellas tramas de origen 172.20.0.0/24 con destino al puerto 80 Acciones a Realizar: Qué se hará con la trama que cumpla las condiciones -j DNAT: Se realizará una acción (-j) que será, en este caso un enmascaramiento de destino de la trama (DNAT) –to 172.20.0.1:8080: Aquí se indica el nuevo destino de la trama procesada. En este caso el nuevo destino será el puerto 8080 de 172.20.0.1, casualmente el punto por el que escucha Squid. Nuestro listado de reglas A continuación un listado comentado con las diferentes reglas que se van a aplicar. Como son una serie comandos que serán ejecutados uno tras otro a modo de Script. Las líneas que comienzan por almohadilla (#) no se ejecutarán y sólo sirven para comentar la función de los comandos inmediatamente inferiores. En la sección Ejecutar nuestras reglas de iptables al arrancar el equipo veremos cómo implementar el script. Aquí sólo analizaremos a grandes rasgos la función del mismo. La primera sección del archivo sirve para definir variables que iremos utilizando a lo largo del Script. De esta manera si cambiamos la dirección IP de nuestro servidor, únicamente tendremos que modificar el valor de la variable $SQUID_SERVER, en lugar de modificar una a una las reglas en las que aparezca esa IP. 1 2 3 4 5 6 7 8 # IP de la Maquina con Squid SQUID_SERVER ="172.20.0.1" # Interfaz conectada a Internet INTERNET =" eth0" # Interfaz conectada a la Red Local LAN_IN =" eth1" # Puerto por el que escucha Squid SQUID_PORT ="8080" Ahora reiniciamos todas las tablas. Las de Filtrado (por defecto), las NAT y las MANGLE. Se utiliza el parámetro -F (flush) y -X (borrar cadenas). Una vez ejecutados estas líneas del script las reglas quedarán a cero, haciendo que las futuras reglas no interfieran con otras que pudiésemos tener definidas anteriormente. 50 1 2 3 4 5 6 7 8 9 # Limpiando filtros , tablas NAT y tablas MANGLE # Con esto quedara todo pro defecto y podre aplicar # mis propias reglas sin que interfieran las anteriores iptables -F iptables -X iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X Carga de módulos en el Kernel. Necesario para poder enmascarar protocolos como FTP. 1 2 3 4 # Cargando modulos necesarios modprobe ip_conntrack modprobe ip_conntrack_ftp modprobe ip_nat_ftp Importante: Este comando activa el reenvío IP en nuestro Kernel. Es fundamental para conseguir que las futuras reglas funcionen. 1 # Activamos el reenvio IP en el Kernel 2 echo 1 > /proc/sys/net/ipv4/ ip_forward Comenzamos con las reglas más generales que afectarán a todo lo que entra y todo lo que sale de nuestra máquina. Vamos a hacer que todo el tráfico de entrada (INPUT) sea cortado, ocasionando consecuencias como no permitir que alguien inicie una sesión SSH, FTP, Web… contra mi servidor. Luego ya crearemos excepciones con reglas más particulares que prevaleceran sobre esta regla general. El tráfico de salida (OUTPUT) será permitido. 1 2 3 4 5 # Ajustamos politicas por defecto . # Trafico de entrada con destino el servidor --> Cortado # Trafico de salida procedente del servidor --> Aceptado iptables -P INPUT DROP iptables -P OUTPUT ACCEPT Estas dos reglas son más particulares que las anteriores (luego predominan) y hacen que la interfaz de red Loopback tenga acceso ilimitado tanto de entrada (-i = INPUT) como de salida (-o = OUTPUT). Pesando un poco nos podemos dar cuenta de que la segunda regla, la de salida, no es necesaria, ya que existe una regla más general que ya permitía el acceso… de todas maneras se ha incluído para hacer que siga permitiéndose tráfico de salida a Loopback aunque modifiquemos las reglas anteriores con un iptables -P OUTPUT DROP. 1 # Acceso ilimitado de entrada / salida para Loopback 2 iptables -A INPUT -i lo -j ACCEPT 3 iptables -A OUTPUT -o lo -j ACCEPT Recordemos que está cortado todo el tráfico de entrada. La regla siguiente hará que sean aceptadas peticiones UDP, DNS y FTP procedentes de la interfaz de internet (eth0). Importante para lo que vendrá luego. 51 1 # Permitir UDP , DNS y FTP pasivo procedente de Internet 2 iptables -A INPUT -i $INTERNET -m state --state ESTABLISHED , RELATED -j ACCEPT Una regla doble y muy importante, ya que dará conectividad con Internet a toda la red interna. La primera regla realiza un MASQUERADE a . Dicho masquerade consiste en que cada vez que que una máquina de la red interna intenta acceder a un recurso del exterior, la máquina Linux automáticamente ruteara toda la información a la dirección correspondiente de Internet. Cuando los datos retornen al ruteador éste sera capaz de enviar la información al Host original. La segunda regla habilita todo aquel reenvío de tramas procedentes de la interfaz de red Interna (eth1), de esa manera no habrá problema con la regla anterior. 1 # Hace que el sistema actue como un Router para el resto de la red 2 iptables -t nat -A POSTROUTING -o $INTERNET -j MASQUERADE 3 iptables -A FORWARD -i $LAN_IN -j ACCEPT La regla siguiente da acceso total de entrada y salida a la interna (eth1). 1 # Acceso ilimitado para la LAN 2 iptables -A INPUT -i $LAN_IN -j ACCEPT 3 iptables -A OUTPUT -o $LAN_IN -j ACCEPT Una regla aún más particular que prevalecerá sobre el resto. Consistirá el captar todo el tráfico que entre por la interfaz Interna (eth1) con destino puerto 80 y modificará su destino (DNAT), haciendo que vaya a la IP y puerto del servidor Squid. 1 # Entrada que efectua DNAT a todas las peticiones recibidas por la interfaz de red interna 2 # con destino puerto 80 (www) y efectura un DNAT ( cambia destino ) haciendo que vayan al 3 # puerto 8080 de la IP del servidor Squid. Esto hace que nuestra maquina actue como proxy 4 # transparente . 5 iptables -t nat -A PREROUTING -i $LAN_IN -p tcp -s 172.20.0.0/24 --dport 80 -j DNAT --to $SQUID_SERVER : $SQUID_PORT Con esto ya tenemos completado nuestro Cortafuegos/Router. Ahora vamos a abrir algunos puertos en la Interfaz externa (eth0, recordemos que cerrada -DROP- por defecto) para permitir conexiones SSH, Web y Webmin desde el exterior. Podemos añadir tantas reglas como quedamos para abrir otros servicios, o inclusive realizar reglas con DNAT que nos redirijan ciertas peticiones a puertos e IP distintos… ¡imaginación al poder! 1 2 3 4 5 6 7 # Abrimos algunos puertos para # Webmin ( puerto 10000) iptables -A INPUT -i $INTERNET # SSH ( puerto 22) iptables -A INPUT -i $INTERNET # WWW ( puerto 80) iptables -A INPUT -i $INTERNET que sean accesibles desde Internet -p tcp --dport 10000 -j ACCEPT -p tcp --dport 22 -j ACCEPT -p tcp --dport 80 -j ACCEPT Finalmente Logeamos todo lo que suceda a /var/log/messages. Podremos ver en tiempo real lo que va sucediendo con un tail -f /var/log/messages. 52 1 # Realizamos un log de todo lo que suceda (/ var/log/ messages ) 2 iptables -A INPUT -j LOG Ejecutar nuestras reglas de iptables al arrancar el equipo Generando el Script nat.sh Muy bien, ya sabemos qué reglas necesitamos y con que comandos se llaman. Ahora tenemos que buscar la manera de que se ejecuten todas de golpe y al iniciar el sistema. La manera más sencilla de que se ejecuten todas de golpe sería con un script que generaríamos con un editor de texto. Yo lo generaré en un buen lugar como /usr/local/bin y le llamaré nat.sh. Además insertaré las siguientes líneas al inicio del mismo para poder ejecutarlo automáticamente al iniciar el sistema y nos funcione (luego veremos cómo se hace eso): 1 2 3 4 5 6 7 8 9 10 11 #!/ bin/sh ### BEGIN INIT INFO # Provides : # Required - Start: # Required -Stop: # Default -Start: # Default -Stop: # Short - Description : # Description : # ### END INIT INFO blabla $syslog $syslog 2 3 4 5 0 1 6 blabla Una vez generado el archivo lo convertiremos en ejecutable: sudo chmod +x /usr/local/bin/nat.sh De esa manera podremos arrancarlo siempre que queramos escribiendo nat.sh desde la línea de comandos. Arrancando nat.sh automáticamente al iniciar el sistema Ya tenemos nuestro Script. Ahora deberemos hacer que se ejecute automáticamente al iniciar el sistema. Lo primero que deberíamos hacer es copiar nuestro Script al directorio /etc/init.d, pero como no queremos tener nuestro archivo duplicado en dos ubicaciones, lo que haremos será generar un enlace simbólico con este comando sudo ln -s /usr/local/nat.sh /etc/init.d/nat.sh 53 Un enlace simbólico vendría a ser similar a un acceso directo de Windows pero con la diferencia que a todos los efectos el enlace es tan válido como el archivo original, cosa que hará que nuestro nat.sh sea ubicuo. Una vez enlazado nat.sh en el directorio init.d, deberemos informar al sistema de que hay un archivo nuevo en ese directorio y que deseamos que se ejecute automáticamente al arrancar. Se hará así update-rc.d nat.sh defaults 99 Si por algún motivo deseamos no seguir ejecutando nat.sh al iniciar el sistema, deberemos utilizar este otro comando update-rc.d -f nat.sh remove Videotutorial: Squid+Iptables A partir del minuto 21 del vídeo anterior se comienza a hablar de temas relacionados con el tema actual. Se configuran Squid en modo transparente y se ejecutan los comandos iptables necesarios para que toda trama destinada al puerto 80 alimente a nuestro squid. Lo podemos ver en esta dirección: http://youtu.be/FFxCdQZaVAs?t=21m2s Documentación Adicional Lo visto en este capítulo no es más que una visión muy por encima de todo lo que nos puede aportar IPTables. Dado que hay multitud de opciones que se escapan de la finalidad de este proyecto, aportaré algunos enlaces interesantes para ampliar información sobre esta magnífica herramienta. • • • • • • • Sitio Web de IPTables: http://www.netfilter.org/projects/iptables/index.html Wikipedia: https://wiki.archlinux.org/index.php/Iptables_(Espa%C3%B1ol) IPTables en Debian: https://wiki.debian.org/iptables IPTables en 21 Segundos: http://www.pello.info/filez/IPTABLES_en_21_segundos.html Manual Práctico con Ejemplos: http://www.pello.info/filez/firewall/iptables.html Documentación de Ubuntu: http://doc.ubuntu-es.org/Iptables Página MAN de IPTables: http://ipset.netfilter.org/iptables.man.html 7 OpenDNS: Filtrado por DNS Introducción Ya hemos generado una serie de filtros a nivel de proxy. Ahora vamos a utilizar un sistema externo de listas negras que complemente todo lo visto anteriormente y que además nos proporcione una seguridad extra. Existen varias herramientas para ello, pero vamos a utilizar una que es especialmente útil: OpenDNS (http://www.opendns.com/). Según Wikipedia (http://es.wikipedia.org/wiki/OpenDNS): OpenDNS es una empresa que ofrece el servicio de resolución de nombres de dominio (DNS) gratuito (para uso privado en el hogar) y abierto en su versión más básica y original. Fue fundada en noviembre de 2005 por David Ulevitch. Más tarde añadió características opcionales gratuitas: corrección de errores ortográficos, filtrado de contenidos, protección contra phishing y robo de identidad, malware básico (Conficker y vulnerabilidades de Internet Explorer) configurables a través de un panel de control, previo registro en su sitio web. El servicio básico gratuito se financia a través de publicidad en las páginas de bloqueo de contenidos y en páginas de búsqueda generadas tras un intento de navegación fallido como resultado de la introducción de dominios inexistentes en la URL de la barra de navegación del navegador. A nivel práctico consiste en dos servidores DNS que deberemos configurar en nuestra máquina como DNS primaria y DNS secundaria (208.67.222.222 y 208.67.220.220). Se trata en realidad de un entramado de servidores DNS con varias localizaciones y un sistema de caché DNS que, en teoría, aporta un extra de velocidad a nuestras peticiones DNS. Sin embargo también aporta caracteristicas avanzadas de seguridad, pudiendo hacer que estos servidores DNS rechacen peticiones a recursos no seguros o que no nos interesan. Hacer que BIND utilice OpenDNS En realidad éste es un paso que ya deberíamos tener hecho. La idea es que nuestro servidor Proxy, tenga configurados los DNS de OpenDNS como forwarders. De esta manera toda petición DNS que no pudiera ser resuelta por nuestro Bind (las direcciones locales) se enviarían a los servidores de OpenDNS. 54 55 Como estamos forzando a nuestros usuarios a usar nuestro servidor trasto como servidor DNS, se los estará forzando también a usar OpenDNS para la salida a Internet y, por consiguiente, a pasar por los filtros OpenDNS que queramos imponer. Recordemos que para configurar nuestro servidor DNS como forwarder, es necesario editar el archivo named.conf.options y hacer que aparezcan estas líneas. 1 2 3 4 forwarders { 208.67.222.222; 208.67.220.220; }; Hacer que Squid utilice OpenDNS Otra manera de hacer que nuestros usuarios pasen por los servicios de OpenDNS es configurar sus servidores dentro del archivo de configuración de Squid (/etc/squid3/squid.conf). La manera de conseguir esto es mediante una directiva nueva que deberemos declarar dentro de dicho archivo de configuración. dns_nameservers 208.67.222.222 208.67.220.220 De esta manera Squid dejará de usar el servidor DNS por defecto del sistema y pasará a utilizar los que les indiquemos en ese archivo. Configurar los filtros de OpenDNS Si nos damos de alta como usuarios en OpenDNS, podremos asociar nuestra dirección IP de Internet con nuestro usuario, haciendo que cada vez que alguien entre a internet a través de nuestra conexión usando los DNS de OpenDNS, sea filtrado por los criterios que nosotros impongamos. Con OpenDNS podremos. Usar listas de filtrado predeterminadas. Por defecto nos protegen de páginas de phising y nada más, pero podemos añadir categorías pre-establecidas como sexo, juego, webmail… Dichas listas son mantenidas por la comunidad de OpenDNS y aunque no lo parezca son muy eficaces. • Crear Alias. Puedo hacer, por ejemplo, que al escribir “gg” en la barra del navegador se me envíe a http://www.google.es. • Crear listas de dominios prohibidos que se añadirán a las listas de filtrado anteriores. Si una URL está incluída en una de esas listas, se nos propondrá bloquear todas las URL de esa lista. • Estadísticas: Gracias a OpenDNS tendremos estadísticas de uso del servicio web a través de nuestraIP+OpenDNS. Podremos saber qué páginas han sido las más bloqueadas, cuáles las más populares, qué horario es el que tiene más tráfico de red, etc… • El funcionamiento de OpenDNS y la creación de estas listas será tratado con más detalle a través de un video desde el que veremos su funcionamiento y lo simple de su configuración 56 Configurando ddclient OpenDNS va muy bien si tenemos una dirección IP fija en internet. Sin embargo nos dará problemas si intentamos acceder desde una conexión con dirección IP dinámica (lo más normal hoy en día) ya que cada vez que cambie nuestra IP OpenDNS ya no nos reconocerá como usuarios de su servicio y ya no bloqueará ningún contenido indeseado. Para evitar esto existe una herramienta que informará automáticamente a openDNS de que nuestro usuario ha cambiado de dirección IP. Esta herramienta se llama ddclient y está incluída en los repositorios de Debian, de manera que podremos instalarla fácilmente ejecutando el comando siguiente. sudo aptitude install ddclient Nos aparecerá un asistente de configuración. No importan los datos que introduzcamos, ya que al final todo se configurará correctamente dejando el archivo /etc/ddclient.conf tal y como aparece a continuación: 1 2 3 4 5 6 7 8 daemon =60 use=web , web=myip. dnsomatic .com ssl=yes server = updates . opendns .com protocol = dyndns2 login = micorreo@enopendns .com password = micontraseña mi_red Donde deberemos cambiar estos datos: - [email protected]: Dirección de correo con la que nos hemos dado de alta en OpenDNS - micontraseña: Contraseña asociada a nuestra cuenta de OpenDNS - mi_red: Nombre de la red que hemos creado en nuestra cuenta de OpenDNS Finalmente, y una vez hemos editado correctamente el archivo, deberemos reiniciar el servicio ddclient. sudo service ddclient restart De esta manera el servicio ddclient se actualizará cada minuto (daemon=60), pudiendo aumentar este valor a voluntad editando el archivo y reiniciando el servicio. Video Tutorial: Un paseo por OpenDNS Se ha creado un pequeño vídeo en el que hago un repaso a lo largo de las diferentes opciones de OpenDNS y su utilidad. Por otra parte se habla un poco del cliente de actualización ddclient así como del proceso de alta en OpenDNS. El vídeo puede ser accedido desde esta dirección: G5ZDJl9Y-i8 https://www.youtube.com/watch?v=