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.
Dans le diagramme d’intégration OPA, chaque numéro représente la tâche correspondante dans la liste suivante :
-
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.
-
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.
-
Envoi d’une demande de ressources aux utilisateurs depuis le client. L’utilisateur peut être authentifié si des CRD d’authentification sont créés.
-
Envoi d’un appel HTTP au serveur OPA au format JSON depuis Citrix ADC avec des paramètres d’autorisation.
-
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.
-
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-->