OCI Bastion Service : An Alternate way of connecting to your private resources using OCI-CLI

Shadab Mohammad
Oct 8 · 4 min read

The OCI bastion service is a fully managed serverless offering on Oracle Cloud Infrastructure (OCI) to connect to your resources in a private subnet of your Oracle Virtual Cloud Network (VCN) . Though the Bastion service is amazing at what it does, but to ensure you have a session you have to always click through a lot of menu options in OCI console to create a session before you can start working with your private resources.

OCI Bastion Service

There is an alternate way to do this by using OCI command line utility to do the same without jumping through so many options in the GUI.

Before we proceed ensure you have OCI-CLI installed and have created API keys to access your OCI account programmatically. Once the oci-cli is installed and keys are created. Create a Bastion host service for the target subnet in which your resources sit. We will now use the OCI command line utility to create a session on the bastion host

  1. Edit the $HOME/.oci/config file, add the API key and Create your bastion host service
$ cat $HOME/.oci/config [DEMO]
user=ocid1.user.oc1..aaaaaaaacvk*******7q
fingerprint=de:50*******:d6
tenancy=ocid1.tenancy.oc1..aaa******l3fq
region=ap-sydney-1
key_file=/Users/shadab/.oci/oci_api_key.pem
-- Create the Bastion Host -- oci bastion bastion create --bastion-type Standard --compartment-id ocid1.compartment.oc1..aaaaaaaa5o****6cq --target-subnet-id ocid1.subnet.oc1.ap-sydney-1.aaaaaaaao4*****q --client-cidr-list '["0.0.0.0/0"]' --profile DEMO-- List the Bastion Service --oci bastion bastion list --compartment-id ocid1.compartment.oc1..aaaaaa*******q --profile DEMO --all

2. Create a sample JSON response file to create a Bastion session

oci bastion session create-port-forwarding --generate-full-command-json-input

3. Customize the JSON file which was generated in Step 2. with your input parameters and save to a file bastion_input.json

{
"bastionId": "ocid1.bastion.oc1.ap-sydney-1.amaaaaaaeetb******4q",
"definedTags": {
"tagNamespace1": {
"tagKey1": "tagValue1",
"tagKey2": "tagValue2"
},
"tagNamespace2": {
"tagKey1": "tagValue1",
"tagKey2": "tagValue2"
}
},
"displayName": "Shadab-SSH-Session-Bastion",
"freeformTags": {
"tagKey1": "tagValue1",
"tagKey2": "tagValue2"
},
"keyType": "PUB",
"maxWaitSeconds": 0,
"sessionTtl": "10800",
"sshPublicKeyFile": "/Users/shadab/Downloads/Keys/publickey.pub",
"targetPort": "22",
"targetPrivateIp": "10.43.0.34",
"targetResourceId": "ocid1.instance.oc1.ap-sydney-1.anzxsl******tlq",
"waitForState": [
"SUCCEEDED"
],
"waitIntervalSeconds": 20
}

4. Create Port forwarding Session from oci-cli

oci bastion session create-port-forwarding --from-json file://bastion_input.json --profile DEMO

This now provisions a session to connect to port 22 on the remote host.

Another example which is commonly used is creating a port forwarding session for a private Windows host on OCI.

{
"bastionId": "ocid1.bastion.oc1.ap-sydney-1.amaaaaaaeetb5t****p4q",
"definedTags": {
"tagNamespace1": {
"tagKey1": "tagValue1",
"tagKey2": "tagValue2"
},
"tagNamespace2": {
"tagKey1": "tagValue1",
"tagKey2": "tagValue2"
}
},
"displayName": "Shadab-Windows-Session-Bastion",
"freeformTags": {
"tagKey1": "tagValue1",
"tagKey2": "tagValue2"
},
"keyType": "PUB",
"maxWaitSeconds": 0,
"sessionTtl": "10800",
"sshPublicKeyFile": "/Users/shadab/Downloads/Keys/publickey.pub",
"targetPort": "3389",
"targetPrivateIp": "10.43.0.39",
"targetResourceId": "ocid1.instance.oc1.ap-sydney-1.anzxsljreetb5*****yz2q",
"waitForState": [
"SUCCEEDED"
],
"waitIntervalSeconds": 20
}

Now launch the second session for port 3389 (Windows RDP port)

oci bastion session create-port-forwarding --from-json file://bastion_windows.json --profile DEMO

5. Now that the session is created let us get the session details like Session ID and view the session SSH command which we need to run on local machine to create the port-forwarding

To list the session ID’s of the latest sessions created programmatically run

oci bastion session list --bastion-id ocid1.bastion.oc1.ap-sydney-1.amaaaaaaee*******p4q --session-lifecycle-state ACTIVE --sort-order asc --profile DEMO --all

In the JSON output the Session ID for your particular session will be the “id” tag

“id”: “ocid1.bastionsession.oc1.ap-sydney-1.amaaaaaaee***********2gda”

6. Using the session id which you can got by running the previous command input the session ID and output the session details

oci bastion session get --session-id ocid1.bastionsession.oc1.ap-sydney-1.amaaaaaaeetb*********pa --profile DEMO

The output of the above command will list the SSH command with which you will create the port forwarding

“ssh-metadata”: {
“command”: “ssh -i <privateKey> -N -L <localPort>:10.43.0.39:3389 -p 22 ocid1.bastionsession.oc1.ap-sydney-1.amaaaaaa***********gda@host.bastion.ap-sydney-1.oci.oraclecloud.com”
}

7. Finally run the local port forwarding on your client machine to connect your private instance

-- Linux SSH port forwarding --
ssh -i privatekeyfile.key -N -L 2222:10.43.0.34:22 -p 22 ocid1.bastionsession.oc1.ap-sydney-1.amaaaaaa***********gda@host.bastion.ap-sydney-1.oci.oraclecloud.com
-- Windows RDP Port Forwarding --
ssh -i privatekeyfile.key -N -L 8933:10.43.0.39:3389 -p 22 ocid1.bastionsession.oc1.ap-sydney-1.amaaaaaa***********gda@host.bastion.ap-sydney-1.oci.oraclecloud.com

A. Create Bastion Host : OciBastionCreateBastion.sh

#!/bin/bash
export bastion_type=Standard
export compartment_id=ocid1.compartment.oc1..aaaaaaaa******bpi6cq
export target_subnet_id=ocid1.subnet.oc1.ap-sydney-1.aaaaaaaao*******nbnnq
export profile=DEMO
export cidr_allow='["0.0.0.0/0"]'
oci bastion bastion create --bastion-type $bastion_type --compartment-id $compartment_id --target-subnet-id $target_subnet_id --client-cidr-list $cidr_allow --profile $profile

Output

./OciBastionCreateBastion.sh

{
"data": {
"bastion-type": "STANDARD",
"client-cidr-block-allow-list": [
"0.0.0.0/0"
],
"compartment-id": "ocid1.compartment.oc1..aaaaaaaa*****q",
"defined-tags": {
"Oracle-Tags": {
"CreatedBy": "email@acme.com",
"CreatedOn": "2021-10-10T08:17:13.489Z"
}
},
"freeform-tags": {},
"id": "ocid1.bastion.oc1.ap-sydney-1.amaaaaaa*******42q",
"lifecycle-details": null,
"lifecycle-state": "CREATING",
"max-session-ttl-in-seconds": 10800,
"max-sessions-allowed": 20,
"name": "bastion20211010081715",
"phone-book-entry": null,
"private-endpoint-ip-address": null,
"static-jump-host-ip-addresses": null,
"system-tags": {},
"target-subnet-id": "ocid1.subnet.oc1.ap-sydney-1.aaaaaaaao*********bnnq",
"target-vcn-id": "ocid1.vcn.oc1.ap-sydney-1.amaaaa*********vq",
"time-created": "2021-10-10T08:17:16.177000+00:00",
"time-updated": "2021-10-10T08:17:16.177000+00:00"
},
"opc-work-request-id": "ocid1.bastionworkrequest.oc1.ap-sydney-1.amaaaaaa******a"
}

B. Create Session : OciBastionCreateSession.sh

#!/bin/bash
export bastion_id=ocid1.bastion.oc1.ap-sydney-1.amaaaaaa*****4q
export profile=DEMO
export path=file://bastion_input.json
export path2=file://bastion_windows.json
oci bastion session create-port-forwarding --from-json $path --profile $profile
oci bastion session create-port-forwarding --from-json $path2 --profile $profile

C. List Session : OciBastionListSession.sh

#!/bin/bash
export bastion_id=ocid1.bastion.oc1.ap-sydney-1.amaaaaaa*********qp4q
export profile=DEMO
oci bastion session list --bastion-id $bastion_id --session-lifecycle-state ACTIVE --sort-order asc --profile $profile --all

D. Get Session Details : OciBastionGetSession.sh

#!/bin/bash
export session_id=ocid1.bastionsession.oc1.ap-sydney-1.amaaaaaa***********zvq
export profile=DEMO
oci bastion session get --session-id $session_id --profile $profile

Oracle Developers

A community for developers by developers.

Oracle Developers

Aggregation of articles from Oracle engineers, Groundbreaker Ambassadors, Oracle ACEs, and Java Champions on all things Oracle technology. The views expressed are those of the authors and not necessarily of Oracle.

Shadab Mohammad

Written by

Principal Cloud Solutions Architect at Oracle

Oracle Developers

Aggregation of articles from Oracle engineers, Groundbreaker Ambassadors, Oracle ACEs, and Java Champions on all things Oracle technology. The views expressed are those of the authors and not necessarily of Oracle.