5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ネットワーク自動化Advent Calendar 2019

Day 25

Cisco MerakiをAnsibleから操作する(②Firewallポリシー操作)

Last updated at Posted at 2019-12-24

はじめに

前回の記事でCisco Merakiのデバイス情報取得、MSシリーズのスイッチポート操作をAnsibleから行いました。
今回は、MXシリーズ(SD-WANとセキュリティアプライアンス)のレイヤー3 Fiwarallポリシーの取得と設定変更をAnsibleのmeraki_mx_l3_firewallを使って実施してみました。

環境セットアップやInventoryファイルは前回同様ですので割愛します。

1. Firewallポリシー取得

まず始めに、現状のFirewallポリシーを取得します。

1-1. ダッシュボード画面

デフォルト状態では、全許可設定×1行だけだったため、その前に拒否設定×2行を追加しています。
無題1222_07.png

1-2. Playbook

タスク1で、meraki_mx_l3_firewallモジュールを使って、Firewallポリシーを取得したい組織名・ネットワーク名を指定します。情報取得のため、statequeryを指定します。続いてタスク2で結果を表示しています。

playbook_meraki_mx_l3_firewall.yml
---

- 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.と同じモジュールを使っています。ただし、statepresentを指定し、rulesオプションでACL設定を2つ定義しています。

playbook_meraki_mx_l3_firewall2.yml
---

- 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行にリプレイスされてしまいました:fearful:

$ 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. ダッシュボード画面

無題1222_08.png

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] }}"とする事で、最後の全許可設定を設定対象から除外。(デフォルト設定のため、除外しても最終的な設定は変わらない。)

playbook_meraki_mx_l3_firewall4.yml
---

- 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. ダッシュボード画面

ダッシュボードにも問題なく設定反映されていました。
無題1222_09.png

最後に

少しトリッキーなやり方ですが、Firewallポリシーの設定追加までできました。今回はポリシー設定を直接Playbook内に記載しましたが、例えばCSVファイルに定義したパラメーターを読み込ませることも可能です。
GUI設定は確かに直感的で分かりやすいですが、大量のFirewallポリシーをメンテナンスする際は、今回ご紹介したREST APIとAnsibleの組み合わせも選択肢の一つになるのではないでしょうか。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?