Control de uso de contextos usando irules en F5

ACL

"with respect to a computer file system, is a list of permissions attached to an object. An ACL specifies which users or system processes are granted access to objects, as well as what operations are allowed on given objects."
-- from wikipedia [search: access control list]

Vaya que estos días han sido extenuantes, desde revisar arquitecturas hasta entregables, he trabajado sobre varias cosas que buscaré comentar lo más pronto posible. Por lo pronto, un problema que me hizo pasar una buena tarde en el trabajo fue el denegar el tráfico de un contexto web por determinados segmentos de red o dicho de otra manera "quiero que la red 10.10.10.0/24 no pueda ver el contexto /webmaps/ del dominio principal", al tener diversificados los servicios (apaches, IIS) no era posible entrar a cada uno y hacer la configuración correspondiente así que lo más rápido fue realizar una irule en el balanceador de carga.

Lo siguiente fue definir la lista de control (ACL), un sencillo algoritmo y manos a la obra..

irule: acl-bycontext.irule

Veamos, el algoritmo es bastante sencillo:
  1. En una solicitud HTTP
    1. ¿La dirección IP pertenece a alguno de los segmentos restringidos?
      1. Si, entonces validar el contexto: ¿esta restringido?
        1. Si, redigirir a una pagina por defecto
  2. Puede consumir el contexto sin problema
Quizás la parte interesante de estos equipos es que puedes "jugar" con el tráfico como si se tratara de de una arreglo de cadenas (si me permiten la analogía), obviamente existe una documentación bastante extensa e interesante al respecto.

Se han declarado dos conjuntos de datos (datasets) donde se almacenan los segmentos de red y por otro lado, los contextos restringidos, por lo tanto el formato de cada conjunto tendrá que cumplir con ciertas características, veamos.

Address Dataset

Este formato deberá de indicarse si lo que se va a declarar es un equipo o una red (host, network), la dirección mencionada y un identificador.
dg-mobilenetwork.cfg
-
network 20.59.0.0/26 := "Network59",
network 20.91.0.0/26 := "Network91",
.

String Dataset

Este formato es muy sencillo, el contexto a restringir y un identificador. Cabe mencionar que este orden puede alterarse según convenga.
dg-restrictedcontext.cfg
-
"/myapps/" := "Local Application",
"/mysites/" := "Local Portal Sites",

Posteriormente se tendrán que registrar en el LTM del F5, para que el sistema pueda disponer de ellos; ahora vamos con la iRule donde las líneas de interés podrían ser, donde se valida la información de los datasets que declaramos hace unos momentos.

Validar si la dirección IP del cliente se encuentra en uno de los segmentos del datagroup:
# Is client IP address defined in the dg-mobilenetwork?
if { [ class match [IP::client_addr] equals $static::DGMobileNetwork ] } {

Y por otro lado, si el contexto que estamos filtrando se encuentra registrado:
# Is requested URL contained in dg-restrictedcontext?
set urlpermited [ class match -value [HTTP::uri] starts_with $static::DGRestrictedContext ]
log local0. " Pattern | $urlpermited "

Acá el código final:
acl-bycontext.irule
-
# iRule F5
# vim: set ts=2 sw=2 sts=2 et si ai syntax=tcl:

# Copyright (c) 2014, Andres Aquino <andres.aquino(at)gmail.com>
# This file is licensed under the BSD License version 3 or later.
# See the LICENSE file.

# This event is triggered when the rule is saved
when RULE_INIT {

  # Drop unknown source IP addresses?  0 = no, 1 = yes
  set static::GoHome 1

  # Enable to debug? 0 = no, 1 = yes
  set static::AclNetworkDebug 1

  # Set datagroups
  set static::DGMobileNetwork "dg-mobilenetwork"
  set static::DGRestrictedContext "dg-restrictedcontext"

}

# triggered with a client connection
when HTTP_REQUEST {

  # Is client IP address defined in the dg-mobilenetwork?
  if { [ class match [IP::client_addr] equals $static::DGMobileNetwork ] } {

    # Log accepted request
    if { $static::AclNetworkDebug > 0 } {
      log local0. "  Client | [IP::client_addr]:[TCP::client_port] "
      log local0. "    Host | [HTTP::host] "
      log local0. "     URI | [HTTP::uri] "
    }

    # Is requested URL contained in dg-restrictedcontext?
    set urlpermited [ class match -value [HTTP::uri] starts_with $static::DGRestrictedContext ]
    log local0. " Pattern | $urlpermited "

    # pattern found!
    if { "$urlpermited" ne "" } {

      # Drop request if the option is enabled.
      if { $static::GoHome > 0 } {
        log local0. "  Status | DENIED "
        HTTP::redirect "http://www.portal.com.mx/"
      }

    } else {
      # Log accepted request
      if { $static::AclNetworkDebug > 0 } {
        log local0. "  Status | ACCEPTED "
      }

    }

  }

}

Los siguientes pasos serán registrarlo a un VirtualServer para observar su comportamiento via lo registro (log) del sistema operativo

Referencias


¡kualli ohtli / buen camino!

Popular Posts