#SIDfm

脆弱性の管理と対策に纏わる話

  • 脆弱性情報 /
  • 脆弱性の管理の方法、プロセスの自動化 /
  • パッチ対応の自動化、SOAR

AWS Systems Manager の Ansible Playbook 実行機能を利用したパッチ適用

2021.6.29

はじめに

脆弱性には速やかな対応が求められる

脆弱性には速やかな対応が求められます。 ベンダによって脆弱性情報が公開された後、攻撃者は脆弱性を分析し、攻撃コードを作成。その後、攻撃を開始します。 防御側はこの攻撃開始までに脆弱性への対応を行わなければなりません。 攻撃開始までの期間は年々短くなっており、脆弱性への対応は以前と比較してより短期間での実施が求められています。

Ansible® によるパッケージ更新の自動化

このエントリでは、Amazon Web Services (AWS) Systems Manager (旧称 SSM) の Ansible Playbook 実行機能を利用して、 AWS EC2 インスタンス (Amazon Linux 2 AMI/Ubuntu 20.04 LTS) のパッケージを更新する方法をご紹介します。

  1. 通常の Ansible 構成と AWS Systems Manager の Ansible Playbook 実行構成の違い
  2. 想定する環境
  3. マネージドインスタンスにする
  4. Ansible Playbook の用意
  5. Ansible Playbook の保存
  6. Ansible Playbook の実行
  7. 補足
  8. まとめ
Ansible

Ansible とは、オープンソースの構成管理ツールの一種です。 エージェントレスのため、管理対象ノードに追加でインストールするソフトウェアは一部を除き不要です。(ssh 経由での接続は必要)

このエントリで扱う内容は、下図に示された脆弱性対策のフローの中で、「適用」フェーズに含まれるものです。

脆弱性対策フローでの位置づけ
出典:独立行政法人情報処理推進機構(IPA) セキュリティセンター, 脆弱性対策の効果的な進め方(ツール活用編), p.7

通常の Ansible 構成と AWS Systems Manager の Ansible Playbook 実行構成の違い

通常の Ansible の運用構成では、コントロールノードとターゲットノードが存在します。 Ansible は、コントロールノードにのみインストールされ、操作対象となるターゲットノードにはインストールされません。 コントロールノード上で実行された Playbook は Python 実行コードなどに変換されターゲットノードへ送信、実行されます。

通常のAnsible構成

AWS Systems Manager による Ansible Playbook の実行では、操作対象となる EC2 インスタンス (図中のターゲットインスタンス) に Ansible がインストールされます。 Playbook の実行では、まずターゲットインスタンスから AWS Systems Manager にポーリングを行い、 Run Command やステートマネージャーの SSM ドキュメント (AWS-ApplyAnsiblePlaybooks) に定義された処理を取得します。 次に、SSM ドキュメントに指定されたダウンロード元 (ここでは Amazon S3 バケット) から Playbook をダウンロードします。 最後に、ダウンロードした Playbook をターゲットインスタンス上で実行します。

AWS Systems Manager による Ansible Playbook 実行構成

違いをまとめると次の表のようになります。

通常 AWS Systems Manager
Ansible のインストール先 コントロールノード ターゲットノード
ターゲットの指定 コントロールノード AWS Systems Manager
Playbook の保存場所 コントロールノード Amazon S3 または Github

想定する環境

想定する環境を下図に示します。

Amazon Virtual Private Cloud (Amazon VPC) 内に Public subnet と Private subnet があり、 Public subnet はインターネットからのアクセスが可能なサブネットです。 一方、Private subnet はインターネットからのアクセスはできないサブネットとなっています。 Ansible Playbook を実行する対象である Amazon EC2 インスタンスは Private subnet 内に配置されています。 EC2 インスタンスの OS は Amazon Linux 2 AMI と Ubuntu Server 20.04 LTS とします。 これらの EC2 インスタンスは、SSH も含め、外部からアクセスできませんが、EC2 インスタンスからインターネットへの通信は Public サブネット内に設置された NAT Gateway を経由してインターネットへ接続できることとします。 同様に、EC2 インスタンスから AWS Systems Manager への通信も NAT Gateway 経由で可能であるとします。

想定する環境

マネージドインスタンスにする

AWS Systems Manager の Ansible Playbook 実行機能を利用するために、マネージドインスタンスにします。 マネージドインスタンスにするためには、次の要件を満たす必要があります。

  • AWS Systems Manager Agent (以下、SSM Agent とします) の導入
  • AWS Systems Manager API (以下、SSM API とします) への通信経路の確保
  • IAM ロールの付与

以下、順にご説明します。

  1. SSM Agent の導入

    SSM Agent とは SSM API と連携し、リソース (EC2 インスタンス、オンプレミスサーバー、あるいは仮想マシン) の更新、管理、設定を行うためのソフトウェアです。 AWS Systems Manager 経由で Ansible Playbook を実行する際にも SSM Agent が必要です。 SSM Agent は、Amazon Linux や Ubuntu Server のオフィシャルイメージには導入済みとなっています。 このエントリでは SSM Agent 導入済みのオフィシャルイメージを使用いたします。

  2. SSM API への通信経路の確保

    SSM Agent から SSM API へのアウトバウンド通信の経路を確保します。 今回は NAT Gateway 経由で AWS Systems Manager に接続できるようにネットワークを構成していますが、VPN エンドポイント経由などでも可能です。 ご利用の AWS/オンプレミス 環境に適した方法で、SSM API への通信経路を確保してください。

    SSMへの経路確保
  3. IAM ロールの付与

    AWS Systems Manager へのアクセスを許可するため、IAM ロールを作成して EC2 インスタンスに付与します。 今回は管理コンソールの Identity and Access Management (IAM) から新たに IAM ロールを作成し、以下の IAM ポリシーをアタッチします。

    • AmazonSSMManagedInstanceCore : AWS Systems Manager へのアクセスのため (必須)
    • AmazonS3ReadOnlyAccess : Ansible Playbook を保存している S3 バケットへのアクセスのため (オプション)

    IAMロール

    EC2 インスタンスを新規に作成する場合は、新たに作成した IAM ロールを指定してください。

    既存の EC2 インスタンスの IAM ロールを変更したりアタッチする場合には こちら のエントリをご参照ください。

Ansible Playbook の用意

今回 Amazon Linux 2 AMI および Ubuntu Server 20.04 LTS のパッケージを全て最新にする Ansible Playbook を作成します。 なお、ここでは全てのパッケージを対象にしていますが、実際の運用では特定のパッケージのみ更新することのほうが多いかと思われますので、更新するパッケージは適宜変更してください。

  1. ディレクトリ upgrade_packages を作成し、必要な Playbook を配置します。 upgrade_packages の構造は以下のとおりです。(※ ディレクトリレイアウトは Ansible のベストプラクティスに従ったものになっております。)
    upgrade_packages/
    ├── common
    │   └── tasks
    │       └── main.yml
    └── server.yml
  2. server.yml は通常の Ansible の実行時に
    $ ansible-playbook -i xxx server.yml
    といった形で実行を指定するファイルとなっており、読み込むロールや実行権限などが記載されています。 では server.yml の内容を見てみましょう。
    server.yml:
    - name: upgrade all packages
      hosts: all
      become: true
      become_method: sudo
      roles:
        - common
    2行目では全てのホストを意味する hosts: all となっています。 後述するように、AWS Systems Manager の設定でターゲットとなる EC2 インスタンスやそのグループを指定するので、hosts の項目は特に意味を持ちません。 この点にご注意ください。
  3. パッケージ更新を行う common/tasks/main.yml も見てみましょう。
    main.yml:
    ---
    - name: gather ec2 facts
      ec2_metadata_facts:
     
    - name: upgrade all packages (Red Hat)
      yum:
        name: '*'
        state: latest
      when: ansible_os_family == "RedHat"
     
    - name: upgrade all packages (Debian)
      apt:
        name: '*'
        state: latest
      when: ansible_os_family == "Debian"
    まず、EC2 インスタンスの facts を収集し、次に yum あるいは apt モジュールを使用して全てのパッケージを最新に更新しています。 なお yum モジュールや apt モジュールは Ansible Base (2.10) や Ansible Core (2.11) にも含まれていますので、 上記の Playbook であれば Ansible 2.9 系でも 2.10 系以降でも問題なく動作します。
  4. upgrade_packages ディレクトリを zip ファイルにまとめます。 この zip ファイルを Amazon S3 や Github に保存します。 EC2 インスタンスでの Playbook 実行時には、zip ファイルの展開も自動に行われます。

Ansible Playbook の保存

Amazon S3 への保存

S3 バケットに upgrade_packages.zip をアップロードします。

S3へ保存

Github への保存

Github の適当なリポジトリに upgrade_packages.zip をアップロードします。

Githubへ保存

Ansible Playbook の実行

Ansible Playbook は Run Command ステートマネージャー から実行可能です。 Run Command は一度限りの処理を実行する場合に、ステートマネージャーは定期的に処理を行いたい場合に便利です。 それぞれの設定方法を以下に説明します。

Run Command による実行

  1. AWS Systems Manager のトップ画面の左メニューから [Run Command] をクリックします。

    AWS Systems Manager トップ画面
  2. 画面右上の [Run Command] ボタンをクリックします。

    Run Command 作成
  3. 使用する SSM ドキュメントを指定します。
    ラジオボタンから AWS-ApplyAnsiblePlaybooks ドキュメントを選択してください。

    SSMドキュメント選択
  4. 次に、コマンドのパラメータを指定します。

    • [Source Type] は Ansible Playbook のダウンロード元を指定する項目です。 [Github] あるいは [S3] を選びます。

      Source Type
    • [Source Info] では、Ansible Playbook のファイルへのパス等、より詳細な情報を JSON 形式で指定します。

      例1: Amazon S3 に保存された zip ファイルを指定します

      {
         "path":"https://bucket_name.s3.ap-northeast-1.amazonaws.com/upgrade_packages.zip"
      }

      例2: Github に保存された zip ファイルを指定します

      {
         "owner":"owner_name",
         "repository":"repository_name",
         "path":"upgrade_packages.zip",
         "getOptions":"branch:branch_name"
      }
      Githubに保存
    • [Install Dependencies][True] にした場合、Ansible など必要なパッケージが EC2 インスタンスにインストールされます。 インストールされるパッケージについては こちら の「インストールされている依存関係」を参照してください。

      Install Dependencies
    • [Playbook File] (オプション) に実行する Playbook のパスを指定します。

      Playbook File
    • [Extra Variables] (オプション) にはAnsible 実行時に渡す追加の変数を記載します。

      Extra Variables
    • [Check] (オプション)[True] にした場合、チェックモード (ドライラン) で実行されます。

      Check
    • [Verbose] (オプション) では、ログレベルを指定します。ログレベルは -v、-vv、-vvv、-vvvv から選択できます。(Ansible 実行時に渡すログレベルと同じです)

      Verbose
    • [Timeout Seconds] (オプション) ではタイムアウトの時間を秒単位で指定します。

      Timeout Seconds

  5. Ansible Playbook を実行するターゲットを指定します。ターゲットの選択方法は次のとおりです。

    • [インスタンスタグの指定]
    • [インスタンスを手動で選択する]
    • [リソースグループの選択]
    AWS Systems Manager による Ansible Playbook の実行では、hosts キーワードなどの代わりに、このセクションを使用してターゲットを指定します。 インスタンスタグやリソースグループによってグループ化されたインスタンスを選択できるので、 実行対象をテスト系や運用系で分けたり、データベースを含むインスタンスなど特定の機能で分類されたグループをターゲットにするなど、 柔軟な運用が可能です。

    ターゲット
  6. レート制限 セクションでは、 [同時実行数] (Ansible の serial キーワードに相当) や [エラーのしきい値] を設定できます。

    レート制限
  7. 出力オプション セクションでは、 実行時の出力の Amazon S3 バケットへの書き込みや CloudWatch への書き込みを指定できます。 (Amazon S3 バケットへの書き込みに必要なアクセス権限については こちら を参照してください。)

    出力オプション
  8. [Run] ボタンをクリックし、指定した処理を実行します。

    Run
  9. 実行中の処理について、全体的なステータスやインスタンス毎のステータスが表示されます。

    コマンドステータス 進行中
  10. 処理が終了した際のステータス画面です。もし失敗した場合はインスタンスのリンクを辿ることでエラーなどの出力を確認できます。

    コマンドステータス 成功

ステートマネージャーからの実行

  1. AWS Systems Manager のトップ画面の左メニューから [ステートマネージャー] をクリックします。

    AWS Systems Manager トップ画面
  2. 画面右上の [関連付けの作成] ボタンをクリックします。

    関連付けの作成
  3. 使用する SSM ドキュメントを指定します。
    ラジオボタンから AWS-ApplyAnsiblePlaybooks ドキュメントを選択してください。

    SSMドキュメント選択
  4. コマンドのパラメータ セクションは Run Command による実行と同じため、ここでは説明を省略いたします。

    コマンドのパラメータ
  5. Ansible Playbook を実行するターゲットを指定します。ターゲットの選択方法は次のとおりです。

    • [インスタンスタグの指定]
    • [インスタンスを手動で選択する]
    • [リソースグループの選択]
    AWS Systems Manager による Ansible Playbook の実行では、hosts キーワードなどの代わりに、このセクションを使用してターゲットを指定します。 インスタンスタグやリソースグループによってグループ化されたインスタンスを選択できるので、 実行対象をテスト系や運用系で分けたり、データベースを含むインスタンスなど特定の機能で分類されたグループをターゲットにするなど、 柔軟な運用が可能です。

    ターゲット
  6. スケジュールを指定 セクションでは、定期実行や日時を指定した実行の指定が可能です。

    スケジュールを指定
  7. レート制限 セクションでは、 [同時実行数] (Ansible の serial キーワードに相当) や [エラーのしきい値] を設定できます。

    レート制限
  8. 出力オプション セクションでは、 実行時の出力の Amazon S3 バケットへの書き込みや CloudWatch への書き込みを指定できます。 (Amazon S3 バケットへの書き込みに必要なアクセス権限については こちら を参照してください。)

    出力オプション
  9. [関連付けの作成] ボタンをクリックします。

    関連付けの作成
  10. 作成した関連付けのステータスが表示されます。図ではまだ処理が行われておらず、ステータスが「保留中」になっています。

    関連付けステータス 保留中
  11. 初回の処理が終了した際のステータス画面です。もし失敗した場合はインスタンスのリンクを辿ることでエラーなどの出力を確認できます。

    関連付けステータス 成功

補足

Ansible のバージョンについて

前述したように、AWS Systems Manager による Ansible Playbook 実行ではターゲットとなる EC2 インスタンスに Ansible がインストールされます。 なおインストールされる Ansible のバージョンは、EC2 インスタンスの OS によって異なります。

ここでは、AWS Systems Manager によってインストールされた Ansible のバージョンを見てみましょう。

まず Amazon Linux 2 AMI を確認します。

$ ansible --version
ansible 2.9.21
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/ssm-user/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.18 (default, Feb 18 2021, 06:07:59) [GCC 7.3.1 20180712 (Red Hat 7.3.1-12)]

次に Ubuntu Server 20.04 LTS も確認します。

$ ansible --version
ansible [core 2.11.1]
  config file = None
  configured module search path = ['/home/ssm-user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.8/dist-packages/ansible
  ansible collection location = /home/ssm-user/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.8.5 (default, May 27 2021, 13:30:53) [GCC 9.3.0]
  jinja version = 2.10.1
  libyaml = True

Amazon Linux 2 AMI では 2.9 系が、 Ubuntu Server 20.04 LTS では 2.11 系が インストールされていることがわかります。(バージョンは 2021年06月23日 現在のものです。今後は変更される可能性があります。)

ご存知のように、Ansible は 2.10 で大幅な仕様変更があり、2.9 までは ansible の公式に含まれていたモジュールの大部分が外部のモジュールとして切り出されました。 また Playbook の記述方法も変更されています。そのため、2.9 では動作していた Playbook が 2.10 以降では必要なモジュールが足りないなどの理由で動作しないといったことも発生しています。

AWS Systems Manager を利用して Ansible Playbook を実行する際には、EC2 インスタンスの Ansible バージョンを把握しておくことをお勧めします。

まとめ

AWS Systems Manager の Ansible Playbook 実行機能を利用して EC2 インスタンスのパッケージを更新する方法をご紹介しました。

通常の Ansible 構成、つまりオンプレミスや AWS Cloud にコントロールノードを配置してターゲットノードに接続する方法では、

  • (ダイナミックインベントリを利用したとしても) インベントリの管理
  • EC2 インスタンスへの通信経路の確保
  • EC2 インスタンスへの SSH アクセスの確保

などに頭を悩ませられることが多いかと思います。AWS Systems Manager の Ansible Playbook 実行機能は、これらの悩みを解消できる点が優れています。 またステートマネージャーを使用することで、Ansible Playbook の実行タイミングを指定できますので、Ansible Engine そのものの弱点も補うことができます。

一方で、コントロールノードを配置しない代償として、ターゲットになる EC2 インスタンスに Ansible やその依存関係をインストールしなければならないので、この点には注意が必要です。 また AWS Systems Manager のパッチマネージャーにはパッチ適用前後にフックを利用してスクリプトを実行するといった機能が用意されていますが、Ansible Playbook 実行ではそのような機能が見当たらないため、yum モジュールや apt モジュールによるパッチ適用前後の監視の無効化や有効化は Ansible Playbook に自前で用意する必要がありそうです。

最後に、最もお伝えしたい点ですが、

弊社の脆弱性管理ツール「SIDfm™ VM」には修正プログラムを適用するための Ansible Playbook を出力する機能があります

ので、このエントリでご紹介した方法と組み合わせることによって、管理がグッと楽になります。是非活用をご検討ください。

参照

  1. AWS Systems Manager (Amazon)
  2. チュートリアル: Ansible プレイブックを実行する関連付けの作成 (Amazon)
  3. GitHub からの Ansible プレイブックの実行 (Amazon)
  4. Running Ansible Playbooks using EC2 Systems Manager Run Command and State Manager (Amazon)
  5. Keeping Ansible effortless with AWS Systems Manager (Amazon)
  6. Automate Ansible playbook deployment with Amazon EC2 and GitHub (Amazon)


脆弱性からの組織防衛のために

あなたの組織で脆弱性が対策されていることを確認できますか? 弊社の継続的脆弱性管理ツール SIDfm VM は、管理対象のホストで使用するソフトウェアで新しく報告された脆弱性のピックアップを行い、影響判定や対策工程の把握まで、脆弱性管理をトータルでカバーいたします。

脆弱性の調査パッチ探しは一切不要!
脆弱性対策を自動化できるので工数大幅削減!
さらに自社の脆弱性状況を全て可視化できるので
管理がグッと楽になる!

それらを全て実現するサービスがあります。

脆弱性管理ツール「SIDfm™ VM」について詳 しくはこちらから

SIDfm VM での脆弱性管理の具体的なプロセス

最新の記事

脆弱性と対策のことなら

SIDfm™

  • お問い合わせ

    SIDfm™ 各種サービスの使用法や購入において気になる点などお気軽にお問い合わせ下さい。

    お問い合わせ
  • 無料でトライアル

    SIDfm™ の VM、RA、Biz を実際に無料で使ってみてください。

    無料で試してみる