# [IPTABLES] Redireccionar la accion DROP a una web

## Pablo S. Barrera

Hola. Ante todo gracias por la lectura.

Tengo configurado un Squid 3.1 e Iptables 1.4, todo esto corriendo en un firewall con proxy.

Con el Squid filtro todo el trafico que no deseo http, sitios, videos, etc. Con eso no tengo problemas.

Con Iptables estoy bloqueando todo lo que sea Https con una politica DROP por defecto y cerrando todo, abriendo solamente gmail, hotmail y algun sitio mas. Con esto me saco de encima a ultrasurf, tor y demas esquives existentes.

El problema que tengo que cuando un usuario ingresa a un sitio bloqueado por el squid salta a una pagina de error donde explica lo que se hizo y bla bla bla. Pero cuando el Iptables le cierra las puertas todo se queda dando vueltas sin pagina de error, solo una al final similar a un time out. ¿Que quiero hacer? Redireccionar los DROP o REJECT a un sitio web, como por ejemplo alguno que tenga bloqueado en squid y asi obtener el mismo error. ¿Se entiende? 

¿Es posible hacerlo? Me lei todo y no encuentro forma, el Redirect solo funciona en nat y en esa cadena yo no pongo los DROPS y demas.

Espero alguien pueda ayudarme.

Gracias de antemano

----------

## ZaPa

Hola.

Supongo que estarás aplicandos los DROPS y REJECT'S en la tabla filter (es como debe ser).

Para lo que quieres hacer no te hace falta eliminar o rechazar tráfico, solamente tienes que aplicar la redirección y punto.

Pero para hacer lo que requieres, necesitaras cambiar esas acciones a la tabla NAT para poder hacer la redirección..

Lo primero que debes hacer es eso, quitar la regla/s DROP o REJECT de SSL en la tabla filter, e implementalo de la siguiente forma:

```

iptables -t nat -I PREROUTING  -p tcp --dport 443 -j DNAT --to IP_SERVIDOR_WEB:80

```

** Sustituye IP_SERVIDOR_WEB por la ip que contenga el servidor web

Con esto, el usuario que intente visitar un sitio web con SSL, será redireccionado a tu servidor WEB.

En tu servidor web, colocarías un bonito index, informando del bloqueo y demás.

Prueba y me cuentas!!

Saludos.

----------

## Pablo S. Barrera

Genial. Te cuento algo más para ampliar la inifo. No tengo aca las lineas para mostrarte, pero te las cuento. Todo va en el orden que voy escribiendo. Los DROPS y REJECTS estan en las tablas Filter.

Tengo politica por defecto DROP en INPUT, OUTPUT y FORWARD.

Todas las politicas para los demas puertos y direcciones.

Politica de Habiilitacion de navegacion SSL para sitios que yo selecciono via un "for" y un fichero donde estan las direcciones. 

Esto deja pasar a algunos sitios SSL. El tema son los que quiero bloquear, los que no estan en ese fichero, serian todas las demas direcciones SSL posibles.

¿Donde pongo la linea que mencionas? Por que si pongo solo la linea al principio todo se va a mi servidor web. ¿Se entiende? Algunas deben de ir al servidor web y las otras acceder con normalidad (estas serian las que yo habilito mediante la tabla Filter) 

Con eso tengo mi duda.

Gracias de nuevo.

----------

## opotonil

No se si me estoy complicando demasiado, pero asi lo primero que se me ocurre es que en vez de permitirlas en la tabla filter las marques en la tabla mangle y despues compruebes la marca en la tabla nat.

Algo asi (estoy escribiendo de memoria, asi que espero no meter mucho la pata):

```

iptables -t mangle -A PREROUTING -p tcp -d $IP --dport 443 -j MARK --set-mark 0x1

iptables -t nat -A PREROUTING  -p tcp --dport 443 -m mark ! --mark 0x1 -j DNAT --to IP_SERVIDOR_WEB:80

```

Salu2.

----------

## Pablo S. Barrera

Gracias por los comentarios. No me funciono. Les pongo lo que tengo para que vean. Solo esta lo que es relevante al asunto.

En https-permitidos estan unos rangos de Ips validas. La idea es que las que no son validas vayan a una web, cualquiera sean. 

```

#########################

# Politicas por Defecto #

#########################

iptables -P INPUT DROP                  # Ignora todo el trafico entrante

iptables -P OUTPUT DROP                 # Ignora todo el trafico saliente

iptables -P FORWARD DROP                # Ignora todo el trafico pasante

iptables -t nat -P PREROUTING ACCEPT    # Acepta todo el nateo hacia el exterior

iptables -t nat -P POSTROUTING ACCEPT   # Acepta todo el nateo desde el interior

##################

# Bit de Forward #

##################

echo 1 > /proc/sys/net/ipv4/ip_forward

#################################

# Permision full para localhost #

#################################

iptables -A INPUT -i lo -j ACCEPT

iptables -A OUTPUT -o lo -j ACCEPT

iptables -t nat -A POSTROUTING -s $LAN_NET -o eth0 -j MASQUERADE

iptables -t nat -A PREROUTING -s $LAN_NET -p tcp -m multiport --dport 80,2080 -j REDIRECT --to-port 8080

for HOST in `grep -v ^# /etc/init.d/https-permitidos | awk '{print $1}'`; do

iptables -t filter -A FORWARD -i eth1 -o eth0 -s $LAN_NET -m iprange --dst-range $HOST -p tcp --dport 443 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT

iptables -t filter -A FORWARD -i eth0 -o eth1 -d $LAN_NET -m iprange --src-range $HOST -p tcp --sport 443 -m state --state RELATED,ESTABLISHED -j ACCEPT

done

```

Gracias de nuevo y sigo probando con lo que escribieron a ver si funciona de todos modos.

----------

## ZaPa

Hola.

Sencillo, haz lo siguiente.

Añade las reglas PERMISIVAS de sitios con SSL de la siguiente manera en la tabla NAT:

```

iptables -t nat -I  PREROUTING -p tcp --dport 443 -d 88.88.88.88 -j ACCEPT   //sitio 4 permitido

iptables -t nat -I PREROUTING  -p tcp --dport 443 -d 22.22.22.22 -j ACCEPT   //sitio 3 permitido

iptables -t nat -I PREROUTING  -p tcp --dport 443 -d 33.33.33.33 -j ACCEPT   //sitio 2 permitido

iptables -t nat -I PREROUTING  -p tcp --dport 443 -d 33.33.33.33 -j ACCEPT   //sitio 1 permitido

```

Con esto, añades esas reglas "PERMISIVAS" al inicio de la cadena PREROUTING (**Fijate en -I PREROUTING). 

Si concuerda la dirección de destino con alguna de estas, hará el ACCEPT. Si no, pasará a la siguiente:

Los sitios que no coincidan con las reglas anteriormente citadas, irán a parar para la regla:

```

iptables -t nat -A PREROUTING  -p tcp --dport 443 -j DNAT --to IP_SERVIDOR_WEB:80 

```

En principio esa seria la solución.

Quita el filtrado de SSL de la tabla filter y añadelo como te comento.

Saludos.

----------

## Pablo S. Barrera

ZaPa, gracias!

No se si hoy no es mi idea o algo no esta bien.

Puse lo que mencionaste y no funciona nada. Quite las reglas de la tabla filter.

Lo curioso es que poniendo solo la primer linea no funciona el sitio HTTPS

```
iptables -t nat -I  PREROUTING -p tcp --dport 443 -d MIIPSERVIDORWEBHTTPS -j ACCEPT  
```

Revise todo el script y esta ok. No se que puede ser.

----------

## ZaPa

Hola.

Precisamente en esa linea me dejé sin querer un espacio en blanco, ahora si, (copia y pega)

```

iptables -t nat -I PREROUTING -p tcp --dport 443 -d MIIPSERVIDORWEBHTTPS -j ACCEPT 

```

Habia un espacio en blanco entre -I y PREROUTING, quizás era eso lo que te ocurria.

Prueba y me comentas.

Un saludo.

----------

## Pablo S. Barrera

Lo habia quitado igual el espacio. No se que será pero algo raro hay porque no funciona. Otra forma? 

Gracias y perdon por dar tantas vueltas.

----------

## opotonil

 *Quote:*   

> 
> 
> Puse lo que mencionaste y no funciona nada. Quite las reglas de la tabla filter. 
> 
> 

 

Prueba poniendo la siguiente regla: (si tienes mas de 2 interfaces de red puede ser necesario indicarlas, como hacias)

```

iptables -t filter -A FORWARD -p tcp --dport 443 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT

```

Por lo que entiendo si tu politica por defecto en la tabla filter para FORWARD es DROP necesitaras alguna regla que deje pasar el https a la tabla nat para que lo controlen sus reglas.

Salu2.

PD: Mucho mas sencillo y mejor el sistema de ZaPa, si es que a primera hora de la mañana no soy persona.

----------

## ZaPa

Hola.

Es verdad lo que comenta opotonil, no me habia dado cuenta que tenias como politica por defecto DROP en la tabla FILTER.

Entonces deberias dejarlo todo asi:

```

//Dejamos que "siga adelante el tráfico con destino 443 (SSL)

iptables -t filter -A FORWARD -p tcp --dport 443 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT 

//Definimos lista de sitios permitidos

iptables -t nat -I  PREROUTING -p tcp --dport 443 -d 88.88.88.88 -j ACCEPT   

iptables -t nat -I PREROUTING  -p tcp --dport 443 -d 22.22.22.22 -j ACCEPT   

iptables -t nat -I PREROUTING  -p tcp --dport 443 -d 33.33.33.33 -j ACCEPT   

iptables -t nat -I PREROUTING  -p tcp --dport 443 -d 33.33.33.33 -j ACCEPT   

//Los que no coincidan van a esta regla

iptables -t nat -A PREROUTING  -p tcp --dport 443 -j DNAT --to IP_SERVIDOR_WEB:80 

```

A modo de aclaración:

** Con la primera linea le indicas a iptables que deje pasar los paquetes con estado:

  NEW (primero en entrar)

  RELATED (Paquete relacionado con otra conexión)

  ESTABLISHED (Paquete proveniente de una conexión ya establecida)

Disculpame por el error, no me fijé que tenias como politica por defecto DROP en la tabla filter en el gancho FORWARD.

Te comento otra cosa adicional pero MUY importante.

Vas a tener algunas quejas de algunos usuarios cuando intentan acceder por ejemplo a facebook,twitter y demás redes sociales que utilizan SSL. 

El motivo es que tu, estas permitiendo el acceso HACIA una IP en concreto, pero plataformas gigantescas como puede ser facebook o twitter, tienen más de 10,20, o 30 servidores haciendo balanceo entre las peticiones de los usuarios.

¿Que significa esto? Que vas a tener que anotar TODAS las direcciones ip de estos sitios y dar acceso a ellas, si no, habrán momentos que los usuarios de tu red no podrán acceder a algunas páginas con infraestructuras de este tipo.

Prueba y nos comentas.

Saludos.

----------

## Pablo S. Barrera

Claro.. esa es la idea. Tengo las direcciones a las que quiero entren, y a todas las demas no van a entrar. Esto te libera de varios problemas, mas que nada con el SSL.

El script funciono, pero tengo un pequeño problema conceptual ahora. 

Luego del DNAT --to IPDETUSERVIDOR.

Lo tengo que dirigir a 66.220.158.11 por ejemplo.. que es facebook.com y ahi lo agarra el squid y listo el tema.

Se entiende? 

No me funciona eso, tal vez DNAT es algo interno y ahi me pierdo. Les envio el script en forma privada, lamento tenga que ser asi pero no puedo publicarlo todo.

----------

## ZaPa

Hola.

No te entiendo. No pretendias que el usuario al intentar visitar una pagina web NO PERMITIDA apareciera un mensaje en su navegador? Con esto ya lo tendrias.  ¿O no te funciona?

Respecto a la info adicional que te facilite, creo que no mas has comprendido. Quisé decir que por ejemplo, la página web: facebook.com puede tener 100 ips diferentes y si tu facilitas el acceso solo a 2 ips de facebook en algunos momentos tus usuarios no van a poder acceder a facebook porque simplemente no distes acceso a TODAS las ips de FACEBOOK.

Saludos.

----------

## Pablo S. Barrera

Si. Cuando ingrese a una pagina no permitida daria un error en el navegador. Necesito cuando ingrese a una pagina como por ejemplo httpS://facebook.com lo reenvie a http://facebook.com ahi lo agarria el squid que ya filtra esa pagina.

Entiendo lo que decis.

Mi idea es:

Las ips por el puerto 443 que yo le digo pasan correctamente, son el webmail, gmail, hotmail, yahoo, bancos, etc.

Cualquier otra IP por el puerto 443 se bloquea

Mi idea es bloquear el facebook, y todo lo demas. Es mas facil setear las ips validas que las invalidas, ademas Ultrasurf, Tor y algunos mas tienen infinitas Ips.

----------

## ZaPa

Otra preguntita por curiosidad.... ¿Para que quieres que redireccione desde facebook.com:443 a facebook.com:80? 

Te bastaria con fijar un index en tu servidor web local, explicando al usuario el bloqueo y demás y ya seria suficiente. No entiendo el porque quieres meter a squid por enmedio...

Saludos.

----------

## Pablo S. Barrera

Para que el error que reciba el usuario sea el mismo. Ahi va a recibir informacion de las politicas existentes y los datos necesarios para que se comunique en caso de que no este violando las politicas y sea una pagina a la cual debe de acceder.

El tema es que no llego a mi servidor. Cuando puse la Ip del servidor no llego, si llego hasta ahi hago una redireccion html y listo. Otra cuestion es que la pagina de Squid esta armada en varias partes, las css por un lado y el html por otro. No importa mucho eso, pero llegando a mi server web ya lo tendria todo cocinado.

Las lineas que me pasaste funcionan, al menos deja pasar lo que quiero que pase, ahora la redireccion no me funciona y no entiendo bien porque. Te envie el script por privado, por una cuestion de seguridad. Por otro lado la solucion va a estar escrita aca, creo el esfuerzo de uds y mio tiene que compartirse con todos. Eso hace fuerte a Gnu/Linux, y solidarios a sus usuarios.

Gracias a ambos por ayudar, creo falta poco y nada.

----------

## ZaPa

Hola de nuevo.

Pusiste la ip de tu servidor acompañado del puerto?

iptables -t nat -A PREROUTING...... -j DNAT --to IP:80

¿El servidor web se ubica en un servidor remoto? ¿O en local?

Porfavor, pega la salida de iptables -t nat -L -v -n.

Saludos.

----------

## Pablo S. Barrera

ZaPa, puse IP y puerto como vos escribis. El servidor es el mismo equipo. 

Me parece falta alguna regla que no deja que ese redireccionamiento se de. No tengo aca el equipo, recien mañana puedo darte la salida esa. 

Gracias por la ayuda, para mi es de gran aprecio. Mañana te envio la info que pediste.

----------

## ZaPa

Hola de nuevo.

De nada hombre!! recuerda..esto es Linux  :Very Happy: 

Como pregunta adicional hasta mañana.... ¿Que ip indicaste en la reidrección NAT? La dirección local del equipo 127.0.0.1 o la IP interna de LAN?

Saludos.

----------

## Pablo S. Barrera

ja.

Hay una Ip publica y una privada, le indique esta ultima. 

Eth0=publica

Eth1=169.254.2.1/255.255.255.192

Gracias de nuevo ZaPa

----------

## ZaPa

Hola.

Si el servidor web y el script iptables que se va a encargar de realizar el redireccionamiento estan en la misma maquina, utiliza la ip local: 127.0.0.1 .

Antes en el script que me pasaste, creo haber visto filtrado en los paquetes de entrada. Al pasarle la dirección LOCAL, generará el mismo esa petición y no debes de tener problemas.

Prueba y me comentas.

Saludos.

----------

## Pablo S. Barrera

ZaPa aca esta la salida que me pediste.

IPWEBMAIL lo cambie yo claro. 

```
Chain PREROUTING (policy ACCEPT 4 packets, 562 bytes)

 pkts bytes target     prot opt in     out     source               destination

    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            IPWEBMAIL          tcp dpt:443

    0     0 REDIRECT   tcp  --  *      *       169.254.2.0/26       0.0.0.0/0           multiport dports 80,2080 redir ports 8080

    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp dpt:443 to:127.0.0.1:80

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)

 pkts bytes target     prot opt in     out     source               destination

    0     0 MASQUERADE  all  --  *      eth0    169.254.2.0/26       0.0.0.0/0

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)

 pkts bytes target     prot opt in     out     source               destination
```

Probe de poner 127.0.0.1 y nada! Igual desde un navegador pongo 127.0.0.1 y no llego a ningun lado, si pongo 169.254.2.1 si logro acceder.

----------

## Pablo S. Barrera

Encontre el problema. No tiene que ver con Iptables, sino con el redireccionamiento de un puerto SSL a un HTTP. Por eso no me funciona.

Probe de rediccionar con lo de DNAT de un 80 a un 80 en donde fuera y funciono. Probe lo mismo desde una direccion 443 a otra y me da error de certificado y luego se cae. Me parece que esta en las caracteristicas propias del Puerto 443 el error en cuestion. 

Habria que tomar la direcciones que van al 443, y que no estan en la lista de permitidas y enviarlas a otro lado. El problema es de logica y de iptables, se tienen que dar todas esas cosas.

Lo que digo es.. tomar toda peticion al 443 que este fuera de una lista de direcciones establecida, y esas direcciones marcarlas para que se envien a una pagina con un index o algo similar. Es demasiado complicado me parece.

----------

## ZaPa

Hola.

Si ese es el problema la solución es sencilla, tal cual todo como lo tienes, pon a la escucha el servidor web local en el puerto 443, y ya puedes redireccionar de 443 a tu 443 local y con un index ya en ese servidor, hacer una redirección con javascript o html hacia cualquier sitio con el puerto 80. Posiblemente esa pueda ser una solución.

Prueba y me comentas.

PD: Dudo que pueda haber problemas de redireccion desde el puerto 443 hacia el puerto 80. 

De todas formas voy a hacer la prueba. Pero si fuera así, lo escrito en mi párrafo de arriba te podría servir.

Un saludo.

----------

## ZaPa

Hola.

Comenta como te fué porfavor para ayudar al resto de usuarios de la comunidad.

Saludos.

----------

## ajcalero

 *Pablo S. Barrera wrote:*   

> Hola. Ante todo gracias por la lectura.
> 
> Tengo configurado un Squid 3.1 e Iptables 1.4, todo esto corriendo en un firewall con proxy.
> 
> Con el Squid filtro todo el trafico que no deseo http, sitios, videos, etc. Con eso no tengo problemas.
> ...

 

Esta es la solución. No des más vueltas

Firewall

http://www.maravento.com/2013/03/firewall.html

----------

## matheusluis

ha pasado algun tiempo desde que pulicaron este hilo y quisiera saber si lograron resolver el problema ya que ahora me encuentro buscando la solucion al mismo gracias y espero que puedan ayudarme

----------

