
Linting-Tool für CloudFormation-Vorlagen
Das cfn-nag-Tool sucht in CloudFormation-Vorlagen nach Mustern, die auf unsichere Infrastruktur hindeuten können. Grob gesagt sucht es nach:
Weitere Hintergrundinformationen zum Tool findest du in diesem Beitrag im Stelligent-Blog:
Vorausgesetzt, Ruby >= 2.5.x ist installiert, ist die Installation ganz einfach:
gem install cfn-nag
Unter MacOS oder Linux kannst du alternativ mit brew installieren:
brew install ruby brew-gem
brew gem install cfn-nag
Um cfn_nag als Aktion in CodePipeline auszuführen, kannst du über das AWS Serverless Application Repository bereitstellen.
Zum Ausführen:
cfn_nag_scan --input-path <path to cloudformation json>
Der Pfad kann ein Verzeichnis oder eine bestimmte Vorlage sein. Wenn es ein Verzeichnis ist, werden alle .json, .template, .yml- und .yaml-Dateien verarbeitet, einschließlich der Rekursion in Unterverzeichnisse.
Das Standardausgabeformat ist Freitext, aber die JSON-Ausgabe kann mit dem Flag --output-format json ausgewählt werden.
Optional kann ein --debug-Flag Informationen über die Interna des Regelladens ausgeben.
Führe das Tool mit --help aus, um eine vollständige Liste der unterstützten Schalter zu erhalten.
Um eine Liste aller Regeln zu sehen, die cfn-nag derzeit unterstützt, gibt es ein Befehlszeilenprogramm, das sie auf stdout ausgibt:
cfn_nag_rules
Für die Bequemlichkeit wird ein Dockerfile bereitgestellt. Es wird auf DockerHub als stelligent/cfn_nag veröffentlicht.
https://hub.docker.com/r/stelligent/cfn_nag
Du kannst es auch lokal erstellen.
docker build -t stelligent/cfn_nag .
Du kannst ein lokales Verzeichnis mit Vorlagen in den Docker-Container mounten und dann cfn_nag im Container aufrufen. Dieses Beispiel verwendet die Testvorlagen, die beim Unit-Testen von cfn_nag verwendet werden:
$ docker run -v `pwd`/spec/test_templates:/templates -t stelligent/cfn_nag /templates/json/efs/filesystem_with_encryption.json
{
"failure_count": 0,
"violations": [
]
}
$ docker run -v `pwd`/spec/test_templates:/templates -t stelligent/cfn_nag /templates/json/efs/filesystem_with_no_encryption.json
{
"failure_count": 1,
"violations": [
{
"id": "F27",
"type": "FAIL",
"message": "EFS FileSystem should have encryption enabled",
"logical_resource_ids": [
"filesystem"
]
}
]
}
cfn_nag_scan kann als Teil eines GitHub-Workflows ausgeführt werden, um Code in Continuous-Integration-Pipelines zu bewerten.
Erstelle in deiner GitHub-Workflow-Datei einen Schritt, der die cfn_nag-Action verwendet:
- name: Simple test
uses: stelligent/cfn_nag@master
with:
input_path: tests
Weitere Informationen zur GitHub Action findest du hier.
cfn-nag unterstützt das Konzept eines "Profils", das im Grunde eine Zulassungsliste der anzuwendenden Regeln ist. Das Profil ist eine Textdatei, die pro Zeile eine Regelkennung enthalten muss. Wenn es über das Befehlszeilenargument --profile-path angegeben wird, gibt cfn-nag NUR Verletzungen von diesen bestimmten Regeln zurück.
Die Motivation hinter der Erstellung eines "Profils" ist, dass verschiedene Entwickler an unterschiedlichen Regeln interessiert sein können. Zum Beispiel könnte ein "infrastructure_developer" sich für IAM-Regeln interessieren, während ein "app_developer" möglicherweise nicht einmal IAM-Ressourcen erstellen kann und sich daher nicht für diese Regeln interessiert.
Hier ist ein Beispielprofil:
F1
F2
F27
W3
W5
Die Deny-Liste ist im Grunde das Gegenteil des Profils: Sie ist eine Liste von Regeln, die NIEMALS angewendet werden sollen. Wenn sie über das Befehlszeilenargument --deny-list-path angegeben wird, gibt cfn-nag NIEMALS Verletzungen von den in der Datei angegebenen Regeln zurück.
Falls eine Regel in beiden angegeben ist, hat die Deny-Liste Priorität gegenüber dem Profil, und die Regel wird nicht angewendet.
Das Format ist wie folgt. Die einzigen beiden wichtigen Felder sind RulesToSuppress und die id pro Eintrag. Die reason wird von cfn-nag nicht interpretiert, aber es wird empfohlen, zu begründen und zu dokumentieren, warum die Regel niemals angewendet werden sollte.
RulesToSuppress:
- id: W3
reason: W3 is something we never care about at enterprise X
Falls es eine Regel gibt, die du unterdrücken möchtest, kann dem betroffenen Ressource ein cfn_nag-Metadata-Schlüssel hinzugefügt werden, um cfn_nag mitzuteilen, für diese Regel keinen Fehler oder keine Warnung auszulösen.
Wenn du zum Beispiel einen öffentlich zugänglichen ELB einrichtest, der für eingehende Verbindungen aus dem Internet offen ist, mit Ressourcen wie den folgenden:
public_alb.yaml
# Partial template
PublicAlbSecurityGroup:
Properties:
GroupDescription: 'Security group for a public Application Load Balancer'
VpcId:
Ref: vpc
Type: AWS::EC2::SecurityGroup
PublicAlbSecurityGroupHttpIngress:
Properties:
CidrIp: 0.0.0.0/0
FromPort: 80
GroupId:
Ref: PublicAlbSecurityGroup
IpProtocol: tcp
ToPort: 80
Type: AWS::EC2::SecurityGroupIngress
cfn_nag wird Warnungen wie die folgenden ausgeben:
$ cfn_nag_scan -i public_alb.yaml
------------------------------------------------------------
public_alb.yaml
------------------------------------------------------------------------------------------------------------------------
| WARN W9
|
| Resources: ["PublicAlbSecurityGroup"]
|
| Security Groups found with ingress cidr that is not /32
------------------------------------------------------------
| WARN W2
|
| Resources: ["PublicAlbSecurityGroup"]
|
| Security Groups found with cidr open to world on ingress. This should never be true on instance. Permissible on ELB
Failures count: 0
Warnings count: 2
Durch Hinzufügen der Metadaten können diese Warnungen unterdrückt werden:
public_alb_with_suppression.yaml