L'outil CFN-NAG recherche des modèles dans les modèles CloudFormation qui peuvent indiquer une infrastructure non sécurisée. En gros, il cherchera:
Pour plus d'informations sur l'outil, veuillez consulter cet article sur le blog de Stelligent:
Trouver des problèmes de sécurité au début du processus de développement d'un modèle de formation de cloud avec "CFN-NAG"
Ruby en présumant> = 2.5.x est installé, l'installation n'est qu'une question de:
gem install cfn-nagSur macOS ou Linux, vous pouvez alternativement installer avec Brew:
brew install ruby brew-gem
brew gem install cfn-nag Pour exécuter cfn_nag en tant qu'action dans CodePipeline, vous pouvez déployer via le référentiel d'applications sans serveur AWS.
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 les reproductions en sous-répertoires.
Le format de sortie par défaut est le texte de forme libre, mais la sortie JSON peut être sélectionnée avec l'indicateur --output-format json .
Facultativement, un indicateur --debug déversera des informations sur les internes du chargement des règles.
Exécutez avec --help pour une liste complète des commutateurs pris en charge.
Pour voir une liste de toutes les règles que CFN-NAG prend actuellement en charge, il existe un utilitaire de ligne de commande qui les videra sur stdout:
cfn_nag_rules Un dockerfile est fourni pour la commodité. Il est publié sur DockerHub en tant que 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 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 flux de travail GitHub pour évaluer le code pendant les pipelines d'intégration continue.
Dans votre fichier GitHub Workflow, créez une étape qui utilise l'action CFN_NAG:
- name : Simple test
uses : stelligent/cfn_nag@master
with :
input_path : testsPlus d'informations sur l'action GitHub peuvent être trouvées ici.
CFN-NAG prend en charge la notion de "profil" qui est effectivement une liste de règles à appliquer. Le profil est un fichier texte qui doit contenir un identifiant de règle par ligne. Lorsqu'elle est spécifiée via l'argument de la ligne de commande --profile-path , CFN-NAG ne renverra que des violations de ces règles particulières.
La motivation derrière la création d'un "profil" est que différents développeurs peuvent se soucier des différentes règles. Par exemple, une "infrastructure_developer" peut se soucier des règles IAM, tandis qu'un "App_developer" pourrait même ne pas être en mesure de créer des ressources IAM et donc de ne pas se soucier de ces règles.
Voici un exemple de profil:
F1
F2
F27
W3
W5
La liste de refus est essentiellement l'opposé du profil: c'est une liste de règles à ne jamais s'appliquer. Lorsqu'il est spécifié via l'argument de la ligne de commande --deny-list-path , CFN-NAG ne renverra jamais de violations de ces règles particulières spécifiées dans le fichier.
Dans le cas où une règle est spécifiée dans les deux, la liste de refus sera prioritaire sur le profil et la règle ne sera pas appliquée.
Le format est le suivant. Les deux seuls champs saillants sont RulesToSuppress et l' id par article. 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ù il existe une règle que vous souhaitez supprimer, une clé Metadata cfn_nag peut être ajoutée à la ressource affectée pour dire à CFN_NAG de ne pas augmenter un échec ou un avertissement pour cette règle.
Par exemple, si vous créez un ELB orienté public qui est ouvert aux connexions entrantes à partir d'Internet avec des ressources comme ce qui suit:
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::SecurityGroupIngressCFN_NAG soulèvera les avertissements comme les suivants:
$ 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: 2En ajoutant les métadonnées, ces avertissements peuvent être supprimés:
public_alb_with_suppression.yaml
# Partial template
PublicAlbSecurityGroup :
Properties :
GroupDescription : ' Security group for a public Application Load Balancer '
VpcId :
Ref : vpc
Type : AWS::EC2::SecurityGroup
Metadata :
cfn_nag :
rules_to_suppress :
- id : W9
reason : " This is a public facing ELB and ingress from the internet should be permitted. "
- id : W2
reason : " This is a public facing ELB and ingress from the internet should be permitted. "
PublicAlbSecurityGroupHttpIngress :
Properties :
CidrIp : 0.0.0.0/0
FromPort : 80
GroupId :
Ref : PublicAlbSecurityGroup
IpProtocol : tcp
ToPort : 80
Type : AWS::EC2::SecurityGroupIngress $ cfn_nag_scan -i public_alb_with_suppression.yaml
------------------------------------------------------------
public_alb_with_supression.yaml
------------------------------------------------------------
Failures count: 0
Warnings count: 0Les paramètres de modèle de forme de cloudformation peuvent présenter un problème pour l'analyse statique car les valeurs sont spécifiées au point de déploiement. En d'autres termes, les valeurs ne sont pas disponibles lorsque l'analyse statique est effectuée - l'analyse statique ne peut que regarder le "code" qui est devant. Par conséquent, une règle d'entrée de groupe de sécurité de 0,0.0.0/0 ne sera pas signalée si le CIDR est paramétré et que le 0.0.0.0/0 est passé au moment du déploiement.
Pour permettre la vérification des valeurs des paramètres, un utilisateur peut spécifier les valeurs des paramètres dans un fichier JSON transmis sur la ligne de commande à la fois cfn_nag et cfn_nag_scan avec le drapeau --parameter-values-path=<filename/uri> .
Le format du JSON est une seule clé, "Paramètres", dont la valeur est un dictionnaire avec chaque mappage de paire de clés / valeur aux paramètres:
{
"Parameters" : {
"Cidr" : " 0.0.0.0/0 "
}
}Cela fournira "0.0.0.0/0" au paramètre suivant:
Parameters :
Cidr :
Type : String Méfiez-vous que s'il y a des paramètres supplémentaires dans le JSON, ils sont tranquillement ignorés (pour permettre à cfn_nag_scan d'appliquer le même JSON sur tous les modèles).
Si le JSON est mal formé ou ne répond pas aux spécifications ci-dessus, l'analyse échoue avec une violation mortelle.
Avant 0.5.55, les appels à fn :: FindInmap ont été effectivement ignorés. Le modèle sous-jacent les laisserait être, et ils apparaîtraient donc comme des valeurs de hachage aux règles. Par exemple: { "Fn::FindInMap" => [map1, key1, key2]}
À partir de 0,5.55, le modèle tentera de calculer la valeur d'un appel pour trouver en fin de fin et présenter cette valeur aux règles. Cette évaluation soutient les clés qui sont:
Si la logique d'évaluation ne peut pas déterminer la valeur d'une clé, elle sera par défaut à l'ancien comportement de renvoyer le hachage pour toute l'expression.
Avant 0,5,55, les appels aux pseudofonctions AWS ont également été ignorés. Le modèle sous-jacent les laisserait être, et ils apparaîtraient donc comme des valeurs de hachage aux règles. Par exemple: {"Ref"=>"AWS::Region"} . Un cas d'utilisation courant consiste à organiser des mappages par région, donc l'évaluation des pseudofonctionnement est importante pour mieux soutenir l'évaluation des MAP.
À partir de 0,5.55, le modèle présentera les pseudofonctions AWS suivantes aux règles avec les valeurs par défaut:
'AWS::URLSuffix' => 'amazonaws.com',
'AWS::Partition' => 'aws',
'AWS::NotificationARNs' => '',
'AWS::AccountId' => '111111111111',
'AWS::Region' => 'us-east-1',
'AWS::StackId' => 'arn:aws:cloudformation:us-east-1:111111111111:stack/stackname/51af3dc0-da77-11e4-872e-1234567db123',
'AWS::StackName' => 'stackname'
De plus, l'utilisateur final peut remplacer la valeur fournie via le mécanisme de substitution des paramètres traditionnelle. Par exemple:
{
"Parameters" : {
"AWS::Region" : " eu-west-1 "
}
}Jusqu'à la version 0.4.66 de CFN_NAG, le modèle sous-jacent n'a effectué aucun traitement de fn :: si dans un modèle. Cela signifiait que si une propriété avait une valeur conditionnelle, il appartenait à la règle d'analyser le fn :: si. Étant donné qu'un fn :: si pouvait apparaître à peu près n'importe où, il a créé une situation Whack-a-Mole pour les développeurs de règles. Au mieux, la logique des règles pourrait ignorer les valeurs qui présumaient que la valeur n'était pas un hachage en premier lieu.
Afin de résoudre ce problème, le comportement par défaut de CFN_NAG est maintenant de remplacer FN :: si par le vrai résultat. Cela signifie par défaut que les règles n'inspecteront pas les faux résultats pour les violations de la sécurité.
En plus de remplacer FN :: Si au niveau de la valeur de la propriété, le même comportement est appliqué à FN :: If au niveau supérieur des propriétés. Par exemple:
Resource1 :
Type : Foo
Properties : !If
- IsNone
- Description : Up
- Description : DOwnSera le même que:
Resource1 :
Type : Foo
Properties :
Description : Up Pour fournir un certain contrôle sur ce comportement, un utilisateur peut spécifier les valeurs de condition dans un fichier JSON transmis sur la ligne de commande à la fois cfn_nag et cfn_nag_scan avec le drapeau --condition-values-path=<filename/uri> .
Le format du JSON est un dictionnaire AA avec chaque mappage de paire de clés / valeur aux conditions:
{
"Condition1" : true ,
"Condition2" : false
}La base du SPCM est décrite dans le billet de blog Expérience de réflexion proposée Métrique de complexité pour les documents de politique IAM.
À partir de la version 0.6.0 de CFN_NAG:
spcm_scan peut scanner un répertoire de modèles CloudFormation (comme CFN_NAG_SCAN) et générer un rapport avec les métriques SPCM au format JSON ou HTMLcfn_nag_scan --rule-arguments spcm_threshold:100--rule-arguments . L'objet de règle n'a besoin que de déclarer un attr_accessor , par exemple attr_accessor :spcm_threshold et CFN_NAG s'occupera des détails pour injecter les valeurs de --rule-arguments La libération de 0.5.x comprend quelques changements majeurs dans la façon dont les règles personnalisées (peuvent) être distribuées et chargées. Avant cette version, il y avait deux endroits où les règles étaient chargées à partir de: le répertoire lib/cfn-nag/custom_rules dans le Core CFN_NAG GEM, et le répertoire personnalisé-Rule spécifié sur la ligne de commande.
Il existe deux cas d'utilisation qui ont forcé une refonte de la façon dont les règles personnalisées sont chargées. Le mécanisme de chargement des règles a été généralisé de sorte que les référentiels de règles personnalisés peuvent être utilisés pour découvrir des règles.
Un tas de "fichiers de règles" assis sur un système de fichiers ne sont pas excellents du point de vue du développement logiciel traditionnel. Il n'y a pas de version ni de traçabilité sur ces fichiers, donc 0.5.x introduit la notion de "CFN_NAG Rule Gem". Un développeur peut développer des règles personnalisées dans le cadre d'un joyau séparé, la version et l'installer ... et ces règles sont référencées à partir de CFN_NAG tant que les métadonnées GEM incluent cfn_nag_rules => true . Pour un joyau nommé comme "CFN-NAG-HIPAA-RULES", tout * .rb sous LiB / CFN-NAG-HIPAA-RULES sera chargé. Toutes les règles personnalisées devraient dériver de CFNNAG :: Baserule dans CFN-NAG / Base_rule ( pas CFN-NAG / CUSTOM-RULES / BASE). Si la règle doit dériver de quelque chose d'autre, définissant une méthode cfn_nag_rule? qui renvoie True le fera également être chargé en règle générale.
Lorsque CFN_NAG s'exécute dans un Lambda AWS - il n'y a pas vraiment de système de fichiers (en plus / TMP) au sens traditionnel. Par conséquent, seules les règles de base sont utilisables de la Lambda. Pour prendre en charge les règles personnalisées, CFN_NAG prend en charge la découverte des règles d'un seau S3 au lieu du système de fichiers.
Tout ce que vous avez probablement vu sur la façon de développer des règles personnalisées dans Ruby est toujours vraie.
Pour découvrir les règles d'un seau S3, créez un fichier s3.yml avec ce contenu:
---
repo_class_name : S3BucketBasedRuleRepo
repo_arguments :
s3_bucket_name : cfn-nag-rules-my-enterprise
prefix : /rulesPour appliquer * les fichiers de règle.rb dans le baquet CFN-Nag-Rules-My-Enterprise avec le préfixe / règles (par exemple /rules/mynewrule.rb), spécifiez ce fichier sur la ligne de commande à CFN_NAG en tant que tel:
cat my_cfn_template.yml | cfn_nag --rule-repository s3.yml Si les règles se trouvent dans plus d'un godet, créez plusieurs fichiers S3 * .yml et spécifiez-les dans l'argument --rule-repository .
Si les informations d'identification AWS Ambient ont la permission d'accéder au baquet cfn-nag-rules-enterprise , il trouvera toutes les règles comme /rules/*Rule.rb . Si un AWS_PROFILE particulier doit être utilisé, ajoutez-le comme une clé sous repo_arguments , par exemple aws_profile: my_aws_profile
Au-delà du système de fichiers, GEM Installations et S3 - la nouvelle architecture prend théoriquement le développement d'autres "référentiels de règles" pour charger des règles à partir de DynamoDB, de bases de données relationnelles ou d'autres services Web.
Pour autoriser de nouvelles règles pour votre propre utilisation et / ou la contribution communautaire, voir le développement de règles personnalisés pour plus de détails.
Un screencast démontrant le développement de règles TDD sur la soupe aux noix est disponible ici:
https://www.youtube.com/watch?v=jrzct0nafd4&t=1601s
Pour exécuter les spécifications, vous devez vous assurer que Docker est installé et les dépendances CFN_NAG installées via
gem install bundle
bundle install Ensuite, pour exécuter toutes les spécifications, il suffit d'exécuter rake test:all .
Pour exécuter les tests de bout en bout, exécutez rake test:e2e . Le script regroupera tous les gemmes dans le gemfile, construisera et installer le GEM CFN_NAG localement, installer les dépendances des spécifications, puis exécuter les tests tagués avec 'end_to_end'. Il réduira également les modèles d'échantillons fournis par Amazon et exécutera CFN_NAG_SCAN contre eux, pour voir si des modèles de bons connus provoquent des exceptions dans CFN-NAG.
Pour installer la branche GIT actuelle localement:
bundle install
scripts/deploy_local.shUn environnement de développement à distance complet est créé et configuré avec tous les outils et paramètres préconfigurés pour faciliter le développement et la création des règles. Vous pouvez activer cela en utilisant la fonctionnalité de développement à distance VS Code.
Folder contains a dev container configuration file. Reopen folder to develop in a container Cliquez sur le bouton Reopen in Container[Dev Container] cfn_nag DevelopmentPlus d'informations sur la configuration de développement à distance de code VS Code peuvent être trouvées ici, VS Code Remote Development.
Pour signaler un bogue ou demander une fonctionnalité, soumettez un problème via le référentiel GitHub via: https://github.com/stelligent/cfn_nag/issues/new