
Strumento di linting per template CloudFormation
Lo strumento cfn-nag cerca nei modelli CloudFormation pattern che potrebbero indicare infrastrutture non sicure. In parole povere, cerca:
Per ulteriori informazioni sullo strumento, consulta questo articolo sul blog di Stelligent:
Supponendo che Ruby >= 2.5.x sia installato, l'installazione è solo una questione di:
gem install cfn-nag
Su MacOS o Linux puoi anche installare con brew:
brew install ruby brew-gem
brew gem install cfn-nag
Per eseguire cfn_nag come azione in CodePipeline, puoi eseguire il deploy tramite l'AWS Serverless Application Repository.
Per eseguire:
cfn_nag_scan --input-path <path to cloudformation json>
Il percorso può essere una directory o un modello specifico. Se è una directory, tutti i file .json, .template, .yml e .yaml verranno elaborati, inclusa la ricorsione nelle sottodirectory.
Il formato di output predefinito è testo libero, ma l'output JSON può essere selezionato con il flag --output-format json.
Facoltativamente, un flag --debug scaricherà informazioni sugli interni del caricamento delle regole.
Esegui con --help per un elenco completo delle opzioni supportate.
Per vedere un elenco di tutte le regole attualmente supportate da cfn-nag, esiste un'utilità a riga di comando che le invia a stdout:
cfn_nag_rules
È fornito un Dockerfile per comodità. È pubblicato su DockerHub come stelligent/cfn_nag.
https://hub.docker.com/r/stelligent/cfn_nag
Puoi anche crearlo localmente.
docker build -t stelligent/cfn_nag .
Puoi montare una directory locale contenente i modelli nel container Docker e quindi chiamare cfn_nag all'interno del container. Questo esempio utilizza i modelli di test usati negli unit test di 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 può essere eseguito come parte di un GitHub Workflow per valutare il codice durante le pipeline di integrazione continua.
Nel tuo file GitHub Workflow, crea uno step che utilizza l'Action cfn_nag:
- name: Simple test
uses: stelligent/cfn_nag@master
with:
input_path: tests
Maggiori informazioni sulla GitHub Action sono disponibili qui.
cfn-nag supporta il concetto di "profilo" che è di fatto una lista di consentiti (allow list) delle regole da applicare. Il profilo è un file di testo
che deve contenere un identificatore di regola per riga. Quando viene specificato tramite l'argomento da riga di comando --profile-path,
cfn-nag restituirà SOLO le violazioni di quelle specifiche regole.
La motivazione alla base della creazione di un "profilo" è che diversi sviluppatori potrebbero interessarsi a regole diverse. Ad esempio, uno "sviluppatore di infrastrutture" potrebbe preoccuparsi delle regole IAM, mentre uno "sviluppatore di applicazioni" potrebbe non essere nemmeno in grado di creare risorse IAM e quindi non interessarsi a quelle regole.
Ecco un esempio di profilo:
F1
F2
F27
W3
W5
La deny list è sostanzialmente l'opposto del profilo: è un elenco di regole da NON applicare MAI. Quando viene specificata tramite
l'argomento da riga di comando --deny-list-path, cfn-nag non restituirà MAI violazioni dalle regole specificate
nel file.
Nel caso in cui una regola sia specificata in entrambi, la deny list avrà priorità sul profilo e la regola non verrà applicata.
Il formato è il seguente. Gli unici due campi salienti sono RulesToSuppress e l'id per ogni elemento. La reason non
verrà interpretata da cfn-nag, ma è consigliato giustificare e documentare il motivo per cui la regola non dovrebbe mai essere applicata.
RulesToSuppress:
- id: W3
reason: W3 is something we never care about at enterprise X
Nel caso in cui esista una regola che desideri sopprimere, è possibile aggiungere una chiave Metadata di cfn_nag alla risorsa interessata per dire a cfn_nag di non generare un errore o un avviso per quella regola.
Ad esempio, se stai configurando un ELB pubblico aperto alle connessioni in ingresso da internet con risorse come le seguenti:
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 genererà avvisi come i seguenti:
$ 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
Aggiungendo i metadati, questi avvisi possono essere soppressi:
public_alb_with_suppression.yaml