日本語

Ansible で Device Protection を展開する

SSH 経由でプッシュする Linux フリート全体に、Ansible を使って Device Protection をインストールします。以下のロールは各ホストに適したパッケージを選択し、ユーザーグループトークンを使ってインストールし、サービスを有効化された状態にします。

まず Install Device Protection for Linux を読んで、すべての方法で共通して使用するトークン、パッケージ、インストールオプションを確認してください。その他の内容(トークンの扱い、再起動、繰り返し実行、デバイス ID)は Linux Rollout Reference で説明しています。

ロールの構成

roles/aikido_device_protection/
├── defaults/main.yml
├── handlers/main.yml
└── tasks/main.yml
group_vars/
└── developer_workstations.yml
site.yml

ロールをセットアップする

  1. デフォルト値を追加する

    roles/aikido_device_protection/defaults/main.yml
    ---
    aikido_release_url: https://github.com/AikidoSec/safechain-internals/releases/latest/download
    
    # Reboot after installing. Off by default, see step 3.
    aikido_reboot: false
  2. タスクを追加する

    最初のタスクで実行すべき処理があるかどうかを判定するため、繰り返し実行しても負荷は小さく、トークンに触れることもありません。

    roles/aikido_device_protection/tasks/main.yml
    ---
    - name: Check whether Device Protection is already installed
      ansible.builtin.command: aikidoctl --simple
      register: aikido_installed
      changed_when: false
      failed_when: false
    
    - name: Install Device Protection
      when: aikido_installed.rc != 0
      block:
        - name: Work out the package architecture
          ansible.builtin.set_fact:
            aikido_arch: "{{ 'arm64' if ansible_facts['architecture'] == 'aarch64' else 'amd64' }}"
    
        - name: Work out the package name
          ansible.builtin.set_fact:
            aikido_package: >-
              {{
                'EndpointProtection-' ~ aikido_arch ~ '.deb'
                if ansible_facts['os_family'] == 'Debian'
                else 'EndpointProtection-' ~ aikido_arch ~ '.el'
                     ~ ansible_facts['distribution_major_version'] ~ '.rpm'
              }}
    
        - name: Download the package
          ansible.builtin.get_url:
            url: "{{ aikido_release_url }}/{{ aikido_package }}"
            dest: "/tmp/{{ aikido_package }}"
            mode: "0600"
    
        - name: Install the package on Debian and Ubuntu
          ansible.builtin.apt:
            deb: "/tmp/{{ aikido_package }}"
          environment:
            AIKIDO_TOKEN: "{{ aikido_token }}"
          no_log: true
          when: ansible_facts['os_family'] == 'Debian'
          notify: Reboot to activate Device Protection
    
        - name: Install the package on RHEL, Rocky Linux and CentOS
          ansible.builtin.dnf:
            name: "/tmp/{{ aikido_package }}"
            state: present
          environment:
            AIKIDO_TOKEN: "{{ aikido_token }}"
          no_log: true
          when: ansible_facts['os_family'] == 'RedHat'
          notify: Reboot to activate Device Protection
    
        - name: Remove the downloaded package
          ansible.builtin.file:
            path: "/tmp/{{ aikido_package }}"
            state: absent
    
    - name: Make sure the service is enabled and running
      ansible.builtin.systemd_service:
        name: aikido-endpoint-protection
        state: started
        enabled: true

    ロールで必要となるため、gather_facts は有効のままにしてください。el9 と el10 のどちらのビルドを使うかは distribution_major_version によって決まります。Amazon Linux 2023 は 2023 を返すため、使用している場合は el9 にマッピングしてください。

    environment キーワードによってトークンがインストールに渡され、no_log: true によってトークンがプレイの出力に表示されなくなります。

  3. 再起動ハンドラーを追加する

    roles/aikido_device_protection/handlers/main.yml
    ---
    - name: Reboot to activate Device Protection
      ansible.builtin.reboot:
        reboot_timeout: 600
        msg: Rebooting to activate Aikido Device Protection
      when: aikido_reboot | bool

    誰も作業していないホストでは aikido_reboot: true を設定してください。開発者のマシンでは無効のままにし、ユーザーに一度ログアウトして再ログインするよう依頼してください。When protection becomes active を参照してください。

  4. トークンを Ansible Vault に保存する

    Aikido のユーザーグループに対応するインベントリグループ用にトークンを暗号化します:

    ansible-vault encrypt_string --name aikido_token '<your-token>'

    出力をグループの変数に貼り付けます:

    group_vars/developer_workstations.yml
    ---
    aikido_token: !vault |
      $ANSIBLE_VAULT;1.1;AES256
      62313365396662343061393464336163383764373764613633653634306231386433626436623361
      ...

    複数のユーザーグループを使用する場合は、グループごとに繰り返してください。各グループには専用のトークンと専用の group_vars ファイルを用意します。

    トークンがすでに CI シークレットに保存されている場合は、Vault で暗号化したコピーをコミットする代わりに、コントローラーの環境変数から読み込んでください: aikido_token: "{{ lookup('env', 'AIKIDO_TOKEN') }}"。

  5. Playbook を作成して実行する

    site.yml
    ---
    - name: Deploy Aikido Device Protection
      hosts: developer_workstations
      become: true
      serial: 20%
      roles:
        - aikido_device_protection

    まず少数のマシンで実行し、その後対象を広げます:

    ansible-playbook site.yml --ask-vault-pass --limit pilot
    ansible-playbook site.yml --ask-vault-pass

ロールアウトを確認する

ansible developer_workstations -m command -a "aikidoctl --simple"
ansible developer_workstations -b -m command -a "systemctl is-active aikido-endpoint-protection"

その後、デバイスが デバイス一覧 に Active ステータスで表示されます。

トラブルシューティング

問題対処法
パッケージはインストールされるが、デバイスがダッシュボードに表示されないインストールコマンドに AIKIDO_TOKEN が設定されていませんでした。構成管理ツールはローカル環境をホストに転送しないため、タスク自体に変数を設定してから、パッケージを再度インストールしてください
apt または dnf がファイルをインストールせず、リポジトリ内でパッケージを探してしまう名前ではなくパスを指定してください: apt install ./EndpointProtection-amd64.deb。先頭の ./ によって、パッケージマネージャーはそれをローカルファイルとして扱います
Red Hat 系のホストでインストールが失敗するビルドをメジャーバージョンに合わせてください。バージョン 9 では el9 パッケージを、バージョン 10 では el10 パッケージを使用します
サービスが実行されていないsystemctl status aikido-endpoint-protection を実行し、次に sudo aikidoctl diagnostics を実行して詳細を送信してください
Node.js または uv が依然として Aikido 証明書を拒否するインストール時に NODE_EXTRA_CA_CERTS と UV_SYSTEM_CERTS がシステム全体に設定されますが、実行中のシェルにはこれらが反映されません。新しいログインシェルを開くか、デバイスを再起動してください
トークンが実行出力やログに表示されるツールのマスキング機能を使用してください: Ansible では no_log、Chef では sensitive true、Puppet では Sensitive()
複数のマシンがデバイス一覧で 1 つのエントリを共有しているそれらのマシンは同じ /etc/machine-id で起動しています。Linux のデバイス ID はこのファイルに基づくため、クローン元のイメージでこのファイルをクリアし、初回起動時に systemd に新しいものを書き込ませてください
トレイアイコンが表示されないUbuntu 以外の GNOME では想定どおりの動作であり、見た目上の問題にすぎません。Tray Icon Support on Linux を参照してください