はじめに
前回の記事でCisco Merakiのデバイス情報取得、MSシリーズのスイッチポート操作をAnsibleから行いました。
今回は、MXシリーズ(SD-WANとセキュリティアプライアンス)のレイヤー3 Fiwarallポリシーの取得と設定変更をAnsibleのmeraki_mx_l3_firewall
を使って実施してみました。
環境セットアップやInventoryファイルは前回同様ですので割愛します。
1. Firewallポリシー取得
まず始めに、現状のFirewallポリシーを取得します。
1-1. ダッシュボード画面
デフォルト状態では、全許可設定×1行だけだったため、その前に拒否設定×2行を追加しています。
1-2. Playbook
タスク1で、meraki_mx_l3_firewall
モジュールを使って、Firewallポリシーを取得したい組織名・ネットワーク名を指定します。情報取得のため、state
はquery
を指定します。続いてタスク2で結果を表示しています。
---
- hosts: cisco
gather_facts: no
connection: local
tasks:
- name: Query firewall rules
meraki_mx_l3_firewall:
auth_key: "{{ api_key }}"
org_name: "{{ org_name }}"
net_name: "{{ net_name }}"
state: query
register: result
- name: display output data
debug:
msg: "{{ result.data }}"
1-3. 実行結果
「1-1. ダッシュボード画面」の結果と同じ3行が表示されました。
$ ansible-playbook -i inventory_meraki.ini playbook_meraki_mx_l3_firewall.yml
PLAY [cisco] **********************************************************************************************************
TASK [Query firewall rules] *******************************************************************************************
ok: [meraki]
TASK [display output data] ********************************************************************************************
ok: [meraki] => {
"msg": [
{
"comment": "Block specific HTTPS traffic",
"dest_cidr": "192.0.12.10/32",
"dest_port": "443",
"policy": "deny",
"protocol": "tcp",
"src_cidr": "192.168.128.10/32",
"src_port": "Any",
"syslog_enabled": false
},
{
"comment": "Allow traffic to group of servers",
"dest_cidr": "192.0.12.0/24",
"dest_port": "Any",
"policy": "deny",
"protocol": "any",
"src_cidr": "192.168.128.0/24",
"src_port": "Any",
"syslog_enabled": false
},
{
"comment": "Default rule",
"dest_cidr": "Any",
"dest_port": "Any",
"policy": "allow",
"protocol": "Any",
"src_cidr": "Any",
"src_port": "Any",
"syslog_enabled": false
}
]
}
PLAY RECAP ************************************************************************************************************
meraki : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2. Fiwarwallポリシー設定変更(リプレイス)
続いて、ACL×2行を設定してみます。
2-1. Playbook
1-2.と同じモジュールを使っています。ただし、state
はpresent
を指定し、rules
オプションでACL設定を2つ定義しています。
---
- hosts: cisco
gather_facts: no
connection: local
tasks:
- name: Set two firewall rules
meraki_mx_l3_firewall:
auth_key: "{{ api_key }}"
org_name: "{{ org_name }}"
net_name: "{{ net_name }}"
state: present
rules:
- comment: Block specific HTTPS traffic
src_cidr: 192.168.128.2/32
src_port: any
dest_cidr: 192.0.2.2/32
dest_port: "443"
protocol: tcp
policy: deny
- comment: Allow traffic to group of servers
src_cidr: 192.168.128.0/24
src_port: any
dest_cidr: 192.0.2.0/24
dest_port: any
protocol: any
policy: allow
register: result
- name: display output data
debug:
msg: "{{ result.data }}"
2-2. 実行結果
結果を見ると、全許可設定の前にあった2行が、今回設定した2行にリプレイスされてしまいました
$ ansible-playbook -i inventory_meraki.ini playbook_meraki_mx_l3_firewall2.yml
PLAY [cisco] **********************************************************************************************************
TASK [Set two firewall rules] *****************************************************************************************
changed: [meraki]
TASK [display output data] ********************************************************************************************
ok: [meraki] => {
"msg": [
{
"comment": "Block specific HTTPS traffic",
"dest_cidr": "192.0.2.2/32",
"dest_port": "443",
"policy": "deny",
"protocol": "tcp",
"src_cidr": "192.168.128.2/32",
"src_port": "Any",
"syslog_enabled": false
},
{
"comment": "Allow traffic to group of servers",
"dest_cidr": "192.0.2.0/24",
"dest_port": "Any",
"policy": "allow",
"protocol": "any",
"src_cidr": "192.168.128.0/24",
"src_port": "Any",
"syslog_enabled": false
},
{
"comment": "Default rule",
"dest_cidr": "Any",
"dest_port": "Any",
"policy": "allow",
"protocol": "Any",
"src_cidr": "Any",
"src_port": "Any",
"syslog_enabled": false
}
]
}
PLAY RECAP ************************************************************************************************************
meraki : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2-3. ダッシュボード画面
3. Firewallポリシー設定変更(マージ)
Ansible公式ドキュメントを確認したところ、既存設定にACLを追加したい場合は、Cisco Meraki Guide - Merging Existing and New Dataに従ったPlaybook作成が必要そうです。
試しに、先ほどの2.の設定に対し、全許可設定の前に全拒否設定を追加してみたいと思います。
3-1. Playbook
そのままでは動かなかったため、いくつか修正しています。
-
タスク「set new ruleset」でリストデータをappendする際、上記手順ではネスト構造のリスト
[[ a, b ]]
に対し[[ c, d ]]
をappendをしようとしていたが、これだと[[ a, b ], [ c, d ]]
となってしまい、設定変更ができない。代わりに[ a, b ]
に対し[ c, d ]
をappendするようにし、結果[ a, b, c, d ]
が得られるようにした。 -
タスク「configure firewall rules」で設定変更する際、デフォルトの全許可設定に含まれる
protocol: Any
がエラーではじかれた(正しい値はprotocol: any
)。エラーを防ぐため、"{{ new_ruleset[:-1] }}"
とする事で、最後の全許可設定を設定対象から除外。(デフォルト設定のため、除外しても最終的な設定は変わらない。)
---
- hosts: cisco
gather_facts: no
connection: local
vars:
- front_rules: []
- back_rules: []
tasks:
- name: Query firewall rules
meraki_mx_l3_firewall:
auth_key: "{{ api_key }}"
org_name: "{{ org_name }}"
net_name: "{{ net_name }}"
state: query
register: rules
- name: set output data
set_fact:
original_ruleset: "{{ rules.data }}"
- name: set new rule
set_fact:
new_rule:
- comment: Block all traffic
src_cidr: Any
src_port: Any
dest_cidr: Any
dest_port: Any
protocol: any
policy: deny
- name: set front rules
set_fact:
front_rules: "{{ original_ruleset[:2] }}"
- name: set back rules
set_fact:
back_rules: "{{ original_ruleset[2:] }}"
- name: set new ruleset
set_fact:
new_ruleset: "{{ front_rules + new_rule + back_rules }}"
- name: display new ruleset
debug:
msg: "{{ new_ruleset[:-1] }}"
- name: configure firewall rules
meraki_mx_l3_firewall:
auth_key: "{{ api_key }}"
org_name: "{{ org_name }}"
net_name: "{{ net_name }}"
state: present
rules: "{{ new_ruleset[:-1] }}"
register: result
- name: display output data
debug:
msg: "{{ result.data }}"
3-2. 実行結果
最後のタスクで、想定通り設定変更された事が分かります。
$ ansible-playbook -i inventory_meraki.ini playbook_meraki_mx_l3_firewall4.yml
PLAY [cisco] **********************************************************************************************************
TASK [Query firewall rules] *******************************************************************************************
ok: [meraki]
TASK [set output data] ************************************************************************************************
ok: [meraki]
TASK [set new rule] ***************************************************************************************************
ok: [meraki]
TASK [set front rules] ************************************************************************************************
ok: [meraki]
TASK [set back rules] *************************************************************************************************
ok: [meraki]
TASK [set new ruleset] ************************************************************************************************
ok: [meraki]
TASK [display new ruleset] ********************************************************************************************
ok: [meraki] => {
"msg": [
{
"comment": "Block specific HTTPS traffic",
"dest_cidr": "192.0.2.2/32",
"dest_port": "443",
"policy": "deny",
"protocol": "tcp",
"src_cidr": "192.168.128.2/32",
"src_port": "Any",
"syslog_enabled": false
},
{
"comment": "Allow traffic to group of servers",
"dest_cidr": "192.0.2.0/24",
"dest_port": "Any",
"policy": "allow",
"protocol": "any",
"src_cidr": "192.168.128.0/24",
"src_port": "Any",
"syslog_enabled": false
},
{
"comment": "Block all traffic",
"dest_cidr": "Any",
"dest_port": "Any",
"policy": "deny",
"protocol": "any",
"src_cidr": "Any",
"src_port": "Any"
}
]
}
TASK [configure firewall rules] ***************************************************************************************
changed: [meraki]
TASK [display output data] ********************************************************************************************
ok: [meraki] => {
"msg": [
{
"comment": "Block specific HTTPS traffic",
"dest_cidr": "192.0.2.2/32",
"dest_port": "443",
"policy": "deny",
"protocol": "tcp",
"src_cidr": "192.168.128.2/32",
"src_port": "Any",
"syslog_enabled": false
},
{
"comment": "Allow traffic to group of servers",
"dest_cidr": "192.0.2.0/24",
"dest_port": "Any",
"policy": "allow",
"protocol": "any",
"src_cidr": "192.168.128.0/24",
"src_port": "Any",
"syslog_enabled": false
},
{
"comment": "Block all traffic",
"dest_cidr": "Any",
"dest_port": "Any",
"policy": "deny",
"protocol": "any",
"src_cidr": "Any",
"src_port": "Any",
"syslog_enabled": false
},
{
"comment": "Default rule",
"dest_cidr": "Any",
"dest_port": "Any",
"policy": "allow",
"protocol": "Any",
"src_cidr": "Any",
"src_port": "Any",
"syslog_enabled": false
}
]
}
PLAY RECAP ************************************************************************************************************
meraki : ok=9 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3-3. ダッシュボード画面
最後に
少しトリッキーなやり方ですが、Firewallポリシーの設定追加までできました。今回はポリシー設定を直接Playbook内に記載しましたが、例えばCSVファイルに定義したパラメーターを読み込ませることも可能です。
GUI設定は確かに直感的で分かりやすいですが、大量のFirewallポリシーをメンテナンスする際は、今回ご紹介したREST APIとAnsibleの組み合わせも選択肢の一つになるのではないでしょうか。