Ruter Linux + control trafico

La idea es montar un ruter en linux que conecta 2 subredes, la de empresa y una de clientes, a un canuto de Internet con ancho de banda suficiente de 100/10Mbps. La idea es repartir el ancho de banda de Internet a las 2 subredes, usaré HTB.
Además el ruter crea un tunnel VPN.

ESQUEMA
INTERNET
     |              +------------RED CLIENTES CABLEADA  
     |              |
   eth0             |
     |              |   +-------AP1 
   Linux--eth2------+---+-------AP2
     |              |   +-------AP3 
   eth1             |   +-------APn
     |              |   
     |              |
Red Empresa         +----------- PC's publicos con ip fija


La máquina linux connecta:
  • eth0 con el ruter a internet vía 192.168.1.2
  • eth1 con la red de la empresa via 10.0.3.1 (/24)
  • eth2 con la red de clientes via 192.168.2.1 (/24)
  • tun0 con la vpn openvpn
  • eth2:0 con otra red lógica para el management de los puntos de acceso.
Los puntos de acceso son ruters linksys. Podría hacer que cada cobertura wifi fuera una red propia de manera que el ruter enrutaría entre la red 192.168.2.0 y la red wifi, pero he optado para usar el ruter linksys como un switch:
  • Desactivo la interfície WAN del ruter
  • Pongo que la interfaz br0 del ruter linksys (tomas de cable como wifi) tenga una ip en una red distinta, por ejemplo 192.168.100.10 para AP1, .11 para AP2, etc.
  • Conectar el cable de la red en una toma del switch del AP (que no sea la toma WAN que hemos desactivado!)
  • Desactivar el DHCP de los puntos de acceso!
  • el PC Linux tiene que dar servicio de DHCP por eth2
De esta manera, cuando se conecta un cliente por cable o por wifi, recibe una ip de 192.168.2.x.  En principio, los clientes por cable no tienen porque conocer en que red están configurados los AP por lo que le resultaría mas costoso en tiempo poder acceder a ellos.

En el pc Linux podemos habilitar una interfície alias, eth2:0 con una ip dentro del rango de las ip's de los AP (192.168.100.1, p.e) para poder acceder a la interfaz web de los AP

Para evitar que los clientes se vean entre ellos se necesitaría que el switch de la red 192.168.2.x fueran gestionables y montar una vlan diferente para cada puerto + activar el isolate AP de los APs.


CONFIGURACION RUTER

1. DHCP


  • apt-get install dhcp3-server
  • editar /etc/default/isc-dhcp-server y poner a que interficie tira el dhcp (eth2)
  • editar /etc/dhcp/dhcpd.conf:


ddns-update-style none;
option domain-name "city.local";
option domain-name-servers 8.8.8.8, 8.8.4.4;
default-lease-time 90;
max-lease-time 120;
authoritative;
log-facility local7;
subnet 192.168.2.0 netmask 255.255.255.0 {
   range 192.168.2.20 192.168.2.250;
   option routers 192.168.2.1;
   option subnet-mask 255.255.255.0;
   option broadcast-address 192.168.2.255;
}
2. FIREWALL (iptables)

#!/bin/bash
########################################################
# FIREWALL 
########################################################
#
# CONFIGURACION VARIABLES
#
INET_IFACE="eth0"
INET_IP="192.168.1.2"
HOTEL_IFACE="eth1"
HOTEL_IP="10.0.3.1"
HOTEL_IP_RANGE="10.0.3.0/24"
LO_IFACE="lo"
LO_IP="127.0.0.1"
VPN_IFACE="tun+"
CLIENT_IFACE="eth2"
CLIENT_IP="192.168.2.1"
CLIENT_RANGE="192.168.2.0/24"

IPTABLES="/sbin/iptables"

#echo "1" > /proc/sys/net/ipv4/ip_forward
#mejor tocar el /etc/sysctl.conf
#######################################################
# FILTER
#######################################################
# Politicas = chaped total
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -t mangle -F

#############################################################################
# Input Chains
#############################################################################
$IPTABLES -N bad_tcp_packets
$IPTABLES -N icmp_packets

# bad_tcp_paquets
# paquetes tcp mal construidos = no aceptar
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j DROP
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,FIN,PSH SYN,FIN,PSH -j DROP
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,FIN,RST SYN,FIN,RST -j DROP
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,FIN,RST,PSH SYN,FIN,RST,PSH -j DROP
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags FIN FIN -j DROP
#$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags ALL NONE -j DROP
#$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags ALL ALL -j DROP
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP

# icmp_paquets
# aceptamos pings excepto la subred de clientes no "vea" las otras interficies
# del ruter adsl (eth1, eth2:0)
$IPTABLES -A icmp_packets -p icmp -i $CLIENT_IFACE -d 10.0.3.1 -j DROP
$IPTABLES -A icmp_packets -p icmp -i $CLIENT_IFACE -d 172.16.0.1 -j DROP
$IPTABLES -A icmp_packets -p icmp --icmp-type 8 -j ACCEPT
$IPTABLES -A icmp_packets -p icmp --icmp-type 11 -j ACCEPT
$IPTABLES -A icmp_packets -p icmp --icmp-type 0 -j ACCEPT
$IPTABLES -A icmp_packets -p icmp --icmp-type 3 -j ACCEPT

############################################################################
# INPUT
############################################################################
$IPTABLES -A INPUT -p tcp -j bad_tcp_packets
$IPTABLES -A INPUT -p icmp -j icmp_packets
$IPTABLES -A INPUT -p ALL -m state --state ESTABLISHED,RELATED -j ACCEPT

# desde la red de la empresa podemos acceder al SSH (22) y proxy (3128)
$IPTABLES -A INPUT -i $HOTEL_IFACE -s $HOTEL_IP_RANGE -p tcp --dport 22 -j ACCEPT
$IPTABLES -A INPUT -i $HOTEL_IFACE -s $HOTEL_IP_RANGE -p tcp --dport 3128 -j ACCEPT

# desde la vpn podemos accedir al SSH
$IPTABLES -A INPUT -i $VPN_IFACE -p tcp --dport 22 -j ACCEPT

# desde el localhost = ok
$IPTABLES -A INPUT -i $LO_IFACE -s $LO_IP -p ALL -j ACCEPT


#############################################################################
# Forward Chains
#############################################################################
# Hay pc's con antivirus y alguno se actualiza desde internet. Aqui pongo las 
# ips de los servidores de kaspersy a los que se permite acceder (desde la subred 
# de empresa)
$IPTABLES -N kaspersky
$IPTABLES -A kaspersky -d 82.129.8.135 -j ACCEPT
$IPTABLES -A kaspersky -d 85.12.30.211 -j ACCEPT
$IPTABLES -A kaspersky -d 193.138.220.187 -j ACCEPT
$IPTABLES -A kaspersky -d 213.206.94.83 -j ACCEPT
$IPTABLES -A kaspersky -d 193.138.220.147 -j ACCEPT
$IPTABLES -A kaspersky -d 85.12.57.81 -j ACCEPT
$IPTABLES -A kaspersky -d 85.12.58.201 -j ACCEPT
$IPTABLES -A kaspersky -d 212.47.219.83 -j ACCEPT
$IPTABLES -A kaspersky -d 212.47.219.86 -j ACCEPT
$IPTABLES -A kaspersky -d 94.75.236.122 -j ACCEPT
$IPTABLES -A kaspersky -d 95.211.85.42 -j ACCEPT
$IPTABLES -A kaspersky -d 85.17.72.66 -j ACCEPT
$IPTABLES -A kaspersky -d 195.122.169.4 -j ACCEPT
$IPTABLES -A kaspersky -d 195.122.169.15 -j ACCEPT
$IPTABLES -A kaspersky -d 195.122.169.18 -j ACCEPT
$IPTABLES -A kaspersky -d 195.122.169.15 -j ACCEPT
$IPTABLES -A kaspersky -d 38.117.98.231 -j ACCEPT
$IPTABLES -A kaspersky -d 195.122.169.18 -j ACCEPT
$IPTABLES -A kaspersky -d 94.75.236.122 -j ACCEPT
$IPTABLES -A kaspersky -d 195.122.169.4 -j ACCEPT
$IPTABLES -A kaspersky -d 195.122.169.7 -j ACCEPT
$IPTABLES -A kaspersky -d 212.47.219.86 -j ACCEPT
$IPTABLES -A kaspersky -d 195.122.169.18 -j ACCEPT
$IPTABLES -A kaspersky -d 85.12.58.201 -j ACCEPT
$IPTABLES -A kaspersky -d 85.12.58.10 -j ACCEPT
$IPTABLES -A kaspersky -d 130.117.190.137 -j ACCEPT
$IPTABLES -A kaspersky -d 80.239.169.135 -j ACCEPT
$IPTABLES -A kaspersky -d 80.239.197.100 -j ACCEPT

# El trafico que venga de la subred de la empresa la filtramos por esta "chain" (trafic_hotel)
$IPTABLES -N trafic_hotel
#vpn
$IPTABLES -A trafic_hotel -o $VPN_IFACE -j ACCEPT
#hotline de gestion
$IPTABLES -A trafic_hotel -d x.x.x.x -j ACCEPT
$IPTABLES -A trafic_hotel -d y.y.y.y -j ACCEPT
$IPTABLES -A trafic_hotel -d z.z.z.z -j ACCEPT
#dns
$IPTABLES -A trafic_hotel -d 8.8.8.8 -j ACCEPT
$IPTABLES -A trafic_hotel -d 8.8.4.4 -j ACCEPT
#time.windos.com
$IPTABLES -A trafic_hotel -p udp --dport 123 -j ACCEPT
# poder acceder al ruter adsl
$IPTABLES -A trafic_hotel -d 192.168.1.1 -j ACCEPT
#antivirus
$IPTABLES -A trafic_hotel -j kaspersky
#ejemplo para dejar salir a un host
#$IPTABLES -A trafic_hotel -s 10.0.3.2 -j ACCEPT
#$IPTABLES -A trafic_hotel -s 10.0.3.3 -j ACCEPT


#############################################################################
# FORWARD
#############################################################################
$IPTABLES -A FORWARD -p tcp -j bad_tcp_packets
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

# desde la vpn podemos acceder a la subred de la empresa (y viceversa)
$IPTABLES -A FORWARD -i $VPN_IFACE -o $HOTEL_IFACE -j ACCEPT

# trafico que me entra por la red de la empresa -> trafic_hotel
 $IPTABLES -A FORWARD -i $HOTEL_IFACE -s 10.0.3.0/24 -j trafic_hotel

# trafico que viene de la subred de clientes
## si va dirigido al ruter adsl = bye bye
$IPTABLES -A FORWARD -i $CLIENT_IFACE -d 192.168.1.0/24 -j DROP
## si va dirigido a internet = ok
$IPTABLES -A FORWARD -i $CLIENT_IFACE -s 192.168.2.0/24 -o $INET_IFACE -j ACCEPT

# Falta ver reglas para poder acceder a la red "phantom" de los AP's desde la vpn/red empresa

#######################################################
# NAT
########################################################
$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_IP

# politicas de trafico
/root/htb.sh

3. CONTROL DE TRÁFICO

.
                           +-------+
                           |  1:   |
                           +---+---+
                               |
                           +---+---+
                           |  1:1  |
                           +---+---+
                               |
                +--------------+--------------+--------------------+
                |                             |                    |
            +---+---+                     +---+---+            +---+---+
            |  1:10 | EMPRESA             |  1:20 | CLIENTES   |  1:30 | LOCAL
            +---+---+                     +---+---+            +---+---+
                |                             |
     +---+------+----------+            +-----+----+
     |          |          |            |          |
 +---+---+  +---+---+  +---+---+    +---+---+  +---+---+
 |  1:11 |  |  1:12 |  |  1:13 |    |  1:21 |  |  1:22 |
 +-------+  +-------+  +-------+    +-------+  +-------+
    ACK        VPN       OTROS         ACK       OTROS


El objetivo es garantizar la mitad del ancho de banda (5 Mbps de subida) a los clientes y a la empresa. Para intentar dar fluidez a la comunicación, priorizamos los paquetes ACK, RST, SYN que controlan las comunicaciones tcp, (añadir icmp???) y en el caso del tráfico de la empresa, como usan una vpn, priorizamos este tráfico (trafico udp dirigido al puerto 5000) delante de tráfico directo de internet.

Si una de las bandas (clientes o empresa) no usan sus 5 Mbps, la otra puede aprovechar ese ancho de banda no usado.

# Limpiar qdiscs
tc qdisc del dev eth0 root
tc qdisc del dev eth1 root
tc qdisc del dev eth2 root

#########################################################
# ETH0
#
# Dividir subida de 10Mbits en 3 partes de 5Mbits (aprox)
# 1.- Empresa - 5Mbits
# 2.- Clientes - 4,5 Mbits
# 3.- otros - 0,5 Mbits
# priorizando vpn, ack's 
#########################################################
# instalamos htb
tc qdisc add dev eth0 root handle 1: htb default 30

# clases htb
tc class add dev eth0 parent 1: classid 1:1 htb rate 10Mbit ceil 10Mbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 5Mbit ceil 9Mbit
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 4500Kbit ceil 9Mbit
tc class add dev eth0 parent 1:1 classid 1:30 htb rate 500Kbit ceil 3Mbit

tc class add dev eth0 parent 1:10 classid 1:11 htb rate 1Mbit ceil 9Mbit prio 0
tc class add dev eth0 parent 1:10 classid 1:12 htb rate 2Mbit ceil 9Mbit prio 1
tc class add dev eth0 parent 1:10 classid 1:13 htb rate 2Mbit ceil 9Mbit prio 2
tc class add dev eth0 parent 1:20 classid 1:21 htb rate 2000Kbit ceil 9Mbit prio 0
tc class add dev eth0 parent 1:20 classid 1:22 htb rate 2500Kbit ceil 9Mbit prio 1

# cola de paquetes de cada clase hoja = sfq (esfq molaría mas)
tc qdisc add dev eth0 parent 1:11 handle 11: sfq perturb 10
tc qdisc add dev eth0 parent 1:12 handle 12: sfq perturb 10 
tc qdisc add dev eth0 parent 1:13 handle 13: sfq perturb 10 
tc qdisc add dev eth0 parent 1:21 handle 21: sfq perturb 10 
tc qdisc add dev eth0 parent 1:22 handle 22: sfq perturb 10 


# marcamos paquetes vía iptables (con el u32 no me clasifica por la direccion src :()
# eth0 -> adsl
# eth1 -> empresa
# eth2 -> clientes
iptables -t mangle -F
iptables -t mangle -A FORWARD -i eth1 -p ALL -s 10.0.3.0/24 -j MARK --set-mark 13
iptables -t mangle -A FORWARD -i eth1 -p tcp -m tcp --tcp-flags SYN,RST,ACK ACK -j MARK --set-mark 11
iptables -t mangle -A FORWARD -i eth2 -p ALL -s 192.168.2.0/24 -j MARK --set-mark 22
iptables -t mangle -A FORWARD -i eth2 -p tcp -m tcp --tcp-flags SYN,RST,ACK ACK -j MARK --set-mark 21
# OJO! EL ORDEN IMPORTA!!!, los paquetes de 10.0.3.0/24 -> 13 y aquellos que sean ACK's -> 11. Si lo ponemos al reves
# tendriamos que los paquetes ack -> 11 y despues los paquetes de la red -> 13, que pasa? que los paquetes ack son de la
# red ergo al final todos los paquetes que entrasen por eth1 tendrian la marca 13

### classificacion de paquetes de la empresa
# los que tengan la marca 11 (ACK's) -> 1:11
tc filter add dev eth0 protocol ip parent 1: handle 11 fw classid 1:11
# los que sean de la vpn (udp dirigidos al puerto 5000) -> 1:12
tc filter add dev eth0 protocol ip parent 1: u32 match ip protocol 0x11 0xff match ip dport 5000 0xffff flowid 1:12
# Resto de paquetes de la subred de la empresa -> 1:13
tc filter add dev eth0 protocol ip parent 1: handle 13 fw classid 1:13
# Como la red de empresa usa este pc como http proxy, ocurre que las peticiones web NO vienen de la red 10.0.3.0/24,
# sino que las hace el propio ruter, por tanto, los paquetes dirigidos al puerto 80 -> 1:13
# Peticiones web que no sean por el puerto 80 iran a caer al 1:30
tc filter add dev eth0 protocol ip parent 1:0 u32 match ip dport 80 0xffff flowid 1:13

### classificacion de paquetes de clientes
tc filter add dev eth0 protocol ip parent 1: handle 21 fw classid 1:21
tc filter add dev eth0 protocol ip parent 1: handle 22 fw classid 1:22


#########################################################################
# ETH1
#
# ponemos que la eth1 envie como maximo a 45Mbits, de esta manera limitamos a la mitad el 
# ancho de banda de BAJADA en la red de empresa
##########################################################################
tc qdisc add dev eth1 root handle 1: htb default 1
tc class add dev eth1 parent 1: classid 1:1 htb rate 45Mbit ceil 45Mbit

##############################################################################
# ETH2
#
# idem para la red de clientes, ellos tienen la otra mitat del ancho de banda de bajada
###############################################################################
tc qdisc add dev eth2 root handle 1: htb default 1
tc class add dev eth2 parent 1: classid 1:1 htb rate 45Mbit ceil 45Mbit

# inspeccionar la reglas
#tc -s qdisc ls dev ethX
#tc -s class ls dev ethX

Hay que comentar que ojo con las prio que se meten. Tal y como esta puesto implica que mientras haya paquetes en la "cola" de la vpn, se enviarán estos y no los paquetes que estan en la "cola" de navegación... puede no ser deseable.

Además, para distribuir el ancho de banda de download, supongo que lo correcto seria utilizar las colas IMQ (o sus nuevas IFB o IFQ... no recuerdo las siglas). La idea es que los paquetes de entrada se redirigen a una interficie IMQ y en esta interficie se aplica la política de envío (hacia nosotros mismos) con lo que limitas el download. Yo he optado al asumir que como el tráfico irá dirigido a la interficie de salida sera eth1 (empresa) o eth2 (clientes) pos limitar a que velocidad puede transmitir esas interfícies. Primero he usado una TBF pero me ha dado malos resultados.

Para probar-lo he conectado 2 pc's, 1 en eth1 y otro en eth2. Si lanzo tests de velocidads en tiempos diferentes, entonces me daba una bajada de unos 45Mbits de bajada y unos 8,5Mbits de subida. Si lanzo los tests de velocidad a la vez, los dos pc's pillan 45Mbits de bajada y 5Mbits de subida!! Objetivo cumplido!!

Comentarios