- 重要な情報
- はじめに
- 用語集
- エージェント
- インテグレーション
- OpenTelemetry
- 開発者
- API
- CoScreen
- アプリ内
- インフラストラクチャー
- アプリケーションパフォーマンス
- 継続的インテグレーション
- ログ管理
- セキュリティ
- UX モニタリング
- 管理
Agent の構成ファイルにプレーンテキストでシークレットを保存したくない場合は、シークレット管理パッケージを使用できます。
Agent は、secrets
パッケージを利用してユーザー指定の実行可能ファイルを呼び出し、シークレットの取得と復号化を処理できます。その後、シークレットは Agent によってメモリにロードされます。このアプローチにより、ユーザーはシークレット管理バックエンド(HashiCorp Vault や AWS Secrets Manager など)に依存し、好みの認証方法を選択してイニシャルトラストを確立できます。Agent のコンテナデプロイには、この実行ファイルに使用する Helper Scripts があらかじめパッケージされているため、便利です。
バージョン 6.12 以降、シークレット管理パッケージは、メトリクス、APM、プロセスモニタリングのために Linux で、メトリクスと APM のために Windows で一般に利用可能です。
ENC[]
表記を使用して、構成内の任意の YAML フィールドの値としてシークレットを示します。
シークレットは、ファイル、etcd、consul などのあらゆる構成バックエンドおよび環境変数でサポートされています。
また、シークレットは datadog.yaml
でもサポートされています。Agent は最初にメイン構成をロードし、シークレットを復号化した後にそれをリロードします。これは、シークレットを secret_*
設定で使用できないことを意味します。
シークレットは常に文字列です。シークレットを使用して整数またはブール値を設定することはできません。
例:
instances:
- server: db_prod
# 2 つの有効なシークレットハンドル
user: "ENC[db_prod_user]"
password: "ENC[db_prod_password]"
# `ENC[]` ハンドルは YAML 値全体である必要があります。これは、
# 以下がシークレットハンドルとして検出されないことを意味します。
password2: "db-ENC[prod_password]"
ここには、db_prod_user
と db_prod_password
という 2 つのシークレットがあります。これらはシークレットの_ハンドル_であり、それぞれがシークレット管理バックエンド内でシークレットを一意に識別します。
角括弧の間では、YAML 構成が有効である限り、あらゆる文字が許可されます。これは、引用符をエスケープする必要があることを意味します。例:
"ENC[{\"env\": \"prod\", \"check\": \"postgres\", \"id\": \"user_password\"}]"
上記の例では、シークレットのハンドルは文字列 {"env": "prod", "check": "postgres", "id": "user_password"}
です。
内部の [
と ]
をエスケープする必要はありません。例:
"ENC[user_array[1234]]"
上記の例では、シークレットのハンドルは文字列 user_array[1234]
です。
シークレットはオートディスカバリーテンプレート変数が解決された後に解決されます。つまり、シークレットハンドルで使用できます。例:
instances:
- server: %%host%%
user: ENC[db_prod_user_%%host%%]
password: ENC[db_prod_password_%%host%%]
シークレットを取得するには、シークレット管理バックエンドに対してシークレットを認証してフェッチできる実行可能ファイルを提供する必要があります。
Agent はメモリ内にシークレットを内部的にキャッシュして、呼び出しの回数を減らします(たとえば、コンテナ化された環境で役立ちます)。Agent は、シークレットがまだメモリにロードされていないシークレットハンドルを少なくとも 1 つ含むチェック構成ファイルにアクセスするたびに実行可能ファイルを呼び出します。特に、既にメモリにロードされているシークレットは、実行可能ファイルへの追加の呼び出しをトリガーしません。具体的には、Agent は起動時にシークレットハンドルを含むファイルごとにユーザー提供の実行可能ファイルを 1 回呼び出し、Agent またはインスタンスが再起動された場合、または Agent がシークレットハンドルを含む新しいチェックを動的にロードした場合(オートディスカバリーからなど)、後で実行可能ファイルに対する追加の呼び出しを行う可能性があるということです。
APM とプロセスモニタリングは独自のプロセス/サービスで実行され、プロセスはメモリを共有しないため、それぞれがシークレットをロード/復号化できる必要があります。したがって、datadog.yaml
にシークレットが含まれている場合、各プロセスが実行可能ファイルを 1 回呼び出すことがあります。たとえば、APM とプロセスモニタリングを有効にして datadog.yaml
ファイルに api_key
をシークレットとして格納すると、シークレットバックエンドへの呼び出しが 3 回行われる可能性があります。
設計上、ユーザー提供の実行可能ファイルは、ユーザーが必要とする可能性のあるエラー処理メカニズムを実装する必要があります。逆に、メモリ内でシークレットを更新する必要がある場合は(例: パスワードの失効)、Agent を再起動する必要があります。
ユーザー提供の実行可能ファイルに依存することには、複数の利点があります。
datadog.yaml
で次の変数を設定します。
secret_backend_command: <EXECUTABLE_PATH>
Agent はサブプロセスとして secret_backend_command
実行可能ファイルを実行します。Linux と Windows では実行パターンが異なります。
Linux では、secret_backend_command
として設定される実行可能ファイルは以下である必要があります。
dd-agent
、またはコンテナ内の root
)。Windows では、secret_backend_command
として設定される実行可能ファイルは以下である必要があります。
ddagentuser
(Agent の実行に使用したユーザー)の読み取り/実行を持っている。Administrators
グループ、ビルトインローカルシステムアカウント、または Agent ユーザーコンテキスト(デフォルトでは ddagentuser
)以外のユーザーまたはグループの権限を持っていない。注: 実行可能ファイルは、Agent と同じ環境変数を共有します。
絶対に stderr
に機密情報を出力しないでください。バイナリが 0
以外のステータスコードで終了する場合、トラブルシューティングを容易にするために、Agent は実行可能ファイルの標準エラー出力をログします。
実行可能ファイルは単純な API を尊重します。標準入力から JSON を読み取り、復号化されたシークレットを含む JSON を標準出力に出力します。
実行可能ファイルの終了コードが 0
以外の場合、現在復号化されているインテグレーション構成はエラーと見なされ、ドロップされます。
実行可能ファイルは、取得するシークレットのリストを含む JSON ペイロードを標準入力から受信します。
{"version": "1.0", "secrets": ["secret1", "secret2"]}
version
: フォーマットバージョン(現在は 1.0)を含む文字列です。secrets
: 文字列のリストです。各文字列は、取得するシークレットに対応する構成からのハンドルです。実行可能ファイルは、取得したシークレットを含む JSON ペイロードを標準出力に出力することが期待されます。
{
"secret1": {"value": "secret_value", "error": null},
"secret2": {"value": null, "error": "シークレットを取得できませんでした"}
}
予想されるペイロードは JSON オブジェクトで、各キーは入力ペイロードでリクエストされたハンドルの 1 つです。各ハンドルの値は、2 つのフィールドを持つ JSON オブジェクトです。
value
: 文字列。チェック構成で使用される実際のシークレット値(エラーの場合は null にできます)。error
: 文字列。必要に応じて、エラーメッセージ。エラーが null 以外の場合、このハンドルを使用するインテグレーション構成はエラーと見なされ、ドロップされます。以下は、すべてのシークレットの先頭に decrypted_
を付けたダミーの Go プログラムです。
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
)
type secretsPayload struct {
Secrets []string `json:secrets`
Version int `json:version`
}
func main() {
data, err := ioutil.ReadAll(os.Stdin)
if err != nil {
fmt.Fprintf(os.Stderr, "標準入力から読み込めませんでした: %s", err)
os.Exit(1)
}
secrets := secretsPayload{}
json.Unmarshal(data, &secrets)
res := map[string]map[string]string{}
for _, handle := range secrets.Secrets {
res[handle] = map[string]string{
"value": "decrypted_" + handle,
}
}
output, err := json.Marshal(res)
if err != nil {
fmt.Fprintf(os.Stderr, "res をシリアル化できませんでした: %s", err)
os.Exit(1)
}
fmt.Printf(string(output))
}
これにより、この構成(チェックファイル内)
instances:
- server: db_prod
user: ENC[db_prod_user]
password: ENC[db_prod_password]
が次に更新されます(Agent のメモリ内)。
instances:
- server: db_prod
user: decrypted_db_prod_user
password: decrypted_db_prod_password
多くの Datadog インテグレーションは、メトリクスを取得するために資格情報を必要とします。オートディスカバリーテンプレートにこれらの資格情報を直接入力しないように、機密情報管理を使用し、資格情報をテンプレートと切り離すことができます。
バージョン 7.32.0 からは、Agent のコンテナイメージに /readsecret_multiple_providers.sh
というヘルパースクリプトが用意され、Kubernetes Secrets に加えて、ファイルからシークレットを取得するために使用することができるようになりました。以前のバージョンで提供されていた 2 つのスクリプト (readsecret.sh
と readsecret.py
) もサポートされていますが、ファイルからしか読み込むことができません。
スクリプト readsecret_multiple_providers.sh
は、Kubernetes Secrets と同様に、両方のファイルから読み取るために使用できます。これらの Secret は ENC[provider@some/path]
という形式である必要があります。例:
プロバイダー | 形式 |
---|---|
ファイルからの読み込み | ENC[file@/path/to/file] |
Kubernetes Secrets | ENC[k8s_secret@some_namespace/some_name/a_key] |
この実行ファイルを Helm チャートで使用するには、次のように設定します。
datadog:
[...]
secretBackend:
command: "/readsecret_multiple_providers.sh"
この実行ファイルを使用するには、環境変数 DD_SECRET_BACKEND_COMMAND
を以下のように設定します。
DD_SECRET_BACKEND_COMMAND=/readsecret_multiple_providers.sh
Agent は、指定されたファイルを指定されたパスから相対的に読み込むことができます。このファイルは、Kubernetes Secrets、Docker Swarm Secrets、または他のカスタムメソッドから持ってくることができます。
Agent コンテナにファイル /etc/secret-volume/password
があり、その内容が平文のパスワードである場合、ENC[file@/etc/secret-volume/password]
という表記でこれを参照することができます。
Kubernetes は、ポッド内の Secret をファイルとして公開することをサポートしています。例を考えてみましょう。Secret: test-secret
という Secret は、db_prod_password: example
というデータを持っています。この Secret は、以下のような構成で Agent コンテナにマウントされています。
containers:
- name: agent
#(...)
volumeMounts:
- name: secret-volume
mountPath: /etc/secret-volume
#(...)
volumes:
- name: secret-volume
secret:
secretName: test-secret
この例では、Agent コンテナに /etc/secret-volume/db_prod_password
というファイルがあり、example
というコンテンツが含まれています。これは構成内で ENC[file@/etc/secret-volume/db_prod_password]
を使って参照されます。
注:
/var/run/secrets/kubernetes.io/serviceaccount/token
を含むすべてのサブフォルダにアクセスすることが可能です。そのため、Datadog では /var/run/secrets
の代わりに専用フォルダを使用することを推奨しています。Docker swarm シークレットは /run/secrets
フォルダにマウントされます。例えば、Docker シークレットの db_prod_passsword
は Agent コンテナ内の /run/secrets/db_prod_password
に格納されます。これを構成から参照するには、ENC[file@/run/secrets/db_prod_password]
とします。
以下の設定により、Agent は自身のネームスペースと他のネームスペースの両方で Kubernetes Secrets を直接読み取ることができます。これを行うには、Agent の ServiceAccount
に適切な Roles
と RoleBindings
の権限が付与されている必要があることに注意してください。
Secret: database-secret
が Namespace: database
に存在し、データ password: example
を含む場合、これは構成内で ENC[k8s_secret@database/database-secret/password]
と共に参照されます。この設定により、Agent は Kubernetes から直接この Secret を取得するため、Agent と異なるネームスペースに存在する Secret を参照する際に便利な場合があります。
これには、Agent のサービスアカウントに手動で付与される追加の権限が必要です。たとえば、次のような RBAC ポリシーを考えてみましょう。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: datadog-secret-reader
namespace: database
rules:
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["database-secret"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: datadog-read-secrets
namespace: example
subjects:
- kind: ServiceAccount
name: datadog-agent
apiGroup: ""
namespace: default
roleRef:
kind: Role
name: datadog-secret-reader
apiGroup: ""
この Role
は Namespace: database
内の Secret: database-secret
にアクセスできるようにします。RoleBinding
はこの権限を Namespace: default
内の ServiceAccount: datadog-agent
に紐付けます。これは、クラスターにデプロイされたリソースに対して、手動で追加する必要があります。
これらの権限に加えて、Kubernetes Secrets プロバイダーを使用する場合は、スクリプトで複数のプロバイダーから読み込めるようにする必要があります: "/readsecret_multiple_providers.sh"
。
Datadog Agent v7.32 は readsecret_multiple_providers.sh
スクリプトを導入しました。Datadog は Agent v6.12 の /readsecret.py
と /readsecret.sh
の代わりにこのスクリプトを使用することを推奨しています。なお、ファイルを読み込むための /readsecret.py
と /readsecret.sh
はまだ Agent に含まれており、サポートされています。
これらのスクリプトは、引数として渡されるフォルダを必要とします。シークレットハンドルは、このフォルダからの相対的なファイル名として解釈されます。機密情報の漏洩を防ぐため、指定されたルートフォルダ外のファイルへのアクセスは拒否されます (シンボリックリンクターゲットを含む)。
これらのスクリプトは OpenShift の制限付き SCC オペレーションとの互換性を持たないため、Agent を root
ユーザーとして実行する必要があります。
Docker Swarm シークレットは /run/secrets
フォルダにマウントされています。これらは、以下の環境変数を Agent コンテナに渡すことで読み込むことができます。
DD_SECRET_BACKEND_COMMAND=/readsecret.py
DD_SECRET_BACKEND_ARGUMENTS=/run/secrets
このセットアップでは、Datadog Agent は /run/secrets
ディレクトリにあるすべてのシークレットファイルを読み取ります。例えば、ENC[password]
という構成は、Agent に /run/secrets/password
ファイルを探させることになります。
Kubernetes は、ポッド内の Secrets をファイルとして公開することをサポートしています。例えば、Secrets が /etc/secret-volume
にマウントされている場合、以下の環境変数を使用します。
DD_SECRET_BACKEND_COMMAND=/readsecret.py
DD_SECRET_BACKEND_ARGUMENTS=/etc/secret-volume
このセットアップでは、Datadog Agent は /etc/secret-volume
ディレクトリにあるすべてのシークレットファイルを読み取ります。例えば、ENC[password]
という構成は、Agent に /etc/secret-volume/password
ファイルを探させることになります。
Agent CLI の secret
コマンドは、セットアップに関連するエラーが表示します。たとえば、実行可能ファイルの権限が正しくない場合などです。また、見つかったすべてのハンドルとそれらの場所もリストされます。
Linux では、コマンドは実行可能ファイルのファイルモード、所有者、グループを出力します。Windows では、ACL 権限がリストされます。
Linux の例
$> datadog-agent secret
=== Checking executable rights ===
Executable path: /path/to/you/executable
Check Rights: OK, the executable has the correct rights
Rights Detail:
file mode: 100700
Owner username: dd-agent
Group name: dd-agent
=== Secrets stats ===
Number of secrets decrypted: 3
Secrets handle decrypted:
- api_key: from datadog.yaml
- db_prod_user: from postgres.yaml
- db_prod_password: from postgres.yaml
Windows の例(管理者の PowerShell から)
PS C:\> & "$env:ProgramFiles\Datadog\Datadog Agent\bin\agent.exe" secret
=== Checking executable rights ===
Executable path: C:\path\to\you\executable.exe
Check Rights: OK, the executable has the correct rights
Rights Detail:
Acl list:
stdout:
Path : Microsoft.PowerShell.Core\FileSystem::C:\path\to\you\executable.exe
Owner : BUILTIN\Administrators
Group : WIN-ITODMBAT8RG\None
Access : NT AUTHORITY\SYSTEM Allow FullControl
BUILTIN\Administrators Allow FullControl
WIN-ITODMBAT8RG\ddagentuser Allow ReadAndExecute, Synchronize
Audit :
Sddl : O:BAG:S-1-5-21-2685101404-2783901971-939297808-513D:PAI(A;;FA;;;SY)(A;;FA;;;BA)(A;;0x1200
a9;;;S-1-5-21-2685101404-2783901971-939297808-1001)
=== Secrets stats ===
Number of secrets decrypted: 3
Secrets handle decrypted:
- api_key: from datadog.yaml
- db_prod_user: from sqlserver.yaml
- db_prod_password: from sqlserver.yaml
configcheck
コマンドを使うと、チェックの構成がどのように解決されるかを素早く確認できます。
sudo -u dd-agent -- datadog-agent configcheck
=== a check ===
Source: File Configuration Provider
Instance 1:
host: <decrypted_host>
port: <decrypted_port>
password: <obfuscated_password>
~
===
=== another check ===
Source: File Configuration Provider
Instance 1:
host: <decrypted_host2>
port: <decrypted_port2>
password: <obfuscated_password2>
~
===
注: 構成ファイルの変更を適用するには、Agent を再起動する必要があります。
Agent の外部でテストまたはデバッグするには、Agent の実行方法を模倣できます。
sudo -u dd-agent bash -c "echo '{\"version\": \"1.0\", \"secrets\": [\"secret1\", \"secret2\"]}' | /path/to/the/secret_backend_command"
Datadog Agent をインストールすると、dd-agent
ユーザーが作成されます。
次のいずれかのエラーが発生した場合、セットアップに何かが欠落しています。Windows の説明をご覧ください。
必要以外のグループまたはユーザーが実行可能ファイルに対する権限を持っている場合、次と同様のエラーがログに記録されます。
error while decrypting secrets in an instance: Invalid executable 'C:\decrypt.exe': other users/groups than LOCAL_SYSTEM, Administrators or ddagentuser have rights on it
ddagentuser
がファイルの読み取りと実行を行わない場合、同様のエラーがログに記録されます。
error while decrypting secrets in an instance: could not query ACLs for C:\decrypt.exe
実行可能ファイルは有効な Win32 アプリケーションである必要があります。そうでない場合、次のエラーがログに記録されます。
error while running 'C:\decrypt.py': fork/exec C:\decrypt.py: %1 is not a valid Win32 application.
実行可能ファイルは、シークレットを取得するときに Agent によって実行されます。Datadog Agent は ddagentuser
を使用して実行されます。このユーザーには特定の権限はありませんが、Performance Monitor Users
グループの一部です。このユーザーのパスワードはインストール時にランダムに生成され、どこにも保存されることはありません。
これは、実行可能ファイルがデフォルトのユーザーまたは開発ユーザーで動作する可能性があることを意味しますが、ddagentuser
にはより制限された権限があるため、Agent によって実行されるときは動作しません。
Agent と同じ条件で実行可能ファイルをテストするには、開発ボックスの ddagentuser
のパスワードを更新します。このようにして、ddagentuser
として認証し、Agent が実行するのと同じコンテキストで実行可能ファイルを実行できます。
これを行うには、次の手順を実行します。
Local Security Policy
の Local Policies/User Rights Assignement/Deny Log on locally
リストから ddagentuser
を削除します。ddagentuser
に新しいパスワードを設定します(インストール時に生成されたパスワードはどこにも保存されないため)。PowerShell で、次を実行します。$user = [ADSI]"WinNT://./ddagentuser";
$user.SetPassword("a_new_password")
DatadogAgent
サービスで使用されるパスワードを更新します。PowerShell で、次を実行します。sc.exe config DatadogAgent password= "a_new_password"
これで、ddagentuser
としてログインして実行可能ファイルをテストできます。Datadog には、実行可能ファイルを別のユーザーとしてテストするのに役立つ [Powershell スクリプト][7]があります。これはユーザーコンテキストを切り替え、Agent が実行可能ファイルを実行する方法を模倣します。
使用方法の例
.\secrets_tester.ps1 -user ddagentuser -password a_new_password -executable C:\path\to\your\executable.exe -payload '{"version": "1.0", "secrets": ["secret_ID_1", "secret_ID_2"]}'
Creating new Process with C:\path\to\your\executable.exe
Waiting a second for the process to be up and running
Writing the payload to Stdin
Waiting a second so the process can fetch the secrets
stdout:
{"secret_ID_1":{"value":"secret1"},"secret_ID_2":{"value":"secret2"}}
stderr: None
exit code:
0
Agent が起動時に最初に行うことは、datadog.yaml
をロードし、その中のシークレットを復号化することです。これは、ロギングを設定する前に行われます。これは、Windows のようなプラットフォームでは、datadog.yaml
の読み込み時に発生するエラーはログに書き込まれず、stderr
に書き込まれることを意味します。これは、シークレット用に Agent に提供された実行可能ファイルがエラーを返したときに発生する可能性があります。
datadog.yaml
にシークレットがあり、Agent が起動を拒否した場合は
stderr
を表示できるように、Agent を手動で起動してみます。datadog.yaml
からシークレットを削除し、最初にチェック構成ファイルでシークレットをテストします。Kubernetes から直接 Secrets を読み込む場合、kubectl auth
コマンドで権限をダブルチェックすることができます。一般的な形は以下のとおりです。
kubectl auth can-i get secret/<SECRET_NAME> -n <SECRET_NAMESPACE> --as system:serviceaccount:<AGENT_NAMESPACE>:<AGENT_SERVICE_ACCOUNT>
先ほどの Kubernetes Secrets 例で、Secret Secret:database-secret
が Namespace: database
に存在し、サービスアカウント ServiceAccount:datadog-agent
が Namespace: default
に存在していると考えてみましょう。
この場合、以下のコマンドを使用します。
kubectl auth can-i get secret/database-secret -n database --as system:serviceaccount:default:datadog-agent
このコマンドは、Agent がこの Secret を閲覧するための権限が有効であるかどうかを返します。
お役に立つドキュメント、リンクや記事: