マルチクラウド時代の「一貫性」こそが最強の要塞——IaCで実現するセキュアなネットワーク設計
「AWSで設定したセキュリティグループをAzureにも移植する」。この作業、手動でやっていないだろうか? もしそうなら、今すぐやめるべきだ。人間はミスをする。特に疲弊した深夜のデプロイ時、クリック一つで 0.0.0.0/0 をフルオープンにしてしまう悲劇を、私は現場で何度も見てきた。
クラウドプロバイダーを跨ぐマルチクラウド環境において、最も危険なのは「設定の乖離」だ。攻撃者は、組織の中で一番セキュリティが甘い「穴」を見逃さない。今回は、Terraformを用いてネットワークポリシーをコード化し、環境間の差異を消し去るための実践的な戦略を解説する。
なぜ「IaCでの一貫性」がセキュリティの命運を分けるのか
攻撃者は、ツールを使ってIPレンジをスキャンし、管理画面(SSHやRDP、あるいはWeb管理コンソール)がインターネット側に露出しているインスタンスを探している。
例えば、AWS側では Security Group で厳格にソースIPを制限していても、急いで立ち上げたAzure側の Network Security Group (NSG) で「とりあえずテスト用だから」と Any/Any を許可してしまったらどうなるか。攻撃者はそこから侵入し、内部ネットワーク経由でAWS側のバックエンドデータベースへ横移動(Lateral Movement)を開始する。
これを防ぐ唯一の手段は、「人間がポチポチ設定を変える余地を排除すること」だ。
Terraformによるネットワークポリシーの一元管理
Terraformを使えば、AWSの aws_security_group も Azureの azurerm_network_security_rule も、単一の論理として管理できる。以下は、特定の踏み台サーバーからのアクセスのみを許可する、堅牢なポリシーの雛形だ。
実践:Terraformによるセキュアなアクセス制御の定義
# AWS: セキュリティグループの定義
resource "aws_security_group" "web_server_sg" {
name = "web-server-sg"
description = "Webサーバー用セキュリティグループ"
vpc_id = var.vpc_id
# 許可するソースを組織内のIPレンジに限定
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["10.0.0.0/16"] # 社内VPNや踏み台のセグメントのみ
description = "SSHアクセスを許可"
}
# 出力は必要最小限に抑える
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# Azure: NSGでの同様のポリシー定義
resource "azurerm_network_security_rule" "web_server_nsg_rule" {
name = "AllowSSHFromInternal"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "10.0.0.0/16" # AWS側と一貫性を持たせる
destination_address_prefix = "*"
resource_group_name = azurerm_resource_group.main.name
network_security_group_name = azurerm_network_security_group.main.name
}
OSレベルの要塞化:不要なサービスを「物理的に」消せ
ネットワークで境界防御を固めたとしても、OS内部に脆弱なサービスが動いていれば意味がない。特に、telnet や ftp、古い rpcbind などが動いていないか?
現場でよくある失敗は、「とりあえず全部入り」のAMI/イメージを使ってしまうことだ。後から systemctl stop するのではなく、ビルド段階で削除するのがプロの流儀である。
Linux要塞化の自動化スクリプト例(Ansible/Shell)
#!/bin/bash
# 不用なサービスを完全に無効化し、パッケージを削除する
# 攻撃対象領域(Attack Surface)を最小化する
REQUIRED_SERVICES=("sshd" "chronyd")
# 稼働中のサービスを精査
for service in $(systemctl list-unit-files --type=service --state=enabled --no-legend | awk '{print $1}'); do
if [[ ! " ${REQUIRED_SERVICES[@]} " =~ " ${service} " ]]; then
echo "停止中: $service"
systemctl stop "$service"
systemctl disable "$service"
fi
done
# 不要なパッケージの削除(例: telnet, rsh)
apt-get purge -y telnet rsh-client rsh-server
最後に:セキュリティは「継続的なエンジニアリング」である
IaCによる管理を導入したからといって、それで終わりではない。最も重要なのは、「ポリシーの乖離を自動検知する仕組み」だ。Terraformの plan をCI/CDパイプラインに組み込み、意図しない変更(ドリフト)が発生した瞬間にアラートを飛ばすこと。そして、月に一度は「本当にこのポートは開いている必要があるか?」をコードベースで見直すこと。
セキュリティとは、堅牢な城を建てることではなく、城の周りに常に目を光らせ、穴が開いた瞬間に埋める「運用プロセスそのもの」だ。
皆さんのインフラが、単なるリソースの集合体ではなく、攻撃者が手出しできない「要塞」になることを期待している。もし不明点があれば、またいつでも聞きに来てほしい。現場からは以上だ。
コメント