Contrôleur d'entrée Citrix ADC

Support de Open Policy Agent pour Kubernetes avec Citrix ADC

Open Policy Agent (OPA) est un moteur de politiques open source à usage général qui unifie l’application des politiques sur différents systèmes et technologies. OPA fournit un langage déclaratif de haut niveau qui vous permet de spécifier la politique sous forme de code et des API simples pour décharger la prise de décisions politiques de votre logiciel. À l’aide de l’OPA, vous pouvez dissocier la prise de décisions relatives aux politiques de leur application. Vous pouvez utiliser OPA pour appliquer des politiques via Citrix ADC dans un environnement Kubernetes.

Avec OPA, vous pouvez créer un système centralisé de prise de décision stratégique pour un environnement impliquant plusieurs Citrix ADC ou plusieurs appareils distribués. L’avantage de cette approche est que vous devez apporter des modifications uniquement sur le serveur OPA pour toute modification spécifique à une décision applicable à plusieurs appareils.

Pour plus d’informations sur l’OPA, consultez la documentation OPA.

L’intégration d’OPA sur Citrix ADC peut être prise en charge via une légende HTTP, où OPA peut être utilisé avec ou sans authentification. Une légende HTTP est une demande HTTP ou HTTPS que l’appliance Citrix ADC génère et envoie à une application externe dans le cadre de l’évaluation de la politique.

Pour plus d’informations sur la prise en charge des légendes HTTP, consultez la documentation relative aux légendes HTTP.

Pour plus d’informations sur la prise en charge de l’authentification, consultez les Politiques d’authentification et d’autorisation pour Kubernetes avec Citrix ADC.

Le schéma suivant fournit une vue d’ensemble de la manière d’intégrer OPA à la solution native cloud Citrix ADC.

Intégration d'OPA

Dans le diagramme d’intégration OPA, chaque numéro représente la tâche correspondante dans la liste suivante :

  1. Création des objets Kubernetes requis à l’aide des commandes Kubernetes. Cette étape doit inclure la création du CRD pour envoyer l’appel HTTP au serveur OPA.

  2. Configuration de Citrix ADC. Citrix ADC est automatiquement configuré par le contrôleur d’entrée Citrix ADC en fonction des objets Kubernetes créés.

  3. Envoi d’une demande de ressources aux utilisateurs depuis le client. L’utilisateur peut être authentifié si des CRD d’authentification sont créés.

  4. Envoi d’un appel HTTP au serveur OPA au format JSON depuis Citrix ADC avec des paramètres d’autorisation.

  5. Envoi de la décision d’autorisation depuis le serveur OPA en fonction des règles définies dans REGO, le langage de politique de l’OPA.

  6. Envoi d’une réponse au client en fonction de la décision d’autorisation.

Exemples de cas d’utilisation

Exemple 1 : Autoriser ou refuser l’accès aux ressources en fonction de l’adresse IP source du client

Voici un exemple de politique d’appel HTTP au serveur OPA utilisant la politique de réécriture CRD pour autoriser ou refuser l’accès aux ressources en fonction de l’adresse IP source du client et des règles OPA correspondantes.

Dans l’exemple, le serveur OPA répond avec "result": true si l’adresse IP source du client est 192.2.162.0/24, sinon il répond par "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-->

Voici les règles définies via le langage de politique Rego sur le serveur OPA pour la politique d’appel HTTP pour cet exemple :

    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.
    }

Exemple 2 : Autoriser ou refuser l’accès en fonction du groupe d’utilisateurs après authentification

Voici un exemple de politique d’appel HTTP au serveur OPA utilisant la politique de réécriture CRD pour autoriser ou refuser l’accès aux ressources en fonction du groupe d’utilisateurs après authentification et des règles OPA correspondantes.

Dans cet exemple, le serveur OPA répond avec "result":true si l’utilisateur fait partie du groupe beverages, sinon il répond par "result":false.

Voici la politique d’appel HTTP au serveur OPA via la politique de réécriture 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-->

Voici les règles définies via le langage Rego sur le serveur OPA pour cet exemple :

    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.
    }

Vous pouvez effectuer une authentification à l’aide de l’en-tête de demande (basé sur 401) ou via des formulaires.

Vous trouverez ci-dessous un exemple de politique d’authentification utilisant l’authentification basée sur l’en-tête de demande. Dans cette politique, l’authentification locale est utilisée.

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-->

Vous trouverez ci-dessous un exemple de politique d’authentification utilisant l’authentification par formulaire. Dans cette politique, l’authentification locale est utilisée.


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-->

Exemple 3 : Autoriser ou refuser l’accès en fonction des attributs d’authentification obtenus lors de l’authentification

Voici un exemple de politique d’appel HTTP au serveur OPA utilisant la politique de réécriture CRD pour autoriser ou refuser l’accès en fonction des attributs d’authentification obtenus lors de l’authentification et des règles OPA correspondantes.

Dans l’exemple, le serveur OPA répond avec "result":true' si l’attribut utilisateur memberof contient grp1, sinon il répond par "result":false.

Voici un exemple de politique d’appel HTTP au serveur OPA via la politique de réécriture 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-->

Voici les règles définies via le langage Rego sur le serveur OPA pour cet exemple :

    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. }

Vous pouvez effectuer une authentification à l’aide de l’en-tête de demande (basé sur 401) ou via des formulaires. Dans cet exemple, l’authentification LDAP est utilisée, où l’attribut utilisateur memberof est obtenu auprès du serveur LDAP lors de l’authentification.

Vous trouverez ci-dessous un exemple de politique d’authentification utilisant l’authentification basée sur l’en-tête de demande.

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-->

Vous trouverez ci-dessous un exemple de politique d’authentification utilisant l’authentification par formulaire.


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-->
Support de Open Policy Agent pour Kubernetes avec Citrix ADC