S3-Zugangsdaten

Last change on 2024-12-03 • Created on 2024-09-23 • ID: ST-30458

Warum brauche ich sowohl einen Access Key als auch einen Secret Key?

Die Keys dienen zwei verschiedenen Zwecken, weshalb in jedem Request beide Keys angegeben werden müssen.

  • Der Access Key liefert Informationen über Benutzer und deren Rechte. Der API-Service benötigt diesen Key, um zu bestimmen ob der Client die nötigen Berechtigungen für den Request besitzt (z.B. Datei hochladen oder lesen).
  • Der Secret Key wird benötigt, um festzustellen ob es einen Man-in-the-Middle-Angriff gab, bei welchem der Request verändert wurde. Mit dem Secret Key wird eine temporäre Signatur generiert. Diese Signatur wird genutzt, um den Request zu authentifizieren. Mit Tools wie s3cmd oder rclone wird die Signatur automatisch im Hintergrund erstellt.

Wie verwendet man den Access Key und den Secret Key?

Wie in "Wie kann ich auf meine Buckets zugreifen?" bereits erwähnt, muss bei jedem Request der Access Key angegeben werden und die Signatur, die mittels des Secret Keys erstellt wurde. In den meisten Fällen möchte man es vermutlich vermeiden, die Signatur selbst zu generieren, und dank Tools wie s3cmd oder rclone muss man das auch nicht. Damit gibt es zwei Optionen:

  • Tools wie s3cmd oder rclone nutzen, die automatisch eine Signatur erstellen. bevorzugte Option
  • Etwas wie beispielsweise HTTP-Requests nutzen und die Signatur selbst erstellen.

Mit Tools wie s3cmd oder rclone werden der Access Key und der Secret Key in einer Konfigurationsdatei hinterlegt. Nachdem die Keys einmal gespeichert wurden, müssen diese in künftigen Befehlen nicht mehr angegeben werden. Das Tool nutzt automatisch die hinterlegten Keys für alle wichtigen Schritte (Signatur erstellen, wichtige Informationen im Request ergänzen). Weitere Informationen und Beispielbefehle können in dem Getting Started S3-kompatible API-Tools verwenden nachgelesen werden.


Mit "manuellen" Requests muss man die Signatur selbst generieren und den Access Key, die Signatur, und weitere wichtige Informationen dem Request hinzufügen. Weitere Informationen können in Amazon S3 Docs » Authenticating REST Requests nachgelesen werden.

Was passiert während der Authentifizierung?

Beachten Sie, dass die folgenden Erklärungen sehr allgemein sind und zum besseren Verständnis vereinfacht wurden.

Wenn ein Request gesendet wird, sind zwei Parteien beteiligt:

CLIENT
  • symmetrischer Secret Key
  • Access Key
  • API-Service
  • symmetrischer Secret Key

    1. Bevor der Request gesendet wird, muss eine Signatur erstellt werden. Um die Signatur erstellen zu können, benötigt man einen "Intermediate Key" und einen "StringToSign". Mit dem persönlichen Secret Key und einem "Canonical Request" können jeweils der "Intermediate Key" und der "StringToSign" erstellt werden:

      • Secret Key » Intermediate Key
      • Canonical Request » StringToSign

      Object Storage verwendet einen HMAC-Hash als Intermediate Key und als Signatur. Um einen HMAC-Hash zu erstellen, verwendet HMAC eine kryptografische Hash-Funktion (z.B. AWS4-HMAC-SHA256), einen geheimen Schlüssel (z.B. Secret Key) und einen String (z.B. Datum) und wandelt diese Informationen in einen Hash.

      Intermediate Key:

      aws4_request ist ein feststehender String, der nicht geändert oder mit anderen Informationen ersetzt werden sollte.

      Intermediate_Key_First  = HMAC ( AWS4-HMAC-SHA256, Secret_Key, <Date> )
      Intermediate_Key_Second = HMAC ( AWS4-HMAC-SHA256, Intermediate_Key_First, <Region> )
      Intermediate_Key_Third  = HMAC ( AWS4-HMAC-SHA256, Intermediate_Key_Second, <Service> )
      Intermediate_Key_Final  = HMAC ( AWS4-HMAC-SHA256, Intermediate_Key_Third, aws4_request )

      Der Client muss einen Canonical Request angeben. Dieser enthält noch keine Keys. Es wird lediglich in String-form angegeben, was man ausführen möchte. Der Canonical Request muss in einem standardisierten String-Format angegeben werden, welches die HTTP-Methode (z.B. PUT, DELETE), die URL, den Query-Parameter, Header und andere Informationen enthält. Der Canonical Request wird gespeichert (z.B. in einer Datei namens canonical_request.creq) und anschließend im StringToSign ergänzt.

      StringToSign:

      AWS4-HMAC-SHA256                  # Hash function
      <date_and_time>                   # Timestamp
      <date>/<location>                 # Scope
      SHA256( canonical_request.creq )  # SHA256-Hash vom Canonical Request

    2. Mit dem finalen Intermediate Key wird der HMAC-SHA256-Hash vom StringToSign generiert. Der generierte HMAC-SHA256-Hash wird als einzigartige Signatur verwendet:

      Signature = HMAC ( AWS4-HMAC-SHA256, Intermediate_Key_Final, StringToSign )

    3. Als nächstes erstellt der Client den tatsächlichen Request und ergänzt Folgendes:

      • Den Access Key
      • Die einzigartige Signatur
      • Die Informationen, die genutzt wurden, um die Intermediate Keys und den StringToSign zu erstellen (z.B. Timestamp)

      Dieser Request wird an den API-Service geschickt.


    4. Nachdem der API-Service den Request empfängt, passiert Folgendes:

      • Der Service nutzt den Access Key, um zu prüfen, ob der Client die notwendigen Berechtigungen für die Anfrage besitzt.
      • Der Service nutzt den Secret Key, welcher zu dem Access Key aus dem Request gehört, um den ersten Intermediate Key zu erstellen. Der Secret Key ist ein symmetrischer Key. Der API-Service sollte daher denselben Intermediate Key erhalten wie der Client. Als nächstes erstellt der Service den finalen Intermediate Key und den StringToSign auf dieselbe Weise, wie es der Client getan hat und verwendet diese, um die einzigartige Signatur zu erstellen.

    5. Im vorherigen Schritt hat der API-Service seine eigene Signatur erstellt. Wenn die Signatur des API-Services identisch zu der Signatur des Clients ist und der Client die notwendigen Berechtigungen besitzt, führt der API-Service den API-Request entsprechend aus.

    Was ist meine Object Storage User-ID?

    Um die User-ID zu erhalten, muss das Präfix p vor die Projekt-ID gesetzt werden. Um auf einen bestimmten Key zu verweisen, müssen am Ende ein Doppelpunkt und der Access Key ergänzt werden.

    • Alle Keys innerhalb desselben Projekts

      p<project_id>
    • Ein einzelner Key

      p<project_id>:<access_key>

    Um die Projekt-ID herauszufinden, kann man beispielsweise das entsprechende Projekt in der Cloud Console öffnen und die Projekt-ID der URL entnehmen:

    https://console.hetzner.cloud/projects/<project-ID>/servers

    Beispiel:

    cloud console project id de

    Aus den Informationen aus dem Beispielbild, ergibt sich folgende ID:

    p1231234:MJ9VO12DNIH0DHLYOT75

    Wie begrenze ich die Zugriffsrechte eines einzelnen Keys?

    Jedes "Access Key & Secret Key"-Paar kann automatisch für jeden Bucket innerhalb desselben Projekts verwendet werden.

    Bei der Verwaltung von Berechtigungen wird oft empfohlen, dem Least-Privilege-Prinzip zu folgen. Das bedeutet, einem Nutzer zunächst nur die Berechtigungen zuzuweisen, die dieser tatsächlich benötigt. Zusätzliche Berechtigungen werden nur nach Bedarf gewährt. Dieser Ansatz stellt sicher, dass Nutzer nur Zugriff auf die Ressourcen haben, die sie benötigen, was die Sicherheit erhöht.

    Keys sollten daher im besten Fall nur an Nutzer herausgegeben werden, denen Sie vertrauen. Wenn Sie einem Nutzer nicht vollständig vertrauen oder schlicht die Sicherheit erhöhen möchten, gibt es folgende Möglichkeiten:

    • Separate Projekte nutzen für jede "Gruppe an Nutzern", die Zugriff auf dieselben Buckets benötigen und die Buckets jeweils in den entsprechenden Projekten hinzufügen.
    • Keys und Buckets im selben Projekt speichern, über Bucket-Richtlinien den gesamten Zugriff auf einen bestimmten Bucket blockieren und für ausgewählte Keys Ausnahmen hinzufügen.
    • Keys und Buckets in unterschiedlichen Projekten speichern und über Bucket-Richtlinien einzelnen Keys den Zugriff erlauben.

    Im Folgenden wird erklärt, wie man die beiden oben genannten Richtlinien beispielsweise einrichten kann.


    • Den gesamten Zugriff auf einen bestimmten Bucket blockieren und für ausgewählte Keys Ausnahmen hinzufügen

      Für Details zu p<project_id>:<access_key>, siehe diesen FAQ-Eintrag.

      {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Sid": "DenyAllUsersButOne",
            "Effect": "Deny",
            "Action": "s3:*",
            "Resource": [
              "arn:aws:s3:::<bucket_name>",
              "arn:aws:s3:::<bucket_name>/*"
            ],
            "NotPrincipal": {
              "AWS": "arn:aws:iam:::user/p<project_id>:<access_key>"
            }
          }
        ]
      }

    • Einzelnen Keys den Zugriff erlauben

      Dieses Beispiel geht davon aus, dass die Keys und Buckets in separaten Projekten gespeichert wurden, um die Sicherheit zu erhöhen.

      Hinweis: In dem Projekt mit den Buckets muss mindestens ein Key-Paar angelegt werden, mit dem die Bucket-Richtlinien angewendet werden können.

      Projekt S3 credentials
      access_key_1
      secret_key_1
      access_key_2
      secret_key_2
      Projekt Buckets
      bucket1.fsn1.your-objectstorage.com
      bucket2.fsn1.your-objectstorage.com
      bucket3.fsn1.your-objectstorage.com

      Für Details zu p<project_id>:<access_key>, siehe diesen FAQ-Eintrag.

      {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
              "AWS": "arn:aws:iam:::user/p<project_id>:<access_key>"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::your-bucket-name",
                "arn:aws:s3:::your-bucket-name/*"
                ]
          }
        ]
      }

    Der Befehl zum Anwenden der Zugriffs-Richtlinien unterscheidet sich je nach S3-kompatiblen Tool. Prüfen Sie für weitere Informationen daher die Dokumentation des Tools, das Sie verwenden. Mit dem MinIO Client würde der Befehl beispielsweise so aussehen:

    mc anonymous set-json my-policy.json <alias_name>/<bucket_name>
    Table of Contents