Use a bastion to access your VM

To increase security and avoid Internet based attacks, it might make sense to run your VMs without a public IP address and just use a private IP instead. The only way to access such a VM will be through your private network in the Oracle Cloud VCN (Virtual Cloud Network).

Oracle’s bastion feature provides time-limited access to VMs that do not have a public endpoint. It enables you to create a bastion - that controls authorized users and allows them to SSH into a VM from specific IP addresses. Using this feature means that you do not need to deploy and maintain your own security-hardened bastion exposed to both your internal network and the public internet. It also provides a more managed method to inject your SSH key into the target instance and the bastion.

Prerequisites

To use a bastion, you’ll need a gateway in your VCN and a route rule for the gateway in your VM. The gateway could be a service gateway, an internet gateway, or a NAT gateway. The setup will work in any of the following combinations:

  • VM in a public subnet with a public IP address and a route to an internet gateway

  • VM in a private subnet (with no public IP address) and a route to a NAT gateway - this option will allow the VM to have an outgoing internet connection through the NAT Gateway.

  • VM in a private subnet (with no public IP address) and a route to a service gateway - this option will result in a completely air-gapped VM with no internet connectivity at all. But you’ll still be able to access it through your Bastion.

Note that having a VM in a public subnet, but without a public IP won’t work. For more details about these gateways and how to handle their services, refer to the Oracle Cloud documentation for - Service gateway, Internet gateway, or NAT gateway.

Create the IAM policy

If you are not an Administrator, you need to request the administrator of your Oracle Cloud tenancy to create an IAM policy granting access for you to use bastions. This will allow you to create bastions and operate it through the console, CLI or API.

Refer to the Oracle Cloud documentation for details on how to create the required IAM policy. It contains an example of the policy statements that the administrator can use to grant access to services in the whole tenancy, and that can be optionally restricted to a single compartment if desired.

You can create the policy using the console or the CLI.

Go to Identity & Security > Identity > Policies and select the compartment where you want to create the policy (or root if you want to create a policy for the whole tenancy).

Select create policy and provide a name and description. In the Policy Builder section, enable Show manual editor and paste your policy statements (as from the example in the Oracle Cloud documentation).

../../_images/1_create_policy.png

Install oracle-cloud-agent on the VM

If you are using the images created by Canonical and published by Oracle (as described in Find Ubuntu images on Oracle Cloud), they already have the oracle-cloud-agent pre-installed by default, and no additional action is necessary.

To check if the agent is installed, run:

sudo snap list

To list the available channels for the oracle-cloud-agent (you need to select the channel matching your Ubuntu release), run:

sudo snap info oracle-cloud-agent

To install the agent, run:

sudo snap install oracle-cloud-agent --channel=<release-specific-channel>

Enable the bastion plugin on the VM

You can enable the bastion plugin on your VM using either the console or the CLI.

Go to your instance, navigate to the Oracle Cloud Agent tab and enable the Bastion plugin (it is disabled by default):

../../_images/2_enable_bastion_plugin.png

Even though enabled, the status will initially show up as Stopped. It might take up to 10 minutes for the plugin to start running in the VM. Wait until the status changes to Running before proceeding.

Create a bastion

When the bastion plugin shows up as Running in the cloud console, if you have access to the VM (through console or some other method), you should see a new log directory created inside the VM under /var/log/oracle-cloud-agent/plugins/bastions/. Also, if you look at /var/log/oracle-cloud-agent/agent.log, you should see indications that the plugin has started, something similar to:

2023/12/29 18:30:48.004902 health.go:107: health check of plugin:[bastions], desiredState:[Enable], currentState:[notStarted], status:[yet to start] version:[v0.0.0] err:[<nil>]
2023/12/29 18:30:48.004912 orphan.go:28: cleaning orphans of plugin:[bastions] with signal SigTerm
2023/12/29 18:30:48.008749 orphan.go:33: cleaning orphans of plugin:[bastions] with signal SigKill
2023/12/29 18:30:48.011165 health.go:137: starting plugin:[bastions]
2023/12/29 18:30:48.011180 plugin.go:52: creating plugin:[bastions], elevated: false, runas: , exe: /var/snap/oracle-cloud-agent/common/bastions
2023/12/29 18:30:48.203266 health.go:145: started plugin:[bastions]

You can create the bastion using either the console or the CLI.

Go to Identity & Security > Bastion and select Create bastion. Provide a name and select the VCN and subnet where the bastion should be created.

Under CIDR block allowlist, specify the network address range from which you want to provide access to your bastion. For instance, you can restrict the bastion access to only valid IP addresses that your ISP assigns to you, so that it would be accessible only from your network. Note that currently, only IPv4 ranges are allowed.

If you want a less secure approach, you can let the bastion be accessed by any address, as in the example below:

../../_images/3_create_bastion.png

Create a session to access the VM

Once the bastion goes into an Active state, you can create a session using either the console or the CLI.

Select your bastion and choose Create session. Fill in the details:

  • Session type: Managed SSH session

  • Session name: any name of your choice

  • Username: ubuntu (if your VM is an Ubuntu instance, the default user is ubuntu)

  • Compute instance: <the VM that you would like to access through the bastion>

  • Add SSH key: Add a public SSH key to inject into the bastion and the VM (you must have access to the corresponding private key)

../../_images/4_create_session.png

Note

The SSH key that you use here, will be temporarily added to .ssh/authorized_keys in both the bastion and the VM. So when you try to access the VM in the next step, you’ll have to provide your private key twice - once to SSH into the bastion, and then again within a proxy command to SSH into the VM.

Access the VM

You can access the VM using either the console or the CLI.

When the session is created, use the Copy SSH command from the 3 dots menu to get a command similar to:

ssh -i <privateKey> -o ProxyCommand="ssh -i <privateKey> -W %h:%p -p 22 ocid1.bastionsession.oc1.<region>.<id>@host.bastion<region>.oci.oraclecloud.com" -p 22 ubuntu@<ip>

This command will create a tunnel through the public hostname of the bastion to the private IP address of your VM. Replace <privateKey> with the path of your private key, and you should have SSH access to your VM using the bastion.

Further references

The Oracle Cloud documentation is a good resource for more information about its bastions: