Once you have a few AWS EC2 instances, it's time to start thinking about setting up an EC2 instance as an SSH bastion server so you can centralize and secure
management and access to your compute infrastructure.
Strictly speaking, you don't need a SSH bastion server. You can perform Linux hardening on every EC2 instance you have and tie them into security primitives that AWS provides to avoid bastion servers completely. However, this will create more work for you and likely reduce your security posture.
Think of your EC2 instances as buildings within a medieval city. You can secure every single building in your city, but that will be costly and there is a good chance you'll forget about one of them. A better option would be to build a strong wall around them with a few gates where you can focus your hardening efforts and control access to your entire city.
Once you start thinking about bastions from that perspective, bastions become an important part of your efforts to reduce and mitigate attacks on your infrastructure. A few nice properties emerge.
- Your SSH servers (other than the bastion itself) no longer need to be
accessible from the internet.
- Bastion hosts are single-purpose machines and you can dramatically reduce what runs on them.
- You can enforce centralized SSH key management (grant, revoke, and rotate keys).
- You can enforce centralized audit logging to track who logged into a server and what they did on a server.
There are many ways to set up SSH bastion servers on AWS. Below is a list of the most popular ways.
Running OpenSSH on an EC2 instance is the classic way to build a bastion server on AWS. The internet is full of guides on how to do this — we've listed a few below.
- Setting Up an SSH Bastion Host
- SSH Best Practices using Certificates, 2FA and Bastions
In general, at the minimum, you'll have to do the following.
1. Create a hardened Linux EC2 instance. Use CIS or STIG hardening guides.
Enable automatic upgrades. Consider using a CIS Hardened AMI.
2. Create a hardened OpenSSH configuration. Don't allow or limit interactive sessions on the bastion server (use `ProxyJump instead).
3. Create security groups and network ACLs to control access to the bastion (public internet) and servers with a VPC (can only be accessed via bastion)
4. Capture and send all logs to centralized logging infrastructure.
5. Update configuration management to handle SSH key lifecycle (grant, revoke, and rotate keys) on the bastion and target hosts.
If you implement the above five items, this will put you ahead of 80% of the internet. Most attackers will simply move on to lower-hanging fruit.
This is a great place to get started. It saves you time and gives you flexibility on how you configure your infrastructure. The downside is creating and managing OpenSSH, AWS, and a SIEM.
Figure 1: Setting up a SSH Bastion on AWS.
The next option is running self-hosted OSS Teleport. Self-hosted Teleport reduces the amount of work you have to do to get a SSH bastion running on AWS as it is secure by default out of the box. For example, when you run the internet facing Teleport Proxy Service, by default you can't even create an interactive shell on the proxy. OSS Teleport takes care of all of the software configuration tasks you would have to take on with the self-hosted OpenSSH approach.
1. Create a hardened Linux EC2 instance. Use CIS or STIG hardening guides. Enable automatic upgrades.
2. Create hardened OpenSSH configuration. Don't allow or limit interactive sessions on the bastion server (use ProxyJump instead).
3. Create security groups and network ACLs / firewall to control access to the bastion (public internet) and servers in VPCs and private subnets (can only be accessed via bastion)
4. Capture and send all logs to centralized logging infrastructure.
5. Update configuration management to handle SSH key lifecycle (grant, revoke, and rotate keys) on the bastion and target hosts.
6. Connect to the bastion. Access to servers will now be conducted via the ip address of the bastion server.
If you have a hard requirement to self-host your SSH bastion on AWS, using OSS Teleport is a good balance between the full flexibility you get with self-hosted OpenSSH and your time.
Figure 2: Teleport takes care of the items in gray so you don't have to worry about them anymore.
The simplest option is to use Teleport Cloud which you can try for free. With Teleport Cloud, you simply attach your EC2 instances to Teleport Cloud (which itself runs in us-west2) and that's It — you’re done. No software configuration, no cloud configuration, no additional infrastructure to provision. Teleport Cloud takes care of all of that for you.
1. Create a hardened Linux EC2 instance. Use CIS or STIG hardening guides. Enable automatic upgrades.
2. Create hardened OpenSSH configuration. Don't allow or limit interactive sessions on the bastion server (use ProxyJump instead).
3. Create security groups and network ACLs to control access to the bastion (public internet) and servers (can only be accessed via bastion)
4. Capture and send all logs to centralized logging infrastructure.
5. Update configuration management to handle SSH key lifecycle (grant, revoke, and rotate keys) on the bastion and target hosts.
After you create your Teleport Cloud account, protecting your EC2 instances is just three clicks away.
Figure 3: The three clicks it takes to protect your EC2 infrastructure with Teleport Cloud.
Simply paste the command from Click (3) on any running EC2 instance and it will automatically connect to your Teleport Cloud SSH Bastion on AWS.
Teleport Cloud is a great option for teams that need security but don't have the bandwidth to provision infrastructure or software for their SSH bastions.
Figure 4: Teleport takes care of the items in gray (all of your bastion infrastructure) — you simply connect your EC2 instances to Teleport Cloud.
Running a SSH bastion to access your AWS account can be a daunting task. This post outlines the options you have, from the most flexible to the simplest, so you can decide what works best for your needs.
Once set up, Teleport can be used as a bastion for other AWS services such as RDS, EC2, DynamoDB, AWS Management Console, and CLI for IAM delegation.