Skip to content

Instantly share code, notes, and snippets.

@heri16
Last active August 17, 2021 16:43
Show Gist options
  • Save heri16/3ffdac34a3190efeae199fd5bd83b561 to your computer and use it in GitHub Desktop.
Save heri16/3ffdac34a3190efeae199fd5bd83b561 to your computer and use it in GitHub Desktop.
AWS Bastion Setup - Arch Linux

AWS Bastion Setup

This tutorial will help you setup a Bastion host on AWS.

Arch Linux is most suitable for this task as it is the most lightweight distro after the likes of TinyCoreLinux and Alpine Linux, runs the latest Stable Linux Kernel with up-to-date security, and allows rolling upgrades with no downtime. (Such features are not available from common distros like Centos and Ubuntu server.)

1. Create AWS VPC

This step is optional but avoids "VPC Peering" issues with other AWS regions (if you need them in future).

1a. VPC CIDR Block

Create a new VPC via AWS Console or CLI.

Go to AWS Console -> Services -> VPC -> Virtual Private -> Your VPCs -> Create VPC.

  • IPv4 CIDR block: 10.10.0.0/16

  • IPv6 CIDR block: Amazon provided IPv6 CIDR block

    Then, select created VPC, click Actions -> Edit DNS hostname -> Enable "DNS hostnames".

1b. VPC Internet Gateway

Create an Internet Gateway and attach it to your VPC.

1c. VPC Egress-only Internet Gateway

Create an Egress-only Internet Gateway and attach it to your VPC.

1d. VPC Subnets

Create a new Subnet under this VPC for each Availability Zone in your region.

  • IPv4 CIDR block: 10.10.0.0/20 / 10.10.16.0/20 / 10.10.32.0/20

  • IPv6 CIDR block: 00::/64 / 16::/64 / 32::/64

    Then, select each created Subnet, click Actions -> Modify auto-assign IP settings -> Enable "Auto-assign IPv6".

1e. VPC Route Table

Add the rules below your VPC's Main Route Table:

  • Destination 0.0.0.0/0 via Internet Gateway
  • Destination ::/0 via Egress Only Internet Gateway

2. Create AWS ENI

It is not recommended to use the primary network interface of the Bastion for routing or NAT.

As such we will have to create a new secondary network interface.

Go to: AWS Console -> Services -> EC2 -> Network & Security -> Network Interfaces -> Create Network Interface

  • Subnet: Subnet A from above
  • IPv4 Private IP: Custom 10.0.1.0
  • IPv6 Setting: Auto-Assign
  • Security groups: ZeroTier-Gateway

You will have to create a new security group named ZeroTier-Gateway, and allow inbound/outbound traffic from/to your CIDR block 10.10.0.0/16. There are lots of tutorials elsewhere on how to do this.

  • Inbound means traffic from your cloud resources to your dev-machines.
  • Outbound means traffic from your dev-machines to your cloud resources.

Then select the new interface, and note down the MAC address. Then click Actions -> Change Source/Dest Check to disable the check. This enables the interface to send/route traffic with a source IP that is not part of the AWS VPC CIDR block. This also enables the interface to receive/route traffic with a destination IP that is not part of the AWS VPC CIDR block.

After that return to your VPC Route Table and add the rule below:

  • Destination 172.22.0.0/16 via Network Interface.

3. Launch Bastion Instance

The Bastion is a server that runs as an EC2 Instance (Virtual Machine).

Go to: https://www.uplinklabs.net/projects/arch-linux-on-ec2/

  1. Select one of the LTS release for your region.
  2. The AWS Console should open automatically when you click the link. Verfiy that you are in the correct region.
  • Subnet: Subnet A from above
  • Auto-assign Public IP: Enable
  • IAM role: bastion
  • Security Group: default
  • Name: bastion

You should create a new IAM named bastion with no policies. There are lots of tutorials elsewhere on why you should do this.

Then select the new Bastion instance, and click Actions -> Networking -> Attach Network Interface to attach the new Network Interface from Step 2.

4. SSH into your Bastion

Go to: AWS Console -> Services -> EC2 -> Instances-> bastion -> Connect

ssh arch@ec2-<xxxxx>.ap-southeast-1.compute.amazonaws.com

You will have to allow SSH and ZeroTier (UDP/9993) on your default security group's inbound rules. There are lots of tutorials elsewhere on how to do this.

5. Install Pamac Package Manager

This step is optional but helps managing packages on Arch Linux.

# Install git
sudo pacman -S git

## Install pamac package from AUR
git clone https://aur.archlinux.org/pamac-cli.git
cd pamac-cli/
makepkg -si
cd ..
rm -rf pamac-cli

# Upgrade all packages
sudo pamac upgrade -a

6. ZeroTier SDN Network

Many AWS services do not come with a public IP. Or have lower performance when Public IP is enabled. This step is optional but gives development machines easy access to cloud resources on AWS services.

We are going to make this Bastion a ZeroTier Gateway which route traffic between dev machines and AWS private ip addresses.

6a. Install ZeroTier

sudo pamac install zerotier-one
sudo systemctl enable zerotier-one
sudo systemctl start zerotier-one

6b. Create ZeroTier Network

ZeroTier networks can be created for free on https://my.zerotier.com

  • Managed Routes -> Add Routes: 10.10.0.0/16 via 172.22.1.0
  • IPv4 Auto-Assign -> Auto-Assign from Range: 172.22.*.*
  • IPv6 Auto-Assign -> Enable ZeroTier 6PLANE (/80 routable for each device)

6c. Join ZeroTier Network

After creating the network, join the network.

ZT_NWID=0cccb752f7464e77

sudo zerotier-cli info
sudo zerotier-cli join $ZT_NWID
sudo zerotier-cli listnetworks
sudo zerotier-cli listnetworks -j

## Disable managed routes and ip assignment from ZeroTier
sudo zerotier-cli set $ZT_NWID allowManaged=0
cat /var/lib/zerotier-one/networks.d/${ZT_NWID}.local.conf

# Setup static ip adress on ZeroTier virtual network interface
curl -o- https://gist.githubusercontent.com/heri16/3ffdac34a3190efeae199fd5bd83b561/raw/6346679258c5fbd8b05ac4cfd81a56fb1418f860/zt0.network | sudo tee /etc/systemd/network/zt0.network
curl -o- https://gist.githubusercontent.com/heri16/3ffdac34a3190efeae199fd5bd83b561/raw/6346679258c5fbd8b05ac4cfd81a56fb1418f860/eth1.network | sudo tee /etc/systemd/network/eth1.network
ip link | sed -n '/: zt/ {p;n;p}'
sudo nano /etc/systemd/network/zt0.network # Update mac address from ip link
sudo nano /etc/systemd/network/eth1.network # Update mac address from Step 2
sudo systemctl restart systemd-networkd.service

# Show zerotier node id
sudo zerotier-cli info

Go back to: https://my.zerotier.com

  • Under Members, authorize the node id from above.
  • Assign IP address 172.22.1.0 to the node.

6d. Enable IP Forwarding

sysctl net.ipv4.ip_forward=1

curl -o- https://gist.githubusercontent.com/heri16/3ffdac34a3190efeae199fd5bd83b561/raw/6346679258c5fbd8b05ac4cfd81a56fb1418f860/30-ipforward.conf | sudo tee /etc/sysctl.d/30-ipforward.conf

6e. Join on dev machine

Install ZeroTier from https://zerotier.com/download/

Join the Network, using the Network ID that you have created from Step 6b.

Authorize the new member node via https://my.zerotier.com

7. Add a Non-sudo user

Add a non-sudo user to ensure no malicious scripts/software is installed as root. Use this user for troubleshooting connectivity issues with netcat.

## Install netcat (troubleshoot firewall and security groups)
sudo pamac install openbsd-netcat

## Add non-sudo user
sudo useradd -m user

## Allow SSH access with authorized_keys
sudo cp -rp ~/.ssh /home/user/
sudo chown -R user:user /home/user/.ssh
sudo ls -la /home/user/.ssh
net.ipv4.ip_forward=1
net.ipv6.conf.default.forwarding=1
net.ipv6.conf.all.forwarding=1
[Match]
MACAddress=06:7c:e8:1e:ab:1a
[Network]
DHCP=yes
[DHCP]
UseMTU=yes
UseDNS=yes
UseDomains=yes
RouteMetric=1024
[Route]
Destination=10.10.0.0/16
Gateway=10.10.0.1
Metric=100
[Match]
MACAddress=76:f3:67:cc:6c:07
[Network]
Address=172.22.1.0/16
Address=fcfb:8af9:25bd:213b:3eb0::1/40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment