miércoles, 18 de mayo de 2016

Manual para la creación de un proxy transparente

Manual para la creación de un proxy transparente.

Facultad de Estudios Superiores Cuatitlán C-4. Licenciatura en Informática.
Proyecto realizado para la materia de Redes II.
Integrantes del equipo:

Allende Ponciano Ricardo.
Carrillo Frías Daniel.
Durán Cruz Gustavo.
Martínez García César.
Martínez Segundo Ricardo Josúe.

En este blog se mostrarán los pasos a seguir para poder crear un servidor proxy transparente que corra sobre una distribución GNU/Linux. La máquina que sirve como proxy será llamada a lo largo del proyecto como máquina servidor y las que reciban conexión a la red por medio de ella las llamaremos máquinas cliente o cliente.
Si se quiere conocer más acerca de un proxy, se puede encontrar información en los siguientes enlaces:

Información de un proxy.
Tipos de Proxy.

La siguiente figura ejemplifica qué se quiere hacer.


Dicho de una forma, se brindará Internet a 2 redes de computadoras privadas a través de la conexión que nos brinda nuestro ISP (es este caso es el de la FES Cuautitlán). El servidor proxy (o proxy caché) estará en la máquina servidor contará con 3 interfaces de red, una que estará conectada a Internet, y las otras 2 a un switch, de donde se conectarán los equipos cliente.

Los componentes que se utilizarán son los siguientes.
Computadora que servirá como proxy.
3 tarjetas o interfaces de red.
Cables ethernet.
Conexión a Internet.

Software utilizado para la creación del servidor proxy transparente.
Distribución GNU/Linux. Es el sistema operativo sobre el que se ejecutará el servidor. En este caso nosotros optamos por utilizar Ubuntu en su versión 15.10 (aunque cualquier distribución GNU/Linux debería funcionar de forma semejante, salvo por algunos comandos como el de instalación de paquetes o la verificación de servicios activos).
En el siguiente enlace se muestran los pasos a seguir para instalar Ubuntu junto a un sistema Windows en Dual Boot (que se pueda iniciar uno u otro mediante un menú que aparece al encenderse la computadora [GRUB], dependiendo de la necesidad).

Guía para instalar Ubuntu 15.10


Una vez que tengamos el sistema Ubuntu, debemos de instalar los siguientes paquetes:

Servidor DHCP. Con este servidor podremos asignar una dirección IP de un segmento que más adelante determinaremos, además claro de una puerta de enlace (Gateway) y el servidor DNS con el que podrá resolver nombres a los clientes de la red. En este caso se utiliza uno llamado isc-dhcp-server y la forma de instalarlo es la siguiente: Ir a la terminal de Ubuntu (presionar tecla Windows y escribir terminal), después de eso lo instalamos mediante el siguiente comando:
sudo apt-get install isc-shcp-server
NOTA: debemos ingresar nuestra contraseña de súper usuario para poder continuar con la instalación.

Servidor proxy. Éste es uno de los principales paquetes que necesitamos y en este caso usaremos un llamado squid; el comando para instalarlo es el siguiente:
sudo apt-get install squid3
Recordemos que, para crear un proxy transparente, es necesario enrutar las peticiones de las máquinas cliente hacia la máquina servidor, para que ésta pueda responderlas adecuadamente. Para ello utilizaremos un Firewall (cortafuegos).

Información de IPTables.



Comenzando con el proceso.


Para crear nuestro proxy transparente, nosotros utilizamos una computadora portátil con las siguientes características:

Una interfaz de red con el nombre: enp2s0
Una interfaz de red inalámbrica.
Memoria RAM 8 GB.
Procesador Intel Core i5 5200U
Ubuntu 15.10 con el kernel Linux 4.2 instalado en una partición con 20 GB.

Recordemos que para realizar este servidor con 2 redes privadas, requerimos de 3 interfaces de red en la máquina servidor (una que esté conectada al ISP, y las otras dos darán conexión a las subredes a través de switchs), por lo que necesitamos de otras 2 interfaces para poder hacer trabajar el servidor.
Al utilizar una computadora portátil, no tenemos posibilidad de conectar otras dos tarjetas de red por medio de expansión PCI, pero sí pudimos hacerlo a través de 2 adaptadores de red USB Ethernet como los de la siguiente imagen:




Los nombres de esos dos adaptadores son:

enx00e04c362abd                           y                             enx00e04c534458

Para conocer el nombre de las tarjetas que están conectadas a la computadora, se utiliza el siguiente comando:

ifconfig


Configurando la dirección IP de las interfaces de red.

El primer paso que realizamos es configurar dos interfaces para que tengan una dirección IP estática y sirvan como puertas en enlace, y otra que tenga una IP dinámica y que la reciba desde el servidor DHCP de nuestro Proveedor de Servicios de Internet. En nuestro caso fue de la siguiente manera:

Nombre de la interfaz de red
Dirección IP
Tipo de dirección
enx00e04c362abd
Asignada dinámicamente
Dinámica
enp2s0
192.168.1.254
Estática
enx00e04c534458
192.168.2.254
Estática







Eso se hace editando un archivo que está en la ruta /etc/network/interfaces
Para su edición debemos tener permisos de super usuario, por lo que podemos abrirlos con un editor como nano, o de forma gráfica seleccionándolo con el gestor de archivos, nosotros optamos por la segunda forma, ya que es un poco más visual y para ello escribimos lo siguiente en la consola:
sudo nautilus
En este caso nuestro gestor de archivos se llama nautilus, por eso en la línea de arriba se escribe eso, si por ejemplo nuestro gestor de archivos fuera dolphin escribiríamos dolphin en lugar de nautilus.
El contenido del archivo interfaces debe ser el siguiente.

auto lo
iface lo inet loopback

#interfaz por la cual recibimos Internet
auto enx00e04c362abd
iface enx00e04c362abd inet dhcp

#brinda servicio a los clientes
auto enp2s0
                iface enp2s0 inet static
                address 192.168.1.254
                netmask 255.255.255.0
                network 192.168.1.0
                broadcast 192.168.1.255

#brinda servicio a los clientes
auto enx00e04c534458
                iface enx00e04c534458 inet static
                address 192.168.2.254
                netmask 255.255.255.0
                network 192.168.2.0
                broadcast 192.168.2.255

A continuación, paso a explicar para qué sirve cada una de estas opciones.
· auto nombre_interfaz: Hace que la interfaz se inicialice automáticamente al arrancar el equipo o al reiniciar los servicios de red (sudo service networking restart).
·  iface enp2s0 inet static: Indica que la interfaz enp2s0 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 192.168.1.254: Asigna la dirección IP 192.168.1.254 al adaptador de res que hayamos inicializado previamente (en esta línea se muestra la instrucción para la tarjeta enp2s0, es semejante para la otra, pero utilizando una dirección distinta).
·  netmask 255.255.255.0: Asigna una máscara de 24 bits a la red de la que se establezca el parámetro.
· network 192.168.1.0/192.168.2.0: Indica la dirección de red.
·  broadcast 192.168.1.255/192.168.2.255: Indica la dirección de difusión de la red. Adicionalmente podríamos introducir la línea gateway seguido de la dirección de la puerta de enlace, aunque en el caso de este proyecto no se hará uso de ésta opción.

Después de modificar el archivo interfaces, debemos reiniciar el servicio de red, con el siguiente comando:

sudo /etc/init.d/networking  restart

Configurando DHCP.

Lo primero que haremos 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). El comando para instalarlo es el siguiente

sudo apt-get install isc-dhcp-server

El siguiente paso es hacer que nuestro servidor dhcp escuche a través de las interfaces que brindarán Internet a las redes privadas internas (en nuestro caso son: enp2s0  y   enx00e04c534458). Eso lo hacemos editando el archivo que está en la ruta:
/etc/default/isc-dhcp-server

El contenido de dicho archivo es en nuestro caso (el archivo tendrá algunas líneas de cómo debe utilizarse, pero todas ellas están comentadas y se pueden borrar sin problema para la configuración, por lo que sólo ponemos la instrucción necesaria):

INTERFACES="enp2s0 enx00e04c534458"


Donde podemos ver que estamos poniendo el nombre de nuestras tarjetas de red que brindarán servicio a las 2 redes privadas separadas por un espacio en blanco.
Para que los cambios efectuados surjan efecto, debemos reiniciar el servicio con el siguiente comando en la terminal:
sudo /etc/init.d/isc-dhcp-server restart

El siguiente paso es asignar los rangos IP que se asignarán a las máquinas cliente.
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
El contenido del archivo será el siguiente

subnet 192.168.1.0 netmask 255.255.255.0{
range 192.168.1.10 192.168.1.100;
option routers 192.168.1.254;
option domain-name-servers 208.67.222.222;
default-lease-time 68000;
}

subnet 192.168.2.0 netmask 255.255.255.0{
range 192.168.2.10 192.168.2.100;
option routers 192.168.2.254;
option domain-name-servers 208.67.222.222;
default-lease-time 68000;
}


Lo que hicimos en cada línea es lo siguiente
(Las instrucciones son similares para ambas tarjetas, con la excepción del nombre y la dirección, por lo que sólo se explicaran las que correspondan a la primera)
subnet 192.168.1.0 netmask 255.255.255.0 { ... }: Define una subred 192.168.1.0/24 con máscara 255.255.255.0 y, obviamente, 192.168.1.255 como dirección de difusión.
range 192.168.1.10 192.168.1.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 192.168.1.254;: 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 interfaz de red respectiva (la dirección que en un principio pusimos como estática).
option domain-name-servers 208.67.222.222;              En esta línea establecemos qué servidor DNS resolverá las direcciones que los clientes pidan. En este caso utilizamos los servidores ‘Open 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.

Después de eso debemos reiniciar el servicio DHCP
sudo /etc/init.d/isc-dhcp-server restart

Con eso conseguimos que la máquina servidor asgine direcciones a las máquinas cliente que se conecten a él, pero aún no tienen conexión a Internet.

Preparación de un Proxy utilizando SQUID

Para instalar squid, debemos ejecutar el siguiente comando en la terminal:
sudo apt-get install squid3

Después de la instalación, debemos configurar el archivo que está en la ruta: /etc/squid3/squid.conf

El contenido del archivo será el siguiente:


http_port 3128 transparent
acl red1 src 192.168.1.0/24
acl red2 src 192.168.2.0/24
acl localh src 127.0.0.1
http_access allow localh
http_access allow red1
http_access allow red2

Con el cual ponemos la configuración más simple que brinde Internet a las máquinas cliente conectadas, poniendo las redes por las cuales se van a conectar, también se agrega el localhost de la máquina servidor. De momento no se niega ningún sitio a las máquinas cliente.
El puerto por el cual escucha Squid es por defecto el 3128, y no tiene sentido que lo cambiemos, pues cuando utilicemos IPTables direccionaremos las peticiones independientemente si es el 3128 u otro, pero es importante ponerlo en modo transparente para nuestros fines de crear un proxy transparente.
Después de realizar esas configuraciones, el siguiente paso es reiniciar Squid, para lo que usamos el siguiente comando en la terminal:

sudo /etc/init.d/squid3 restart



IPTables

Después de poner en ejecución el servicio squid correctamente, lo que procede es utilizar IPTables para trabajar de manera que nuestra máquina servidor actúe como un Router, es decir, que sepa gestionar eficientemente peticiones que en un principio no eran para él (si no que eran de las máquinas clientes a la interred).
Para este proyecto y de forma superficial podemos decir que IPTables es un comando que debemos ejecutar tantas veces como reglas tengamos, pero se debe ejecutar cada vez que la máquina se inicie. Por ello se nos hizo conveniente crear un script con todas las reglas que necesitamos y colocarlo en init.d para que se inicie solo como si fuera un daemon.

Por ello creamos un archivo en la siguiente ruta:
/etc/init.d/                                        El nombre del archivo puede ser el que nosotros queramos, en nuestro caso es                                               reglas.sh             pero para crearlo en esa ruta necesitamos permisos de súper usuario, por lo que simplemente se los damos. El contenido del archivo es el siguiente:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          Proxy_transparente
# Required-Start:    $syslog
# Required-Stop:     $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Redireccionamiento IPTables proxy
# Description: Se redireccionan las peticiones desde las 2 interfaces hacia el puerto de salida de la conexión a Internet.
#
### END INIT INFO
# IP de las puertas de enlace
SQUID_SERVER="192.168.1.254"
SQUID_SERVER2="192.168.2.254"
# Interfaz conectada a Internet
INTERNET="enx00e04c362abd"
# Interfaces conectadas a la Red Local (Las 2 tarjetas de red USB)
LAN_IN="enp2s0"
LAN_IN2="enx00e04c534458"
# Puerto por el que escucha Squid (En este caso es el que nos da por defecto, pero en modo transparente)
SQUID_PORT="3128"
# 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
# Cargando modulos necesarios
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
# Activamos el reenvio IP en el Kernel
echo 1 > /proc/sys/net/ipv4/ip_forward
}# 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
# Acceso ilimitado de entrada/salida para Loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Permitir UDP, DNS y FTP pasivo procedente de Internet
iptables -A INPUT -i $INTERNET -m state --state ESTABLISHED,RELATED -j ACCEPT
# Hace que el sistema actue como un Router para el resto de la red
iptables -t nat -A POSTROUTING -o $INTERNET -j MASQUERADE
iptables -A FORWARD -i $LAN_IN -j ACCEPT
iptables -A FORWARD -i $LAN_IN2 -j ACCEPT
# Acceso ilimitado para la LAN
iptables -A INPUT -i $LAN_IN -j ACCEPT
iptables -A INPUT -i $LAN_IN2 -j ACCEPT
iptables -A OUTPUT -o $LAN_IN -j ACCEPT
iptables -A OUTPUT -o $LAN_IN2 -j ACCEPT
# Entrada que efectua DNAT a todas las peticiones recibidas por la interfaz de red interna
# con destino puerto 80 (www) y efectura un DNAT (cambia destino) haciendo que vayan al
# puerto 8080 de la IP del servidor Squid. Esto hace que nuestra maquina actue como proxy
# transparente.
iptables -t nat -A PREROUTING -i $LAN_IN -p tcp -s 192.168.1.0/24 --dport 80 -j DNAT --to $SQUID_SERVER:$SQUID_PORT
iptables -t nat -A PREROUTING -i $LAN_IN2 -p tcp -s 192.168.2.0/24 --dport 80 -j DNAT --to $SQUID_SERVER:$SQUID_PORT
# Abrimos algunos puertos para que sean accesibles desde Internet
# SSH (puerto 22)
iptables -A INPUT -i $INTERNET -p tcp --dport 22 -j ACCEPT
# WWW (puerto 80)
iptables -A INPUT -i $INTERNET -p tcp --dport 80 -j ACCEPT
# Realizamos un log de todo lo que suceda (/var/log/messages)
iptables -A INPUT -j LOG

#######             fin del archivo   #######


Después de eso le damos permisos de ejecución con el siguiente comando en la terminal:
sudo chmod +x /etc/init.d/reglas.sh

Por último 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á con el siguiente comando en la terminal:
update-rc.d reglas.sh defaults 99


Monitoreo a través de los registros de squid.

Una forma sencilla de revisar las cosas que descargan las máquinas cliente es a través de los registros de Squid. Uno de esos archivos es Access.log , en el cual se guarda información dividida por IP de las máquinas cliente, fecha en que realizó la acción y más cosas.
La ruta del archivo es:
/var/log/squid3/access.log
Y para verla en tiempo real debemos ingresar en la terminal el siguiente comando:
tail -f /var/log/squid3/access.log
Pero esa forma de ver los registros es demasiado plana, por lo que optamos por instalar un paquete que nos ayude a verlo con un formato de colores que nos ayude a visualizarlo mejor, como lo es ccsze, para su instalación se utiliza el siguiente comando:
sudo apt-get install ccsze
Y llamamos de nuevo al registro de squid en tiempo real, usando además la aplicación que acabamos de obtener:

tail -f /var/log/squid3/access.log | ccze -CA

Lo que vemos en las columnas es lo siguiente:
1.      Hora: Muestra la hora y día en en los que se ha realizado la petición.
2.      Duracion: Muestra el tiempo transcurrido por la petición
3.      Dirección del cliente: Dirección IP del cliente que ha realizado la petición
4.  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).
5.      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.
6.      Método: Método utilizado en la petición (GET, PUT, POST, DELETE, HEAD...)
7.      URL: Dirección URL sobre la que se ha realizado la petición
8.      rfc931: Deshabilitado por defecto
9.      Hierarchy code: Codigo de SQUID que nos indica cómo fue tratado el cache
10.   Type: Tipo de objeto al que se ha accedido.


Por último mostramos una fotografía de las conexiones realizadas,  aunque por falta de presupuesto sólo pudimos tener un switch:






Su funcionamiento final visto de forma práctica es el siguiente: Conectamos computadoras al switch por medio de un cable Ethernet y con eso bastará para que esas máquinas cliente tengan conexión a Internet, sin hacer ningún tipo de configuración, como si se conectaran a su módem, pero con la pequeña diferencia de que ahora estarán navegando a través de un proxy.