翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
Image Builder でのセキュリティのベストプラクティス
EC2 Image Builder には、独自のセキュリティポリシーを開発および実装する際に考慮すべきいくつかのセキュリティ機能が用意されています。以下のベストプラクティスは一般的なガイドラインであり、完全なセキュリティソリューションを説明するものではありません。これらのベストプラクティスはお客様の環境に適切ではないか、十分ではない場合があるため、これらは指示ではなく、有用な考慮事項と見なしてください。
-
Image Builder レシピでは、過度に制限の厳しいセキュリティグループを使用しないでください。
-
信頼できないアカウントとイメージを共有しないでください。
-
プライベートまたは機密のデータを含むイメージを公開しないでください。
-
イメージのビルド時には、Windows または Linux で使用可能なすべてのセキュリティパッチを適用してください。
-
macOS レシピにマネージドAMI更新を定期的に適用し、新しいイメージを作成して、最新のセキュリティパッチが適用されたインスタンスを起動します。
セキュリティのポスチャーおよび該当するセキュリティコンプライアンスレベルを検証するために、イメージをテストすることを強くお勧めします。 Amazon Inspector などのソリューションは、イメージのセキュリティとコンプライアンス状態を検証するのに役立ちます。
IMDSv2 Image Builder パイプラインの
Image Builder パイプラインが実行されると、Image Builder がイメージの構築とテストに使用するEC2インスタンスを起動するHTTPリクエストが送信されます。パイプラインIMDSが起動リクエストに使用する のバージョンを設定するには、Image Builder インフラストラクチャ設定インスタンスメタデータ設定で httpTokens
パラメータを設定します。
Image Builder がパイプラインビルドから起動するすべてのEC2インスタンスを設定して、インスタンスメタデータの取得リクエストで署名付きトークンヘッダーが必要になるIMDSv2ようにすることをお勧めします。
Image Builder インフラストラクチャ設定の詳細については、「Image Builder インフラストラクチャ設定の管理」を参照してください。Linux イメージのEC2インスタンスメタデータオプションの詳細については、「Amazon ユーザーガイド」の「インスタンスメタデータオプションの設定」を参照してください。 EC2Windows イメージについては、「Amazon ユーザーガイド」の「インスタンスメタデータオプションの設定」を参照してください。 EC2
ビルド後のクリーンアップが必要
Image Builder がカスタムイメージのすべてのビルドステップを完了すると、Image Builder はテストとイメージ作成のためにビルドインスタンスを準備します。ビルドインスタンスをシャットダウンしてスナップショットを作成する前に、Image Builder は次のクリーンアップを実行してイメージのセキュリティを確保します。
- Linux
-
Image Builder パイプラインはクリーンアップスクリプトを実行して、最終的なイメージがセキュリティのベストプラクティスに従っていることを確認し、スナップショットに引き継がれてはならないビルドアーティファクトや設定をすべて削除します。ただし、スクリプトのセクションをスキップしたり、ユーザーデータを完全に上書きしたりすることはできます。そして、Image Builder パイプラインによって生成されるイメージは、必ずしも特定の規制基準に準拠しているとは限りません。
パイプラインがビルド段階とテスト段階を完了すると、Image Builder は出力イメージを作成する直前に次のクリーンアップスクリプトを自動的に実行します。
レシピのユーザーデータをオーバーライドすると、スクリプトは実行されません。その場合は、perform_cleanup
という名前の空のファイルを作成するコマンドをユーザーデータに含めてください。Image Builder はこのファイルを検出し、新しいイメージを作成する前にクリーンアップスクリプトを実行します。
#!/bin/bash
if [[ ! -f {{workingDirectory}}/perform_cleanup ]]; then
echo "Skipping cleanup"
exit 0
else
sudo rm -f {{workingDirectory}}/perform_cleanup
fi
function cleanup() {
FILES=("$@")
for FILE in "${FILES[@]}"; do
if [[ -f "$FILE" ]]; then
echo "Deleting $FILE";
sudo shred -zuf $FILE;
fi;
if [[ -f $FILE ]]; then
echo "Failed to delete '$FILE'. Failing."
exit 1
fi;
done
};
# Clean up for cloud-init files
CLOUD_INIT_FILES=(
"/etc/sudoers.d/90-cloud-init-users"
"/etc/locale.conf"
"/var/log/cloud-init.log"
"/var/log/cloud-init-output.log"
)
if [[ -f {{workingDirectory}}/skip_cleanup_cloudinit_files ]]; then
echo "Skipping cleanup of cloud init files"
else
echo "Cleaning up cloud init files"
cleanup "${CLOUD_INIT_FILES[@]}"
if [[ $( sudo find /var/lib/cloud -type f | sudo wc -l ) -gt 0 ]]; then
echo "Deleting files within /var/lib/cloud/*"
sudo find /var/lib/cloud -type f -exec shred -zuf {} \;
fi;
if [[ $( sudo ls /var/lib/cloud | sudo wc -l ) -gt 0 ]]; then
echo "Deleting /var/lib/cloud/*"
sudo rm -rf /var/lib/cloud/* || true
fi;
fi;
# Clean up for temporary instance files
INSTANCE_FILES=(
"/etc/.updated"
"/etc/aliases.db"
"/etc/hostname"
"/var/lib/misc/postfix.aliasesdb-stamp"
"/var/lib/postfix/master.lock"
"/var/spool/postfix/pid/master.pid"
"/var/.updated"
"/var/cache/yum/x86_64/2/.gpgkeyschecked.yum"
)
if [[ -f {{workingDirectory}}/skip_cleanup_instance_files ]]; then
echo "Skipping cleanup of instance files"
else
echo "Cleaning up instance files"
cleanup "${INSTANCE_FILES[@]}"
fi;
# Clean up for ssh files
SSH_FILES=(
"/etc/ssh/ssh_host_rsa_key"
"/etc/ssh/ssh_host_rsa_key.pub"
"/etc/ssh/ssh_host_ecdsa_key"
"/etc/ssh/ssh_host_ecdsa_key.pub"
"/etc/ssh/ssh_host_ed25519_key"
"/etc/ssh/ssh_host_ed25519_key.pub"
"/root/.ssh/authorized_keys"
)
if [[ -f {{workingDirectory}}/skip_cleanup_ssh_files ]]; then
echo "Skipping cleanup of ssh files"
else
echo "Cleaning up ssh files"
cleanup "${SSH_FILES[@]}"
USERS=$(ls /home/)
for user in $USERS; do
echo Deleting /home/"$user"/.ssh/authorized_keys;
sudo find /home/"$user"/.ssh/authorized_keys -type f -exec shred -zuf {} \;
done
for user in $USERS; do
if [[ -f /home/"$user"/.ssh/authorized_keys ]]; then
echo Failed to delete /home/"$user"/.ssh/authorized_keys;
exit 1
fi;
done;
fi;
# Clean up for instance log files
INSTANCE_LOG_FILES=(
"/var/log/audit/audit.log"
"/var/log/boot.log"
"/var/log/dmesg"
"/var/log/cron"
)
if [[ -f {{workingDirectory}}/skip_cleanup_instance_log_files ]]; then
echo "Skipping cleanup of instance log files"
else
echo "Cleaning up instance log files"
cleanup "${INSTANCE_LOG_FILES[@]}"
fi;
# Clean up for TOE files
if [[ -f {{workingDirectory}}/skip_cleanup_toe_files ]]; then
echo "Skipping cleanup of TOE files"
else
echo "Cleaning TOE files"
if [[ $( sudo find {{workingDirectory}}/TOE_* -type f | sudo wc -l) -gt 0 ]]; then
echo "Deleting files within {{workingDirectory}}/TOE_*"
sudo find {{workingDirectory}}/TOE_* -type f -exec shred -zuf {} \;
fi
if [[ $( sudo find {{workingDirectory}}/TOE_* -type f | sudo wc -l) -gt 0 ]]; then
echo "Failed to delete {{workingDirectory}}/TOE_*"
exit 1
fi
if [[ $( sudo find {{workingDirectory}}/TOE_* -type d | sudo wc -l) -gt 0 ]]; then
echo "Deleting {{workingDirectory}}/TOE_*"
sudo rm -rf {{workingDirectory}}/TOE_*
fi
if [[ $( sudo find {{workingDirectory}}/TOE_* -type d | sudo wc -l) -gt 0 ]]; then
echo "Failed to delete {{workingDirectory}}/TOE_*"
exit 1
fi
fi
# Clean up for ssm log files
if [[ -f {{workingDirectory}}/skip_cleanup_ssm_log_files ]]; then
echo "Skipping cleanup of ssm log files"
else
echo "Cleaning up ssm log files"
if [[ $( sudo find /var/log/amazon/ssm -type f | sudo wc -l) -gt 0 ]]; then
echo "Deleting files within /var/log/amazon/ssm/*"
sudo find /var/log/amazon/ssm -type f -exec shred -zuf {} \;
fi
if [[ $( sudo find /var/log/amazon/ssm -type f | sudo wc -l) -gt 0 ]]; then
echo "Failed to delete /var/log/amazon/ssm"
exit 1
fi
if [[ -d "/var/log/amazon/ssm" ]]; then
echo "Deleting /var/log/amazon/ssm/*"
sudo rm -rf /var/log/amazon/ssm
fi
if [[ -d "/var/log/amazon/ssm" ]]; then
echo "Failed to delete /var/log/amazon/ssm"
exit 1
fi
fi
if [[ $( sudo find /var/log/sa/sa* -type f | sudo wc -l ) -gt 0 ]]; then
echo "Deleting /var/log/sa/sa*"
sudo shred -zuf /var/log/sa/sa*
fi
if [[ $( sudo find /var/log/sa/sa* -type f | sudo wc -l ) -gt 0 ]]; then
echo "Failed to delete /var/log/sa/sa*"
exit 1
fi
if [[ $( sudo find /var/lib/dhclient/dhclient*.lease -type f | sudo wc -l ) -gt 0 ]]; then
echo "Deleting /var/lib/dhclient/dhclient*.lease"
sudo shred -zuf /var/lib/dhclient/dhclient*.lease
fi
if [[ $( sudo find /var/lib/dhclient/dhclient*.lease -type f | sudo wc -l ) -gt 0 ]]; then
echo "Failed to delete /var/lib/dhclient/dhclient*.lease"
exit 1
fi
if [[ $( sudo find /var/tmp -type f | sudo wc -l) -gt 0 ]]; then
echo "Deleting files within /var/tmp/*"
sudo find /var/tmp -type f -exec shred -zuf {} \;
fi
if [[ $( sudo find /var/tmp -type f | sudo wc -l) -gt 0 ]]; then
echo "Failed to delete /var/tmp"
exit 1
fi
if [[ $( sudo ls /var/tmp | sudo wc -l ) -gt 0 ]]; then
echo "Deleting /var/tmp/*"
sudo rm -rf /var/tmp/*
fi
# Shredding is not guaranteed to work well on rolling logs
if [[ -f "/var/lib/rsyslog/imjournal.state" ]]; then
echo "Deleting /var/lib/rsyslog/imjournal.state"
sudo shred -zuf /var/lib/rsyslog/imjournal.state
sudo rm -f /var/lib/rsyslog/imjournal.state
fi
if [[ $( sudo ls /var/log/journal/ | sudo wc -l ) -gt 0 ]]; then
echo "Deleting /var/log/journal/*"
sudo find /var/log/journal/ -type f -exec shred -zuf {} \;
sudo rm -rf /var/log/journal/*
fi
sudo touch /etc/machine-id
- Windows
-
Image Builder パイプラインが Windows イメージをカスタマイズすると、Microsoft Sysprep ユーティリティが実行されます。これらのアクションはAWS 、イメージの強化とクリーニングのベストプラクティスに従います。
- macOS
-
Image Builder パイプラインはクリーンアップスクリプトを実行して、最終的なイメージがセキュリティのベストプラクティスに従っていることを確認し、スナップショットに引き継がれてはならないビルドアーティファクトや設定をすべて削除します。ただし、スクリプトのセクションをスキップしたり、ユーザーデータを完全に上書きしたりすることはできます。そして、Image Builder パイプラインによって生成されるイメージは、必ずしも特定の規制基準に準拠しているとは限りません。
パイプラインがビルド段階とテスト段階を完了すると、Image Builder は出力イメージを作成する直前に次のクリーンアップスクリプトを自動的に実行します。
レシピのユーザーデータをオーバーライドすると、スクリプトは実行されません。その場合は、perform_cleanup
という名前の空のファイルを作成するコマンドをユーザーデータに含めてください。Image Builder はこのファイルを検出し、新しいイメージを作成する前にクリーンアップスクリプトを実行します。
#!/bin/bash
if [[ ! -f {{workingDirectory}}/perform_cleanup ]]; then
echo "Skipping cleanup"
exit 0
else
sudo rm -f {{workingDirectory}}/perform_cleanup
fi
function cleanup() {
FILES=("$@")
for FILE in "${FILES[@]}"; do
if [[ -f "$FILE" ]]; then
echo "Deleting $FILE";
sudo rm -f $FILE;
fi;
if [[ -f $FILE ]]; then
echo "Failed to delete '$FILE'. Failing."
exit 1
fi;
done
};
# Clean up for cloud-init files
CLOUD_INIT_FILES=(
"/etc/sudoers.d/90-cloud-init-users"
"/etc/locale.conf"
"/var/log/cloud-init.log"
"/var/log/cloud-init-output.log"
)
if [[ -f {{workingDirectory}}/skip_cleanup_cloudinit_files ]]; then
echo "Skipping cleanup of cloud init files"
else
echo "Cleaning up cloud init files"
cleanup "${CLOUD_INIT_FILES[@]}"
if [[ $( sudo find /var/lib/cloud -type f | sudo wc -l ) -gt 0 ]]; then
echo "Deleting files within /var/lib/cloud/*"
sudo find /var/lib/cloud -type f -exec rm -f {} \;
fi;
if [[ $( sudo ls /var/lib/cloud | sudo wc -l ) -gt 0 ]]; then
echo "Deleting /var/lib/cloud/*"
sudo rm -rf /var/lib/cloud/* || true
fi;
fi;
# Clean up for temporary instance files
INSTANCE_FILES=(
"/etc/.updated"
"/etc/aliases.db"
"/etc/hostname"
"/var/lib/misc/postfix.aliasesdb-stamp"
"/var/lib/postfix/master.lock"
"/var/spool/postfix/pid/master.pid"
"/var/.updated"
"/var/cache/yum/x86_64/2/.gpgkeyschecked.yum"
)
if [[ -f {{workingDirectory}}/skip_cleanup_instance_files ]]; then
echo "Skipping cleanup of instance files"
else
echo "Cleaning up instance files"
cleanup "${INSTANCE_FILES[@]}"
fi;
# Clean up for ssh files
SSH_FILES=(
"/etc/ssh/ssh_host_rsa_key"
"/etc/ssh/ssh_host_rsa_key.pub"
"/etc/ssh/ssh_host_ecdsa_key"
"/etc/ssh/ssh_host_ecdsa_key.pub"
"/etc/ssh/ssh_host_ed25519_key"
"/etc/ssh/ssh_host_ed25519_key.pub"
"/root/.ssh/authorized_keys"
)
if [[ -f {{workingDirectory}}/skip_cleanup_ssh_files ]]; then
echo "Skipping cleanup of ssh files"
else
echo "Cleaning up ssh files"
cleanup "${SSH_FILES[@]}"
USERS=$(ls /home/)
for user in $USERS; do
echo Deleting /home/"$user"/.ssh/authorized_keys;
sudo find /home/"$user"/.ssh/authorized_keys -type f -exec rm -f {} \;
done
for user in $USERS; do
if [[ -f /home/"$user"/.ssh/authorized_keys ]]; then
echo Failed to delete /home/"$user"/.ssh/authorized_keys;
exit 1
fi;
done;
fi;
# Clean up for instance log files
INSTANCE_LOG_FILES=(
"/var/log/audit/audit.log"
"/var/log/boot.log"
"/var/log/dmesg"
"/var/log/cron"
"/var/log/amazon/ec2/ec2-macos-init.log"
"/var/log/amazon/ec2/ena-ethernet.log"
"/var/log/amazon/ec2/system-monitoring.log"
)
if [[ -f {{workingDirectory}}/skip_cleanup_instance_log_files ]]; then
echo "Skipping cleanup of instance log files"
else
echo "Cleaning up instance log files"
cleanup "${INSTANCE_LOG_FILES[@]}"
fi;
# Clean up for TOE files
if [[ -f {{workingDirectory}}/skip_cleanup_toe_files ]]; then
echo "Skipping cleanup of TOE files"
else
echo "Cleaning TOE files"
if [[ $( sudo find {{workingDirectory}}/TOE_* -type f | sudo wc -l) -gt 0 ]]; then
echo "Deleting files within {{workingDirectory}}/TOE_*"
sudo find {{workingDirectory}}/TOE_* -type f -exec rm -f {} \;
fi
if [[ $( sudo find {{workingDirectory}}/TOE_* -type f | sudo wc -l) -gt 0 ]]; then
echo "Failed to delete {{workingDirectory}}/TOE_*"
exit 1
fi
if [[ $( sudo find {{workingDirectory}}/TOE_* -type d | sudo wc -l) -gt 0 ]]; then
echo "Deleting {{workingDirectory}}/TOE_*"
sudo rm -rf {{workingDirectory}}/TOE_*
fi
if [[ $( sudo find {{workingDirectory}}/TOE_* -type d | sudo wc -l) -gt 0 ]]; then
echo "Failed to delete {{workingDirectory}}/TOE_*"
exit 1
fi
fi
# Clean up for ssm log files
if [[ -f {{workingDirectory}}/skip_cleanup_ssm_log_files ]]; then
echo "Skipping cleanup of ssm log files"
else
echo "Cleaning up ssm log files"
if [[ $( sudo find /var/log/amazon/ssm -type f | sudo wc -l) -gt 0 ]]; then
echo "Deleting files within /var/log/amazon/ssm/*"
sudo find /var/log/amazon/ssm -type f -exec rm -f {} \;
fi
if [[ $( sudo find /var/log/amazon/ssm -type f | sudo wc -l) -gt 0 ]]; then
echo "Failed to delete /var/log/amazon/ssm"
exit 1
fi
if [[ -d "/var/log/amazon/ssm" ]]; then
echo "Deleting /var/log/amazon/ssm/*"
sudo rm -rf /var/log/amazon/ssm
fi
if [[ -d "/var/log/amazon/ssm" ]]; then
echo "Failed to delete /var/log/amazon/ssm"
exit 1
fi
fi
if [[ $( sudo find /var/log/sa/sa* -type f | sudo wc -l ) -gt 0 ]]; then
echo "Deleting /var/log/sa/sa*"
sudo rm -f /var/log/sa/sa*
fi
if [[ $( sudo find /var/log/sa/sa* -type f | sudo wc -l ) -gt 0 ]]; then
echo "Failed to delete /var/log/sa/sa*"
exit 1
fi
if [[ $( sudo find /var/lib/dhclient/dhclient*.lease -type f | sudo wc -l ) -gt 0 ]]; then
echo "Deleting /var/lib/dhclient/dhclient*.lease"
sudo rm -f /var/lib/dhclient/dhclient*.lease
fi
if [[ $( sudo find /var/lib/dhclient/dhclient*.lease -type f | sudo wc -l ) -gt 0 ]]; then
echo "Failed to delete /var/lib/dhclient/dhclient*.lease"
exit 1
fi
if [[ $( sudo find /var/tmp -type f | sudo wc -l) -gt 0 ]]; then
echo "Deleting files within /var/tmp/*"
sudo find /var/tmp -type f -exec rm -f {} \;
fi
if [[ $( sudo find /var/tmp -type f | sudo wc -l) -gt 0 ]]; then
echo "Failed to delete /var/tmp"
exit 1
fi
if [[ $( sudo ls /var/tmp | sudo wc -l ) -gt 0 ]]; then
echo "Deleting /var/tmp/*"
sudo rm -rf /var/tmp/*
fi
# Shredding is not guaranteed to work well on rolling logs
if [[ -f "/var/lib/rsyslog/imjournal.state" ]]; then
echo "Deleting /var/lib/rsyslog/imjournal.state"
sudo rm -f /var/lib/rsyslog/imjournal.state
sudo rm -f /var/lib/rsyslog/imjournal.state
fi
if [[ $( sudo ls /var/log/journal/ | sudo wc -l ) -gt 0 ]]; then
echo "Deleting /var/log/journal/*"
sudo find /var/log/journal/ -type f -exec rm -f {} \;
sudo rm -rf /var/log/journal/*
fi
sudo touch /etc/machine-id
Linux クリーンアップスクリプトをオーバーライドする
Image Builder は、デフォルトで安全で、セキュリティのベストプラクティスに従ったイメージを作成します。ただし、より高度なユースケースでは、組み込みのクリーンアップスクリプトの 1 つ以上のセクションをスキップする必要がある場合があります。クリーンアップの一部をスキップする必要がある場合は、イメージのセキュリティAMIを確認するために出力をテストすることを強くお勧めします。
クリーンアップスクリプトのセクションをスキップすると、所有者アカウントの詳細やSSHキーなどの機密情報が最終イメージや、そのイメージから起動されたインスタンスに含まれる可能性があります。また、異なるアベイラビリティーゾーン、リージョン、またはアカウントで起動すると問題が発生する可能性があります。
次の表は、クリーンアップスクリプトのセクション、そのセクションで削除されるファイル、および Image Builder がスキップすべきセクションにフラグを立てるために使用できるファイル名の概要を示しています。クリーンアップスクリプトの特定のセクションをスキップするには、CreateFileのコンポーネントアクションモジュールまたはユーザーデータ内のコマンド (オーバーライドする場合) を使用して、「セクションをスキップ」列で指定した名前の空のファイルを作成します。
クリーンアップスクリプトのセクションをスキップするために作成するファイルには、ファイル拡張子を付けないでください。例えば、スクリプトのCLOUD_INIT_FILES
セクションをスキップしたいが、skip_cleanup_cloudinit_files.txt
という名前のファイルを作成した場合、Image Builder はスキップファイルを認識できません。
Input
クリーンアップセクション |
削除されたファイル |
セクションファイル名をスキップする |
CLOUD_INIT_FILES
|
/etc/sudoers.d/90-cloud-init-users
/etc/locale.conf
/var/log/cloud-init.log
/var/log/cloud-init-output.log
|
skip_cleanup_cloudinit_files
|
INSTANCE_FILES
|
/etc/.updated
/etc/aliases.db
/etc/hostname
/var/lib/misc/postfix.aliasesdb-stamp
/var/lib/postfix/master.lock
/var/spool/postfix/pid/master.pid
/var/.updated
/var/cache/yum/x86_64/2/.gpgkeyschecked.yum
|
skip_cleanup_instance_files
|
SSH_FILES
|
/etc/ssh/ssh_host_rsa_key
/etc/ssh/ssh_host_rsa_key.pub
/etc/ssh/ssh_host_ecdsa_key
/etc/ssh/ssh_host_ecdsa_key.pub
/etc/ssh/ssh_host_ed25519_key
/etc/ssh/ssh_host_ed25519_key.pub
/root/.ssh/authorized_keys
/home/<all users>/.ssh/authorized_keys;
|
skip_cleanup_ssh_files
|
INSTANCE_LOG_FILES
|
/var/log/audit/audit.log
/var/log/boot.log
/var/log/dmesg
/var/log/cron
|
skip_cleanup_instance_log_files
|
TOE_FILES
|
{{workingDirectory}}/TOE_*
|
skip_cleanup_toe_files
|
SSM_LOG_FILES
|
/var/log/amazon/ssm/*
|
skip_cleanup_ssm_log_files
|