1. はじめに
今回は、AWS Systems Manager の Session Manager を利用して、踏み台サーバー(Bastion Host)の代替手段を構築する方法を紹介します。
Session Manager を活用することで、従来の踏み台サーバーに比べてセキュリティや運用性が向上します。たとえば、SSH鍵の管理や開放ポートの運用から解放され、よりシンプルかつセキュアなアクセス環境を実現できます。
2. Session Managerとは
AWS Session Managerは、AWS System Manager の機能の1つで、EC2インスタンスやオンプレミスサーバーに対して、安全にサーバーにアクセス可能にするサービスです。
2.1 Session Managerを利用するメリット
- ポートを開く必要がない・鍵管理不要
- 従来の踏み台サーバーには、sshの22番ポートを開く必要がありますが、AWS Session Managerを利用すれば、ポートを開く必要がなくセキュアに踏み台サーバーを運用することが可能になります。また、sshキーの管理が不要になります。
- ポート転送
- EC2インスタンスで動いているアプリケーションに対して、ローカルPCのローカルポートからアクセスできるようになります。また、ローカルPCからEC2インスタンスを踏み台にして、プライベートサブネットに配置されているRDSなどのデータベースにアクセス可能になります。
3. 実際の構成図
4. AWS Session Managerで踏み台サーバー構築する
4.1. VPCを作成する
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 192.168.0.0/20
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: 'vpc'
4.2. プライベートサブネットを作成する
PrivateSubnetAZ1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [0, !GetAZs '']
CidrBlock: 192.168.0.0/24
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: 'private-subnet-az1'
PrivateSubnetAZ2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [2, !GetAZs '']
CidrBlock: 192.168.1.0/24
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: 'private-subnet-az2'
4.3. データベースを構築する
RdsDbCluster:
Type: 'AWS::RDS::DBCluster'
Properties:
AvailabilityZones:
- !Select [0, !GetAZs '']
- !Select [2, !GetAZs '']
BackupRetentionPeriod: 7
DBClusterIdentifier: !Sub '${ProjectName}-database'
DBClusterParameterGroupName: !Sub '${ProjectName}-aurora-parameter-group'
DatabaseName: gym_db
DBSubnetGroupName: !Sub '${ProjectName}-aurora-subnet-group'
Engine: 'aurora-mysql'
Port: 3306
MasterUsername: 'admin_user'
MasterUserPassword: "DBのパスワード"
PreferredBackupWindow: '17:20-17:50'
PreferredMaintenanceWindow: 'sun:15:00-sun:16:00'
VpcSecurityGroupIds:
- !ImportValue SgDbSecurityGroup
StorageEncrypted: true
EnableIAMDatabaseAuthentication: false
# 通常のAuroraかAurora Serverlessか選択可能
EngineMode: 'provisioned'
DeletionProtection: false
EnableHttpEndpoint: false
AuroraSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupDescription: 'subnet group'
DBSubnetGroupName: 'aurora-subnet-group'
SubnetIds:
- !Ref PrivateSubnetAZ1
- !Ref PrivateSubnetAZ2
AuroraClusterParameterGroup:
Type: AWS::RDS::DBClusterParameterGroup
Properties:
Description: Aurora MySQL 8.0 cluster parameter group
DBClusterParameterGroupName: 'aurora-parameter-group'
Family: aurora-mysql8.0
Parameters:
time_zone: Asia/Tokyo
character_set_database: utf8mb4
Tags:
- Key: Name
Value: 'aurora-cluster-param-group'
DbInstance:
Type: AWS::RDS::DBInstance
Properties:
AllowMajorVersionUpgrade: false
# DBインスタンスの変更を即時反映させるかメンテナンスウィンドウ時に反映させるか
ApplyImmediately: true
AutoMinorVersionUpgrade: false
# 自動バックアップの保持期間
BackupRetentionPeriod: 0
DBClusterIdentifier: !Ref RdsDbCluster
DBInstanceClass: db.t3.medium
DBInstanceIdentifier: 'db-instance'
DBSubnetGroupName: 'aurora-subnet-group'
DeleteAutomatedBackups: true
Engine: aurora-mysql
PreferredMaintenanceWindow: 'sun:17:00-sun:17:30'
PubliclyAccessible: false
4.4. EC2を作成する
BastionInstance:
Type: AWS::EC2::Instance
Properties:
AvailabilityZone: !Select [0, !GetAZs '']
DisableApiTermination: false
IamInstanceProfile: !Ref BastionInstanceProfile
ImageId: ami-07b0c09aab6e66ee9
InstanceType: t2.small
Monitoring: true
SecurityGroupIds:
- !Ref BastionSecurityGroup
SubnetId: !Ref PrivateSubnetAZ1
Tags:
- Key: Name
Value: 'bastion-instance'
BastionInstanceProfile:
Type: "AWS::IAM::InstanceProfile"
Properties:
Path: "/"
Roles:
- !Ref SessionManagerRole
4.5. VPCエンドポイント
SsmEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ssm'
VpcId: !Ref VPC
VpcEndpointType: Interface
SubnetIds:
- !Ref PrivateSubnetAZ1
- !Ref PrivateSubnetAZ2
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref SsmVpcEndpointSg
Tags:
- Key: Name
Value: 'logs-vpc-endpoint'
SsmMeessagesEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ssmmessages'
VpcId: !Ref VPC
VpcEndpointType: Interface
SubnetIds:
- !Ref PrivateSubnetAZ1
- !Ref PrivateSubnetAZ2
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref SsmVpcEndpointSg
Tags:
- Key: Name
Value: 'logs-vpc-endpoint'
4.6. IAM
Resources:
SessionManagerRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Outputs:
SessionManagerRole:
Value: !Ref SessionManagerRole
Export:
Name: SessionManagerRole
4.8. セキュリティグループ
BastionSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Security group for Bastion host using Session Manager"
VpcId: !Ref VPC
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 3306
ToPort: 3306
CidrIp: 0.0.0.0/0
SsmVpcEndpointSg:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Allow SSM traffic"
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
4.9. SSMプラグインをローカルPCにインストールする
以下のページを参考にSSMプラグインをPCにインストールする。
AWS CLI 用の Session Manager プラグインをインストールする
4.10. ssm start
aws ssm start-session \
--target i-xxxxxxxxxxxxxxxxx \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters '{
"host":["<aurora-endpoint>"],
"portNumber":["3306"],
"localPortNumber":["13306"]
}'
Session Managerとの通信に成功すれば、Auroraに接続可能になります。 お使いのデータベースクライアントから接続お願いいたします。
※ データベースクライアントは事前にインストールお願いします。 ※ aws cliのインストール、設定は事前にお願いします。
6. よくあるトラブルとその解決策
6.1 AmazonSSMServiceRolePolicy
AmazonSSMServiceRolePolicy は、AWSが提供するマネージドポリシーです。このポリシーは、AWS Systems Manager を使うためにEC2インスタンスにアタッチする必要があり、このポリシーがなければ、EC2とAWS Systems Managerの連携を行うことができません。
6.2 SSM エージェントがEC2にインストールされていない
EC2インスタンスにSSMエージェントがインストールされていなかれば、ローカルPCからSession Managerを利用してアクセスすることはできません。
※ Amazon Linux2やAmazon Linux2023を利用している場合デフォルトでインストールされています。
7. まとめ
AWS Session Managerを利用するとセキュアに、踏み台サーバーを運用することができたり、煩雑な鍵管理から開放されます。
AWS上で踏み台サーバーを作成する際は、導入を検討してみるのも良いかもしれません。