Citrix ADC による Kubernetes のオープンポリシーエージェントサポート
Open Policy Agent(OPA)は、さまざまなテクノロジーやシステムにわたるポリシー適用を統合するオープンソースの汎用ポリシーエンジンです。OPAは、ポリシーをコードとして指定できる高レベルの宣言型言語と、ソフトウェアからポリシーの意思決定をオフロードするためのシンプルなAPIを提供します。OPAを使用すると、ポリシーの意思決定とポリシー適用を切り離すことができます。OPAを使用すると、Kubernetes環境でCitrix ADCを通じてポリシーを適用できます。
OPAを使用すると、複数のCitrix ADCまたは分散された複数のデバイスが関与する環境向けに、一元化されたポリシー意思決定システムを作成できます。この方法の利点は、複数のデバイスに適用される決定固有の変更については、OPAサーバーでのみ変更を加える必要があることです。
OPA の詳細については、OPA のドキュメントを参照してください。
Citrix ADCでのOPA統合は、HTTPコールアウトを通じてサポートでき、OPAは認証の有無にかかわらず使用できます。HTTPコールアウトは、Citrix ADCアプライアンスがポリシー評価の一環として生成して外部アプリケーションに送信するHTTPまたはHTTPS要求です。
HTTP コールアウトサポートの詳細については、 HTTP コールアウトのドキュメントを参照してください。
認証サポートの詳細については、「 Citrix ADC を使用した Kubernetes の認証および承認ポリシー」を参照してください。
次の図は、OPAをCitrix ADCクラウドネイティブソリューションと統合する方法の概要を示しています。
OPA統合図では、各数字は次のリストの対応するタスクを表しています。
-
Kubernetes コマンドを使用して必要な Kubernetes オブジェクトを作成します。このステップには、HTTPコールアウトをOPAサーバーに送信するためのCRDの作成を含める必要があります。
-
Citrix ADC の設定。Citrix ADCは、作成されたKubernetesオブジェクトに基づいてCitrix ADC入力コントローラーによって自動的に構成されます。
-
クライアントからリソースに対するユーザーリクエストを送信しています。認証 CRD が作成されると、ユーザーが認証されることがあります。
-
認証パラメータを含むCitrix ADCからHTTPコールアウトをJSON形式でOPAサーバーに送信します。
-
OPAのポリシー言語であるREGOで定義されたルールに基づいて、OPAサーバーから承認決定を送信します。
-
承認決定に基づいてクライアントに応答を送信します。
ユースケースの例
例 1: クライアントソース IP アドレスに基づいてリソースへのアクセスを許可または拒否する
以下は、リライト・ポリシーCRDを使用してクライアントのソースIPアドレスと対応するOPAルールに基づいてリソースへのアクセスを許可または拒否するOPAサーバーへのHTTPコールアウト・ポリシーの例です。
この例では、OPAサーバーは、クライアントの送信元IPアドレスが192.2.162.0/24の場合は"result": true
で応答し、それ以外の場合は"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-->
以下は、この例のHTTPコールアウト・ポリシー用にOPAサーバー上のRegoポリシー言語で定義されているルールです。
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.
}
例 2: 認証後にユーザーグループに基づいてアクセスを許可または拒否する
以下は、認証後のユーザー・グループと対応するOPAルールに基づいてリソースへのアクセスを許可または拒否するリライト・ポリシーCRDを使用するOPAサーバーへのHTTPコールアウト・ポリシーの例です。
この例では、OPAサーバーは、ユーザーがbeverages
グループの一部である場合は"result":true
で応答し、 それ以外の場合は"result":false
で応答します。
以下は、リライト・ポリシーCRDによるOPAサーバーへのHTTPコールアウト・ポリシーです。
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-->
この例では、OPAサーバー上のRego言語で定義されているルールは次のとおりです。
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.
}
リクエストヘッダー(401ベース)またはフォームベースを使用して認証を実行できます。
以下は、リクエストヘッダーベースの認証を使用した認証ポリシーのサンプルです。このポリシーでは、 ローカル認証が使用されます。
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-->
以下は、フォームベース認証を使用した認証ポリシーの例です。このポリシーでは、ローカルベースの認証が使用されます。
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-->
例 3: 認証中に取得した認証属性に基づいてアクセスを許可または拒否する
以下は、リライト・ポリシーCRDを使用して、認証中に取得した認証属性と対応するOPAルールに基づいてアクセスを許可または拒否するOPAサーバーへのHTTPコールアウト・ポリシーの例です。
この例では、OPAサーバーは、ユーザーmemberof
属性にgrp1
が含まれている場合は"result":true'
で応答し 、 それ以外の場合は"result":false
で応答します。
以下は、リライト・ポリシーCRDによるOPAサーバーへのHTTPコールアウト・ポリシーのサンプルです。
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-->
この例では、OPAサーバー上のRego言語で定義されているルールは次のとおりです。
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. }
リクエストヘッダー(401ベース)またはフォームベースを使用して認証を実行できます。この例では、LDAP認証が使用され、認証時にLDAPサーバーからユーザーmemberof
属性が取得されます。
以下は、リクエストヘッダーベースの認証を使用した認証ポリシーのサンプルです。
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-->
以下は、フォームベース認証を使用した認証ポリシーの例です。
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-->