てんこ

ブログ名は愛猫(てん)の愛称です。中身は個人のIT系学習記録です。

AnsibleでFortigate(Fortiosモジュール)を触りはじめてみた

Ansible2.8以降で、fortios系のモジュールが大量に追加されています。

つい先日リリースされた2.9でも、さらに200以上のfortios用モジュールが追加されました。

ただ、「ansible fortigate」とかでググっても、日本語情報はよこちさんの「てくなべ/Qiita」(いつもお世話になっております!)しかヒットせず、それも随分昔の記事だったこともあり、実際に国内で利用されているのか???な状況でした。

なので、怖いもの見たさでいろいろと調べ始めました。

今後、Fortigate系でansibleによる自動化を実践してみた結果をちまちまと上げていこうと思いますが、今回は実際の利用前にいろいろと調べた結果を中心に書いてみます。

Ansible関連の実践記事一覧はこちら。

Ansible自動化の実践記事一覧 - てんこ


目的

AnsibleでのFortigate自動化について調べた結果を整理するため

検証環境

  • ansible: 2.8.6 / 2.9.0
  • pip: 19.3.1
  • Fortios: 6.0.6

Ansibleリリースバージョンとfortios系モジュール数の推移

fortios系モジュールはこのページから確認できます。

ざっと調べてみたところ、以下のような結果になりました。

Ansible Version 2.3 2.4 2.5 2.6 2.7 2.8 2.9
追加モジュール数 2 1 0 1 0 219 204
メインライブラリ pyFG netaddr - fortiosapi - fortiosapi fortiosapi

Ansible2.3系から少しだけモジュールは存在しましたが、2.8から一気に増えているのがわかると思います。

必要になるライブラリとしては、pyFG / fotriosapiなどがあるようです。

補足(httpapiについて)

実際には、ansible2.9からfortiosもhttpapiというコネクションプラグインに対応したため、ライブラリ無しでも動くようになったようです。(流石よこちさん)

公式ドキュメント側のhttpapiに関する説明はこちら↓。確かにfortiosも含まれてますね。

Httpapi plugins — Ansible Documentation

今回はfortiosapiベースで書いていますが、今後書くときはどちらなのか冒頭に明記していきたいと思います。

動作環境の整備

pyFGライブラリの導入→検証環境だと失敗

以下のGitHubで公開されているライブラリです。

github.com

中身については、paramikoのssh接続を利用したライブラリのようでした。(違ってたらすみません)

導入方法については、以下の通り。

pip install pyfg

ただ、検証環境でリファレンス通りに導入しようとすると、以下のようなエラーが発生しインストールに失敗しました。(画像内は一部省略済み)

見た感じだとインストール時にimportすべきライブラリがない、というエラーのようです。おそらく対処方法はあるのだと思いますが、私も詳しくないため、まずは華麗にスルーします。

pyfgで出来ることは限られていますし、2年以上アップデートもされていないため、ここにはあまり手をかける理由もないかな、とも思いました。

fortiosapiライブラリの導入

以下のGitHubで公開されているライブラリです。

github.com

上記URL内に以下のような記述もあり、非常に心強い感じです。実質メーカー公式ライブラリ&モジュールと言っても差し支えない!

Known Usage

Fortiosapi library is used in Fortinet Ansible modules and in Cloudify plugins. Maintained mainly by Fortinet employees.

とはいえ、コミュニティモジュールでありREDHATさんのサポート対象外なのはご注意ください。

こちらは、Fortigate のREST APIを利用するライブラリです。

導入方法については、以下の通り。

pip install fortiosapi

こちらは問題なく導入することができました。

(ansible28) ansible@ENVY360:~/ansible-study$ pip install fortiosapi
(略)
Collecting fortiosapi
  Downloading https://files.pythonhosted.org/packages/53/10/0647648a7e199cff5389d697d03553c41e682d14be475287377041d10a99/fortiosapi-1.0.1-py2.py3-none-any.whl
(略)
Installing collected packages: urllib3, certifi, chardet, idna, requests, oyaml, pynacl, bcrypt, paramiko, fortiosapi
Successfully installed bcrypt-3.1.7 certifi-2019.9.11 chardet-3.0.4 fortiosapi-1.0.1 idna-2.8 oyaml-0.9 paramiko-2.6.0 pynacl-1.3.0 requests-2.22.0 urllib3-1.25.6
(ansible28) ansible@ENVY360:~/ansible-study$ 

動作確認(疎通試験)

サーバ系のものと異なり、pingモジュールみたいな疎通試験的に使えるものがansible2.8の頃のモジュール群では見つからず後述する色々に悩まされてました。

ansible2.9で新たに実装された"fortios_facts"モジュールが疎通試験的に利用できそうだったため、情報が取れるかやってみました。

なお、利用ライブラリは「fortiosapi」側です。Legacy Modeと呼ばれる状態で利用しています。そのため、Playbookもその書式で書いています。

---
- hosts: localhost 
  gather_facts: false
  vars:
    host: "10.254.254.254"
    username: "admin"
    password: "password"
    vdom: "root"
    ssl_verify: "no"

  tasks:
  - name: Get Facts.
    fortios_facts:
      host: "{{ host }}"
      username: "{{ username }}"
      password: "{{ password }}"
      vdom: "{{ vdom }}"
      ssl_verify: "{{ ssl_verify }}"
      https: "yes"
      gather_subset:
        - fact: 'system_status_select'
    register: getfact_result

  - name: Debug
    debug: 
      var: getfact_result

以下の通り、情報が取得できました。

感想

最近ではfortios用のモジュールも豊富に整ってきており、かなり恵まれた状況なようにも思えます。

ただ、現状は冒頭にも書いた通り、ググッてもansible2.3/2.4の頃によこちさんが検証された記事くらいしか情報がなかったため、触り始める前は、いろいろと不安を感じてしまいました。

まだ酸いも甘いも味わえていませんが、今のところ調べたり試してみた限りではAnsibleでのFortigate自動化も現実的なレベルで実現可能まだまだ色々課題がありそうだと思います。

今後やっていくこと

今後は、ansible2.9以降でのFortigate自動化について、ググったら日本語情報が出てきて、他の方の【やってみよう】の後押しなるように、初学者ながらちまちまと記事を追加していきたいと思います。

特に、『運用を視野に入れたうえでも本当に使えるの?(使う必要あるの?)』ってところにも切り込んでいきたいです。

おまけ

いろいろと参考になりそうなドキュメント

調べている中で、「Fortinet Ansible Modules Documentation Release 1.0」というものを見つけました。

以下URLで公開されています。

https://buildmedia.readthedocs.org/media/pdf/ftnt-ansible-docs/latest/ftnt-ansible-docs.pdf

なんと、1600P超の大ボリュームのPDFファイルで、Fortinetモジュールに関するソースやPlaybookのサンプルがずらずらと…

FortiGateだけでなく、FortiAnalyzerやFortiManagerのモジュールに関する記述もあります。

ansible2.8のときからあったものなので、2.9バージョンがそのうちリリースされるのかもしれません。

ssl_verifyに悩まされた

AnsibleでFortigateの自動化できないかと触り始めた当初はansible2.8.6でした。

その当時はfortios_factsというものはなかったので、アドレスオブジェクトを追加するPlaybookを書いて試していたのですが、まあうまくいかず…

上手くいかなかった理由は、大別すると以下のような感じです。

  • fortiosapiは1.0以降で下位互換性を切り捨てている模様

    • 0.9.8のころは、HTTPSで利用されるのが自己証明書でもverifyはしていなかったため使えた
    • 1.0以降では標準動作でセキュリティを重視した作りとしており、その結果、自己証明書を使っているHTTPSは蹴られるようになった

    • 回避策としてはhttpsでアクセスさせたくない場合は、モジュール的にはhttps: "no"を入れる、という手段が提供された

  • fortigateは、デフォルトのhttpsでは自己証明書を利用している

  • fortigateは、デフォルトでhttpアクセスするとhttpsにリダイレクトされるようになっている

  • →この結果、fortigate初期状態ではverifyエラーで使えない状態になった。(試し始める障壁に)

このあたりが曲者で、Playbook側でhttps: "no"ってやっても証明書エラーでるのなんでやろ…と数時間悩みました。

結局、以下の設定箇所で Redirect to HTTPS をOFFにしてHTTPSへのリダイレクトを回避するかたちで対応しました。

ただ、アクセスそのものはできるようになったのですが、結局アドレスオブジェクトの追加すらうまくいかず…

色々とGitにあるモジュールのissueやらを眺めていたところ、2.9でモジュール側にssl_verifyで証明書の確認が無視できる機能が追加されるという情報を見つけました。

悩んだ結果、しっかりとした原因にたどり着かないまま、先に2.9に手を出してしまいました…

いつか戻って復習します…

ちなみに、最新の公式モジュールでも、https: no + ssl_verify: no みたいな記述があるのですが、Sampleに記載のあるssl_verifyの宣言はあくまで「変数としての宣言」までなので、実際使うならタスクごとにusernameなどと同様に呼び出しが必要です。

この辺は、タスクごとに大量に同じ文字列が並ぶので、Playbookも見やすいとは思えませんでした。 なので、たぶんこのあたりのつらみに悩まされないようにするためにも、httpapiを今後の標準としていく流れなのだと理解しています。

エラー応答をみてもさっぱり理由がわからない

これはおそらく今も同じエラーが出る場合もあると思いますが、Playbookのエラーなどが原因でリクエストが失敗した場合、大体が以下の2種類のエラーでした。

こういうのが出ると、どうしてもググってサンプルやらリファレンスやら見たくなるのですが、手軽に見れる情報があまりない状態だったのもあり、うぎゃーと叫びながら

  • HTTPS使わない状態でWireSharkでキャプチャデータのリクエスト/レスポンスを眺める
  • FortiGateのdiagnose debugしながら何かヒントがないか眺める

とかをやっていました。

Wiresharkは日常茶飯事で使うものの、普段からdiagnose debug見てる職業の人ではないので直観でなんかないかなーレベルで見ていましたが、まあわかるはずもなく。

多分、2.9系からはその辺が補強されたのか、エラー見てもだいぶ分かりやすくなってる気がします。(気のせいかもしれない)

いずれにしても、失敗談は失敗談として掲載したほうが、同じようなハマりをした方の助けにもなりますし、自分の覚書にもなるので、駄目だったケースも積極的に載せていこうと思います。

FortiはAPIではPOSTは無理では?というような検索結果に震える

"fortigate ansible"でググって出てこないので、"fortigate api"とかで検索をかけてみると、少しだけ記事はあったのですが、「参照専用」とか書かれていることが多く、「本当にできるんだろうか…」と不安になりながら進めていました。

実際、今回の記事では触れていませんが、問題なく設定追加や変更も可能です。

やはり、ググって結果が出てくる状態は素敵だなあと思います。少しでも貢献できるように微力ながらがんばります。