Hinweis:

Automatische Rotation von Oracle Cloud Infrastructure Identity and Access Management-Zugangsdaten aktivieren

Einführung

In diesem Tutorial können Sie Oracle Cloud Infrastructure Identity and Access Management-(OCI IAM-)Zugangsdaten automatisch rotieren, die API-Schlüssel, Authentifizierungstoken, Kunden-Secret-Keys und Anmeldekennwörter der OCI-Konsole sind. Sie basiert auf der Problembehebung mit Oracle Cloud Guard und dem OCI Notifications-Service. Außerdem erfüllt es die Lücke der Standard-Responder-Regeln zum Rotieren der OCI-IAM-Zugangsdaten.

Oracle Cloud Guard erkennt Probleme basierend auf Regeln, die in den Policys definiert sind. Sobald eine Regel erfüllt ist, entsteht ein Problem.

Es ist eine Best Practice zur Sicherheit und wird von der Center for Internet Security Oracle Cloud Infrastructure Foundations (CIS OCI Foundations)-Benchmark empfohlen, die Zugangsdaten alle 90 Tage zu rotieren.

Hinweis: Diese Lösung wurde für eine Standardidentitätsdomain getestet.

Ziele

Voraussetzungen

OCI-IAM-Administrator muss Folgendes erstellen:

Aufgabe 1: OCI-Funktionen erstellen und bereitstellen

  1. Melden Sie sich bei der OCI-Konsole an, und klicken Sie in der oberen Navigation auf Cloud Shell.

    Hinweis: Sie können auch ein eigenes IDE-Tool verwenden, um eine Funktion zu erstellen und bereitzustellen.

  2. Erstellen Sie eine Funktion mit der Fn-Projekt-CLI aus der cloud shell. Weitere Informationen finden Sie unter Hloworld-Funktion erstellen, bereitstellen und aufrufen.

    fn init --runtime python <function-name>
    
    Example: fn init --runtime python rotatecred-func
    
  3. Ändern Sie das Verzeichnis in das neu erstellte Verzeichnis.

  4. Erstellen Sie eine App, um die Funktion mit dem folgenden Befehl bereitzustellen.

    # Specify the OCID of subnet
    fn create app <app-name> --annotation oracle.com/oci/subnetIds='["<subnet OCID>"]'
    
    Example:  fn create app rotatecredapp --annotation oracle.com/oci/subnetIds='["ocid1.subnet.oc1.ap-mumbai-1.aaaaaaaabitp32dkyox37qa3tk3evl2nxivwb....."]'
    
  5. Kopieren Sie das folgende Skript, und fügen Sie es in die Datei func.py ein, indem Sie den vorhandenen Inhalt überschreiben.

    # python script for auto rotation of OCI IAM credentials
    import io
    import json
    import logging
    import oci
    import base64
    from fdk import response
    from Cryptodome.PublicKey import RSA
    
    # Get Resource Principal Credentials
    signer = oci.auth.signers.get_resource_principals_signer()
    
    # Initialize client
    identity_client = oci.identity.IdentityClient(config={}, signer=signer)
    onsclient = oci.ons.NotificationDataPlaneClient(config={}, signer=signer)
    vault_client = oci.vault.VaultsClient(config={}, signer=signer)
    
    # Get tenancy id and name
    tenancy_data = identity_client.get_tenancy(tenancy_id=signer.tenancy_id).data
    t_name = str(tenancy_data.name)
    t_id = signer.tenancy_id
    
    # Get secret OCID from comments
    def get_secret_ocids(comments_items,find_name):
       secret_ocid = ""
       for comment in comments_items:
          if comment.split(":")[0] == find_name:
                secret_ocid = comment.split(":")[1]
       return secret_ocid
    
    # Function to store secret in OCI vault
    def update_secret(vault_client,secret_id,new_value):
       # Base64 encode
       new_token_ascii = new_value.encode("ascii")
       base64_bytes = base64.b64encode(new_token_ascii)
       base64_string = base64_bytes.decode("ascii")
    
       # Create new version of secret
       vault_client.update_secret(secret_id=secret_id,update_secret_details=oci.vault.models.UpdateSecretDetails(secret_content=oci.vault.models.Base64SecretContentDetails(content_type="BASE64", content=base64_string)))
    
    def handler(ctx, data: io.BytesIO=None):
       try:
          cfg = ctx.Config()
          ons_topic = cfg["ons_topic"]
          body = json.loads(data.getvalue())
    
          # Get common parameters values
          e_time = str(body["eventTime"]).lstrip()
          problem_name = str(body["data"]["additionalDetails"]["problemName"]).lstrip()
          status = "NOT RESOLVED"
          resource_name = str(body["data"]["resourceName"]).lstrip()
          user_ocid = str(body["data"]["additionalDetails"]["problemAdditionalDetails"]["User OCID"]).lstrip()
          target_resource_name = str(body["data"]["additionalDetails"]["resourceName"]).lstrip()
          target_resource_id = str(body["data"]["additionalDetails"]["resourceId"]).lstrip()
          risk_level = str(body["data"]["additionalDetails"]["riskLevel"]).lstrip()
          comments = str(body["data"]["additionalDetails"]["problemAdditionalDetails"]["comments"]).lstrip()
          comments_items = comments.split(",")
          additional_details = "\r\r\nAction : Closure comments was not in required format hence, no action by automation."
    
          try:
                # Check Problem Type
                if problem_name == "PASSWORD_TOO_OLD":
                   identity_client.create_or_reset_ui_password(user_id=user_ocid)
                   additional_details = "\r\r\nAction : Your password has been reset by the System Administrator as per password policy rotation. Please set new password by clicking on forgot password from OCI console. "
                   status = "RESOLVED"
    
                elif problem_name == "AUTH_TOKEN_TOO_OLD":
                   auth_secret_ocid = get_secret_ocids(comments_items,"auth_secret_ocid")
                   if auth_secret_ocid != "":
                      # Delete existing auth token
                      identity_client.delete_auth_token(user_id=user_ocid, auth_token_id=target_resource_id)
                      # Create new auth token
                      create_auth_token_response = identity_client.create_auth_token(
                      create_auth_token_details=oci.identity.models.CreateAuthTokenDetails(description=target_resource_name),user_id=user_ocid).data
                      new_value = create_auth_token_response.token
                      # Store new auth token in vault secret
                      update_secret(vault_client,auth_secret_ocid,new_value)
                      additional_details = '\r\nAuth Token - Secret OCID : ' + auth_secret_ocid
                      status = "RESOLVED"
    
                elif problem_name == "SECRET_KEY_TOO_OLD":
                   access_id_secret_ocid = get_secret_ocids(comments_items, "accesskey_secret_ocid")
                   secret_key_secret_ocid = get_secret_ocids(comments_items, "secretkey_secret_ocid")
                   if access_id_secret_ocid != "" and secret_key_secret_ocid != "":
                      # Delete existing customer secrete key
                      delete_secret_key_response = identity_client.delete_customer_secret_key(user_ocid, target_resource_id).data
                      # Create new customer secret key
                      create_customer_secret_key_response = identity_client.create_customer_secret_key(create_customer_secret_key_details=oci.identity.models.CreateCustomerSecretKeyDetails(display_name=target_resource_name),user_id=user_ocid).data
                      new_secret_key = str(create_customer_secret_key_response.key)
                      new_access_key_id = str(create_customer_secret_key_response.id)
                      # Store new customer secret key in vault secret
                      update_secret(vault_client,secret_key_secret_ocid,new_secret_key)
                      update_secret(vault_client,access_id_secret_ocid,new_access_key_id)
                      additional_details = '\r\nAccess Key - Secret OCID : ' + access_id_secret_ocid + \
                               '\r\nSecret Key - Secret OCID : ' + secret_key_secret_ocid
                      status = "RESOLVED"
    
                elif problem_name == "API_KEY_TOO_OLD":
                   key_fingerprint = target_resource_id.split("/")[2]
                   api_secret_ocid = get_secret_ocids(comments_items,"api_secret_ocid")
                   if api_secret_ocid != "":
                      key = RSA.generate(2048)
                      key_private = key.exportKey()
                      pubkey = key.publickey()
                      key_public = pubkey.exportKey()
                      # Delete existing API key
                      delete_api_key_response = identity_client.delete_api_key(user_id=user_ocid,fingerprint=key_fingerprint)
                      # Upload new public API key in OCI for the user
                      upload_api_key_response = identity_client.upload_api_key(user_id=user_ocid,
                                                                               create_api_key_details=oci.identity.models.CreateApiKeyDetails(
                                                                                     key=key_public.decode()))
                      # Store content of new private key in vault secret
                      update_secret(vault_client,api_secret_ocid,key_private.decode())
                      additional_details = '\r\nSecret OCID for private API key : ' + api_secret_ocid
                      status = "RESOLVED"
          except Exception as e:
                additional_details = '\r\r\n Error: '+ str(e)
    
          # Message Body Customization, it can be updated as per need
          line_head = 'Oracle Cloud Notification' + '\n====================='
          message_body = line_head + \
                         '\r\r\nProblem Name : ' + problem_name + \
                         '\r\r\nRisk Level : ' + risk_level + \
                         '\r\nEvent Time : ' + e_time + \
                         '\r\nTenancy Name : ' + t_name + \
                         '\r\nTenancy ID : ' + t_id + \
                         '\r\r\nAdditional Details : ' + '\n-------------------------' \
                         '\r\nResource Name : ' + target_resource_name + \
                         '\r\nResource ID : ' + target_resource_id + \
                         '\r\nResource User OCID : ' + user_ocid + ' ' + additional_details
    
          # Message Title
          message_title = 'Problem : ' + resource_name + ' | ' + status +' by automation '
    
          # Message Detail
          message_details = oci.ons.models.MessageDetails(body=message_body, title=message_title)
    
          # Publish message to ONS
          onsclient.publish_message(ons_topic, message_details)
    
       except (Exception, ValueError) as ex:
          logging.getLogger().info('error parsing json payload: ' + str(ex))
    
       return response.Response(ctx, response_data=json.dumps({"message": "success"}),headers={"Content-Type": "application/json"})
    
  6. Aktualisieren Sie requirements.txt wie unten gezeigt.

    fdk>=0.1.59
    oci
    pycryptodomex
    
  7. Führen Sie den folgenden Befehl aus, um die Funktion bereitzustellen.

    fn -v deploy --app <app-name>
    
    Example: fn -v deploy --app rotatecredapp
    
  8. Führen Sie den folgenden Befehl aus, um die Funktionskonfiguration für Konfigurationsschlüssel und -wert hinzuzufügen.

    • ons_topic: Verwenden Sie die Oracle Cloud-ID (OCID) des Benachrichtigungsthemas für den Empfang von E-Mail-Benachrichtigungen.
    fn config function <app-name> <function-name> <config-key> <config-value>
    
    Example: fn config function rotatecredapp rotatecred-func ons_topic ocid1.onstopic.oc1.ap-mumbai-1.aaaaaaaau3onlufcfz.......kae26637zovwd7q
    

Aufgabe 2: Ereignisregeln erstellen

  1. Gehen Sie zur OCI-Konsole, und klicken Sie auf Observability and Management.

  2. Klicken Sie im Events-Serviceauf Regeln und Regel erstellen.

  3. Geben Sie auf der Seite Regel erstellen den Namen für die Regel und die Beschreibung der jeweiligen Regel ein.

  4. Geben Sie im Abschnitt Regelbedingungen die folgenden Informationen ein, um den Ereignistyp und die Aktion zum Auslösen der Funktion anzugeben.

    • Bedingung: Event Type.
    • Service-Name: Cloud Guard.
    • Ereignistyp: Remediated-Problem.
    • Attributname: ProblemRecommendation.
    • Attributwerte:
      • Rotate IAM Console password regularly, at least every 90 days.,
      • Rotate IAM Auth token regularly, at least every 90 days.,
      • Rotate IAM Customer secret keys regularly, at least every 90 days.,
      • Rotate API keys regularly, at least every 90 days.

    Das folgende Image ist ein Beispiel für ein Problembehebungsereignis von Oracle Cloud Guard.

    image

Aufgabe 3: Oracle Cloud Guard-Problem beheben

  1. Gehen Sie zur OCI-Konsole, und klicken Sie auf Identität und Sicherheit.

  2. Klicken Sie unter Cloud Guard auf Probleme.

  3. Klicken Sie auf eines der unterstützten Probleme für die automatische Rotation.

  4. Klicken Sie auf Als gelöst markieren, und geben Sie die folgenden Informationen im Abschnitt Kommentar entsprechend dem folgenden Format ein. Sie können zusätzliche Informationen gemäß Ihrem Organisationsprozess zusammen mit den folgenden durch Kommas (,) getrennten Informationen hinzufügen.

    • IAM-Customer Secret-Schlüssel ist zu alt.

      accesskey_secret_ocid:<OCID of access key secret>,secretkey_secret_ocid:<OCID of secret key secret>,<additional comments>

      image

    • API-Schlüssel ist zu alt.

      api_secret_ocid:<OCID of api key secret>,<additional comments>

      image

    • IAM-Authentifizierungstoken ist zu alt.

      auth_secret_ocid:<OCID of auth token secret>,<additional comments>

      image

    • Kennwort ist zu alt.

      Hinweis:

      • Für Kommentare zu diesem Problem sind keine Informationen erforderlich.
      • Das Kennwort muss vom einzelnen Benutzer zurückgesetzt werden, indem bei der nächsten Anmeldung auf Kennwort vergessen geklickt wird. Der Benutzer muss über eine gültige E-Mail-Adresse verfügen, um E-Mail-Benachrichtigungen zu erhalten.

Aufgabe 4: Neue OCI IAM-Zugangsdaten und E-Mail-Benachrichtigung validieren

Sie erhalten eine E-Mail-Benachrichtigung zur Problemlösung mit Details zur rotierten Secret-OCID und weiteren Informationen.

image

Danksagungen

Weitere Lernressourcen

Lernen Sie andere Übungen auf docs.oracle.com/learn kennen, oder greifen Sie auf weitere kostenlose Lerninhalte im Oracle Learning YouTube Channel zu. Außerdem können Sie education.oracle.com/learning-explorer besuchen, um Oracle Learning Explorer zu werden.

Die Produktdokumentation finden Sie im Oracle Help Center.