Ingress Controller de Citrix ADC

Función de agente de directivas abiertas para Kubernetes con Citrix ADC

El agente de directivas abiertas (OPA) es un motor de directivas de código abierto y uso general que unifica la aplicación de directivas en diferentes tecnologías y sistemas. OPA proporciona un lenguaje declarativo de alto nivel que le permite especificar la directiva como código y API sencillas para eliminar la toma de decisiones directivas de su software. Con OPA, puede desvincular la toma de decisiones directivas de la aplicación de directivas. Puede usar OPA para aplicar directivas a través de Citrix ADC en un entorno de Kubernetes.

Con OPA, puede crear un sistema centralizado de toma de decisiones directivas para un entorno que involucre varios ADC de Citrix o varios dispositivos distribuidos. La ventaja de este enfoque es que solo tiene que realizar cambios en el servidor OPA para cualquier cambio específico de decisión aplicable a varios dispositivos.

Para obtener más información sobre OPA, consulte la documentación de la OPA.

La integración de OPA en Citrix ADC se puede admitir mediante una llamada HTTP, donde OPA se puede usar con o sin autenticación. Una llamada HTTP es una solicitud HTTP o HTTPS que el dispositivo Citrix ADC genera y envía a una aplicación externa como parte de la evaluación de la directiva.

Para obtener más información sobre la compatibilidad con llamadas HTTP, consulte la documentación de llamadas HTTP.

Para obtener más información sobre la compatibilidad con la autenticación, consulte las directivas de autenticación y autorización de Kubernetes con Citrix ADC.

El siguiente diagrama proporciona una descripción general de cómo integrar OPA con la solución nativa de nube Citrix ADC.

Integración OPA

En el diagrama de integración de OPA, cada número representa la tarea correspondiente de la siguiente lista:

  1. Crear los objetos de Kubernetes necesarios mediante los comandos de Kubernetes. Este paso debe incluir la creación de la CRD para enviar la llamada HTTP al servidor OPA.

  2. Configuración de Citrix ADC. El Citrix Ingress Controller ADC configura automáticamente Citrix ADC en función de los objetos de Kubernetes creados.

  3. Envío de la solicitud de recursos del usuario desde el cliente. Es posible que el usuario se autentique si se crean CRD de autenticación.

  4. Envío de llamadas HTTP al servidor OPA en formato JSON desde Citrix ADC con parámetros de autorización.

  5. Envío de la decisión de autorización desde el servidor OPA en función de las reglas definidas en REGO, el lenguaje de directivas de OPA.

  6. Enviar una respuesta al cliente en función de la decisión de autorización.

Ejemplo de casos de uso

Ejemplo 1: Permitir o denegar el acceso a los recursos en función de la dirección IP de origen del cliente

A continuación se presenta un ejemplo de directiva de llamadas HTTP para el servidor OPA que utiliza la CRD de directiva de reescritura para permitir o denegar el acceso a los recursos en función de la dirección IP de origen del cliente y las reglas OPA correspondientes.

En el ejemplo, el servidor OPA responde con "result": true si la dirección IP de origen del cliente es 192.2.162.0/24; de lo contrario, responde con "result":false.


apiVersion: citrix.com/v1
kind: rewritepolicy
metadata:
  name: calloutexample
spec:
  responder-policies:
    - servicenames:
        - frontend
      responder-policy:
        respondwith:
          http-payload-string: '"HTTP/1.1 401 Access denied\r\n\r\n"' #Access is denied if the respose from OPA server contains false.
        respond-criteria: 'sys.http_callout("callout_name").CONTAINS("false")'
        comment: 'Invalid access'
  httpcallout_policy:
    - name: callout_name
      server_ip: "192.2.156.160" #OPA Server IP
      server_port: 8181 #OPA Server Port
      http_method: 'POST'
      host_expr: ""192.2.156.160""
      url_stem_expr: ""/v1/data/example/allow"" #URL stem expression to be used
      body_expr: '"{"input": {"clientinfo": [{"id": "ci", "ip": [""+ CLIENT.IP.SRC +""]}]}}"' #JSON to OPA server carrying client IP
      headers:
      - name: Content-Type
        expr: '"application/json"'
      return_type: TEXT
      result_expr: "HTTP.RES.BODY(100)"

<!--NeedCopy-->

Las siguientes son las reglas definidas a través del lenguaje de directivas Rego en el servidor OPA para la directiva de llamadas HTTP para este ejemplo:

    package example

    default allow = false                               # unless otherwise defined, allow is false

    allow = true {                                      # allow is true if...
        count(violation) != 0                           # the ip matches regex.
    }

    violation[client.id] {                              # a client is in the violation set if...
        client := input.clientinfo[_]
        regex.match("192.2.162.", client.ip[_])         # the client is not part of 192.2.162.0/24 network.
    }

Ejemplo 2: Permitir o denegar el acceso según el grupo de usuarios después de la autenticación

A continuación se presenta un ejemplo de directiva de llamadas HTTP para el servidor OPA que utiliza la directiva de reescritura CRD para permitir o denegar el acceso a los recursos basados en el grupo de usuarios después de la autenticación y las reglas OPA correspondientes.

En este ejemplo, el servidor OPA responde con "result":true si el usuario forma parte del beverages grupo; de lo contrario, responde con "result":false.

A continuación se presenta la directiva de llamadas HTTP para el servidor OPA a través de la directiva de reescritura CRD.

apiVersion: citrix.com/v1
kind: rewritepolicy
metadata:
  name: calloutexample
spec:
  responder-policies:
    - servicenames:
        - frontend
      responder-policy:
        respondwith:
          http-payload-string: '"HTTP/1.1 401 Access denied\r\n\r\n"' #Access is denied if the respose from OPA server contains false.
        respond-criteria: 'sys.http_callout("callout_name").CONTAINS("false")'
        comment: 'Invalid access'

  httpcallout_policy:
    - name: callout_name
      server_ip: "192.2.156.160" #OPA Server IP
      server_port: 8181 #OPA Server Port
      http_method: 'POST'
      host_expr: ""192.2.156.160""
      url_stem_expr: ""/v1/data/example/allow"" #URL stem expression to be used
      body_expr: '"{"input": {"users": [{"name": ""+ AAA.USER.NAME +"", "group": [""+ AAA.USER.GROUPS +""]}]}}"' #JSON to OPA server carrying username and group information
      headers:
      - name: Content-Type
        expr: '"application/json"'
      return_type: TEXT
      result_expr: "HTTP.RES.BODY(100)"
<!--NeedCopy-->

Las siguientes son las reglas definidas mediante el lenguaje Rego en el servidor OPA para este ejemplo:

    package example

    default allow = false                               # unless otherwise defined, allow is false

    allow = true {                                      # allow is true if...
        count(isbeveragesuser) != 0                     # the user is part of beverages group.
    }

    isbeveragesuser[user.name] {                        # a user is beverages user...
        user := input.users[_]
        user.group[_] == "beverages"                    # if it is part of beverages group.
    }

Puede realizar la autenticación mediante el encabezado de la solicitud (basado en el plan 401) o mediante formularios.

A continuación, se muestra un ejemplo de directiva de autenticación que utiliza la autenticación basada en el encabezado En esta directiva, se utiliza la autenticación local.

apiVersion: citrix.com/v1beta1
kind: authpolicy
metadata:
  name: localauth
spec:
    servicenames:
    - frontend

    authentication_mechanism:
      using_request_header: 'ON'

    authentication_providers:

        - name: "local-auth-provider"
          basic_local_db:
              use_local_auth: 'YES'

    authentication_policies:

        - resource:
            path: []
            method: []
          provider: ["local-auth-provider"]

    authorization_policies:

        - resource:
            path: []
            method: []
            claims: []
<!--NeedCopy-->

El siguiente es un ejemplo de directiva de autenticación que utiliza la autenticación basada en formularios En esta directiva, se utiliza la autenticación local.


apiVersion: citrix.com/v1beta1
kind: authpolicy
metadata:
  name: localauth
spec:
    servicenames:
    - frontend

    authentication_mechanism:
      using_forms:
        authentication_host: "fqdn_authenticaton_host"
        authentication_host_cert:
          tls_secret: authhost-tls-cert-secret
        vip: "192.2.156.156"

    authentication_providers:

        - name: "local-auth-provider"
          basic_local_db:
              use_local_auth: 'YES'

    authentication_policies:

        - resource:
            path: []
            method: []
          provider: ["local-auth-provider"]


    authorization_policies:

        - resource:
            path: []
            method: []
            claims: []

<!--NeedCopy-->

Ejemplo 3: Permitir o denegar el acceso en función de los atributos de autenticación obtenidos durante la autenticación

A continuación se presenta un ejemplo de directiva de llamadas HTTP para el servidor OPA que utiliza la directiva de reescritura CRD para permitir o denegar el acceso en función de los atributos de autenticación obtenidos durante la autenticación y las reglas OPA correspondientes.

En el ejemplo, el servidor OPA responde con "result":true' si el memberof atributo de usuario contiene grp1, de lo contrario responde con "result":false.

A continuación se muestra un ejemplo de directiva de llamadas HTTP para el servidor OPA a través de la directiva de reescritura CRD:

apiVersion: citrix.com/v1
kind: rewritepolicy
metadata:
  name: calloutexample
spec:
  responder-policies:
    - servicenames:
        - frontend
      responder-policy:
        respondwith:
          http-payload-string: '"HTTP/1.1 401 Access denied\r\n\r\n"' #Access is denied if the respose from OPA server contains false.
        respond-criteria: 'sys.http_callout("callout_name").CONTAINS("false")'
        comment: 'Invalid access'

  httpcallout_policy:
    - name: callout_name
      server_ip: "192.2.156.160" #OPA Server IP
      server_port: 8181 #OPA Server Port
      http_method: 'POST'
      host_expr: ""192.2.156.160""
      url_stem_expr: ""/v1/data/example/allow"" #URL stem expression to be used
      body_expr: '"{"input": {"users": [{"name": ""+ AAA.USER.NAME +"", "attr": [""+ aaa.user.attribute("memberof") +""]}]}}"' #JSON to OPA server carrying username and "memberof" attribute information
      headers:
      - name: Content-Type
        expr: '"application/json"'
      return_type: TEXT
      result_expr: "HTTP.RES.BODY(100)"
<!--NeedCopy-->

Las siguientes son las reglas definidas mediante el lenguaje Rego en el servidor OPA para este ejemplo:

    package example

    default allow = false                               # unless otherwise defined, allow is false

    allow = true {                                      # allow is true if...
        count(isbeveragesuser) != 0                     # the user is part of grp1.
    }

    isbeveragesuser[user.name] {                        # a user is part of allow group...
        user := input.users[_]
        regex.match("CN=grp1", user.attr[_])            # if it is part of grp1 group. }

Puede realizar la autenticación mediante el encabezado de la solicitud (basado en el plan 401) o mediante formularios. En este ejemplo, se utiliza la autenticación LDAP, donde el atributo memberof de usuario se obtiene del servidor LDAP durante la autenticación.

A continuación, se muestra un ejemplo de directiva de autenticación que utiliza la autenticación basada en el encabezado

apiVersion: citrix.com/v1beta1
kind: authpolicy
metadata:
  name: ldapauth
spec:
    servicenames:
    - frontend

    authentication_mechanism:
      using_request_header: 'ON'

    authentication_providers:
        - name: "ldap-auth-provider"
          ldap:
              server_ip: "192.2.156.160"
              base: 'dc=aaa,dc=local'
              login_name: accountname
              sub_attribute_name: CN
              server_login_credentials: ldapcredential
              attributes_to_save: memberof #memberof attribute to be obtained from LDAP server for user

    authentication_policies:
        - resource:
            path: []
            method: []
          provider: ["ldap-auth-provider"]

    authorization_policies:
        - resource:
             path: []
             method: []
             claims: []
<!--NeedCopy-->

El siguiente es un ejemplo de directiva de autenticación que utiliza la autenticación basada en formularios


apiVersion: citrix.com/v1beta1
kind: authpolicy
metadata:
  name: authhotdrinks
spec:
    servicenames:
    - frontend

    authentication_mechanism:
      using_forms:
        authentication_host: "fqdn_authenticaton_host"
        authentication_host_cert:
          tls_secret: authhost-tls-cert-secret
        vip: "192.2.156.156"

    authentication_providers:
        - name: "ldap-auth-provider"
          ldap:
              server_ip: "192.2.156.160"
              base: 'dc=aaa,dc=local'
              login_name: accountname
              sub_attribute_name: CN
              server_login_credentials: ldapcredential
              attributes_to_save: memberof #memberof attribute to be obtained from LDAP server for user

    authentication_policies:

        - resource:
            path: []
            method: []
          provider: ["ldap-auth-provider"]
<!--NeedCopy-->
Función de agente de directivas abiertas para Kubernetes con Citrix ADC