Archive for September, 2008

Portal captivo muy simple

Sunday, September 21st, 2008

Introducción

Recientemente se me ocurrió la idea de si sería posible que si un equipo no registrado se conectara a una red privada (un consultor que llega a una empresa, por ejemplo) se le presentara una página web indicando que debe ponerse en contacto con el soporte técnico para que le den acceso. Vaya, una especie de portal captivo pero mucho más simple.

Después de darle unas pocas vueltas llegué a una posible solución, que es la que voy a exponer a continuación. Mi intención no es dar una configuración detallada al 100%, básicamente porque no dispongo de un entorno donde poderlo probar todo. Lo que quiero es dar las ideas y poner parte de las configuraciones necesarias para conseguirlo.

La idea es la siguiente:

  1. Tenemos el DHCP configurado de tal manera que a los equipos de la red se les asigna siempre la misma dirección IP de un determinado rango a partir de su dirección MAC. A las MACs no registradas les asignamos una dirección IP de un pool formado por direcciones de una rango totalmente diferente al de la red que se le asigna a las MACs conocidas y que no está enrutada (por tanto no tiene salida fuera de la red local). El pool “captivo” estará configurado para que el servidor DNS que se asignará a esos dispositivos sea uno que estará en el mismo segmento de red y dentro de la misma red IP que las direcciones (recordad que la red del pool no esta enrutada).
  2. Configuraremos el servidor DNS que usaran esos equipos no registrados de manera que resuelva todos los nombres de dominio con una misma dirección IP, la de un servidor local que también estará dentro de la misma red IP que el pool (que es la única red que pueden ver).
  3. Y el servidor Web siempre devolverá la misma página independientemente de la URL que se le solicite. En esa página se le indicará al usuario que el equipo desde el que está accediendo no esta autorizado, que se ha registrado su acceso y que se ponga en contacto con el soporte técnico para que le den acceso.

Por ejemplo, supongamos que en nuestra red usamos las direcciones 192.168.0.0/24, que el DNS “bueno” está en la dirección 192.168.0.1 y el default gateway también es el 192.168.0.1. Para las MACs no registradas, el pool tendrá direcciones de la red 172.16.0.0/24, de la 172.16.0.16 a la 172.16.0.254, el servidor DNS para los equipos no registrados será la 172.16.0.1 y el servidor web estará en la misma máquina.

De esta forma, cuando alguien enchufe un PC a la red y no lo haya notificado previamente, cuando intente acceder a alguna web le saldrá la página que le indicará que debe registrar su equipo.

Configuración

Vamos a ver como debemos configurar los diferentes servicios que intervienen para implementar esta funcionalidad.

DHCP

La configuración del servidor de DHCP no tiene mucho misterio. Básicamente es traducir los requisitos a nivel de DHCP a configuración. Pego la parte relevante de la configuración.

/etc/dhcp.conf

shared-network LAN {
  subnet 172.16.0.0 netmask 255.255.255.0 {
    allow unknown-clients;
    option routers 172.16.0.1;
    option domain-name-servers 172.16.0.1;
    range   172.16.0.16 172.16.0.254;
    max-lease-time 30;
    default-lease-time 30;
  }

  subnet 192.168.0.0 netmask 255.255.255.0 {
    option routers 192.168.0.1;
    option domain-name-servers 192.168.0.1;
    option subnet-mask 255.255.255.0;
    max-lease-time 86400;
    default-lease-time 86400;
  }
}

# Equipos registrados
group {
  host PC1 {
    hardware ethernet 00:01:02:e7:ef:15;
    fixed-address 192.168.17;
  }

  host PC2 {
    hardware ethernet 00:00:21:cb:22:fa;
    fixed-address 192.168.18;
  }
}

Bind

Como servidor DNS usaremos el Bind y tal y como he comentado anteriormente, debemos configurarlo de manera que resuelva cualquier nombre de dominio que le solicitemos con la dirección IP del servidor en el que configuraremos el Apache. Por suerte, Bind tiene soporte de wildcards.

Importante: poner el TTL de esas resoluciones muy bajo, varios segundos a lo sumo. Si no, tras registrar el PC, seguiría sin ver las páginas a las que hubiera intentado acceder mientras tenÍa configurado el DNS del portal captivo ya que la cache de DNS de su S.O. seguiría “resolviendo” el nombre de dominio como la IP de la web del portal captivo.

/etc/bind/named.conf

options {
  directory "/var/cache/bind";
  listen-on { 172.16.0.1; };
  version "Captive Portal DNS Server";
  recursion no;
};

zone "." {
  type master;
  file "/etc/bind/db.captive";
};

/etc/bind/db.captive

$TTL    1
@       IN      SOA     captive.local. netmaster.local. (
                        0000001         ; Serial
                        604800         ; Refresh
                        86400         ; Retry
                        2419200         ; Expire
                        1 )       ; Negative Cache TTL
;
@       IN      NS      captive.local.
*.      IN      A       172.16.0.1

Apache

Partiremos de una instalación estándar de Apache2 de Debian y configuraremos el host virtual por defecto de manera que la web tendrá simplemente una página HTML y como mucho unas cuantas imágenes (por ejemplo, el logo de la empresa). También configuraremos unas reglas de rewrite para que pidan la URL que pidan salga la misma página.

Importante: para evitar problemas con las caches de los navegadores, la página debería tener una cabecera de Cache-Control forzando que el navegador siempre se la descargue en cada consulta.

/etc/apache2/sites-available

<Directory /var/www/>
  Options Indexes FollowSymLinks MultiViews
  AllowOverride FileInfo
  Order allow,deny
  allow from all
</Directory>

Pondremos el index.html que queramos mostrar en /var/www/index.html y crearemos el fichero .htaccess con las reglas de reescritura y de no-cache:

/var/www/.htaccess

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

<IfModule mod_headers.c>
  Header set Cache-Control "no-cache"
</IfModule>

No debemos olvidarnos de habilitar los modulos de rewrite y header:

a2enmod rewrite
a2enmod headers

Y con esto ya tendríamos nuestro portal captivo.

Mejoras

Si no quisiéramos/pudiéramos tener un servidor dedicado al portal captivo, podríamos poner la configuración necesaria de DNS en una vista y configurar el Bind para que las IPs del rango captivo fueran a esa vista en particular, y a nivel de Apache podríamos usar un Virtual Host basado en dirección IP. Si alguien no supiera como hacerlo, le debería ser bastante fácil encontrar documentación en Internet sobre somo hacerlo.

Si lo que nos interesa es que los equipos no registrados no tengan ningún tipo de conectividad, escenario mucho más seguro, deberemos pensar en una solución basada en 802.1x. Pero para ello, tanto la electrónica de red como los equipos deben soportar ese protocolo.