
Outil de linting pour les modèles CloudFormation
L'outil cfn-nag recherche des motifs dans les modèles CloudFormation qui peuvent indiquer une infrastructure non sécurisée. En gros, il recherche :
Pour plus d'informations sur l'outil, veuillez consulter cet article sur le blog de Stelligent :
En supposant que Ruby >= 2.5.x est installé, l'installation est simplement une question de :
gem install cfn-nag
Sur MacOS ou Linux, vous pouvez également installer via brew :
brew install ruby brew-gem
brew gem install cfn-nag
Pour exécuter cfn_nag en tant qu'action dans CodePipeline, vous pouvez le déployer via le AWS Serverless Application Repository.
Pour exécuter :
cfn_nag_scan --input-path <path to cloudformation json>
Le chemin peut être un répertoire ou un modèle particulier. S'il s'agit d'un répertoire, tous les fichiers .json, .template, .yml et .yaml seront traités, y compris en parcourant récursivement les sous-répertoires.
Le format de sortie par défaut est un texte libre, mais la sortie json peut être sélectionnée avec l'option --output-format json.
En option, --debug affichera des informations sur les mécanismes internes de chargement des règles.
Exécutez avec --help pour obtenir la liste complète des options prises en charge.
Pour voir la liste de toutes les règles actuellement prises en charge par cfn-nag, il existe un utilitaire en ligne de commande qui les affiche sur stdout :
cfn_nag_rules
Un Dockerfile est fourni pour plus de commodité. Il est publié sur DockerHub sous le nom stelligent/cfn_nag.
https://hub.docker.com/r/stelligent/cfn_nag
Vous pouvez également le construire localement.
docker build -t stelligent/cfn_nag .
Vous pouvez monter un répertoire local contenant des modèles dans le conteneur Docker, puis appeler cfn_nag dans le conteneur. Cet exemple utilise les modèles de test utilisés dans les tests unitaires de cfn_nag :
$ 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 peut être exécuté dans le cadre d'un workflow GitHub pour évaluer le code pendant les pipelines d'intégration continue.
Dans votre fichier de workflow GitHub, créez une étape qui utilise l'action cfn_nag :
- name: Simple test
uses: stelligent/cfn_nag@master
with:
input_path: tests
Plus d'informations sur l'action GitHub sont disponibles ici.
cfn-nag prend en charge la notion de « profil », qui est en réalité une liste d'autorisation de règles à appliquer. Le profil est un fichier texte qui doit contenir un identifiant de règle par ligne. Lorsqu'il est spécifié via l'argument de ligne de commande --profile-path, cfn-nag ne renverra QUE les violations de ces règles particulières.
La motivation derrière la création d'un « profil » est que différents développeurs peuvent être concernés par différentes règles. Par exemple, un « infrastructure_developer » peut être concerné par les règles IAM, tandis qu'un « app_developer » peut ne même pas être en mesure de créer des ressources IAM et donc ne pas se soucier de ces règles.
Voici un exemple de profil :
F1
F2
F27
W3
W5
La liste de refus est en quelque sorte l'opposé du profil : c'est une liste de règles à NE JAMAIS appliquer. Lorsqu'elle est spécifiée via l'argument de ligne de commande --deny-list-path, cfn-nag ne renverra JAMAIS de violations pour les règles particulières spécifiées dans le fichier.
Si une règle est spécifiée dans les deux, la liste de refus aura priorité sur le profil et la règle ne sera pas appliquée.
Le format est le suivant. Les deux seuls champs importants sont RulesToSuppress et le id de chaque élément. La reason ne sera pas interprétée par cfn-nag, mais il est recommandé de justifier et de documenter pourquoi la règle ne devrait jamais être appliquée.
RulesToSuppress:
- id: W3
reason: W3 is something we never care about at enterprise X
Dans le cas où vous souhaitez supprimer une règle, une clé Metadata de cfn_nag peut être ajoutée à la ressource concernée pour indiquer à cfn_nag de ne pas signaler d'échec ou d'avertissement pour cette règle.
Par exemple, si vous configurez un ELB public ouvert aux connexions entrantes depuis Internet avec des ressources comme celles-ci :
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 lèvera des avertissements comme ceux-ci :
$ 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
En ajoutant les métadonnées, ces avertissements peuvent être supprimés :
public_alb_with_suppression.yaml