Intro

OCI’s Native Bastion service is built into Oracle Cloud providing simple and secure connectivity. In this blog post we will go through a “crawl, walk, run” approach for connecting to the Bastion service, starting with port forwarding commands and ending with examples of how to fully automate the Bastion Session lifecycle.

Make sure to follow the first blog post in this series, where we focus on best practices for deploying the Bastion Host.

Bastion Host Architecture Best Practices

Getting Started

Deploy a SOCKS5 Bastion Host:

1.) Make sure the proper IAM poilicies are in place for both Bastion Host deployement and Bastion Session creation.

2.) In the OCI Console, go to Identity & Security -> Bastion -> Create Bastion

  • Set a Memorable Name
  • Set an existing VCN and subnet you want to access.
  • Check “Enable FQDN Support and SOCKS5”
  • On the “CIDR block allow list”, add `YourPublicIpAddr/32`, or `0.0.0.0/0` for internet access from any resource

Creating a Bastion Host Connection Using a Bastion Session:

OCI makes it easy to build Bastion Sessions as soon as the Bastion Host is finished provisioning. You can easily go into the Console, copy the SSH command and connect to the Bastion host. My collegue has also written a blog post that walks through a real world example of the connection. This is the recommended method if you don’t plan to refresh your Bastion Sessions often.

Read below to see how to automate this procedure!

Connecting to a Bastion without the Cloud Console

By automating the task of building a new Bastion session and building port forwarding sessions we can significantly simplify our connectivity experience to OCI. No more need to memorize obscure commands or log into the console every time you need to refresh your Bastion Session. The only requirements are to install the OCI CLI client and verify that a native SSH client is available on your operating system. In Windows, SSH is available in PowerShell. Most other operating systems have an SSH client on with their default shell.

One time configuration – Generate a json configuration file.

Run the following command to get a configuration file for the Bastion Host. Once these parameters are set you will be able to reference this file every time you need to make a new connection to the Bastion Host. This example generates the JSON data required to make a SOCKS5 session and outputs the requirements to a file that we will modify.

oci bastion session create-session-create-dynamic-port-forwarding-session-target-resource-details –generate-full-command-json-input > bastion.json

 

Use your favorite text editor and update the required values. Here is an example of a modified bastion.json file that creates 1 hour sessions to the Bastion Host.

 {

  “bastionId”: “ocid1.bastion.oc1.iad.xxx”,

  “displayName”: “Automated Bastion Session”,

  “keyDetails”: {

    “publicKeyContent”: “ssh-rsa xxxxxx”

  },

  “keyType”: “PUB”,

  “maxWaitSeconds”: 0,

  “sessionTtlInSeconds”: 3600,

  “waitForState”: [

    “ACCEPTED”

  ],

  “waitIntervalSeconds”: 0

}

 

Now that the one time configuration is out of the way you can quickly create new Bastion Sessions with Two Commands:

1.) Create a new Bastion Session using the JSON file you created. The output of this command will show the unique Bastion Session ID for the next command.

oci bastion session create-session-create-dynamic-port-forwarding-session-target-resource-details –from-json file://~/bastion.json –query ‘data.resources[0].identifier’

 

2.) Get the SSH command from the session

oci bastion session get –query ‘data.”ssh-metadata”.command’ –session-id OUTPUT_FROM_PREVIOUS_COMMAND

 

The output of the second command will look something like this. You will need to fill out the private key and local port. For the local port, use an ephemeral port number such as 25000.

ssh -i <privateKey> -N -D 127.0.0.1:<localPort> -p 22 ocid1.bastionsession.oc1.iad.xxxxx@host.bastion.us-ashburn-1.oci.oraclecloud.com

 

Once the SSH command is sucuessfully run, set up your application to have a SOCKS5 proxy on “localhost:25000” (if your ephemeral port is 25000). For example, you can set up your Firefox web browser with a SOCKS5 proxy to forward your HTTP requests to OCI!

If your destination is not SOCKS5 aware, such as forwarding RDP traffic, you can swap the ‘-D’ flag for a ‘-L’ flag in the SSH command and do a 1:1 mapping of your OCI target. Connect to `localhost:ephemeral_port` and your traffic will be forwarded to the Bastion. Here is a full example where I will be able to connect to RDP (port 3389) on OCI resource 10.0.0.100 by connecting to “localhost:25002” on my RDP client.

ssh -N -L 25002:10.0.0.100:3389 -p 22 ocid1.bastionsession.oc1.iad.xxx@host.bastion.us-ashburn-1.oci.oraclecloud.com

 

TIP:

1.) You can create multiple 1:1 mappings with the same Bastion Session by using unique ephemeral port numbers for your instances with the command above.

2.) You can add these the OCI CLI commands to an alias file to your local machine and quickly reference them for faster access.

Automate Everything

To make Bastion connectivity as simple as possible, you can automate the end to end process eliminating the need to memorize complex commands and get right to connecting to your workloads simply and easily.

These scripts are for reference only and recommended for engineers and architects that have experience with shell scripts or Python. There is no responsibility assumed if you choose to use these code examples. These sample codes are not supported by Oracle, it is just my interpretation of how to use the Bastion service.

 

(Shell) Automate Bastion Sessions – Sample Code

Builds upon the example above and automates SOCKS5 and port forward mapping for Bash or WSL.

https://github.com/jake-oci/oci-cli_bastion_session_automator

 

(Python) Automate Bastion Sessions – Sample Code

Fully manages the Bastion Session Lifecycle as well as many other features such as automatically adding public CIDRs to the allow list, creating ephemeral SSH RSA keys, create untimed bastion connections, and allow up to 20 active users on a Bastion Host at the same time.

https://github.com/jake-oci/bastion_session_automator

 

Now you will be able to connect to your OCI resources quickly and securely using the OCI Bastion service!

Troubleshooting

“Unable to negotiate with 111.222.333.444 port 22: no matching host key type found. Their offer: ssh-rsa”

While connecting to your Bastion host, you may see the error above. Starting in Open_SSH8.8, ssh-rsa keys are not allowed by default.

You can append these flags to your SSH command to allow ssh-rsa keys specifically for your Bastion host.

-o PubkeyAcceptedKeyTypes=ssh-rsa
-o HostKeyAlgorithms=ssh-rsa

OR

Add this configuration to your ~/.ssh/config file

Host host.bastion.*.oci.oraclecloud.com
    PubkeyAcceptedKeyTypes +ssh-rsa
    HostkeyAlgorithms +ssh-rsa

“My sessions close 5 minutes after I start them”

Port forwarding session will close the session after 5 minutes of inactivity. Set up a server alive interval which will send a probe through your tunnel to keep the tunnel up. 

Add this flag to your SSH command:

-o serveraliveinterval=60

Outro

Automation can save your many hours of frustration and simplify your end user’s experince for accessing resource in OCI, making it a win-win for everyone. I hope you enjoyed the blog!