The CloudSOE Bastion Host image is a hardened SSH jump host on Ubuntu: fail2ban brute-force protection, the AIDE file-integrity checker (its database is initialised on your VM at first boot), ntpd-rs time sync, and a full Active Directory join toolchain (sssd, realmd, adcli, Kerberos, Samba) preinstalled but unconfigured. There are no baked-in credentials — access is your SSH key, nothing else.

What you’ll need

  • An Azure subscription
  • An SSH public key (password login is disabled in the image)
  • About five minutes

Step 1 — Create the VM

  1. Find the CloudSOE Bastion Host offer in the Azure Marketplace and click Create.
  2. Choose a resource group, region and VM name.
  3. Pick a small size — a bastion forwards SSH traffic, so Standard_B2s (or even Standard_B1s) is plenty for most teams.
  4. Under Administrator account, select SSH public key, pick a username (e.g. azureuser) and paste your key.
  5. Place it in the virtual network that contains your private VMs, attach a public IP, and make the public IP Static for production — your team’s SSH configs will reference this address.

Step 2 — Open exactly one port

In the VM’s network security group, allow inbound:

PortProtocolPurpose
22TCPSSH — restrict to your office/VPN ranges

That’s the whole table. A bastion’s value is its tiny attack surface: no other inbound rule belongs here, and port 22 should be limited to known source ranges, never Any. On the private VMs’ NSGs, allow port 22 only from the bastion’s subnet or private IP.

Step 3 — Let first boot finish

On the very first boot the bastion-firstboot service initialises the AIDE integrity database — a fingerprint of your VM’s files that later checks compare against. It runs in the background and can take a few minutes; the bastion is usable immediately. Check it:

ssh <admin-user>@<public-ip>
systemctl status bastion-firstboot

fail2ban starts automatically at boot and begins watching the SSH log:

sudo fail2ban-client status sshd

Step 4 — Jump to a private VM

The whole point of a bastion — reach VMs that have no public IP (use private addresses for the hop; an Azure VM often cannot reach its own public IP from inside the VNet anyway):

ssh -J <admin-user>@<bastion-public-ip> <user>@<private-vm-ip>

-J (ProxyJump) tunnels through the bastion without leaving your private key on it. Don’t copy private keys to the bastion, and prefer ProxyJump over agent forwarding (-A) — with ProxyJump the bastion never sees your agent at all. Make it permanent with an SSH config block — see tips & tricks.

Next steps