Estas aquíBlogs / blog de calel / Creando un router en Debian
Creando un router en Debian
Esta es una receta para crear un router en Debian (Squeeze). La idea es sustituir el típico router inalámbrico de casa con una máquina corriendo en Debian, mientras que la función del router inalámbrico cambiaría a la de Access Point/switch para manejar la red interna.
Es necesario que el servidor Debian tenga dos tarjetas de red. Vamos a llamarlas eth0 y eth1, siguiendo la denominación convencional. La interfaz eth0 se conecta a Internet mientras que eth1 se conecta al router inalámbrico.
Antes de continuar, debemos ingresar a la interfaz de administración del router inalámbrico y anotar la sub-red que utiliza. Vamos a suponer que es 192.168.1.0/24.
La conexión a Internet es generalmente de tipo Banda Ancha, mediante un cable modem. En este caso, el cable módem se encarga de adquirir un número IP del proveedor a través de DHCP y el servidor Debian simplemente lo agarra como suyo. Edita /etc/network/interfaces y define eth0 como DHCP,
# The primary network interface
auto eth0
iface eth0 inet dhcp
Conecta eth0 al módem con un cable de red ("twisted pair"), luego reinicia el módem y el computador Debian. Prueba conexiones Internet. El comando,
# ifconfig eth0
debería retornar los parámetros de red asignados.
Alternativa, la conexión a Internet es de tipo ADSL, en cuyo caso se requiere PPPoE. Sigue las instrucciones de la guía,
http://man-es.debianchile.org/adsl.html
Edita /etc/network/interfaces y define eth1 como una sub-red estática privada,
auto eth1
iface eth1 inet static
address 192.168.0.1
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.0.255
Es muy importante que esta definición no contenga una pasarela (gateway). Es igualmente importante que esta sub-red sea diferente a la sub-red del router inalámbrico, esta siendo 192.168.0.0/24 mientras que la del router inalámbrico 192.168.1.0/24.
Levanta la interfaz eth1 con,
# ifup eth1
'ifconfig eth1' debería retornar los parámetros de red recién asignados.
Conecta eth1 al router inalámbrico con un cable de red ("twisted pair") al mismo puerto que antes estaba conectado a Internet.
Vamos a suponer que el router inalámbrico estaba configurado para adquirir valores de red WAN vía DHCP. Como ahora está conectado al servidor Debian, necesitamos reconfigurarlo en una red estática, con valores,
IP Address : 192.168.0.2
Subnet Mask : 255.255.255.0
Default Gateway : 192.168.0.1
Primary DNS Server : 192.168.0.1
La pasarela (gateway) debe ser el número IP del servidor Debian.
Si no es posible definir una red estática, debido a que el router inalámbrico no permite la opción de red más que con DHCP, es necesario instalar y configurar el servidor DHCP en el servidor Debian. Instala isc-dhcp-server,
# apt-get install isc-dhcp-server
Edita /etc/default/isc-dhcp-server y modifica la variable INTERFACES con,
INTERFACES="eth1"
Edita /etc/dhcp/dhcpd.conf. Descomenta el instructivo "authoritative",
authoritative;
y define una sub-red,
subnet 192.168.0.0 netmask 255.255.255.0 {
range 192.168.0.2 192.168.0.2;
option routers 192.168.0.1;
option ip-forwarding off;
option broadcast-address 192.168.0.255;
option subnet-mask 255.255.255.0;
option domain-name-servers 192.168.0.1;
default-lease-time 86400;
max-lease-time 86400;
}
Esta definición va a servir un solo IP; 192.168.0.2. Observa /var/log/syslog en un terminal con,
$ tail -f /var/log/syslog
luego reinicia en otro terminal el servidor DHCP,
# /etc/init.d/isc-dhcp-server restart
Observa en /var/log/syslog como el router inalámbrico automáticamente adquiere un IP,
May 30 20:27:01 debian dhcpd: DHCPDISCOVER from 00:24:b2:28:8e:f7 via eth1
May 30 20:27:01 debian dhcpd: icmp_echorequest 192.168.0.2: Operation not permitted
May 30 20:27:02 debian dhcpd: DHCPOFFER on 192.168.0.2 to 00:24:b2:28:8e:f7 via eth1
May 30 20:27:05 debian dhcpd: DHCPREQUEST for 192.168.0.2 (192.168.0.1) from 00:24:b2:28:8e:f7 via eth1
May 30 20:27:05 debian dhcpd: DHCPACK on 192.168.0.2 to 00:24:b2:28:8e:f7 via eth1
El router inalámbrico tiene dirección Internet 192.168.0.2, pasarela y servidor DNS 192.168.0.1.
Necesitamos instalar y configurar el servidor DNS. Instala bind9,
# apt-get install bind9
Edita el archivo /etc/bind/named.conf.options para que lea,
options {
directory "/var/cache/bind";
// If there is a firewall between you and nameservers you want
// to talk to, you may need to fix the firewall to allow multiple
// ports to talk. See http://www.kb.cert.org/vuls/id/800113
// If your ISP provided one or more IP addresses for stable
// nameservers, you probably want to use them as forwarders.
// Uncomment the following block, and insert the addresses replacing
// the all-0's placeholder.
forwarders {
100.10.0.3;
100.10.0.7;
};
auth-nxdomain no; # conform to RFC1035
listen-on-v6 { any; };
};
en donde los números IP en "forwarders" son los DNS del proveedor de Internet. Para obtener estos números IP inspecciona el archivo /etc/resolv.conf. Este fue escrito automáticamente con los valores retornados por el servidor DHCP del proveedor. Otra alternativa es obtener el número IP del servidor,
# ifconfig eth0 | egrep "inet addr:"
inet addr:100.50.210.134 Bcast:255.255.255.255 Mask:255.255.248.0
luego correr,
$ nslookup 100.50.210.134
Los servidores DNS se listan a partir de "Authoritative answers can be found from:"
Reinicia el servidor DNS,
# /etc/init.d/bind9 restart
Ahora edita /etc/resolv.conf para que lea,
nameserver 127.0.0.1
Remueve los instructivos "domain" y "search" si existen. Esto transforma a localhost en servidor DNS, que vía BIND9 resuelve nombres haciendo requerimientos a los DNS del proveedor. En particular, 192.168.0.1 también es un servidor DNS.
Falta un pequeño detalle. Cada vez que el lease se renueva, el servidor DHCP del proveedor reenvía valores con que /etc/resolv.conf se reescribe automáticamente. Para evitar esto, edita /etc/dhcp/dhclient.conf y remueve de "request" las opciones,
domain-name, domain-name-servers, domain-search
Debe leer,
request subnet-mask, broadcast-address, time-offset, routers,
# domain-name, domain-name-servers, domain-search, host-name,
host-name,
netbios-name-servers, netbios-scope, interface-mtu,
rfc3442-classless-static-routes, ntp-servers;
Esto evita que el cliente DHCP solicite un nombre de dominio, servidores DNS y dominios de busqueda y que /etc/resolv.conf sea reescrito con estos valores.
Falta redirigir eth1 a eth0 para que la red interna 192.168.1.0/24 del router inalámbrico pueda salir a Internet. Aquí debemos hacer dos cosas: 1) redirigir eth1 a eth0 y 2) reescribir los números IP 192.168.1.x con el número IP público del servidor Debian. Esto se llama enmascarar. Si no se enmascara, los paquetes de red salientes de la red interna tendrian IP 192.168.1.x y serían bloqueados ("IP spoofing").
En Debian, redirigir no es una opción por omisión. Para activarlo hay que modificar el valor de /proc/sys/net/ipv4/ip_forward de 0 a 1.
# echo 1 > /proc/sys/net/ipv4/ip_forward
Un,
$ cat /proc/sys/net/ipv4/ip_forward
debería retornar 1.
Falta otro pequeño detalle. Al reiniciar el computador, se reescribe /proc/sys/net/ipv4/ip_forward con el valor por omisión, que es 0, deshabilitando la redirección. Para evitar esto, edita /etc/sysctl.conf y descomenta,
net.ipv4.ip_forward=1
Ahora el valor de /proc/sys/net/ipv4/ip_forward se reescribe a 1.
Enmascarar se hace fácilmente con iptables en la tabla NAT. Pero, el problema que se presenta es que el IP público del servidor Debian es generalmente dinámico y el proveedor puede renovar el lease con un nuevo IP cada 24 horas o menos. Para solucionar esto debemos crear un script que se corra cada vez que se levante la red externa en eth0,
#!/bin/sh
#
# masquerade: Script to masquerade an external network connection
# (modem or ADSL) upon bringing the interface up. Name this
# script masquerade.sh, put it in /etc/network/if-up.d/ and
# make it executable (755).
# Change INET_IFACE and LAN_IP_RANGE to suit your needs.
# You will need to have packet filtering (iptables) enabled
# in your kernel and module iptable_nat.
#
# This script is intended for Debian systems. May not work on
# other Linux distributions.
#
# Author: Ricardo Yanez <ricardo.yanez@calel.org>, Mon May 30, 2011
#
# Define external interface
INET_IFACE="eth0"
# LAN IP range
LAN_IP_RANGE="192.168.0.0/24"
# Get IP number
INET_IP=`ifconfig $INET_IFACE | egrep "inet addr" | cut -d : -f2 | cut -d \ -f1`
# please note the extra space in the last cut, right after \ (very important).
# Clear all rules in POSTROUTING chain
iptables -t nat -F POSTROUTING
# Masquerade
echo -n "Masquerading interface $INET_IFACE to source $INET_IP... "
iptables -t nat -A POSTROUTING -s $LAN_IP_RANGE -o $INET_IFACE \
-j SNAT --to-source $INET_IP
echo "done."
Descarga este script (masquerade.sh_.txt), muévelo a /etc/network/if-up.d/masquerade.sh y dale permisos de ejecución,
# chmod 755 /etc/network/if-up.d/masquerade.sh
Corre el script por primera vez,
# /etc/network/if-up.d/masquerade.sh
Masquerading interface eth0 to source 100.50.210.134... done.
Ahora el router inalámbrico rutea la sud-red privada 192.168.1.0/24, cuyo IP "externo" es 192.168.0.2 y el servidor Debian conectado a Internet rutea la red 192.168.0.0/24.
En este punto puede ser ventajoso entrar a la administración del router inalámbrico, quizás con otro computador de la sub-red 192.168.1.0/24, y activar la administración remota desde el IP 192.168.0.1.
Queda un último detalle. El servidor Debian está conectado directamente a Internet y es aconsejable crearle un cortafuegos. La base de este cortafuegos es el descrito en http://man-es.debianchile.org/cortafuego.html, versión para un servidor, pero tomando en cuenta que existe una segunda interfaz de red (eth1) y que el IP puede no ser estático.
Primero, crea el archivo /etc/network/if-pre-up.d/firewall,
#!/bin/sh
# Author: Ricardo Yanez <ricardo.yanez@calel.org>
IPTABLES=/sbin/iptables
if [ ! -x $IPTABLES ]; then
exit 0
fi
# números IP loopback
LO_IP="127.0.0.0/8"
# números de red interna
LAN_IP="192.168.0.0/24"
if [ "$IFACE" = "lo" ]; then
$IPTABLES -F
$IPTABLES -X
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT ACCEPT
###############################################
############### cadena INPUT ##################
###############################################
# 1) new not in syn
$IPTABLES -A INPUT -p TCP -m state --state NEW ! --syn -j DROP
# 2) Aceptar paquetes en estado establecido y relacionado
$IPTABLES -A INPUT -i $IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
# 3) loopback
$IPTABLES -A INPUT -i $IFACE -s $LO_IP -j ACCEPT
$IPTABLES -A INPUT -i $IFACE -s $LAN_IP -j ACCEPT
$IPTABLES -A INPUT -i $IFACE -j ACCEPT
# 4) inserta reglas en este punto (ver más adelante)
###############################################
############## cadena FORWARD #################
###############################################
# (Aquí van reglas si el servidor actua de router)
###############################################
############## cadena OUTPUT ##################
###############################################
# new not in syn
$IPTABLES -A OUTPUT -p TCP -m state --state NEW ! --syn -j DROP
# establecido, relacionado
$IPTABLES -A OUTPUT -o $IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
fi
Dale permisos de ejecución,
# chmod 755 /etc/network/if-pre-up.d/firewall
Luego crea el archivo /etc/network/if-up.d/firewall,
#!/bin/sh
# Author: Ricardo Yanez <ricardo.yanez@calel.org>
IPTABLES=/sbin/iptables
if [ ! -x $IPTABLES ]; then
exit 0
fi
# interfaz de red externa
INET_IFACE="eth0"
# interfaz de red interna
LAN_IFACE="eth1"
LAN_IP="192.168.0.0/24"
if [ "$IFACE" = "$INET_IFACE" ]; then
# 5) Definir la cadena "bloquear-spoof"
$IPTABLES -N bloquear-spoof
$IPTABLES -A bloquear-spoof -i $IFACE -s 10.0.0.0/8 -j DROP
$IPTABLES -A bloquear-spoof -i $IFACE -s 172.16.0.0/12 -j DROP
$IPTABLES -A bloquear-spoof -i $IFACE -s 192.168.0.0/16 -j DROP
# 6) Cadena "pqtes-icmp-permitidos"
$IPTABLES -N pqtes-icmp-permitidos
# $IPTABLES -A pqtes-icmp-permitidos -p ICMP --icmp-type 8 -m limit --limit 1/second --limit-burst 3 -j ACCEPT
$IPTABLES -A pqtes-icmp-permitidos -p ICMP -j DROP
# 7) Cadena "pqtes-udp-permitidos"
$IPTABLES -N pqtes-udp-permitidos
# $IPTABLES -A pqtes-udp-permitidos -p UDP -m state --state NEW --dport 53 -j ACCEPT
# $IPTABLES -A pqtes-udp-permitidos -p UDP -m state --state NEW --dport 123 -j ACCEPT
$IPTABLES -A pqtes-udp-permitidos -p UDP -m state --state NEW -j DROP
# 8) Cadena "pqtes-tcp-permitidos"
$IPTABLES -N pqtes-tcp-permitidos
# $IPTABLES -A pqtes-tcp-permitidos -p TCP -m state --state NEW --dport 25 -j ACCEPT
# $IPTABLES -A pqtes-tcp-permitidos -p TCP -m state --state NEW --dport 80 -j ACCEPT
# $IPTABLES -A pqtes-tcp-permitidos -p TCP -m state --state NEW --dport 443 -j ACCEPT
# $IPTABLES -A pqtes-tcp-permitidos -p TCP -m state --state NEW -m multiport --dports 110,995 -j ACCEPT
# $IPTABLES -A pqtes-tcp-permitidos -p TCP -m state --state NEW -m multiport --dports 143,993 -j ACCEPT
# $IPTABLES -A pqtes-tcp-permitidos -p TCP -m state --state NEW --dport 22 -s 100.10.2.0/24 -j ACCEPT
$IPTABLES -A pqtes-tcp-permitidos -p TCP -m state --state NEW -j DROP
# 9) Agregar cadenas a INPUT
###############################################
############### cadena INPUT ##################
###############################################
# establecido, relacionado
$IPTABLES -A INPUT -i $IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A INPUT -i $IFACE -j bloquear-spoof
$IPTABLES -A INPUT -i $IFACE -p ICMP -j pqtes-icmp-permitidos
$IPTABLES -A INPUT -i $IFACE -p UDP -j pqtes-udp-permitidos
$IPTABLES -A INPUT -i $IFACE -p TCP -j pqtes-tcp-permitidos
# 10) Optativo: Registrar paquetes que van a ser desechados
#$IPTABLES -A INPUT -j LOG --log-level debug --log-prefix "Drop INPUT: "
###############################################
############## cadena FORWARD #################
###############################################
# (Aquí van reglas si el servidor actua de router)
###############################################
############## cadena OUTPUT ##################
###############################################
# establecido, relacionado
$IPTABLES -A OUTPUT -o $IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
fi
if [ "$IFACE" = "$LAN_IFACE" ]; then
###############################################
############### cadena INPUT ##################
###############################################
# establecido, relacionado
$IPTABLES -A INPUT -i $IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A INPUT -i $IFACE -s $LAN_IP -j ACCEPT
###############################################
############## cadena FORWARD #################
###############################################
# established, related
$IPTABLES -A FORWARD -i $INET_IFACE -o $LAN_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -i $LAN_IFACE -o $INET_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -i $INET_IFACE -o $IFACE -m state --state NEW -j DROP
$IPTABLES -A FORWARD -i $IFACE -o $INET_IFACE -m state --state NEW -j ACCEPT
###############################################
############## cadena OUTPUT ##################
###############################################
# establecido, relacionado
$IPTABLES -A OUTPUT -o $IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
###############################################
############## cadena NAT #####################
###############################################
/etc/network/if-up.d/masquerade.sh
fi
La segunda parte de este script protege la redirección en la cadena FORWARD. Nota el particular que se debe enmascarar en algún punto. Lo mejor es hacerlo cuando se levanta eth1.
Dale al script permisos de ejecución,
# chmod 755 /etc/network/if-up.d/firewall
y carga el cortafuegos en el núcleo,
# export IFACE=lo ; /etc/network/if-pre-up.d/firewall ; export IFACE=eth0 ; /etc/network/if-up.d/firewall ; export IFACE=eth1 ; /etc/network/if-up.d/firewall
Las cadenas se pueden observar con,
# iptables -L -v
y la tabla NAT con,
# iptables -t nat -L -v
- blog de calel
- 1789 lecturas
Enviar un comentario nuevo