the bastion host

1. Goals

We want to create a bastion network and a bastion host in order to have an isolated network for accessing and manipulating all of our other resources.

This will imply that we also have to do all of your deployments from this host:

All others hosts we are going to create will have direct access to the Internet but no input connections will be allowed.
I just don’t want to create an AWS NAT system because it costs $35 per month.

The bastion provisioning is included in the infrasecrets project.
It is the most obvious place to put it as they are the 2 first projects we want to create.

The bastion network and the bastion host will only be created in the region1.

2. Terraform

We are first going to create the network, then the host using the AMI we previously created.

First the network:

[workstation] (ansible_virtualenv) ~/demo_big_infra
$ cd infrasecrets/terraform/demo/bastion

[workstation] (ansible_virtualenv) ~/demo_big_infra/infrasecrets/terraform/demo/bastion
$ cd network
$ terraform init
$ terraform apply -var-file '../../vars_network.tf'
$ cd ..

Then the host:

[workstation] (ansible_virtualenv) ~/demo_big_infra/infrasecrets/terraform/demo/bastion
$ cd system
$ terraform init
$ terraform apply -var-file '../../vars_network.tf'
$ cd ..

You can see in the AWS Console the result:

AWS bastion

3. SSHFP

Terraform created a SSHFP entry in the DNS zone at Cloudflare for the newly created host (you can check in the dashboard).

Cloudflare Bastion SSHFP

We will use this security feature to securely identify the bastion host.
But you have to be sure that your resolver can handle DNSSEC and the EDNS0 option.

If not, the following Ansible command will fail or ask you to verify the fingerprint: ssh or Ansible don’t ask anything if SSHFP and DNSSEC are working.

If it’s not the case, edit your /etc/resolv.conf file and put the following lines:

options edns0
nameserver 1.1.1.1

4. Ansible

Now that we have a host, we will provision it with Ansible.

Terraform created the ~/demo_big_infra/infrasecrets/inventories/demo/hosts_bastion.lst and ~/demo_big_infra/infrasecrets/inventories/demo/extra_vars_terraform.yml files with everything Ansible need:

  • the public IP address of the bastion host
  • the name of the chosen primary datacenter for the Consul cluster: the name of region1 (for me it’s eu-west-3) it’s not usefull when initializing the infrastructure but will later be if we need to recreate the bastion host.
[workstation] (ansible_virtualenv) ~/demo_big_infra/infrasecrets/terraform/demo/bastion/system
$ cd ~/demo_big_infra/infrasecrets

[workstation] (ansible_virtualenv) ~/demo_big_infra/infrasecrets
$ ansible-playbook INIT_bastion.yml -i inventories/demo/hosts_bastion.lst -D -e @inventories/demo/extra_vars_terraform.yml

5. Connect to the bastion

Let’s try to connect to the bastion.
An initial user, persecutor, has been created and you can connect with your SSH key.

We will use SSH Agent Forwarding because we will provision all other hosts inside our “private” networks.

[workstation] (ansible_virtualenv) ~/demo_big_infra
$ ssh -i ~/.ssh/demo_big_infra -A persecutor@bastion-eu-west-3a-0.terror.ninja

From this moment, everything will be done on the bastion host: no more commands on your computer

6. Next page!

We are done, let’s create our Consul and Vault clusters