Configuring Instances for Calling Services

A Private Cloud Appliance compute instance can be configured to enable applications running on the instance to call services and manage resources similar to the way Private Cloud Appliance users call services to manage resources.

The IAM service feature that enables instances to be authorized actors (or principals) to perform actions on service resources is called an instance principal.

Perform the following steps to set up and use an instance as a principal:

Configuring Instance Firewalls to Allow Calling Services

This topic describes how to modify the instance firewall configuration and how to create a systemd service to restore the changes if the system reboots.

Modify the Firewall Configuration

As a privileged user, modify the instance firewall configuration to enable the instance to access service endpoints such as iaas and identity.

Use the iptables command to add the following BareMetalInstanceServices rules to the instance firewall:

iptables -I BareMetalInstanceServices 14 -p tcp -d 169.254.169.254 --dport 443 -j ACCEPT
iptables -I BareMetalInstanceServices 14 -p tcp -d 169.254.240.254 --dport 443 -j ACCEPT

The first entry is required for all endpoints. The second entry is required to contact the Object Storage endpoint.

Make the Configuration Changes Persistent

Use the following procedure to make these firewall configuration changes persist across instance reboots.

  1. Save the updated IP tables configuration.

    iptables-save > /etc/sysconfig/iptables.rules
  2. Create a script to automatically restore the current (modified) firewall configuration on reboot.

    In this example, the script is named /sbin/restore-iptables.sh. The following is the content of the file /sbin/restore-iptables.sh:

    #!/bin/sh
    /sbin/iptables-restore < /etc/sysconfig/iptables.rules
  3. Set executable bit on the script.

    chmod +x /sbin/restore-iptables.sh
  4. Create a systemd oneshot service to execute the /sbin/restore-iptables.sh script at boottime.

    In this example, the service is named /etc/systemd/system/restore-iptables.service. The following is the content of the file /etc/systemd/system/restore-iptables.service:

    [Unit]
    Description=Restore IP Tables
    After=cloud-final.service
    
    [Service]
    ExecStart=/sbin/restore-iptables.sh
    User=root
    Group=root
    Type=oneshot
    
    [Install]
    WantedBy=multi-user.target
  5. Reload the systemd manager configuration, and enable the service to run at boot time.

    systemctl daemon-reload
    systemctl enable restore-iptables

Configuring Instance Certificates to Allow Calling Services

By default, Private Cloud Appliance endpoints (such as iaas and identity) offer a certificate that is signed by a CA that is specific to that appliance. By default, operating systems do not trust certificates that are signed by a CA that is specific to this Private Cloud Appliance. If the OS does not trust the certificates that are offered, attempts to use the OCI SDK or OCI CLI will fail with a CERTIFICATE_VERIFY_FAILED error.

Implement one of the solutions described in this topic to successfully use the OCI SDK or OCI CLI on the instance.

Note:

Any user who can SSH to the instance automatically inherits the privileges granted to the instance.

Option 1: Bring Your Own Certificate (BYOC)

If you have a certificate that is signed by a CA that your OS trusts, configure the Private Cloud Appliance to offer that certificate.

On a Linux OS, the following command lists CAs that are trusted by default:

trust list --filter=ca-anchors

For information about how to provide your own certificate, see "Accessing External Interfaces with Your CA Trust Chain" in the Hardware Administration chapter of the Oracle Private Cloud Appliance Administrator Guide.

Option 2: Specify in the SDK Code the CA Bundle to Use

This method copies the appliance-specific CA bundle to the instance, but does not verify the server's certificate (--insecure). To ensure security, verify the content of the retrieved bundle (external_ca.crt).

  1. Retrieve the certificate from the iaas endpoint of the appliance.

    curl --insecure -sS -o external_ca.crt --noproxy "*" https://iaas.pca_name.domain_name/cachain

    This command could be in a script that is passed to the instance at launch time by using either the --user-data-file option or the --metadata option with a user_data field. The script will be run by cloud-init inside the instance during init, saving the effort of manually retrieving this certificate file on a large number of instances.

  2. Verify the content of the CA bundle saved in the external_ca.crt file.

  3. Specify the CA bundle in the Python SDK code.

    signer = oci.auth.signers.InstancePrincipalsSecurityTokenSigner(
        federation_client_cert_bundle_verify="/home/opc/external_ca.crt"
    )
    identity_client = oci.identity.IdentityClient(config={}, signer=signer)
    identity_client.base_client.session.verify = "/home/opc/external_ca.crt"

Option 3: Globally Trust the Private Cloud Appliance CA Bundle

This method is the same as the preceding method with the following difference: Instead of specifying the CA bundle in the SDK code, this method adds the CA bundle to the trust chain.

Note:

When the CA bundle is added to the trust chain, every application on this compute instance will trust certificates signed with the CA specified in this bundle. Consider whether this is an acceptable security risk.

  1. Retrieve the certificate from the iaas endpoint of the appliance.

    curl --insecure -sS -o external_ca.crt --noproxy "*" https://iaas.pca_name.domain_name/cachain
  2. Verify the content of the CA bundle saved in the external_ca.crt file.

  3. Update the global CA trust chain.

    cp external_ca.crt /etc/pki/ca-trust/source/anchors/
    update-ca-trust extract

Steps 1 and 3 in this method could be in a script that is passed to the instance at launch time by using either the --user-data-file option or the --metadata option with a user_data field. The script will be run by cloud-init inside the instance during init, saving the effort of performing these steps manually on a large number of instances.

Configuring Python SDK and OCI CLI for Instance Principals

This topic describes how to enable instance principal authorization for the Python SDK, OCI CLI, or Terraform.

Enabling Instance Principal Authorization for the Python SDK

In your SDK for Python, create an oci.auth.signers.InstancePrincipalsSecurityTokenSigner object as shown in the following example:

# By default this will hit the auth service in the region returned by http://169.254.169.254/opc/v1/instance/region on the instance.
			
signer = oci.auth.signers.InstancePrincipalsSecurityTokenSigner()
identity_client = oci.identity.IdentityClient(config={}, signer=signer)

To refresh the token without waiting, use the following command:

signer.refresh_security_token()

Enabling Instance Principal Authorization for the OCI CLI

Set the authorization option (--auth) for a command as shown in the following example:

oci os ns get --auth instance_principal

Alternatively, set the following environment variable:

OCI_CLI_AUTH=instance_principal

If both are set, the value set for --auth takes precedence over the environment variable.

Enabling Instance Principal Authorization for Terraform

Set the auth attribute to "InstancePrincipal" in the provider definition as shown in the following example:

variable "region" {}

provider "oci" {
   auth = "InstancePrincipal"  
   region = "${var.region}"

}

When you use instance principal authorization you do not need to include the tenancy_ocid, user_ocid, fingerprint, and private_key_path attributes.