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