デプロイメント
本番環境のハードニング
本番環境でのVaultのセキュリティ強化
最終更新: 2026/4/13
本番環境のハードニング
本番環境でVaultを安全に運用するためのセキュリティ強化手順をご紹介します。
本番環境での重要事項開発サーバーモード(
vault server -dev)は本番環境では絶対に使用しないでください。本ガイドに従って、適切な設定でVaultを起動してください。設定ファイルの作成
基本的な設定ファイル
config.hcl:
# ストレージバックエンド
storage "raft" {
path = "/vault/data"
node_id = "node1"
}
# HTTPSリスナー
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/vault/tls/tls.crt"
tls_key_file = "/vault/tls/tls.key"
}
# APIアドレス
api_addr = "https://vault.example.com:8200"
# クラスターアドレス
cluster_addr = "https://vault.example.com:8201"
# UIの有効化
ui = true
# ログレベル
log_level = "info"
# mlock(メモリロック)の有効化
disable_mlock = false
ストレージバックエンドの選択
1. Raft(推奨)
storage "raft" {
path = "/vault/data"
node_id = "node1"
retry_join {
leader_api_addr = "https://vault-1.example.com:8200"
}
retry_join {
leader_api_addr = "https://vault-2.example.com:8200"
}
}
特徴:
- 統合されたストレージ
- 外部依存なし
- 高可用性サポート
2. Consul
storage "consul" {
address = "consul.example.com:8500"
path = "vault/"
token = "consul-token"
}
特徴:
- 高可用性
- サービスディスカバリー
- 外部依存あり
3. その他のバックエンド
- PostgreSQL: リレーショナルデータベース
- MySQL: リレーショナルデータベース
- DynamoDB: AWSマネージドサービス
- Azure Storage: Azureマネージドサービス
- GCS: GCPマネージドサービス
TLS/HTTPSの設定
証明書の準備
自己署名証明書(開発・テスト用)
# 秘密鍵の生成
openssl genrsa -out tls.key 2048
# 証明書署名要求(CSR)の生成
openssl req -new -key tls.key -out tls.csr \
-subj "/C=JP/ST=Tokyo/L=Tokyo/O=Example/CN=vault.example.com"
# 自己署名証明書の生成
openssl x509 -req -days 365 -in tls.csr -signkey tls.key -out tls.crt
Let's Encryptを使用(本番環境推奨)
# Certbotのインストール
sudo apt-get install certbot
# 証明書の取得
sudo certbot certonly --standalone -d vault.example.com
TLSリスナーの設定
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/vault/tls/tls.crt"
tls_key_file = "/vault/tls/tls.key"
# TLSの最小バージョン
tls_min_version = "tls12"
# 推奨される暗号スイート
tls_cipher_suites = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
# クライアント証明書の検証(オプション)
tls_require_and_verify_client_cert = false
tls_client_ca_file = "/vault/tls/ca.crt"
}
Sealの設定
Auto Unseal(推奨)
AWS KMS
seal "awskms" {
region = "ap-northeast-1"
kms_key_id = "arn:aws:kms:ap-northeast-1:123456789012:key/abc123-def456"
}
Azure Key Vault
seal "azurekeyvault" {
tenant_id = "tenant-id"
client_id = "client-id"
client_secret = "client-secret"
vault_name = "vault-name"
key_name = "key-name"
}
GCP Cloud KMS
seal "gcpckms" {
project = "my-project"
region = "asia-northeast1"
key_ring = "vault-keyring"
crypto_key = "vault-key"
}
Shamir's Secret Sharing(デフォルト)
# 初期化時に設定
vault operator init \
-key-shares=5 \
-key-threshold=3
推奨設定:
- key-shares: 5(5つのキーを生成)
- key-threshold: 3(3つのキーでアンシール可能)
監査ログの設定
ファイルベースの監査ログ
# 監査ログを有効化
vault audit enable file file_path=/var/log/vault/audit.log
# ログローテーション設定(logrotate)
cat > /etc/logrotate.d/vault <<EOF
/var/log/vault/audit.log {
daily
rotate 30
compress
delaycompress
notifempty
create 0640 vault vault
sharedscripts
postrotate
systemctl reload vault
endscript
}
EOF
Syslogへの出力
vault audit enable syslog tag="vault" facility="AUTH"
複数の監査デバイス
# ファイルとSyslogの両方を有効化
vault audit enable file file_path=/var/log/vault/audit.log
vault audit enable syslog tag="vault"
監査ログの重要性少なくとも1つの監査デバイスが有効でない場合、Vaultはすべてのリクエストを拒否します。これにより、監査証跡が確実に記録されます。
アクセス制御
ファイアウォール設定
# UFW(Ubuntu)
sudo ufw allow 8200/tcp # API/UI
sudo ufw allow 8201/tcp # クラスター通信(HA構成の場合)
# iptables
sudo iptables -A INPUT -p tcp --dport 8200 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8201 -j ACCEPT
IPアドレス制限
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/vault/tls/tls.crt"
tls_key_file = "/vault/tls/tls.key"
# 特定のIPアドレスからのみアクセス可能
tls_disable_client_certs = false
}
ネットワークセグメンテーション
インターネット
↓
ロードバランサー(TLS終端)
↓
Vaultクラスター(プライベートサブネット)
↓
データベース(プライベートサブネット)
システムの強化
ユーザーとグループ
# Vault専用ユーザーの作成
sudo useradd -r -s /bin/false vault
# ディレクトリの作成と権限設定
sudo mkdir -p /vault/data /vault/tls /var/log/vault
sudo chown -R vault:vault /vault /var/log/vault
sudo chmod 700 /vault/data
sudo chmod 600 /vault/tls/*
systemdサービス
/etc/systemd/system/vault.service:
[Unit]
Description=HashiCorp Vault
Documentation=https://www.vaultproject.io/docs/
Requires=network-online.target
After=network-online.target
ConditionFileNotEmpty=/etc/vault.d/vault.hcl
[Service]
Type=notify
User=vault
Group=vault
ProtectSystem=full
ProtectHome=read-only
PrivateTmp=yes
PrivateDevices=yes
SecureBits=keep-caps
AmbientCapabilities=CAP_IPC_LOCK
CapabilityBoundingSet=CAP_SYSLOG CAP_IPC_LOCK
NoNewPrivileges=yes
ExecStart=/usr/bin/vault server -config=/etc/vault.d/vault.hcl
ExecReload=/bin/kill --signal HUP $MAINPID
KillMode=process
KillSignal=SIGINT
Restart=on-failure
RestartSec=5
TimeoutStopSec=30
LimitNOFILE=65536
LimitMEMLOCK=infinity
[Install]
WantedBy=multi-user.target
# サービスの有効化と起動
sudo systemctl daemon-reload
sudo systemctl enable vault
sudo systemctl start vault
mlockの有効化
# config.hcl
disable_mlock = false
# Vaultバイナリにcapabilityを付与
sudo setcap cap_ipc_lock=+ep /usr/bin/vault
初期化とアンシール
初期化
# 初期化
vault operator init \
-key-shares=5 \
-key-threshold=3 \
-format=json > vault-init.json
# Unseal KeyとRoot Tokenを安全に保管
cat vault-init.json | jq -r '.unseal_keys_b64[]' > unseal-keys.txt
cat vault-init.json | jq -r '.root_token' > root-token.txt
# ファイルの権限を制限
chmod 600 unseal-keys.txt root-token.txt
Unseal KeyとRoot Tokenの管理
- Unseal Keyは複数の管理者に分散して保管
- Root Tokenは初期設定後に無効化
- これらの情報を安全な場所(金庫、パスワードマネージャー等)に保管
- スクリーンショットやログに含めない
アンシール
# 3つのUnseal Keyでアンシール
vault operator unseal <key1>
vault operator unseal <key2>
vault operator unseal <key3>
# ステータス確認
vault status
Root Tokenの管理
Root Tokenの無効化
# Root Tokenでログイン
vault login <root-token>
# 管理者ポリシーとユーザーを作成
vault policy write admin admin-policy.hcl
vault auth enable userpass
vault write auth/userpass/users/admin \
password=<secure-password> \
policies=admin
# Root Tokenを無効化
vault token revoke -self
緊急時のRoot Token生成
# Root Token生成の開始
vault operator generate-root -init
# Unseal Keyを使用して生成
vault operator generate-root
# (3つのUnseal Keyを入力)
# 生成されたトークンをデコード
vault operator generate-root \
-decode=<encoded-token> \
-otp=<otp>
バックアップ
Raftスナップショット
# スナップショットの作成
vault operator raft snapshot save backup.snap
# スナップショットの復元
vault operator raft snapshot restore backup.snap
自動バックアップスクリプト
#!/bin/bash
# /usr/local/bin/vault-backup.sh
BACKUP_DIR="/backup/vault"
DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_FILE="$BACKUP_DIR/vault-snapshot-$DATE.snap"
# スナップショットの作成
vault operator raft snapshot save "$BACKUP_FILE"
# 古いバックアップの削除(30日以上前)
find "$BACKUP_DIR" -name "vault-snapshot-*.snap" -mtime +30 -delete
# バックアップの圧縮
gzip "$BACKUP_FILE"
cronジョブ:
# 毎日午前2時にバックアップ
0 2 * * * /usr/local/bin/vault-backup.sh
モニタリング
ヘルスチェック
# ヘルスチェックエンドポイント
curl https://vault.example.com:8200/v1/sys/health
メトリクス
# config.hcl
telemetry {
prometheus_retention_time = "30s"
disable_hostname = false
}
# Prometheusメトリクスの取得
curl https://vault.example.com:8200/v1/sys/metrics?format=prometheus
Auto Unseal(Enterprise版)
Enterprise版の機能HSM Auto-Unsealを含む高度なAuto Unseal機能は、Vault Enterprise版でのみ利用可能です。OSS版ではクラウドプロバイダーのKMS(AWS KMS、Azure Key Vault、GCP Cloud KMS)を使用したAuto Unsealが利用可能です。
Auto Unsealとは
Auto Unsealは、Vaultの起動時に自動的にアンシールを行う機能です。通常、Vaultは起動時にシール状態で開始し、複数のUnseal Keyを手動で入力する必要がありますが、Auto Unsealを使用すると、外部のキー管理システム(KMS)やハードウェアセキュリティモジュール(HSM)を使用して自動的にアンシールできます。
利点
✅ 運用の簡素化
- 手動でのアンシール作業が不要
- 自動再起動が可能
- 運用負荷の削減
✅ セキュリティの向上
- Unseal Keyの管理が不要
- HSMによる鍵の保護
- FIPS 140-2準拠(HSM使用時)
✅ 可用性の向上
- 迅速な復旧
- 自動フェイルオーバー
- ダウンタイムの最小化
HSM Auto-Unseal(Enterprise版)
ハードウェアセキュリティモジュール(HSM)を使用したAuto Unsealです。
サポートされるHSM
- PKCS#11準拠のHSM
- Thales Luna HSM
- Gemalto SafeNet HSM
- Utimaco HSM
- その他のPKCS#11準拠デバイス
設定例(PKCS#11 HSM)
config.hcl:
storage "raft" {
path = "/vault/data"
node_id = "node1"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/vault/tls/tls.crt"
tls_key_file = "/vault/tls/tls.key"
}
# HSM Auto-Unseal設定
seal "pkcs11" {
lib = "/usr/lib/libCryptoki2_64.so"
slot = "0"
pin = "AAAA-BBBB-CCCC-DDDD"
key_label = "vault-hsm-key"
hmac_key_label = "vault-hsm-hmac-key"
generate_key = "true"
}
api_addr = "https://vault.example.com:8200"
cluster_addr = "https://vault.example.com:8201"
初期化
# HSM Auto-Unsealを使用した初期化
vault operator init \
-recovery-shares=5 \
-recovery-threshold=3
# 出力例
Recovery Key 1: base64-encoded-key-1
Recovery Key 2: base64-encoded-key-2
Recovery Key 3: base64-encoded-key-3
Recovery Key 4: base64-encoded-key-4
Recovery Key 5: base64-encoded-key-5
Initial Root Token: hvs.CAESIJ...
Recovery Keyの保管HSM Auto-Unsealを使用する場合、Unseal Keyの代わりにRecovery Keyが生成されます。Recovery Keyは、HSMが利用できない場合の緊急時に使用するため、安全に保管してください。
起動とアンシール
# Vaultの起動(自動的にアンシールされる)
sudo systemctl start vault
# ステータス確認
vault status
# 出力例
Sealed: false # 自動的にアンシール済み
クラウドKMS Auto-Unseal
クラウドプロバイダーのKMSを使用したAuto Unseal(OSS版でも利用可能)です。
AWS KMS
config.hcl:
storage "raft" {
path = "/vault/data"
node_id = "node1"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/vault/tls/tls.crt"
tls_key_file = "/vault/tls/tls.key"
}
# AWS KMS Auto-Unseal
seal "awskms" {
region = "us-east-1"
kms_key_id = "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
}
api_addr = "https://vault.example.com:8200"
cluster_addr = "https://vault.example.com:8201"
IAMポリシー:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:DescribeKey"
],
"Resource": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
}
]
}
Azure Key Vault
config.hcl:
seal "azurekeyvault" {
tenant_id = "12345678-1234-1234-1234-123456789012"
client_id = "12345678-1234-1234-1234-123456789012"
client_secret = "client-secret"
vault_name = "my-key-vault"
key_name = "vault-unseal-key"
}
GCP Cloud KMS
config.hcl:
seal "gcpckms" {
project = "my-project"
region = "us-east1"
key_ring = "vault-keyring"
crypto_key = "vault-key"
}
マルチシール(Enterprise版)
複数のシールメカニズムを組み合わせることができます。
config.hcl:
# プライマリシール(HSM)
seal "pkcs11" {
lib = "/usr/lib/libCryptoki2_64.so"
slot = "0"
pin = "AAAA-BBBB-CCCC-DDDD"
key_label = "vault-hsm-key"
hmac_key_label = "vault-hsm-hmac-key"
priority = "1"
}
# セカンダリシール(AWS KMS)
seal "awskms" {
region = "us-east-1"
kms_key_id = "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
priority = "2"
}
Seal Migration
既存のVaultをAuto Unsealに移行できます。
手順
1. 新しい設定ファイルの作成:
# 既存のシール設定を"disabled"として保持
seal "shamir" {
disabled = "true"
}
# 新しいAuto-Unseal設定
seal "awskms" {
region = "us-east-1"
kms_key_id = "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
}
2. マイグレーションの実行:
# Vaultの停止
sudo systemctl stop vault
# マイグレーションモードで起動
vault operator unseal -migrate
# Unseal Keyを入力(3回)
vault operator unseal <key1>
vault operator unseal <key2>
vault operator unseal <key3>
# マイグレーション完了後、通常起動
sudo systemctl start vault
ベストプラクティス
1. Recovery Keyの安全な保管
# Recovery Keyを複数の場所に分散保管
# - 物理的な金庫
# - 別のKMS
# - オフラインストレージ
2. HSMの冗長化
# 複数のHSMを設定
seal "pkcs11" {
lib = "/usr/lib/libCryptoki2_64.so"
slot = "0"
pin = "AAAA-BBBB-CCCC-DDDD"
key_label = "vault-hsm-key"
hmac_key_label = "vault-hsm-hmac-key"
}
# フェイルオーバー用のセカンダリHSM
seal "pkcs11" {
lib = "/usr/lib/libCryptoki2_64.so"
slot = "1"
pin = "EEEE-FFFF-GGGG-HHHH"
key_label = "vault-hsm-key-backup"
hmac_key_label = "vault-hsm-hmac-key-backup"
priority = "2"
}
3. 監視とアラート
# HSMの状態を監視
vault status | grep "Seal Type"
# アラート設定(例: Prometheus)
- alert: VaultSealedUnexpectedly
expr: vault_core_unsealed == 0
for: 5m
annotations:
summary: "Vault is sealed"
4. 定期的なテスト
# Recovery Keyのテスト(年1回推奨)
# 1. HSMを一時的に無効化
# 2. Recovery Keyでアンシール
# 3. HSMを再有効化
トラブルシューティング
HSMに接続できない
エラー:
Error initializing seal: error initializing seal: error initializing pkcs11 seal
解決策:
# HSMライブラリのパスを確認
ls -l /usr/lib/libCryptoki2_64.so
# HSMの接続を確認
pkcs11-tool --module /usr/lib/libCryptoki2_64.so --list-slots
# ログを確認
sudo journalctl -u vault -f
KMSの権限不足
エラー:
Error unsealing: error unsealing with awskms: AccessDeniedException
解決策:
# IAMロールの権限を確認
aws iam get-role-policy --role-name vault-role --policy-name vault-kms-policy
# KMSキーのポリシーを確認
aws kms get-key-policy --key-id <key-id> --policy-name default
セキュリティチェックリスト
必須項目
- TLS/HTTPSを有効化
- 開発サーバーモードを無効化
- 監査ログを有効化
- Root Tokenを無効化
- Unseal Keyを安全に保管
- ファイアウォールを設定
- 定期的なバックアップを設定
- mlockを有効化
- 専用ユーザーで実行
推奨項目
- Auto Unsealを設定
- 高可用性構成を構築
- モニタリングを設定
- ログローテーションを設定
- ネットワークセグメンテーション
- 定期的なセキュリティ監査
- インシデント対応計画の策定
次のステップ
本番環境のハードニングを完了したら、次は高可用性構成でVaultクラスターの構築を学びましょう。
継続的なセキュリティセキュリティは一度設定すれば終わりではありません。定期的な監査、アップデート、セキュリティパッチの適用を継続的に行ってください。