You are currently viewing Establish a VPN with Oracle OCI with a dynamic public IP ADDRESS on CPE

Establish a VPN with Oracle OCI with a dynamic public IP ADDRESS on CPE

Oracle Cloud Infrastructure (OCI) does not support the use of Domain Name System (DNS) for configuring the Customer Premises Equipment (CPE) as the VPN tunnel endpoint. This tutorial aims to enable small businesses that do not have access to a static public IP address to use the IPSec service even with a dynamic address. The strategy involves deploying a script capable of automatically generating a new OCI tunnel whenever the public IP of the Customer Premises Equipment (CPE) changes.

In this tutorial, the last two lines in the shell script file are used to update the IP address and shared secret of the new endpoint created on OCI within my router (MikroTik). Depending on your router, you need to update it to reflect these two values.


Create a new Oracle Cloud Infrastructure Site-to-Site VPN tunnel with the new updated CPE IP address.


  • A dynamically update DNS record that point to your public CPE IP ADDRESS
  • A Linux virtual machine (VM).
  • OCI CLI installed and configured
  • Generate an API key (link)
  • Install'sshpass' into the Linux VM. In this tutorial, this will be used to send commands to the MikroTik router.

1 – To achieve a stable VPN IPSEC connection with Oracle OCI that survive to a CPE IP ADDRESS update you have to setup a dynamically update DNS name. There are several public DNS providers that support this feature. Choose your favorite and configure it (ex:

After you have registered and configured a public dynamic DNS record, you can set up your linux VM.

2 – Once the VM is up and running, install and configure the OCI CLI to operate on your OCI tenancy from this machine.

3 – Install the Sshpass application in case you need to use it for update your private router settings (sudo apt-get install Sshpass).

4 – Create the .sh file (ex: nano and copy the following script in the file and make it executable. Remember to modify the script with your data, the compartment ID, DRG ID and DNS name that points to your CPE. (You can find the oci path executing this command into your terminal: ‘which oci’).

   #OCI variables
   export compartment_id=ocid1.compartment.oc1…  #your OCI compartment ID
   export… #your DRG ID

   #Mikrotik variables
   export static_routes= #(YOUR PRIVATE SUBNET)
   export router_ip= #(YOUR ROUTER PRIVATE IP ADDRESS)
   export router_user=USER #(YOUR ROUTER USER)
   export router_password=PWD #(YOUR ROUTER PASSWORD)

   #oci command path (to find the path of oci command type 'which oci' into the terminal)
   export oci_path=PATH #(YOUR oci COMMAND PATH. example: /home/ubuntu/bin/oci)

   export ip_address=$(ping -c 1 $DNS_cpe | gawk -F'[()]' '/PING/{print $2}')
   check_out=$($oci_path network ip-sec-connection list --compartment-id $compartment_id --all --query "data[?\"cpe-local-identifier\"=='$ip_address']" | sed 's|[[]]||g')

   if [[ -n $check_out ]]
       printf -- "%s\n" "IP of the CPE is not changed - EXIT"

       printf -- "%s\n" "create new IPSEC tunnel"

   cpe_id=$($oci_path network cpe create --compartment-id $compartment_id --ip-address $ip_address --query --raw-output)
   $oci_path network cpe update --cpe-id $cpe_id

   ipsc_id=$($oci_path network ip-sec-connection create --compartment-id $compartment_id --cpe-id $cpe_id --drg-id $drg_id --static-routes '["$static_routes"]' --query --raw-output)
   $oci_path network ip-sec-connection update --ipsc-id $ipsc_id

   tunnel_id1=$($oci_path network ip-sec-tunnel list --ipsc-id=$ipsc_id --all --query 'data[0].id' --raw-output)
   tunnel_id2=$($oci_path network ip-sec-tunnel list --ipsc-id=$ipsc_id --all --query 'data[1].id' --raw-output)

   ip_sec_psk1=$($oci_path network ip-sec-psk get --ipsc-id=$ipsc_id --tunnel-id=$tunnel_id1 | grep -oP '(?<="shared-secret": ").*(?=")')
   ip_sec_psk2=$($oci_path network ip-sec-psk get --ipsc-id=$ipsc_id --tunnel-id=$tunnel_id2 | grep -oP '(?<="shared-secret": ").*(?=")')

   vpn_ip1=$($oci_path network ip-sec-tunnel list --ipsc-id=$ipsc_id --all --query 'data[0]."vpn-ip"' --raw-output)
   vpn_ip2=$($oci_path network ip-sec-tunnel list --ipsc-id=$ipsc_id --all --query 'data[1]."vpn-ip"' --raw-output)

   echo $vpn_ip1
   echo $ip_sec_psk1

   echo $vpn_ip2
   echo $ip_sec_psk2

   #Mikrotik router update section. (Execute the sshpass command before run this script). Avoid and delete these two rows if you don't need it.

   sshpass -p '$router_password' ssh $router_user@$router_ip "/ip ipsec/ identity/ set number=0 secret=$ip_sec_psk1"
   sshpass -p '$router_password' ssh $router_user@$router_ip "/ip ipsec/ peer/ set number=0 address=$vpn_ip1"

Make it executable:

chmod +x

The last part of the script (The Mikrotik router section) is intended just if in you have a Mikrotik router. Otherwise you have to implement the commands to update the ORACLE OCI tunnel endpoint IP ADDRESS and the shared secret into your router.

The script can create the tunnels but cannot terminate the old ones. Sometimes you have to log in into the OCI web console and terminate the unused old VPN tunnels or implement this function into it.

5 – Add the script to the crontab if you want automatically execute it.

Crontab -e

Add the frequency and the script path into the last line of the crontab. The following command is intended to be executed every 15 minutes.

*/15 * * * * YOUR_SCRIPT_PATH/

Done! Next time your CPE IP address changes, the OCI tunnel will be recreated with the new IP address and shared secret within a maximum of 15 minutes.

Published on Oracle Help Center

Related Links

Leave a Reply