Adaptive Logo
Adaptive Logo
Get Started
Tutorial5 min read

How to set up an AWS Bastion host or a Jump server

Himanshu GargJan 10, 2023
How to set up an AWS Bastion host or a Jump server

What is an AWS Bastion Host?

A Bastion Host (or a jump server) is a dedicated computer used to access infrastructure resources and helps compartmentalize them. From a security perspective, a Bastion host is the only node in the network exposed for external access.

Remote access to databases and other servers is often required for administrative chores and troubleshooting. But exposing these servers for public access also exposes them to attacks.

Without Bastion

Organizations instead designate a hardened intermediary server (or jump server) that is the only one open for external ssh access. All the other business-critical infrastructure is accessed through this bastion host. Access policies and audit infrastructure are set up just on the bastion host instead on each and every DB and server.

With Bastion

Creating an AWS Bastion Host

The below steps show how to create a simple AWS Bastion Host (or jump server) for your infrastructure. Later we also outline additional considerations for a more sophisticated setup.

Create an EC2 instance

  • Create an EC2 instance to be used as a bastion host. This instance will NOT require high CPU/memory resources as it will not run any services except those required for its function as a bastion host.

Launch an Instance

Configure Security Groups

  • Security groups on AWS are used to allow inbound connections on specified ports from specified IPs. Create a security group to allow SSH access to the bastion host from 0.0.0.0/0 and associate this security group with the bastion host.

    Edit inbound rules for Bastion

  • Create another security group to allow SSH access only from the bastion host’s IP. Associate this security group with the rest of your infrastructure.

    Edit inbound rules for servers

Verify the Setup

Connecting directly to the server/DB fails

$ ssh -i aws.pem admin@13.127.194.184
ssh: connect to host 13.127.194.184 port 22: Connection timed out

Connecting via Bastion host works

$ ssh -i aws.pem admin@65.1.126.16
Linux ip-172-31-25-53 4.19.0-21-cloud-amd64 #1 SMP Debian 4.19.249-2 (2022-06-30) x86_64
Last login: Tue Jan  3 00:52:15 2023 from 122.161.64.244
admin@ip-172-31-25-53:~$ ssh -i aws.pem admin@13.127.194.184
admin@ip-172-31-39-72:~$

The -J option can be used for connecting to the server in a single command.

Additional Considerations

Elastic IP (or Static IP)

The Bastion host's public IP is likely to change on machine restart. When this is an issue, consider allocating an Elastic IP (or Static IP) to the Bastion host.

Limiting Source IPs

If there is a fixed set of IP addresses from which the bastion host will be accessed, allow only those in the inbound rules.

Audit

Openssh on Linux includes logs of successful and failed login attempts, typically in /var/log/auth.log:

Jan  4 04:54:55 ip-172-31-25-53 sshd[13693]: Accepted publickey for admin from 3.131.228.105 port 53574 ssh2: RSA SHA256:ac6wLNaNL7NpWhfJSSD+T3nHnNQQeXJkyBJKi4kO9Zo
Jan  4 04:54:55 ip-172-31-25-53 sshd[13693]: pam_unix(sshd:session): session opened for user admin by (uid=0)
Jan  4 04:54:55 ip-172-31-25-53 systemd-logind[523]: New session 42617 of user admin.
Jan  4 04:54:56 ip-172-31-25-53 sshd[13693]: pam_unix(sshd:session): session closed for user admin
Jan  4 04:54:56 ip-172-31-25-53 systemd-logind[523]: Session 42617 logged out. Waiting for processes to exit.
Jan  4 04:54:56 ip-172-31-25-53 systemd-logind[523]: Removed session 42617.

Subnets

For an additional layer of security, put the bastion host in a public subnet and the remaining infra in a private subnet. Choose VPC and more when creating a new VPC to configure the subnets:

Create VPC

AWS Reference Deployment

AWS’s Reference Deployment provides a reference implementation.

Create a Bastion with Terraform

Terraform scripts for a similar setup are also available here.

Challenges with Bastion Hosts

An AWS Bastion Host is a good start to securing infrastructure access for a company from external threats, but implementing it, especially for larger organization sizes has some major challenges that need to be considered:

High Availability

In rare situations, a single bastion host can also be a single point of failure for accessing the internal systems. If your infrastructure lives in multiple availability zones, consider creating one bastion host for each.

Scaling

As your company infrastructure grows, each with its credentials and maintenance, the use of bastion hosts can become cumbersome.

Key Management

Bastion hosts don’t solve the problem of key management, as whoever needs access to the one server also needs the keys to access the bastion host and the server itself.

Alternatives to a Bastion Host

There are different alternatives to Bastion Hosts that can be implemented based on the company’s requirements and size to manage their infrastructure access and security -

VPN

A VPN or Virtual Private Network allows the client host to become part of the company’s internal infrastructure dynamically. This also means that once inside a VPN one has access to all the hosts in the internal network. It is relatively harder to set up and use.

VPN + Bastion Host

The combination of VPN and Bastion Host provides more security by addressing their limitations when either is used in isolation. The Bastion host limits access to infra within the VPN. And the VPN limits access to the Bastion host on the public internet. While more robust, it may be overkill for an organization with few infrastructure resources.

SOCKS Proxy

A SOCKS Proxy can also be used to access internal applications behind a firewall that allows SSH connections only. e.g. the following ssh command starts a proxy on port 9999 on the local host.

$ ssh -i~/.ssh/aws.pem -D9999 admin@65.1.126.16

Remote applications behind the firewall can then be securely accessed by specifying the proxy to use e.g. the following accesses the remote application running on port 8888 via the proxy started above:

$ all_proxy="socks5://127.0.0.1:9999" curl 127.0.0.1:8888
<!DOCTYPE html>
<html>
<head>
...

Conclusion

Bastion hosts are a way to provide a low-cost layer of security for a company’s infrastructure. They don’t necessarily solve all of the access management issues, but can be a good starting point for a company to secure its infrastructure access, only necessitating replacement with a more comprehensive solution when your company grows.

Further Reading

  1. The manual page for ssh(1) - OpenSSH remote login client
  2. AWS EC2 documentation
  3. Sharing infrastructure access with developers
Enterprise Grade
A Unified Approach to Data Security and Privileged Access
Agentless Architecture
Zero Network Reconfiguration
Deploy in Cloud or On-Prem