日本語

Puppet で Device Protection を展開する

Puppet クラスを使用して、Puppet エージェントがすでに管理している Linux ノードに Device Protection をインストールします。以下のクラスは、プラットフォームごとに適切なパッケージを選択し、ユーザーグループトークンを使用してインストールし、実行のたびにサービスが稼働し続けるようにします。

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

モジュール構成

modules/aikido_device_protection/
└── manifests/init.pp
data/
└── groups/developers.yaml

クラスをセットアップする

  1. トークンを Hiera eyaml に保存する

    Aikido のユーザーグループに対応するノードグループ用にトークンを暗号化します。

    eyaml encrypt -l 'aikido_device_protection::token' -s '<your-token>'

    出力を該当する Hiera レイヤーに貼り付けます。

    data/groups/developers.yaml
    ---
    aikido_device_protection::token: >
      ENC[PKCS7,MIIBiQYJKoZIhvcNAQcDoIIBejCCAXYCAQAxggEhMIIBHQIBADAFMAACAQEw...]

    クラスパラメーターは Sensitive 型で定義されており、Puppet は Hiera から渡される値を自動的にラップするため、ほかに必要な作業はありません。

  2. クラスを追加する

    modules/aikido_device_protection/manifests/init.pp
    class aikido_device_protection (
      Sensitive[String[1]] $token,
      String[1] $release_url = 'https://github.com/AikidoSec/safechain-internals/releases/latest/download',
    ) {
      $arch = $facts['os']['architecture'] ? {
        /^(aarch64|arm64)$/ => 'arm64',
        default             => 'amd64',
      }
    
      case $facts['os']['family'] {
        'Debian': {
          $package_file    = "EndpointProtection-${arch}.deb"
          $install_command = 'apt-get install -y'
          $installed_check = "dpkg-query -W -f='\${db:Status-Status}' aikido-endpoint-protection 2>/dev/null | grep -qx installed"
        }
        'RedHat': {
          $package_file    = "EndpointProtection-${arch}.el${facts['os']['release']['major']}.rpm"
          $install_command = 'dnf install -y'
          $installed_check = 'rpm -q aikido-endpoint-protection'
        }
        default: {
          fail("Aikido Device Protection does not support ${facts['os']['family']}")
        }
      }
    
      $package_path = "/var/cache/aikido/${package_file}"
    
      file { '/var/cache/aikido':
        ensure => directory,
        owner  => 'root',
        group  => 'root',
        mode   => '0700',
      }
    
      exec { 'download aikido-endpoint-protection':
        command  => "curl -fsSLo ${package_path} ${release_url}/${package_file}",
        provider => shell,
        path     => ['/usr/bin', '/bin'],
        creates  => $package_path,
        unless   => $installed_check,
        require  => File['/var/cache/aikido'],
      }
    
      $install_script = @("SCRIPT")
        #!/bin/sh
        set -e
        export AIKIDO_TOKEN='${$token.unwrap}'
        exec ${install_command} ${package_path}
        | SCRIPT
    
      file { '/usr/local/sbin/aikido-install':
        ensure  => file,
        owner   => 'root',
        group   => 'root',
        mode    => '0700',
        content => Sensitive($install_script),
      }
    
      exec { 'install aikido-endpoint-protection':
        command  => '/usr/local/sbin/aikido-install',
        provider => shell,
        path     => ['/usr/bin', '/bin', '/usr/sbin', '/sbin'],
        unless   => $installed_check,
        require  => [
          Exec['download aikido-endpoint-protection'],
          File['/usr/local/sbin/aikido-install'],
        ],
      }
    
      service { 'aikido-endpoint-protection':
        ensure  => running,
        enable  => true,
        require => Exec['install aikido-endpoint-protection'],
      }
    }

    このクラスについて、知っておくべき点が 4 つあります。

    • パッケージには 環境変数に AIKIDO_TOKEN が必要で、Puppet は exec の environment 属性を秘匿化しないため、インストールは Sensitive() でラップされた root 専用スクリプトから実行されます。
    • unless => $installed_check がダウンロードとインストールをガードするため、すでにエージェントが稼働しているノードでは何も実行されません。
    • Debian のチェックはパイプラインであり、exec はデフォルトではシェルを使用しないため、provider => shell を指定しています。
    • ダウンロードには curl を使用しますが、最小構成のイメージには含まれていないことがあります。その場合は、このクラスと併せてインストールしてください。

    トークンは root のみがアクセスできる 2 か所のディスク上に保存されます。1 つはガードがなくインストール後も残る /usr/local/sbin/aikido-install、もう 1 つはエージェントがリソースを適用するために必要とする /opt/puppetlabs/puppet/cache 配下のキャッシュされたカタログです。どちらも機密情報として扱い、レポートへのアクセスを制限してください。

    ノードグループへのインストールが完了したら、file リソースを ensure => absent に切り替えると、すべてのノードからスクリプトが削除されます。そのグループに次の新しいノードが参加する前に、元に戻してください。

  3. ノードを分類する

    ロールとプロファイル、Puppet Enterprise コンソール、または site.pp など、ノードを分類する場所でクラスを宣言します。

    include aikido_device_protection

    次回のエージェント実行時にエージェントがインストールされます。まず 1 つのグループを分類してから、対象を広げてください。

    Puppet には組み込みの再起動リソースがないため、保護はユーザーがログアウトして再度ログインした時点で有効になります。無人のノードを再起動させたい場合は、インストール用の exec から puppetlabs-reboot に通知します。When protection becomes active を参照してください。

ロールアウトを確認する

実行済みのノードで次を実行します。

systemctl is-active aikido-endpoint-protection
aikidoctl version

その後、デバイスが デバイス一覧 に 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 を参照してください