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.

GitHub Logo
cta 200 1

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.

Architecture diagram for Automated configuration of Session Manager without an internet gateway. An EC2 instance in a VPC with VPC endpoints that route to AWS Systems Manager, Amazon Session Manager Message Gateway Service, and Amazon Message Delivery Service.

Figure 1. Architecture Diagram

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 Session 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.