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.)
This step is optional but avoids "VPC Peering" issues with other AWS regions (if you need them in future).
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".
Create an Internet Gateway and attach it to your VPC.
Create an Egress-only Internet Gateway and attach it to your VPC.
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".
Add the rules below your VPC's Main Route Table:
- Destination
0.0.0.0/0
viaInternet Gateway
- Destination
::/0
viaEgress Only Internet Gateway
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
viaNetwork Interface
.
The Bastion is a server that runs as an EC2 Instance (Virtual Machine).
Go to: https://www.uplinklabs.net/projects/arch-linux-on-ec2/
- Select one of the LTS release for your region.
- 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.
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.
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
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.
sudo pamac install zerotier-one
sudo systemctl enable zerotier-one
sudo systemctl start zerotier-one
ZeroTier networks can be created for free on https://my.zerotier.com
- Managed Routes -> Add Routes:
10.10.0.0/16
via172.22.1.0
- IPv4 Auto-Assign -> Auto-Assign from Range:
172.22.*.*
- IPv6 Auto-Assign -> Enable ZeroTier 6PLANE (/80 routable for each device)
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.
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
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
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