Implementieren von Sicherheitskontrollen für Azure Container Instances

Abgeschlossen

Azure Container Instances (ACI) führen containerisierte Workloads aus, ohne dass Sie die zugrunde liegende Infrastruktur verwalten müssen. Diese Einfachheit kann die Sicherheitssteuerelemente verdecken, für die Sie verantwortlich sind: wie sich der Container bei anderen Azure-Diensten authentifiziert, wie er vertrauliche Konfiguration empfängt, ob er aus dem öffentlichen Internet erreichbar ist und was der ausgeführte Prozess auf dem Host tun kann. Diese Einheit schließt die Lücke zwischen einer ACI-Standardbereitstellung und einer, die die Sicherheitsanforderungen des Unternehmens erfüllt.

Zuweisen verwalteter Identitäten zu Containergruppen

Eine verwaltete Identität ist eine Microsoft Entra ID-Identität, die von Azure automatisch verwaltet wird – Sie müssen dafür keine Anmeldeinformationen erstellen oder erneuern. Containergruppen unterstützen sowohl vom System zugewiesene Identitäten (erstellt mit der Gruppe als auch gelöscht, wenn die Gruppe gelöscht wird) und von Benutzern zugewiesene Identitäten (sind unabhängig voneinander vorhanden und können über Ressourcen hinweg freigegeben werden).

Mit einer verwalteten Identität kann sich der Container bei Azure Key Vault, Azure Container Registry, Azure Storage und jedem anderen Azure-Dienst authentifizieren, der die Microsoft Entra-Authentifizierung unterstützt, ohne Anmeldeinformationen in der Containerkonfiguration zu speichern.

Weisen Sie beim Erstellen der Containergruppe eine vom System zugewiesene Identität zu:

az container create \
  --resource-group <rg> \
  --name <container-group-name> \
  --image <image-name> \
  --assign-identity

Nachdem die Identität zugewiesen wurde, gewähren Sie ihr die benötigten RBAC-Rollen, z. B. Key Vault Secrets User, um geheime Schlüssel aus Key Vault zu lesen, oder AcrPull, um Bilder aus einer privaten Containerregistrierung abzurufen.

Auf Key Vault-Geheimnisse statt auf Klartext-Umgebungsvariablen verweisen

Die häufigste Sicherheitslücke für Anmeldeinformationen in Container Instances Bereitstellungen besteht darin, vertrauliche Konfigurationen – Datenbankverbindungszeichenfolgen, API-Schlüssel, Speicherkontoanmeldeinformationen – als Nur-Text-Umgebungsvariablen zu übergeben. Klartextwerte werden im Bereitstellungsverlauf, in den Metadaten der Containergruppe, die für jeden mit Leserzugriff auf die Ressource sichtbar sind, und in der Quellcodeverwaltung angezeigt, wenn die Vorlage eingecheckt wird.

Die sichere Alternative besteht darin, geheime Schlüssel in Azure Key Vault zu speichern und durch geheimen URI in der Containergruppendefinition auf sie zu verweisen. Wenn eine verwaltete Identität zugewiesen ist und die Key Vault Secrets User Rolle gewährt wurde, ruft die Containergruppe den geheimen Wert zur Laufzeit ab, ohne dass der Wert im Bereitstellungsmanifest angezeigt wird.

Verweisen Sie in einer Bicep-Vorlage mithilfe von secureValue auf ein Key Vault-Geheimnis:

environmentVariables: [
  {
    name: 'DB_CONNECTION_STRING'
    secureValue: keyVaultRef.getSecret('db-connection-string')
  }
]

Important

Verwenden Sie secureValue statt value für jede Umgebungsvariable, die vertrauliche Daten enthält. Als secureValue festgelegte Werte werden im Ruhezustand verschlüsselt und nicht in GET Vorgängen in der Containergruppe zurückgegeben – sie werden nicht im Azure Portal, in der CLI-Ausgabe oder in API-Antworten angezeigt.

Bereitstellen von Containern in einem virtuellen Netzwerk

Standardmäßig erhalten Container Instances eine öffentliche IP-Adresse und sind über das Internet erreichbar. Die Integration des virtuellen Netzwerks entfernt die Exposition des öffentlichen Netzwerks, indem die Containergruppe in einem Subnetz eines vorhandenen virtuellen Netzwerks bereitgestellt wird. Die Container empfangen private IP-Adressen und sind nicht von außerhalb des virtuellen Netzwerks erreichbar.

Um sie in einem virtuellen Netzwerk bereitzustellen, delegieren Sie zuerst ein Subnetz an Microsoft.ContainerInstance/containerGroups:

az network vnet subnet update \
  --resource-group <rg> \
  --vnet-name <vnet-name> \
  --name <subnet-name> \
  --delegations Microsoft.ContainerInstance/containerGroups

Erstellen Sie dann die Containergruppe, die das virtuelle Netzwerk und das Subnetz angibt:

az container create \
  --resource-group <rg> \
  --name <container-group-name> \
  --image <image-name> \
  --vnet <vnet-name> \
  --subnet <subnet-name>

In einem VNet bereitgestellte Containergruppen können private Endpunkte – einschließlich eines privaten ACR-Endpunkts und eines privaten Key Vault-Endpunkts – erreichen, ohne den Datenverkehr über das öffentliche Internet zu leiten. Dies ist die empfohlene Netzwerkkonfiguration für Containerarbeitslasten, die vertrauliche Daten verarbeiten.

Note

Nicht alle Container Instances Features sind in virtuellen Netzwerkbereitstellungen verfügbar. Lesen Sie die Dokumentation zu virtuellen Netzwerkszenarien und Ressourcen für aktuelle Einschränkungen, bevor Sie diese Konfiguration entwerfen.

Anwenden von Sicherheitskontexteinstellungen auf Containerebene

Container Instances unterstützen Sicherheitskontexteinstellungen, die einschränken, was ein Containerprozess auf seinem Host ausführen kann. Zwei Steuerelemente eignen sich zum Härten von Arbeitslasten.

Als Nicht-Root ausführen: Standardmäßig werden Containerprozesse als root (Benutzer-ID 0) ausgeführt, sofern im Container-Image nichts anderes angegeben ist. Konfigurieren Sie runAsUser und runAsGroup im Sicherheitskontext des Containers, um den Prozess als nicht privilegierter Benutzer auszuführen. Wenn ein Angreifer einen Ausbruch aus dem Container findet, verfügt er nur über eingeschränkte Berechtigungen auf Betriebssystemebene statt über vollständigen Root-Zugriff.

Schreibgeschütztes Stammdateisystem: Durch die Einstellung readOnlyRootFilesystem: true wird verhindert, dass der Containerprozess in das Stammdateisystem des Containers geschrieben wird. Alle Schreibvorgänge müssen explizit konfigurierte emptyDir Volumes durchlaufen. Dadurch wird verhindert, dass ein Angreifer Binärdateien oder Konfigurationsdateien im Containerdateisystem ändert.

securityContext:
  runAsUser: 1000
  runAsGroup: 3000
  readOnlyRootFilesystem: true

Verwenden Sie beide Einstellungen für Produktionsworkloads. Wenn Ihre Anwendung Protokolle oder temporäre Dateien schreibt, stellen Sie ein emptyDir Volume für diese Pfade ein, bevor Sie das schreibgeschützte Stammdateisystem aktivieren.

Abrufen von Bildern von ACR mithilfe der verwalteten Identität

Container Instances, die Bilder aus einer privaten Azure Container Registry abrufen, benötigen eine Möglichkeit, sich zu authentifizieren. Wenn die Anmeldeinformationen des ACR-Administratorkontos als Geheimnisse in der Konfiguration der Containergruppe gespeichert werden, entsteht dasselbe Problem mit gemeinsam genutzten Anmeldeinformationen wie bei der direkten Verwendung des Administratorkontos: Jeder Workload mit Zugriff auf das Geheimnis kann sich als diese gemeinsam genutzte Identität authentifizieren.

Der richtige Ansatz besteht darin, die verwaltete Identität der Containergruppe der AcrPull Rolle in der Registrierung zuzuweisen und dann auf diese Identität als Image-Pull-Identität zu verweisen:

az role assignment create \
  --assignee <managed-identity-principal-id> \
  --role AcrPull \
  --scope /subscriptions/<subscription-id>/resourceGroups/<rg>/providers/Microsoft.ContainerRegistry/registries/<registry-name>

az container create \
  --resource-group <rg> \
  --name <container-group-name> \
  --image <registry-name>.azurecr.io/<image-name>:<tag> \
  --assign-identity <identity-resource-id> \
  --acr-identity <identity-resource-id>

Bei diesem Ansatz werden gespeicherte Anmeldeinformationen vollständig beseitigt. Die Containergruppe authentifiziert sich gegenüber ACR mithilfe des Tokens der verwalteten Identität, das von Azure automatisch rotiert wird. Wenn Administratoren dies mit der Deaktivierung des ACR-Administratorkontos kombinieren, wird die Lücke bei den gemeinsamen Anmeldeinformationen für den Image-Abrufpfad geschlossen.