Es ist sehr üblich, die von boto3 und dem aws -Client verwendeten AWS-Anmeldeinformationen in ~/.aws/config und ~/.aws/credentials einzurichten. Es gibt jedoch einige Sicherheitsrisiken, die Sie beachten sollten. In diesem Artikel erkläre ich die Risiken und Abhilfemaßnahmen, wenn Sie Skripte für Ihr(e) AWS-Konto(s) erstellen.
Die Risiken, die mit dieser Arbeitsweise verbunden sind, sind:
-
Langfristige Zeugnisse gehen irgendwann verloren
-
die versehentliche Ausführung von destruktivem Code
-
generische Rollen sind für bestimmte Aufgaben zu freizügig
-
Skripting ist keine Infrastruktur als Code
-
ohne mfa ist dies immer noch eine Einzelfaktorauthentifizierung
Ich werde im Folgenden auf jedes dieser Risiken eingehen.
Kompromittierte Anmeldeinformationen

Die in diesem Szenario häufig verwendeten Anmeldedaten sind unbegrenzt gültig. Je länger Sie ein Geheimnis unverändert lassen, desto höher ist die Wahrscheinlichkeit, dass es kompromittiert wird. Kürzlich hat das Center for Internet Security (CIS) in seinen AWS-Benchmarks die erforderliche Mindestrotationshäufigkeit von Anmeldeinformationen und Geheimnissen von 90 auf 45 Tage gesenkt! Wenn Sie die Zugangsdaten nicht selbst regelmäßig rotieren, funktionieren sie so lange, wie Ihr Konto existiert (tragen Sie eine regelmäßige Erinnerung in Ihren Kalender ein!). Wenn Sie Ihren Laptop auch nur eine Minute unbeaufsichtigt lassen, sollten Sie den Inhalt Ihres ~/.aws/credentials als kompromittiert betrachten, insbesondere wenn Sie sich an Orten aufhalten, an denen viele Cloud-Ingenieure arbeiten.
Es ist viel sicherer, überhaupt keine Langzeit-Anmeldedaten zu verwenden. Verwenden Sie stattdessen die Kurzzeit-Anmeldedaten, die Sie auf den sso-Seiten finden, sobald Sie diese eingerichtet haben:

Sie können einfach auf die Exportdaten klicken und sie in die Konsole einfügen, die Sie zum Ausführen des Skripts verwenden. Diese Anmeldeinformationen sind nur für eine begrenzte Zeit gültig und nur der Konsole bekannt, in die Sie sie einfügen. Dies ist vergleichbar mit der Verwendung von get_session_token in Ihrem Code.
Seien Sie sich bewusst, dass dieses Kopieren und Einfügen von Anmeldeinformationen in einem Szenario mit mehreren Konten ein neues Risiko darstellt. Vielleicht haben Sie verschiedene Umgebungen in verschiedenen Konten. Sie haben keine Möglichkeit zu sehen, für welches Konto Sie die Anmeldeinformationen gerade eingefügt haben. Das bedeutet, dass Sie sie am besten bei jeder Skriptausführung kopieren und einfügen, um einen Fehler zu vermeiden. Andernfalls könnten Sie versehentlich ein Skript in der Umgebung production ausführen und es dadurch beschädigen.
Versehentliches Ausführen von destruktivem Code
Zufälligerweise erwähnt Joris Conijn diese Risiken in seinem Blogbeitrag. Es geht um die versehentliche Ausführung von Code, der ohne Warnmeldung etwas Zerstörerisches tut. Dabei muss es sich nicht einmal um Ihren eigenen Code handeln. Jeder heruntergeladene Code, z.B. in einer Paketinitialisierung, bei der boto3 wird dem bösartigen Code sogar helfen, indem sie boto3.Session().available_profiles zur Verfügung stellt).
Es könnte auch Ihr eigener Code sein, der bösartig ist. Ich hatte einmal ein Skript, das die Ingress-Regeln der Standardeinstellung # vor diesem if würde diesen Code zu einer Bedrohung immensen Ausmaßes für die Organisation werden lassen! (Ich wüsste nicht einmal, wo ich anfangen sollte, diesen Code wiederherzustellen, wenn er versehentlich ausgeführt würde...)
Dies zeigt auch das nächste Risiko einer zu großen Freizügigkeit.
Übermäßig freizügige Sitzungen
In den meisten Fällen sind die Berechtigungen, die Sie über das Profil oder SSO erhalten, sehr allgemein oder vielleicht sogar als Administrator. Sobald Sie eine Sitzung mit diesen Anmeldeinformationen haben, laufen Sie im Grunde mit einem voll geladenen Gewehr herum und schießen sich selbst in den Fuß. Ich habe die Erfahrung gemacht, dass es eine gute Praxis ist, die Berechtigungen über eine Sitzung einzuschränken.
Ich habe normalerweise eine Funktion in meinem Code, um die boto3-Sitzung wie folgt zu erhalten:
def get_session(role_name: str) -> boto3.Session:
sts = boto3.Session(region_name='us-east-1').client('sts')
account_id = sts.get_caller_identity()['Account']
creds = sts.assume_role(
RoleArn=f'arn:aws:iam::{account_id}:role/{role_name}',
RoleSessionName='my_session',
Policy=json.dumps({
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"organizations:DescribeOrganization"
],
"Resource": "*"
}]
})
)["Credentials"]
return boto3.Session(
aws_access_key_id=creds['AccessKeyId'],
aws_secret_access_key=creds['SecretAccessKey'],
aws_session_token=creds['SessionToken']
)
Das Einzige, was Sie benötigen, ist eine IAM-Rolle, die Sie mit ausreichenden Rechten für Ihren Zweck übernehmen können.
In größeren Skripten gebe ich oft sogar die Richtlinie an, die ich für diesen Abschnitt des Codes haben möchte. Auf diese Weise hat jeder Abschnitt sein eigenes Scoping Down, um die Risiken weiter zu reduzieren.
Wenn Sie Ihrem Skript Code hinzufügen, der andere boto3-Aufrufe verwendet, und den Code ausführen, erhalten Sie in der Regel eine ausführliche Fehlermeldung, in der die Aktion und die Ressource erwähnt werden, die in der Scoping-Down-Richtlinie fehlen. Sie bewerten sie einfach, fügen sie der Richtlinie hinzu und führen das Skript erneut aus. Auf diese Weise sind Sie sich stets bewusst, dass Sie die Dinge sicher tun.
Infrastruktur als Code
Infrastructure as Code (IaC) ist der richtige Weg, wenn Sie Dinge erstellen oder ändern, die in der Cloud gehostet werden. Es sollte Quellcode in einem Repository vorhanden sein, der den gewünschten Zustand Ihrer Infrastruktur angibt. In der Regel hält man CloudFormation für ein gutes Format, um den gewünschten Zustand auszudrücken. Und idealerweise würden Sie nur ein Format wollen. Aber mit CloudFormation sind Sie auf das beschränkt, was es unterstützt, es sei denn, Sie sind bereit, einige CustomResources zu codieren oder in Ihr Infrastrukturprojekt einzuführen. Die Kodierung von CustomResources erfordert allerdings ein gewisses Maß an Erfahrung. Es mag zwar einfach erscheinen, aber das Surfen um all die Randfälle, die der CloudFormation-Prozess hat, ist manchmal nicht so intuitiv. Und die CustomResources bringen auch eine gewisse Verantwortung für die Wartung mit sich. Die beteiligten Lambda-Funktionen liegen oft jahrelang in Ihrem AWS-Konto herum. Die Laufzeitumgebung, die sie verwenden, wird wahrscheinlich nicht mehr unterstützt, wenn die Zeit kommt, Ihre Ressourcen zu vernichten. Möglicherweise müssen Sie Updates für CustomResources einführen und testen, ob sie Ihren Anwendungsfall noch abdecken.
Deshalb gehe ich oft einen Kompromiss mit der Ein-Format-Regel ein. Sie können Ihrem Repo eine yaml-Datei hinzufügen, die den gewünschten Status enthält, und ein Post-Deployment-Skript in Python, das das/die AWS-Zielkonto/-konten aktualisiert, um den Status aus der yaml-Datei wiederzugeben. Sie richten dieses Skript so ein, dass es in derselben Pipeline ausgeführt wird, in der auch Ihre CloudFormation bereitgestellt wird. Das kann sehr viel einfacher sein als das Jonglieren mit benutzerdefinierten Ressourcen und ich glaube, es wird immer noch "Infrastructure as Code" genannt.
Hier sind einige Beispiele, bei denen ich mich für den yaml-script-Ansatz entschieden habe (manchmal ohne yaml):
-
alle Regeln aus den Standard-Sicherheitsgruppen in vpcs löschen
-
IAM-Passwort-Richtlinie (neu) festlegen
-
den Status der SecurityHub-Kontrollen auf ENABLED oder DISABLED konfigurieren
-
Aktualisieren der Confluence-Seite mit Informationen über Ihre Infrastruktur
-
Kontoerstellung Bootstrapping / Zerstörung
Ich denke, solange Sie den tatsächlichen Zustand in separaten Dateien (wie der yaml) ablegen, können Sie es immer noch als Infrastruktur als Code betrachten.
Verfasst von

Jacco Kulman
Jacco is a Cloud Consultant at Binx.io. As an experienced development team lead he coded for the banking- and hospitality- and media-industries. He is a big fan of serverless architectures. In his free time he reads science fiction, contributes to open source projects and enjoys being a life-long-learner.
Unsere Ideen
Weitere Blogs
Contact




