AWS Cloud Operations Blog
Automated configuration of Session Manager without an internet gateway
Session Manager is a fully managed AWS Systems Manager capability that you can use to manage your Amazon Elastic Compute Cloud (Amazon EC2) instances, on-premises instances, and virtual machines (VMs) through an interactive one-click browser-based shell or through the AWS CLI. Session Manager also provides secure and auditable instance management without the need to open inbound ports, maintain bastion hosts, or manage SSH keys. This results in cost savings because it reduces management overhead, centralizes access control by using AWS Identity and Access Management (IAM) policies, and enhances operational security by logging and auditing session activity.
This post describes how, with AWS Systems Manager support for AWS PrivateLink, you can further reduce the attack surface by using virtual private cloud (VPC) endpoints instead of an internet gateway, NAT gateway, or proxy server. This is especially useful for public sector customers, customers in highly regulated industries, or customers who might be forbidden from using internet gateways or required to use cloud access point (CAP) connections.
In addition to Knowledge Center resolutions about SSH tunnels and manual configuration of this solution in the AWS Management Console, there is an AWS CloudFormation template available on GitHub that automates its deployment. The architecture of the solution is illustrated in Figure 1.
Choosing an AMI ID
Session Manager requires use of the SSM Agent. You can either install the SSM Agent on the EC2 instance, or use an Amazon Machine Image (AMI) that already includes the SSM Agent, such as the Amazon Linux 2 AMI. You can query for the latest AMI ID of Amazon Linux 2 using Systems Manager Parameter Store:
Parameters:
pLatestAmiId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
You can use the AMI ID returned from AWS Systems Manager Parameter Store in the ImageId
property when you create the EC2 instance. This ensures you’re using the latest version of the AMI, but it doesn’t require you to update the AWS CloudFormation template as new versions of the AMI are released. It also simplifies multi-Region deployments by eliminating the need for mappings between AWS Regions and AMI IDs.
Select an EC2 instance type available in your AWS Region. You don’t need to configure an EC2 key pair to connect to the EC2 instance using Session Manager. See the following code:
rEc2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref pLatestAmiId
InstanceType: !Ref pInstanceType
SubnetId: !Ref rPrivateSubnet
IamInstanceProfile: !Ref rEc2InstanceProfile
SecurityGroupIds:
- !Ref rSecurityGroupEc2Instance
IAM instance profile for EC2 instance
In the preceding AWS::EC2::Instance
resource, the IamInstanceProfile
property is set. To use Session Manager, the EC2 instance you want to connect to must include an IAM instance profile with Session Manager permissions. This instance profile must have a trust relationship to Amazon EC2 and include the permissions granted by the managed AmazonSSMManagedInstanceCore
policy.
By using pseudo parameters, you can parameterize the AWS CloudFormation template to work in multiple AWS Regions and partitions. For example, you can run the same AWS CloudFormation template in US East (N. Virginia) and AWS GovCloud (US-West) Regions.
See the following code:
rEc2InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles:
- !Ref rEc2InstanceRole
rEc2InstanceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
-
Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
Path: /
ManagedPolicyArns:
# The managed IAM policy AmazonSSMManagedInstanceCore grants access to Session Manager
- !Sub arn:${AWS::Partition}:iam::aws:policy/AmazonSSMManagedInstanceCore
VPC endpoints
EC2 instances in the VPC need a route to Systems Manager, Session Manager Message Gateway Service, and Message Delivery Service. Without an internet gateway, this requires a VPC endpoint for each of the three required services (ssm
, ssmmessages
, and ec2messages
). This solution works only in AWS Regions that offer these three VPC endpoints. Otherwise, you must use an internet gateway or select a different AWS Region. The following code has the resources required to create these VPC endpoints and associate them with the VPC, subnet, and security group:
rSsmVpcEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssm
VpcId: !Ref rVpc
SubnetIds:
- !Ref rPrivateSubnet
SecurityGroupIds:
- !Ref rSecurityGroupVpcEndpoint
VpcEndpointType: Interface
PrivateDnsEnabled: True
rSsmMessagesVpcEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssmmessages
VpcId: !Ref rVpc
SubnetIds:
- !Ref rPrivateSubnet
SecurityGroupIds:
- !Ref rSecurityGroupVpcEndpoint
VpcEndpointType: Interface
PrivateDnsEnabled: True
rEc2MessagesVpcEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
ServiceName: !Sub com.amazonaws.${AWS::Region}.ec2messages
VpcId: !Ref rVpc
SubnetIds:
- !Ref rPrivateSubnet
SecurityGroupIds:
- !Ref rSecurityGroupVpcEndpoint
VpcEndpointType: Interface
PrivateDnsEnabled: True
Security groups
An inspection of the security groups reveals how Session Manager reduces the attack surface. You might be accustomed to bastion hosts that require TCP port 22 to be opened for SSH access or TCP port 3389 to be opened for RDP access. In the following code, the security group attached to the EC2 instance has no inbound rules, but we can connect to the instance through Session Manager. This is because the connection originates outbound through the SSM Agent as opposed to originating inbound through TCP port 22 or 3389, and security group rules are stateful. This is important because it eliminates a common entry point for bad actors. The outbound connections are routed through the VPC endpoint over TCP port 443. Furthermore, access to the VPC endpoint is limited to the security group associated with the EC2 instance.
rSecurityGroupEc2Instance:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: SG for EC2 Instance
VpcId: !Ref rVpc
# Despite this security group containing no ingress rules, Session
# Manager can still provide shell access
SecurityGroupEgress:
# The SSM Agent connects to Session Manager over TCP 443
- Description: allow outbound HTTPS to the VPC
CidrIp: !Ref pCidr
FromPort: 443
ToPort: 443
IpProtocol: tcp
rSecurityGroupVpcEndpoint:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: SG for VPC Endpoints
VpcId: !Ref rVpc
SecurityGroupIngress:
# The SSM Agent connects to Session Manager over TCP 443
- Description: allow inbound HTTPS from the EC2 instance
SourceSecurityGroupId: !Ref rSecurityGroupEc2Instance
FromPort: 443
ToPort: 443
IpProtocol: tcp
SecurityGroupEgress:
# The SSM Agent connects to Session Manager over TCP 443
- Description: allow outbound HTTPS to the VPC
CidrIp: !Ref pCidr
FromPort: 443
ToPort: 443
IpProtocol: tcp
Tunneling RDP traffic using Session Manager
If you require UI access to EC2 instances, you can use Session Manager to redirect traffic from any port inside a remote EC2 instance or on-premises instance to a local port on a client machine. This is especially useful for Remote Desktop access to Windows instances and does not require an internet gateway. For more information, see Now forward traffic between a local and remote port using Session Manager.
Integrating AWS Transit Gateway with AWS PrivateLink and Amazon Route 53 Resolver
To reduce the number of VPC endpoints, simplify VPC endpoint deployment, and help cost-optimize when deploying at scale, consider using AWS Transit Gateway with Amazon Route 53 Resolver to share AWS PrivateLink interface endpoints between multiple connected VPCs and on-premises environments. This way, multiple VPCs across multiple accounts can share a secure, scalable, cost-efficient connection that doesn’t traverse the internet. For more information, see Integrating AWS Transit Gateway with AWS PrivateLink and Amazon Route 53 Resolver.
Summary
You can use AWS PrivateLink and Session Manager for shell access and UI access without the use of an internet gateway. Deploy this solution today to improve security posture, provide cost savings, and enable access for users who are restricted from using internet gateways. The code is open source: join us on GitHub to contribute!
About the author
Brian Landry is a Senior Consultant at AWS working out of San Diego, CA. He enjoys traveling, attending sporting events, and visiting breweries.