
Herramienta de linting para plantillas de CloudFormation
La herramienta cfn-nag busca patrones en las plantillas de CloudFormation que puedan indicar infraestructura insegura. En términos generales, buscará:
Para obtener más información sobre la herramienta, consulte esta publicación en el blog de Stelligent:
Suponiendo que Ruby >= 2.5.x esté instalado, la instalación es solo cuestión de:
gem install cfn-nag
En MacOS o Linux, también puede instalarlo alternativamente con brew:
brew install ruby brew-gem
brew gem install cfn-nag
Para ejecutar cfn_nag como una acción en CodePipeline, puede implementarlo a través del AWS Serverless Application Repository.
Para ejecutar:
cfn_nag_scan --input-path <ruta al json de cloudformation>
La ruta puede ser un directorio o una plantilla en particular. Si es un directorio, se procesarán todos los archivos .json, .template, .yml y .yaml, incluida la recursión en subdirectorios.
El formato de salida predeterminado es texto de forma libre, pero la salida json se puede seleccionar con la bandera --output-format json.
Opcionalmente, una bandera --debug volcará información sobre los entresijos de la carga de reglas.
Ejecute con --help para obtener una lista completa de los modificadores admitidos.
Para ver una lista de todas las reglas que cfn-nag admite actualmente, hay una utilidad de línea de comandos que las volcará a stdout:
cfn_nag_rules
Se proporciona un Dockerfile por conveniencia. Está publicado en DockerHub como stelligent/cfn_nag.
https://hub.docker.com/r/stelligent/cfn_nag
También puede construirlo localmente.
docker build -t stelligent/cfn_nag .
Puede montar un directorio local que contenga plantillas en el contenedor Docker y luego llamar a cfn_nag en el contenedor. Este ejemplo utiliza las plantillas de prueba utilizadas en las pruebas unitarias 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 se puede ejecutar como parte de un GitHub Workflow para evaluar código durante los pipelines de integración continua.
En su archivo de GitHub Workflow, cree un paso que utilice la cfn_nag Action:
- name: Simple test
uses: stelligent/cfn_nag@master
with:
input_path: tests
Puede encontrar más información sobre la GitHub Action aquí.
cfn-nag admite la noción de un "perfil" que es efectivamente una lista de permitidos de reglas a aplicar. El perfil es un archivo de texto
que debe contener un identificador de regla por línea. Cuando se especifica mediante el argumento de línea de comandos --profile-path,
cfn-nag SOLO devolverá violaciones de esas reglas particulares.
La motivación detrás de la creación de un "perfil" es que diferentes desarrolladores podrían preocuparse por diferentes reglas. Por ejemplo, un "desarrollador_de_infraestructura" podría preocuparse por las reglas de IAM, mientras que un "desarrollador_de_aplicaciones" podría ni siquiera poder crear recursos de IAM y, por lo tanto, no le importarían esas reglas.
Aquí hay un ejemplo de perfil:
F1
F2
F27
W3
W5
La lista de denegación es básicamente lo opuesto al perfil: es una lista de reglas que NUNCA se aplican. Cuando se especifica mediante el
argumento de línea de comandos --deny-list-path, cfn-nag NUNCA devolverá violaciones de esas reglas particulares especificadas
en el archivo.
En caso de que una regla se especifique en ambos, la lista de denegación tendrá prioridad sobre el perfil y la regla no se aplicará.
El formato es el siguiente. Los únicos dos campos importantes son RulesToSuppress y el id de cada elemento. El reason no será
interpretado por cfn-nag, pero se recomienda para justificar y documentar por qué la regla nunca debería aplicarse.
RulesToSuppress:
- id: W3
reason: W3 is something we never care about at enterprise X
En caso de que haya una regla que desee suprimir, se puede agregar una clave cfn_nag Metadata al recurso afectado para indicarle a cfn_nag que no genere un fallo o advertencia para esa regla.
Por ejemplo, si está configurando un ELB orientado al público que está abierto a conexiones entrantes desde internet con recursos como los siguientes:
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 generará advertencias como las siguientes:
$ 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
Al agregar los metadatos, estas advertencias se pueden suprimir:
public_alb_with_suppression.yaml