VPC 設計でインターネット非公開を徹底すると、こうした壁にぶつかります。scp や sftp は使えず、FTP は論外。かといって踏み台サーバーを立てれば管理コストが増えます。
この記事では、aws ssm ファイル転送の設計パターンとして、S3 を仲介役にした転送フロー・KMS 暗号化・S3 バケットポリシー・IAM ロール設計を解説します。踏み台なし・インターネット非公開の VPC 設計のまま、コンプライアンスにも対応できる構成を Amazon Linux 2023 / RHEL 9 環境で動作確認した手順で紹介します。
この記事のポイント
・aws ssm ファイル転送は「S3 バケット仲介 + SSM Session Manager」が最も安全な設計
・転送データは KMS カスタマーキーで暗号化し S3 バケットポリシーで VPC 外アクセスを遮断する
・EC2 インスタンスロールに S3 読み書き権・KMS 復号権・SSM マネージドポリシーを付与する
・VPC に S3 Gateway Endpoint と SSM Interface Endpoint を設定しインターネットを経由しない
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
AWS SSMファイル転送のアーキテクチャ — なぜS3を介するのか
通常の Linux サーバーへのファイル転送は scp(SSH)を使います。しかしプライベートサブネットの EC2 は SSH ポート(22番)を外部に開いておらず、そもそも直接到達できません。SSM を使ったファイル転送の基本フローは次のとおりです。
・ローカル PC → S3 バケット(aws s3 cp でアップロード)
・SSM Session Manager で EC2 に接続
・EC2 が S3 バケットから aws s3 cp でダウンロード
・逆方向(EC2 → S3 → ローカル PC)も同様
S3 を仲介するメリットは 3 つあります。
・インターネット非公開のまま転送できる:S3 Gateway Endpoint を使えば通信は AWS バックボーンネットワーク内に留まります。
・転送履歴が残る:S3 アクセスログや CloudTrail で「誰がいつ何を転送したか」を追跡できます。
・KMS 暗号化でコンプライアンス要件を満たせる:自社管理の KMS CMK を使うことで監査対応が容易になります。
KMS暗号化が必要な理由 — VPC設計でのデータ保護要件
S3 はデフォルト(SSE-S3)でも暗号化されますが、VPC 設計で KMS を使う主な理由はキー管理の主権です。SSE-S3 は AWS が管理するキーで暗号化されるため、「どのロールがキーを使えるか」を細かく制御できません。一方、SSE-KMS(カスタマーキー)では KMS キーポリシーで「このロールだけに復号を許可する」という粒度での制御が可能です。
金融・医療・行政系のシステムでは暗号化キーの管理証跡(CloudTrail への KMS API ログ)を求められるケースが多く、SSE-KMS が事実上の標準となっています。AWS の VPC 設計や基礎的なセキュリティ設定を体系的に学びたい方は、AWS Amazon Linux 入門ガイドも参考にしてください。
VPC設計 — S3エンドポイントとSSMエンドポイントの設定
インターネットを経由せず S3 や SSM にアクセスするには VPC エンドポイントが必要です。1. S3 Gateway Endpointの確認・作成
S3 Gateway Endpoint は無料で、ルートテーブルへの経路追加で動作します。# 既存のS3エンドポイントを確認 $ aws ec2 describe-vpc-endpoints --filters "Name=service-name,Values=com.amazonaws.ap-northeast-1.s3" --query 'VpcEndpoints[].{ID:VpcEndpointId,State:State}' --output table -------------------------------------- | DescribeVpcEndpoints | +------------------+-----------------+ | ID | State | +------------------+-----------------+ | vpce-0a1b2c3d4e | available | +------------------+-----------------+
$ aws ec2 create-vpc-endpoint --vpc-id vpc-0123456789abcdef0 --service-name com.amazonaws.ap-northeast-1.s3 --route-table-ids rtb-0123456789abcdef0 --vpc-endpoint-type Gateway { "VpcEndpoint": { "VpcEndpointId": "vpce-0a1b2c3d4e5f67890", "VpcEndpointType": "Gateway", "VpcId": "vpc-0123456789abcdef0", "ServiceName": "com.amazonaws.ap-northeast-1.s3", "State": "available" } }
2. SSM用Interface Endpointの確認
SSM Session Manager を使うには ssm・ssmmessages・ec2messages の 3 つの Interface Endpoint が必要です。$ aws ec2 describe-vpc-endpoints --filters "Name=service-name,Values=com.amazonaws.ap-northeast-1.ssm" --query 'VpcEndpoints[].{ID:VpcEndpointId,Service:ServiceName,State:State}' --output table --------------------------------------------------------------- | DescribeVpcEndpoints | +-------------------+------------------------------+----------+ | ID | Service | State | +-------------------+------------------------------+----------+ | vpce-0b2c3d4e5f | ...ap-northeast-1.ssm |available | +-------------------+------------------------------+----------+
KMSキーとS3バケットの設定
1. KMSカスタマーキーの作成
$ aws kms create-key --description "ssm-filetransfer-cmk" --key-usage ENCRYPT_DECRYPT --key-spec SYMMETRIC_DEFAULT { "KeyMetadata": { "AWSAccountId": "123456789012", "KeyId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "Arn": "arn:aws:kms:ap-northeast-1:123456789012:key/a1b2c3d4-e5f6-7890-abcd-ef1234567890", "CreationDate": "2026-10-15T10:23:41.456000+09:00", "Enabled": true, "KeyUsage": "ENCRYPT_DECRYPT", "KeyState": "Enabled", "KeyManager": "CUSTOMER" } }
$ aws kms create-alias --alias-name alias/ssm-filetransfer-cmk --target-key-id a1b2c3d4-e5f6-7890-abcd-ef1234567890
2. S3バケットの作成とKMS暗号化の有効化
# バケット作成 $ aws s3api create-bucket --bucket ssm-filetransfer-20261015 --region ap-northeast-1 --create-bucket-configuration LocationConstraint=ap-northeast-1 { "Location": "http://ssm-filetransfer-20261015.s3.amazonaws.com/" } # パブリックアクセスを完全ブロック $ aws s3api put-public-access-block --bucket ssm-filetransfer-20261015 --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true" # KMS暗号化をデフォルトに設定 $ aws s3api put-bucket-encryption --bucket ssm-filetransfer-20261015 --server-side-encryption-configuration '{ "Rules": [{ "ApplyServerSideEncryptionByDefault": { "SSEAlgorithm": "aws:kms", "KMSMasterKeyID": "arn:aws:kms:ap-northeast-1:123456789012:key/a1b2c3d4-e5f6-7890-abcd-ef1234567890" }, "BucketKeyEnabled": true }] }'
3. S3バケットポリシーの設定 — VPC外からのアクセス遮断
バケットポリシーで「VPC エンドポイント経由以外のアクセスを拒否」するよう設定します。$ cat bucket-policy.json { "Version": "2012-10-17", "Statement": [ { "Sid": "DenyNonVPCEndpointAccess", "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::ssm-filetransfer-20261015", "arn:aws:s3:::ssm-filetransfer-20261015/*" ], "Condition": { "StringNotEquals": { "aws:sourceVpce": "vpce-0a1b2c3d4e5f67890" } } } ] } $ aws s3api put-bucket-policy --bucket ssm-filetransfer-20261015 --policy file://bucket-policy.json
IAMロール設計 — EC2インスタンスへの権限付与
EC2 インスタンスには SSM マネージドポリシーに加え、S3 アクセスと KMS 復号権限を付与します。$ cat ec2-ssm-s3-policy.json { "Version": "2012-10-17", "Statement": [ { "Sid": "S3FileTransferAccess", "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::ssm-filetransfer-20261015", "arn:aws:s3:::ssm-filetransfer-20261015/*" ] }, { "Sid": "KMSDecryptForS3", "Effect": "Allow", "Action": [ "kms:Decrypt", "kms:GenerateDataKey", "kms:DescribeKey" ], "Resource": "arn:aws:kms:ap-northeast-1:123456789012:key/a1b2c3d4-e5f6-7890-abcd-ef1234567890" } ] } $ aws iam create-policy --policy-name SSMFileTransferPolicy --policy-document file://ec2-ssm-s3-policy.json { "Policy": { "PolicyName": "SSMFileTransferPolicy", "PolicyId": "ANPA1234567890EXAMPLE", "Arn": "arn:aws:iam::123456789012:policy/SSMFileTransferPolicy" } }
# SSMマネージドポリシーのアタッチ $ aws iam attach-role-policy --role-name EC2SSMRole --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore # S3・KMSポリシーのアタッチ $ aws iam attach-role-policy --role-name EC2SSMRole --policy-arn arn:aws:iam::123456789012:policy/SSMFileTransferPolicy # アタッチ確認 $ aws iam list-attached-role-policies --role-name EC2SSMRole { "AttachedPolicies": [ { "PolicyName": "AmazonSSMManagedInstanceCore", "PolicyArn": "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" }, { "PolicyName": "SSMFileTransferPolicy", "PolicyArn": "arn:aws:iam::123456789012:policy/SSMFileTransferPolicy" } ] }
ファイル転送の実施手順
1. ローカルPCからEC2へのファイル転送(S3経由アップロード)
設定ファイルや配布ファイルを EC2 に送る手順です。# ローカルPCで実行 — S3にアップロード $ aws s3 cp ./app-config.tar.gz s3://ssm-filetransfer-20261015/uploads/app-config.tar.gz --sse aws:kms --sse-kms-key-id alias/ssm-filetransfer-cmk upload: ./app-config.tar.gz to s3://ssm-filetransfer-20261015/uploads/app-config.tar.gz
# SSM Session Managerで接続 $ aws ssm start-session --target i-0123456789abcdef0 Starting session with SessionId: tomohiro-0a1b2c3d4e5f67890 sh-5.2$ # EC2上でS3からダウンロード sh-5.2$ aws s3 cp s3://ssm-filetransfer-20261015/uploads/app-config.tar.gz /tmp/app-config.tar.gz download: s3://ssm-filetransfer-20261015/uploads/app-config.tar.gz to /tmp/app-config.tar.gz sh-5.2$ ls -la /tmp/app-config.tar.gz -rw-r--r--. 1 ssm-user ssm-user 45312 Oct 15 10:45 /tmp/app-config.tar.gz
2. EC2からローカルPCへのファイル転送(逆方向)
EC2 上のログファイルや設定ファイルをローカル PC に持ち出す手順です。# EC2上でS3にアップロード sh-5.2$ aws s3 cp /var/log/app/error.log s3://ssm-filetransfer-20261015/downloads/error-20261015.log upload: /var/log/app/error.log to s3://ssm-filetransfer-20261015/downloads/error-20261015.log sh-5.2$ exit Exiting session with sessionId: tomohiro-0a1b2c3d4e5f67890. # ローカルPCでS3からダウンロード $ aws s3 cp s3://ssm-filetransfer-20261015/downloads/error-20261015.log ./error-20261015.log download: s3://ssm-filetransfer-20261015/downloads/error-20261015.log to ./error-20261015.log
3. 転送後のS3オブジェクト削除(保管コスト削減)
転送済みファイルをそのまま S3 に放置するとコストが積み上がります。ライフサイクルポリシーで自動削除を設定しておきましょう。$ aws s3api put-bucket-lifecycle-configuration --bucket ssm-filetransfer-20261015 --lifecycle-configuration '{ "Rules": [{ "ID": "auto-delete-7days", "Filter": {"Prefix": ""}, "Status": "Enabled", "Expiration": {"Days": 7} }] }'
トラブルシュート — よくあるエラーと対処
「An error occurred (AccessDenied)」が出る場合
$ aws s3 cp ./test.txt s3://ssm-filetransfer-20261015/uploads/ An error occurred (AccessDenied) when calling the PutObject operation: User: arn:aws:iam::123456789012:role/EC2SSMRole is not authorized to perform: s3:PutObject
・IAM ポリシーの確認:aws iam simulate-principal-policy でロールが s3:PutObject を許可されているか確認します。
・バケットポリシーの確認:VPC エンドポイント ID がポリシー内の aws:sourceVpce 値と一致しているか確認します。エンドポイントを再作成した場合は ID が変わるため必ずポリシーを更新してください。
・KMS キーポリシーの確認:EC2 インスタンスロールの ARN が KMS キーポリシーの Principal に含まれているか確認します。
「KMSDisabledException」が出る場合
An error occurred (KMSDisabledException) when calling the GetObject operation: arn:aws:kms:ap-northeast-1:123456789012:key/a1b2c3d4-e5f6-7890-abcd-ef1234567890 is disabled.
$ aws kms describe-key --key-id alias/ssm-filetransfer-cmk --query 'KeyMetadata.{KeyState:KeyState,Enabled:Enabled}' { "KeyState": "Disabled", "Enabled": false } $ aws kms enable-key --key-id alias/ssm-filetransfer-cmk # 出力なし(成功時) $ aws kms describe-key --key-id alias/ssm-filetransfer-cmk --query 'KeyMetadata.{KeyState:KeyState,Enabled:Enabled}' { "KeyState": "Enabled", "Enabled": true }
本記事のまとめ
| 設計要素 | 推奨設定 |
|---|---|
| S3エンドポイント | Gateway Endpoint(無料・ルートテーブル経由) |
| SSMエンドポイント | Interface Endpoint(ssm / ssmmessages / ec2messages) |
| S3暗号化 | SSE-KMS + BucketKeyEnabled で KMS コスト削減 |
| バケットポリシー | aws:sourceVpce 条件で VPC 外アクセスを Deny |
| EC2 IAMロール | AmazonSSMManagedInstanceCore + S3 読み書き + KMS 復号 |
| 転送後の整理 | S3 ライフサイクルポリシーで 7 日後自動削除 |
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:AWS SSM WindowsのInventory機能でライセンス管理を自動化するVPC設計|資産台帳の統合
- この記事の属するカテゴリ:AWS(Amazon Linux)へ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます