はじめに
この記事はCisco Systems Japan Advent Calendar 2023の7日目の記事となります。
- 2017年版: https://qiita.com/advent-calendar/2017/cisco
- 2018年版: https://qiita.com/advent-calendar/2018/cisco
- 2019年版: https://qiita.com/advent-calendar/2019/cisco
- 2020年版: https://qiita.com/advent-calendar/2020/cisco
- 2020年版(2枚目): https://qiita.com/advent-calendar/2020/cisco2
- 2021年版: https://qiita.com/advent-calendar/2021/cisco
- 2021年版(2枚目): https://qiita.com/advent-calendar/2021/cisco2
- 2022年版(1,2): https://qiita.com/advent-calendar/2022/cisco
- 2023年版: https://qiita.com/advent-calendar/2023/cisco <=== ここ
Cisco Identy Services Engine (ISE)とは?
Cisco Identy Services Engine (ISE)とは、シスコシステムズが提供するセキュリティソフトウェアの1つで、ネットワーク上のデバイスやユーザの管理、制御を行うセキュリティポリシーサーバ
Cisco ISEセキュリティポリシーの仕組み
セキュリティポリシーは以下の要素で構成される。
- ポリシーセット:以下の2つのポリシーをまとめるコンポーネント
- 認証ポリシー:アクセスしてきたユーザやデバイスの認証方式を定義
- 認可ポリシー:アクセスしてきたユーザやデバイスに割り当てる権限を定義
実施すること
Terraformを使用して、ブラウザから効率的にCisco ISEに以下のポリシーを展開する。
-
ポリシーセットの作成
- ルール名:”Wired MAB”
- 条件:"WiredMAB"
- 許可されたプロトコルサービス:"Default Network Service"
-
認証ポリシーの作成
- ルール名:MAB
- 条件:"WiredMAB"
- アイデンティティ参照場所:"Internal Endpoints"
- 認証失敗時の処理
- 接続に失敗した場合:"REJECT"
- ユーザが見つからない場合:"REJECT"
- プロセスが失敗した場合:"DROP"
-
認可ポリシーの作成
- ルール名:MAB Endpoints
- 条件:"Endpoint Identity Groups:MAB-Endpoints"
- 結果:"PermitAccess"
自動化の流れ
1.ローカルリポジトリからリモートリポジトリにコードをPUSH
2.Terraform CloudにWorkspaceを作成し、Githubとリポジトリの紐づけ
3.手動で実行をトリガーし、Agentにジョブを割り当てる
4.ジョブを実行し、Cisco ISEの設定変更を行う
環境
- GitHub
- Terraform v1.6.5
- providers.ciscoise Version0.6.22-beta
- WSL2(Ubuntu-22.04)
- tfc-agent_1.14.1
構築手順
1.Terraformコード
2.GitHubにコードをPUSH
3.Terraform Cloud設定
4.動作確認
1.Terraformコード
Hashicorp社が提供しているCisco Identity Services Engine(ISE)の公式ドキュメントを参照
Terraform実行の各ファイル構成、役割は以下の通り。
-
Policyset
:ポリシーセットの作成 -
Authentication
:認証ポリシーの作成 -
Authorization
:認可ポリシーの作成
.
├── work
│ ├── Policyset
│ │ ├── main.tf
│ │ ├── providers.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ │
│ ├── Authentication
│ │ ├── main.tf
│ │ ├── providers.tf
│ │ └── variables.tf
│ │
│ ├── Authorization
│ │ ├── main.tf
│ │ ├── providers.tf
│ │ └── variables.tf
1-1. Policyset(ポリシーセット作成)
- main.tf:リソースの定義、メインコード
- providers.tf:サービスプロバイダーの定義
- variables.tf:変数の定義
- output.tf:実行後に出力する内容の定義
main.tf
## Cisco ISEのポリシーセットを管理するリソースを定義
resource "ciscoise_network_access_policy_set" "example" {
provider = ciscoise
parameters {
# ルール名
name = "Wired MAB"
# 備考
description = "test policy set"
# デフォルトポリシーかどうか
default = "false"
# ポリシーが適用された回数
hit_counts = 0
# ポリシーの優先度
rank = 0
# ポリシーセットが適用されるプロトコルサービス名
service_name = "Default Network Access"
# ポリシーセットの状態
state = "enabled"
condition {
# 条件タイプの指定
condition_type = "ConditionAttributes"
# 条件の属性名
attribute_name = "RadiusFlowType"
# 条件の属性値
attribute_value = "WiredMAB"
# 条件の辞書名
dictionary_name = "Normalised Radius"
# 比較演算子
operator = "equals"
}
}
}
resource "ciscoise_network_access_policy_set" "example" {}
:
Cisco ISEのポリシーセットを管理するリソースを定義
parameter{}
:ポリシー名や優先度などポリシーセット自体の定義を行う
condition{}
:ポリシーセットが適用される条件の指定を行う
・ポイント
今回はcondition_typeとして、ConditionAttributes
を指定し、属性の値に基づいた条件を作成しましたが、他の選択肢として以下のようなものがある。
ConditionReference
:既存の条件を参照
ConditionAndBlock/OrBlock
:複数の条件を組み合わせて論理的なANDまたはOR条件を作成
providers.tf
terraform {
required_providers {
ciscoise = {
source = "CiscoISE/ciscoise"
version = "0.6.22-beta"
}
}
}
provider "ciscoise" {
## 認証情報を外部から取得するための変数を定義
username = var.ciscoise_username
password = var.ciscoise_password
base_url = var.ciscoise_base_url
## SSL証明書の検証
ssl_verify = "false"
## リクエストのタイムアウト値
single_request_timeout = 150
}
terraform{}
:プロバイダ、バージョンの指定を行う
provider{}
:認証情報やURLなどプロバイダに対する具体的な設定を行う
variables.tf
variable "ciscoise_username" {
## 変数のデータ型を文字列型に指定
type = string
description = "Username"
## デフォルト値の定義
default = "*****"
}
variable "ciscoise_password" {
## 変数のデータ型を文字列型に指定
type = string
description = "Password"
## デフォルト値の定義
default = "*****"
}
variable "ciscoise_base_url" {
## 変数のデータ型を文字列型に指定
type = string
## デフォルト値の定義
default = "https://*****"
}
variable "ciscoise_username" {}
:変数の定義を行う
output.tf
output "policy_set_id" {
## ポリシーセットIDの取得
value = ciscoise_network_access_policy_set.example.id
}
output "policy_set_id_value" {
## ポリシーセットIDの一部を取得
value = substr(ciscoise_network_access_policy_set.example.id, 4, 36)
}
output "policy_set_id" {}
:実行結果から取得した情報の表示。または、別ディレクトリで利用できるようにする
- ポイント
value = ciscoise_network_access_policy_set.example.id
で取得する値は以下の形式
policy_set_id = "id:=e20eeef6-****-****-****-************\\name:=test-policyset
1-2,1-3でポリシーセットIDを参照する必要があるため、substr()関数でUUIDのみ出力する
value = substr(ciscoise_network_access_policy_set.example.id, 4, 36)
policy_set_id_value = "e20eeef6****-****-****-************"
1-2. Authentication(認証ポリシー作成)
- main.tf
- providers.tf(1.1と同一ファイルのため説明省略)
- variables.tf(1.1と同一ファイルのため説明省略)
main.tf
## リモートステートのデータを取得する
data "terraform_remote_state" "status" {
## リモートバックエンドを指定
backend = "remote"
config = {
## Terraform Cloudの組織名を指定
organization = "Terraform-Cloud-ISE"
workspaces = {
## Workspace名を指定
name = "policyset_create"
}
}
}
## 認証ポリシーを管理するTerraformリソースを定義
resource "ciscoise_network_access_authentication_rules" "example" {
provider = ciscoise
parameters {
## アイデンティティ参照場所
identity_source_name = "Internal Endpoints"
## 認証が失敗した場合の動作
if_auth_fail = "REJECT"
## ユーザが見つからなかった場合の動作
if_user_not_found = "REJECT"
## プロセスが失敗した場合の動作
if_process_fail = "DROP"
## リモートステートから取得した`policy_set_id_value`を参照しポリシーIDを指定
policy_id = data.terraform_remote_state.status.outputs.policy_set_id_value
rule {
condition {
## 条件タイプの指定
condition_type = "ConditionAttributes"
## 条件の属性名
attribute_name = "RadiusFlowType"
## 条件の属性値
attribute_value = "WiredMAB"
## 条件の辞書名
dictionary_name = "Normalised Radius"
## 比較演算子
operator = "equals"
}
## デフォルトポリシーかどうか
default = "false"
## ポリシーが適用された回数
hit_counts = 0
## ルール名
name = "MAB"
## ポリシーの優先度
rank = 0
## ポリシーの状態
state = "enabled"
}
}
}
resource "ciscoise_network_access_authentication_rules" "example"{}
:
Cisco ISEの認証ポリシーを管理するリソース
data "terraform_remote_state" "status{}
:
別フォルダの.tfstateファイルのoutputを参照する
resource "ciscoise_network_access_authentication_rules" "example"{}
:
Cisco ISEのネットワークアクセス認証ルールを管理する
- ポイント
policy_id = data.terraform_remote_state.status.outputs.policy_set_id_value
で
1-1のoutput.tfファイルで出力したポリシーIDを参照する
1.3. Authorization(認可ポリシー作成)
- main.tf
- providers.tf(1.1と同一ファイルのため説明省略)
- variables.tf(1.1と同一ファイルのため説明省略)
main.tf
data "terraform_remote_state" "status" {
## リモートバックエンドを指定
backend = "remote"
config = {
## Terraform Cloudの組織名を指定
organization = "Terraform-Cloud-ISE"
workspaces = {
## Workspace名を指定
name = "policyset_create"
}
}
}
## Cisco ISEの認可ポリシー管理するTerraformリソースを定義
resource "ciscoise_network_access_authorization_rules" "example" {
provider = ciscoise
parameters {
## リモートステートから取得した`policy_set_id_value`を使用してポリシーIDを指定
policy_id = data.terraform_remote_state.status.outputs.policy_set_id_value
## 認可ルールの結果を指定
profile = ["PermitAccess"]
rule {
## ルールの条件を指定
condition {
## 条件タイプの指定
condition_type = "ConditionAttributes"
## 条件の属性名
attribute_name = "Name"
## 条件の属性値
attribute_value = "Endpoint Identity Groups:MAB-Endpoints"
## 条件の辞書名
dictionary_name = "IdentityGroup"
## 比較演算子
operator = "equals"
}
## デフォルトポリシーかどうか
default = "false"
## ポリシーが適用された回数
hit_counts = 0
## ルール名
name = "MAB Endpoints"
## ポリシーの優先度
rank = 0
## ポリシーの状態
state = "enabled"
}
}
}
resource "ciscoise_network_access_authorization_rules" "example" {}
:
Cisco ISEの認可ポリシー管理するリソース
2.GitHubにコードをPUSH
1.で作成したTerraformコードをリモートリポジトリにPUSHする
GitHubにPUSHする方法は省略します
3.Terraform Cloud設定
- Workspaceを3つ作成
-
policy_create
:ポリシーセット作成用 -
authn_create
:認証ポリシー作成用 -
authz_create
:認可ポリシー作成用
-
3-1. Workspaceの作成
リポジトリを選択
選択したリポジトリがリポジトリルートとなり、コードを実行する作業ディレクトリになる
※作成する全てのワークスペースで./work
を選択し、作成完了後に各ワークスペースの作業ディレクトリのPathを個別に設定する
残りのWorkspaceも作成し、全てのWorkspaceの作成が完了!
3-2. Workspaceの設定
Working Directoryの設定
Terraformが実行されるディレクトリを設定する
現在のリポジトリルートは ./work
であるため、各ワークスペースの作業ディレクトリを相対パスで指定する
.
├── work
│ ├── Policyset
│ │ ├── main.tf
│ │ ├── providers.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ │
│ ├── Authentication
│ │ ├── main.tf
│ │ ├── providers.tf
│ │ └── variables.tf
│ │
│ ├── Authorization
│ │ ├── main.tf
│ │ ├── providers.tf
│ │ └── variables.tf
policyset_create
> Settings
に遷移します
ポリシーセット作成用のワークスペースのため、Policyset
ディレクトリを指定する
authn_create
> Settings
に遷移します
認証ポリシー作成用のワークスペースのため、Authentication
ディレクトリを指定する
authz_create
> Settings
に遷移します
認可ポリシー作成用のワークスペースのため、Authorization
ディレクトリを指定する
Auto-applyの設定
・Planが成功したらApplyも自動的に実行するように設定します。
・ワークスペースの適用が完了したら次のワークスペースを実行するための自動トリガーの設定も有効化します。
policyset_create
> Settings
に遷移します
※ authn_create
, authz_create
でも同様の設定を実施
実行トリガーの設定
policyset_create
(ポリシーセット作成)の適用をトリガーに、
authn_create
(認証ポリシー作成),authz_create
(認可ポリシー作成)を自動的に実行するように設定します。
authn_create
> Settings
> Run Triggers
に遷移し、Source Workspacesに policyset_create
を選択する
※ authz_create
でも同様の設定を実施
Remote state sharingの設定
terraform_remote_stateを他のワークスペースと共有するための設定を行います
policyset_create
> Settings
に遷移します
Agentの設定
今回設定変更するCisco ISEがプライベートネットワークに存在するため、Agentを導入する。
Agentのインストール方法は省略します。
Settings
> Agents
> に遷移し、「Create agent pool」を押下
Agent Pool Nameを入力し、「Continue」を押下
Descriptionを入力し、「Create token」を押下し、Tokenを作成
Agentがインストールされたディレクトリに移動し、トークン、エージェント名を設定し、Agentを起動する。※Token生成時に記載されているコマンドを参照
$ export TFC_AGENT_TOKEN= <token>
$ export TFC_AGENT_NAME=CiscoISE-Agent
$ ./tfc-agent
2023-12-06T17:40:30.410+0900 [INFO] agent: Starting: agent_name=CiscoISE-Agent agent_version=1.14.1
2023-12-06T17:40:30.500+0900 [INFO] core: Starting: version=1.14.1
2023-12-06T17:40:31.448+0900 [INFO] core: Agent registered successfully with Terraform Cloud: agent_id=<agent id> agent_pool_id=<agent pool id>
2023-12-06T17:40:31.573+0900 [INFO] agent: Core version is up to date: version=1.14.1
2023-12-06T17:40:31.573+0900 [INFO] core: Waiting for next job
terraform cloud画面に戻り、Settings
> General
> に遷移します。
実行モードにAggentを選択し、Agent Poolに先ほど作成したCiscoISE-Agentを選択します
4.動作確認
準備が整ったので、実際に実行してみる
4.1 Terraform Cloudからデプロイ
実行トリガーの設定より、policyset_create
の実行が成功すると、
authn_create
/ authz_create
が自動的に実行されるため、policyset_create
のみ手動でrun
policyset_create
> 「New run」 を押下
4.2 実行結果(policyset_create)
Cisco ISEにログインし、ポリシーセットが作成されたことが確認できる。
4.3 実行結果(authn_create/authz_create)
policyset_create
の適用が完了したことにより、トリガー設定していた
authn_create
, authz_create
が自動的に実行され、Plan,Applyが成功している。
Cisco ISEにログインし、認証、認可ポリシーが作成されていることを確認
おわりに
今回、Terraformを使用してISEの設定をしてみましたが、コードの書き方が独特であったり、Terraformのバージョンによって動かないリソースがあったりと苦戦しました。
また、セキュリティポリシーだけでなく、設定頻度が高い項目や一般的なユースケースに沿った内容をテンプレートとして作成することで、より効率化が図れそうだと感じました。
今後もTerraformでできることを追求していきます。
免責事項
本サイトおよび対応するコメントにおいて表明される意見は、投稿者本人の個人的意見であり、シスコの意見ではありません。本サイトの内容は、情報の提供のみを目的として掲載されており、シスコや他の関係者による推奨や表明を目的としたものではありません。各利用者は、本Webサイトへの掲載により、投稿、リンクその他の方法でアップロードした全ての情報の内容に対して全責任を負い、本Web サイトの利用に関するあらゆる責任からシスコを免責することに同意したものとします。