Ansibleを使用してNW機器設定を自動化する(PaloAlto-セキュリティポリシー編②)

当記事は、前回の記事「Ansibleを使用してNW機器設定を自動化する(PaloAlto-セキュリティポリシー編①)」からの改善となります。
設定情報がベタ書きで使い勝手が悪い点 を 設定情報をまとめてINPUT(JSON)できる使い勝手の良い仕組みとしました!!
これにより、Anibleとの連携ができるようになりますので、ご参考になれば幸いです。

当記事は、日常の運用業務(NW機器設定)の自動化により、運用コストの削減 および 運用品質の向上 を目標に
「Ansible」を使用し、様々なNW機器設定を自動化してみようと 試みた記事です。

Ansibleは、OSS版(AWX)+OSS版(Ansible)を使用しております。

 

PaloAltoの「セキュリティポリシー」の登録/変更/削除を実施してみた

事前設定

  • Templateを作成し、インベントリーと認証情報を設定する。
  • インベントリー:対象機器(ホスト)の接続先を設定。 ※ホストには以下変数で接続先IPを指定
    ansible_host: xxx.xxx.xxx.xxx
  • 認証情報:対象機器へのログイン情報(ユーザ名/パスワード)を設定。
    ユーザ名は  変数:ansible_user   に保持される
    パスワードは 変数:ansible_password に保持される

 

事前設定2:設定情報をまとめてINPUT(JSON)できるように、「Survey」を活用

  • テンプレートが読み込むことができる変数(Survey)を設定する。※今回は、各設定のデフォルト値に値を設定する。
  • 実際の値(JSON)
    ・input_policy1: {"rule_name":"policy001","description":"policy001","source_zone":"trust","source_address":"test_address001","destination_zone":"trust","destination_address":"test_address002","service":"test_service001","action":"allow"}
    ・input_policy2: {"rule_name":"policy001","description":"policy001","source_zone":"trust","source_address":"test_address001,test_addressgroup001","destination_zone":"trust","destination_address":"test_address002,test_addressgroup001","service":"test_service001,test_servicegroup001","action":"allow"}
    ・input_policy3: {"rule_name":"policy001","description":"policy001","source_zone":"trust","source_address":"test_address003","destination_zone":"trust","destination_address":"test_address003","service":"test_service003","action":"allow"}

 

Playbook作成(YAML)

使用モジュール

 

接続情報(provider)の設定
  • providerには、ip_address/username/password の指定が必要。
    vars:
      provider:
        ip_address: '{{ ansible_host }}'   ← インベントリーのホストで設定
        username: '{{ ansible_user }}'    ← 認証情報で設定
        password: '{{ ansible_password }}'  ← 認証情報で設定

 

変数(Survey)の値取得
  • vars で 各変数(Survey)の値取得。
    ※各変数(Survey)の値は、構造化データのように見えて「文字列」なので、ディクショナリ(構造化データ)として正しく扱えるように、from_json フィルターを使用すること!!                   

    vars:
      wk_input1: '{{ input_policy1 | from_json}}'
      wk_input2: '{{ input_policy2 | from_json}}'
      wk_input3: '{{ input_policy3 | from_json}}'

 

セキュリティポリシーの登録 ★変数(Survey)の値をそのまま使用した場合…エラーとなる
  • 接続情報と ポリシー(送信元/宛先/サービス「Survey:input_policy1」) を指定して登録(state: ‘present’)を行う。
    - name: Security_Policy Present
      paloaltonetworks.panos.panos_security_rule:
        provider: '{{ provider }}'
        rule_name: '{{ input_policy1.rule_name }}'
        description: '{{ input_policy1.description }}'
        source_zone: '{{ input_policy1.source_zone }}'
        source_ip: '{{ input_policy1.source_address }}'
        destination_zone: '{{ input_policy1.destination_zone }}'
        destination_ip: '{{ input_policy1.destination_address }}'
        service: '{{ input_policy1.service }}'
        action: '{{ input_policy1.action }}'
        state: 'present'
      register: wk_result_data
  • 実行結果:構造化データではないので、オブジェクトに項目が無いというエラーとなる。 ※Ansibleの実行結果を抜粋
    "msg": "The task includes an option with an undefined variable.
           The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'name'.
           ...

 

 
セキュリティポリシーの登録
  • 接続情報とポリシー(送信元/宛先/サービス)を指定して登録(state: ‘present’)を行う。
    - name: Security_Policy Present
      paloaltonetworks.panos.panos_security_rule:
        provider: '{{ provider }}'
        rule_name: '{{ wk_input1.rule_name }}'
        description: '{{ wk_input1.description }}'
        source_zone: '{{ wk_input1.source_zone }}'
        source_ip: '{{ wk_input1.source_address }}'
        destination_zone: '{{ wk_input1.destination_zone }}'
        destination_ip: '{{ wk_input1.destination_address }}'
        service: '{{ wk_input1.service }}'
        action: '{{ wk_input1.action }}'
        state: 'present'
      register: wk_result_data
  • 実行結果:対象のセキュリティポリシーが登録された。 ※Ansibleの実行結果(diff)を抜粋
    "before": "",
    "after" : "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"policy001\">\n\t<from>\n\t\t<member>trust</member>\n\t</from>\n\t<to>\n\t\t<member>trust</member>\n\t</to>\n\t<source>\n\t\t<member>test_address001</member>\n\t</source>\n\t<source-user>\n\t\t<member>any</member>\n\t</source-user>\n\t<hip-profiles>\n\t\t<member>any</member>\n\t</hip-profiles>\n\t<destination>\n\t\t<member>test_address002</member>\n\t</destination>\n\t<application>\n\t\t<member>any</member>\n\t</application>\n\t<service>\n\t\t<member>test_service001</member>\n\t</service>\n\t<category>\n\t\t<member>any</member>\n\t</category>\n\t<action>allow</action>\n\t<log-start>no</log-start>\n\t<log-end>yes</log-end>\n\t<description>policy001</description>\n\t<rule-type>universal</rule-type>\n\t<negate-source>no</negate-source>\n\t<negate-destination>no</negate-destination>\n\t<disabled>no</disabled>\n\t<option>\n\t\t<disable-server-response-inspection>no</disable-server-response-inspection>\n\t</option>\n</entry>\n"
 
セキュリティポリシーの登録 ※セキュリティポリシーが既に存在する場合
  • 接続情報とポリシー(送信元/宛先/サービス)を指定して登録(state: ‘present’)を行う。 ※セキュリティポリシーが既に存在する場合は、既存設定の置き換えとなる(state: ‘replaced’と同様)
    - name: Security_Policy Present
      paloaltonetworks.panos.panos_security_rule:
        provider: '{{ provider }}'
        rule_name: '{{ wk_input2.rule_name }}'
        description: '{{ wk_input2.description }}'
        source_zone: '{{ wk_input2.source_zone }}'
        source_ip: '{{ wk_input2.source_address }}'
        destination_zone: '{{ wk_input2.destination_zone }}'
        destination_ip: '{{ wk_input2.destination_address }}'
        service: '{{ wk_input2.service }}'
        action: '{{ wk_input2.action }}'
        state: 'present'
      register: wk_result_data
  • 実行結果:対象のセキュリティポリシーが登録された。 ※Ansibleの実行結果(diff)を抜粋
    "before": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"policy001\">\n\t<from>\n\t\t<member>trust</member>\n\t</from>\n\t<to>\n\t\t<member>trust</member>\n\t</to>\n\t<source>\n\t\t<member>test_address001</member>\n\t</source>\n\t<source-user>\n\t\t<member>any</member>\n\t</source-user>\n\t<hip-profiles>\n\t\t<member>any</member>\n\t</hip-profiles>\n\t<destination>\n\t\t<member>test_address002</member>\n\t</destination>\n\t<application>\n\t\t<member>any</member>\n\t</application>\n\t<service>\n\t\t<member>test_service001</member>\n\t</service>\n\t<category>\n\t\t<member>any</member>\n\t</category>\n\t<action>allow</action>\n\t<log-start>no</log-start>\n\t<log-end>yes</log-end>\n\t<description>policy001</description>\n\t<rule-type>universal</rule-type>\n\t<negate-source>no</negate-source>\n\t<negate-destination>no</negate-destination>\n\t<disabled>no</disabled>\n\t<option>\n\t\t<disable-server-response-inspection>no</disable-server-response-inspection>\n\t</option>\n</entry>\n",
    "after" : "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"policy001\">\n\t<from>\n\t\t<member>trust</member>\n\t</from>\n\t<to>\n\t\t<member>trust</member>\n\t</to>\n\t<source>\n\t\t<member>test_address001</member>\n\t\t<member>test_addressgroup001</member>\n\t</source>\n\t<source-user>\n\t\t<member>any</member>\n\t</source-user>\n\t<hip-profiles>\n\t\t<member>any</member>\n\t</hip-profiles>\n\t<destination>\n\t\t<member>test_address002</member>\n\t\t<member>test_addressgroup001</member>\n\t</destination>\n\t<application>\n\t\t<member>any</member>\n\t</application>\n\t<service>\n\t\t<member>test_service001</member>\n\t\t<member>test_servicegroup001</member>\n\t</service>\n\t<category>\n\t\t<member>any</member>\n\t</category>\n\t<action>allow</action>\n\t<log-start>no</log-start>\n\t<log-end>yes</log-end>\n\t<description>policy001</description>\n\t<rule-type>universal</rule-type>\n\t<negate-source>no</negate-source>\n\t<negate-destination>no</negate-destination>\n\t<disabled>no</disabled>\n\t<option>\n\t\t<disable-server-response-inspection>no</disable-server-response-inspection>\n\t</option>\n</entry>\n"

 

セキュリティポリシーの変更 ※登録のつづき
  • 接続情報とポリシー(送信元/宛先/サービス)を指定して変更(state: ‘replaced’)を行う。 ※replacedの場合は、既存設定の置き換えとなる
    - name: Security_Policy Replaced
      paloaltonetworks.panos.panos_security_rule:
        provider: '{{ provider }}'
        rule_name: '{{ wk_input2.rule_name }}'
        description: '{{ wk_input2.description }}'
        source_zone: '{{ wk_input2.source_zone }}'
        source_ip: '{{ wk_input2.source_address }}'
        destination_zone: '{{ wk_input2.destination_zone }}'
        destination_ip: '{{ wk_input2.destination_address }}'
        service: '{{ wk_input2.service }}'
        action: '{{ wk_input2.action }}'
        state: 'replaced'
      register: wk_result_data
  • 実行結果:対象のセキュリティポリシーが登録された。 ※Ansibleの実行結果(diff)を抜粋
    "before": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"policy001\">\n\t<from>\n\t\t<member>trust</member>\n\t</from>\n\t<to>\n\t\t<member>trust</member>\n\t</to>\n\t<source>\n\t\t<member>test_address001</member>\n\t</source>\n\t<source-user>\n\t\t<member>any</member>\n\t</source-user>\n\t<hip-profiles>\n\t\t<member>any</member>\n\t</hip-profiles>\n\t<destination>\n\t\t<member>test_address002</member>\n\t</destination>\n\t<application>\n\t\t<member>any</member>\n\t</application>\n\t<service>\n\t\t<member>test_service001</member>\n\t</service>\n\t<category>\n\t\t<member>any</member>\n\t</category>\n\t<action>allow</action>\n\t<log-start>no</log-start>\n\t<log-end>yes</log-end>\n\t<description>policy001</description>\n\t<rule-type>universal</rule-type>\n\t<negate-source>no</negate-source>\n\t<negate-destination>no</negate-destination>\n\t<disabled>no</disabled>\n\t<option>\n\t\t<disable-server-response-inspection>no</disable-server-response-inspection>\n\t</option>\n</entry>\n",
    "after" : "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"policy001\">\n\t<from>\n\t\t<member>trust</member>\n\t</from>\n\t<to>\n\t\t<member>trust</member>\n\t</to>\n\t<source>\n\t\t<member>test_address001</member>\n\t\t<member>test_addressgroup001</member>\n\t</source>\n\t<source-user>\n\t\t<member>any</member>\n\t</source-user>\n\t<hip-profiles>\n\t\t<member>any</member>\n\t</hip-profiles>\n\t<destination>\n\t\t<member>test_address002</member>\n\t\t<member>test_addressgroup001</member>\n\t</destination>\n\t<application>\n\t\t<member>any</member>\n\t</application>\n\t<service>\n\t\t<member>test_service001</member>\n\t\t<member>test_servicegroup001</member>\n\t</service>\n\t<category>\n\t\t<member>any</member>\n\t</category>\n\t<action>allow</action>\n\t<log-start>no</log-start>\n\t<log-end>yes</log-end>\n\t<description>policy001</description>\n\t<rule-type>universal</rule-type>\n\t<negate-source>no</negate-source>\n\t<negate-destination>no</negate-destination>\n\t<disabled>no</disabled>\n\t<option>\n\t\t<disable-server-response-inspection>no</disable-server-response-inspection>\n\t</option>\n</entry>\n"
 
  • 接続情報とポリシー(送信元/宛先/サービス)を指定して変更(state: ‘merged’)を行う。
    - name: Security_Policy Merged
      paloaltonetworks.panos.panos_security_rule:
        provider: '{{ provider }}'
        rule_name: '{{ wk_input3.rule_name }}'
        description: '{{ wk_input3.description }}'
        source_zone: '{{ wk_input3.source_zone }}'
        source_ip: '{{ wk_input3.source_address }}'
        destination_zone: '{{ wk_input3.destination_zone }}'
        destination_ip: '{{ wk_input3.destination_address }}'
        service: '{{ wk_input3.service }}'
        action: '{{ wk_input3.action }}'
        state: 'merged'
      register: wk_result_data
  • 実行結果:エラーとなり変更処理はできない。 ※変更は、state:present/replacedで実施する必要あり。。。要注意!! 
    "msg": "Failed update source_devices" ※msgの抜粋

 

セキュリティポリシーの削除 ※変更のつづき
  • 接続情報とポリシーを指定して削除(state: ‘absent’)を行う。
    - name: Security_Policy Absent
      paloaltonetworks.panos.panos_security_rule:
        provider: '{{ provider }}'
        rule_name: '{{ wk_input1.rule_name }}'
        state: 'absent'
      register: wk_result_data
  • 実行結果:対象のセキュリティポリシーが削除された。 ※Ansibleの実行結果(diff)を抜粋
    "before": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry name=\"policy001\">\n\t<from>\n\t\t<member>trust</member>\n\t</from>\n\t<to>\n\t\t<member>trust</member>\n\t</to>\n\t<source>\n\t\t<member>test_address001</member>\n\t\t<member>test_addressgroup001</member>\n\t\t<member>test_address003</member>\n\t</source>\n\t<source-user>\n\t\t<member>any</member>\n\t</source-user>\n\t<hip-profiles>\n\t\t<member>any</member>\n\t</hip-profiles>\n\t<destination>\n\t\t<member>test_address002</member>\n\t\t<member>test_addressgroup001</member>\n\t\t<member>test_address003</member>\n\t</destination>\n\t<application>\n\t\t<member>any</member>\n\t</application>\n\t<service>\n\t\t<member>test_service001</member>\n\t\t<member>test_servicegroup001</member>\n\t</service>\n\t<category>\n\t\t<member>any</member>\n\t</category>\n\t<action>allow</action>\n\t<log-start>no</log-start>\n\t<log-end>yes</log-end>\n\t<description>policy001</description>\n\t<rule-type>universal</rule-type>\n\t<negate-source>no</negate-source>\n\t<negate-destination>no</negate-destination>\n\t<disabled>no</disabled>\n\t<option>\n\t\t<disable-server-response-inspection>no</disable-server-response-inspection>\n\t</option>\n</entry>\n",
    "after" : ""

 

最後に

  • 今回、変数(Survey)を活用したことで、AnsibleにINPUT(JSON)を設定できるようになりました。
    設定情報がYAMLにベタ書きではなくなったので、使い勝手は増しましたが、
    都度 変数(Survey)のデフォルト値に値を設定しての実行の為、まだまだ 使い勝手が悪い。。。
                         

    今後 外部からAnsibleのINPUT(JSON)に値を連携し実行させる仕組みを試みたいと思います。

タイトルとURLをコピーしました