11## CfnNagService
22
3- This repository contains the automation code required to deploy https://github.com/stelligent/cfn_nag as an API Gateway endpoint.
3+ This repository contains the automation code required to deploy https://github.com/stelligent/cfn_nag as either an API Gateway endpoint
4+ or as a Docker container.
45
56### Endpoints
67
7- Each request expects a JSON structure with a single ` template_body ` key. The value of this key should be a Base64 encoded CloudFormation template in either JSON or YAML.
8+ Each request expects a CloudFormation template in either JSON or YAML.
89
910#### /scan
1011
11- This endpoint returns the same response that you would see if you just ran ` cfn_nag ` from the command line.
12-
13- Request example:
14-
15- ```
16- {
17- "template_body": "ewogICJBV1NUZW1wbGF0ZUZvcm1hdFZlcnNpb24iOiAiMjAxMC0wOS0wOSIsCiAgIlJlc291cmNlcyI6IHsKICAgICAgICAiUzNCdWNrZXQiOiB7CiAgICAgICAgICAgICJUeXBlIjogIkFXUzo6UzM6OkJ1Y2tldCIsCiAgICAgICAgICAgICJQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgIkFjY2Vzc0NvbnRyb2wiOiAiUHVibGljUmVhZFdyaXRlIiwKICAgICAgICAgICAgICAgICJDb3JzQ29uZmlndXJhdGlvbiI6IHsKICAgICAgICAgICAgICAgICAgICAiQ29yc1J1bGVzIjogWwogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWxsb3dlZEhlYWRlcnMiOiBbCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIioiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFsbG93ZWRNZXRob2RzIjogWwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHRVQiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFsbG93ZWRPcmlnaW5zIjogWwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIqIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFeHBvc2VkSGVhZGVycyI6IFsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGF0ZSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSWQiOiAibXlDT1JTUnVsZUlkMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWF4QWdlIjogIjM2MDAiCiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBbGxvd2VkSGVhZGVycyI6IFsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAieC1hbXotKiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWxsb3dlZE1ldGhvZHMiOiBbCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRFTEVURSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWxsb3dlZE9yaWdpbnMiOiBbCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cuZXhhbXBsZTEuY29tIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaHR0cDovL3d3dy5leGFtcGxlMi5jb20iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkV4cG9zZWRIZWFkZXJzIjogWwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb25uZWN0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2VydmVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGF0ZSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSWQiOiAibXlDT1JTUnVsZUlkMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWF4QWdlIjogIjE4MDAiCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAogICAgIk91dHB1dHMiOiB7CiAgICAgICAgIkJ1Y2tldE5hbWUiOiB7CiAgICAgICAgICAgICJWYWx1ZSI6IHsKICAgICAgICAgICAgICAgICJSZWYiOiAiUzNCdWNrZXQiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJEZXNjcmlwdGlvbiI6ICJOYW1lIG9mIHRoZSBzYW1wbGUgQW1hem9uIFMzIGJ1Y2tldCB3aXRoIENPUlMgZW5hYmxlZC4iCiAgICAgICAgfQogICAgfQp9Cg=="
18- }
19- ```
12+ This endpoint returns a similar response that you would see if you just ran ` cfn_nag ` from the command line.
2013
2114Response example:
2215
@@ -50,12 +43,9 @@ Response example:
5043}
5144```
5245
53- #### /scan_secure
46+ #### /signed_scan
5447
55- This endpoint will provide a digital signature so you can verify the authenticity of the results. There are two SSM SecureString parameters involved:
56-
57- * /CfnNagService/signing_key - The key the service uses to sign requests
58- * /CfnNagService/verify_key - The key you can use to verify signatures
48+ This endpoint will provide a digital signature so you can verify the authenticity of the results.
5949
6050Response example:
6151
@@ -88,129 +78,22 @@ Response example:
8878 }
8979 ]
9080 },
81+ "encoded_results": "FGSDFSDFW.....",
9182 "signature": "eKlzShFty5tCC/zXo3Cf7L0E0yCxdXejS7dAYauBc2s9eBoCfs9Lmd2AQcGR\nEwrSUzr43s+bUjqy/5Sum1JcCQ==\n"
9283}
9384```
9485
86+ The encoded_results are strict Base64 encoded of the original template body, the results/violations and the list of rules applied.
87+ When verifying the payload, verify the signature of the encoded_results as Base64 (i.e. don't decode the encoded_results
88+ before verifying)
89+
9590#### /status
9691
9792This endpoint just provides a 200 HTTP response and a simple message to let you know the endpoint is up.
9893
99- ### Endpoint options
94+ #### Variations Between Lambda/Docker
10095
101- All endpoints have two parameters that can modify the response. When set to ` true ` it will provide more information in the response.
102-
103- * return_template - Returns the template_body that was originally passed in to the service
104- * return_rule - Returns an array of all rules that were applied
105-
106- Example endpoint request URL:
107-
108- https://dtulcqx04a.execute-api.us-east-1.amazonaws.com/Prod/scan_secure/?return_template=true&return_rules=true
109-
110- Example response:
111-
112- ```
113- {
114- "results": {
115- "failure_count": 1,
116- "violations": [
117- {
118- "id": "W35",
119- "type": "WARN",
120- "message": "S3 Bucket should have access logging configured",
121- "logical_resource_ids": [
122- "S3Bucket"
123- ],
124- "line_numbers": [
125- 5
126- ]
127- },
128- {
129- "id": "F14",
130- "type": "FAIL",
131- "message": "S3 Bucket should not have a public read-write acl",
132- "logical_resource_ids": [
133- "S3Bucket"
134- ],
135- "line_numbers": [
136- 5
137- ]
138- }
139- ]
140- },
141- "signature": "eKlzShFty5tCC/zXo3Cf7L0E0yCxdXejS7dAYauBc2s9eBoCfs9Lmd2AQcGR\nEwrSUzr43s+bUjqy/5Sum1JcCQ==\n",
142- "template": "ewogICJBV1NUZW1wbGF0ZUZvcm1hdFZlcnNpb24iOiAiMjAxMC0wOS0wOSIsCiAgIlJlc291cmNlcyI6IHsKICAgICAgICAiUzNCdWNrZXQiOiB7CiAgICAgICAgICAgICJUeXBlIjogIkFXUzo6UzM6OkJ1Y2tldCIsCiAgICAgICAgICAgICJQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgIkFjY2Vzc0NvbnRyb2wiOiAiUHVibGljUmVhZFdyaXRlIiwKICAgICAgICAgICAgICAgICJDb3JzQ29uZmlndXJhdGlvbiI6IHsKICAgICAgICAgICAgICAgICAgICAiQ29yc1J1bGVzIjogWwogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWxsb3dlZEhlYWRlcnMiOiBbCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIioiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFsbG93ZWRNZXRob2RzIjogWwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHRVQiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFsbG93ZWRPcmlnaW5zIjogWwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIqIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFeHBvc2VkSGVhZGVycyI6IFsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGF0ZSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSWQiOiAibXlDT1JTUnVsZUlkMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWF4QWdlIjogIjM2MDAiCiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBbGxvd2VkSGVhZGVycyI6IFsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAieC1hbXotKiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWxsb3dlZE1ldGhvZHMiOiBbCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRFTEVURSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWxsb3dlZE9yaWdpbnMiOiBbCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cuZXhhbXBsZTEuY29tIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaHR0cDovL3d3dy5leGFtcGxlMi5jb20iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkV4cG9zZWRIZWFkZXJzIjogWwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb25uZWN0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2VydmVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGF0ZSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSWQiOiAibXlDT1JTUnVsZUlkMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWF4QWdlIjogIjE4MDAiCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAogICAgIk91dHB1dHMiOiB7CiAgICAgICAgIkJ1Y2tldE5hbWUiOiB7CiAgICAgICAgICAgICJWYWx1ZSI6IHsKICAgICAgICAgICAgICAgICJSZWYiOiAiUzNCdWNrZXQiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJEZXNjcmlwdGlvbiI6ICJOYW1lIG9mIHRoZSBzYW1wbGUgQW1hem9uIFMzIGJ1Y2tldCB3aXRoIENPUlMgZW5hYmxlZC4iCiAgICAgICAgfQogICAgfQp9Cg==",
143- "rules": [
144- "W34 WARN Batch Job Definition Container Properties should not have Privileged set to true",
145- "W1 WARN Specifying credentials in the template itself is probably not the safest thing",
146- "W10 WARN CloudFront Distribution should enable access logging",
147- "W32 WARN CodeBuild project should specify an EncryptionKey value",
148- "F37 FAIL DMS Endpoint must not be a plaintext string or a Ref to a NoEcho Parameter with a Default value.",
149- "F36 FAIL Directory Service Microsoft AD must not be a plaintext string or a Ref to a NoEcho Parameter with a Default value.",
150- "F31 FAIL DirectoryService::SimpleAD should use a parameter for password, with NoEcho",
151- "W33 WARN EC2 Subnet should not have MapPublicIpOnLaunch set to true",
152- "F32 FAIL EFS FileSystem should have encryption enabled",
153- "F1 FAIL EBS volume should have server-side encryption enabled",
154- "F25 FAIL ElastiCache ReplicationGroup should have encryption enabled for at rest",
155- "F33 FAIL ElastiCache ReplicationGroup should have encryption enabled for in transit",
156- "W26 WARN Elastic Load Balancer should have access logging enabled",
157- "W17 WARN IAM managed policy should not allow Allow+NotAction",
158- "W23 WARN IAM managed policy should not allow Allow+NotResource",
159- "F5 FAIL IAM managed policy should not allow * action",
160- "W13 WARN IAM managed policy should not allow * resource",
161- "W16 WARN IAM policy should not allow Allow+NotAction",
162- "W22 WARN IAM policy should not allow Allow+NotResource",
163- "F4 FAIL IAM policy should not allow * action",
164- "W12 WARN IAM policy should not allow * resource",
165- "W15 WARN IAM role should not allow Allow+NotAction",
166- "W14 WARN IAM role should not allow Allow+NotAction on trust permissions",
167- "F6 FAIL IAM role should not allow Allow+NotPrincipal in its trust policy",
168- "W21 WARN IAM role should not allow Allow+NotResource",
169- "F3 FAIL IAM role should not allow * action on its permissions policy",
170- "F2 FAIL IAM role should not allow * action on its trust policy",
171- "W11 WARN IAM role should not allow * resource on its permissions policy",
172- "F19 FAIL EnableKeyRotation should not be false or absent on KMS::Key resource",
173- "W24 WARN Lambda permission beside InvokeFunction might not be what you want? Not sure!?",
174- "F13 FAIL Lambda permission principal should not be wildcard",
175- "F12 FAIL IAM managed policy should not apply directly to users. Should be on group",
176- "F30 FAIL Neptune database cluster storage should have encryption enabled",
177- "F11 FAIL IAM policy should not apply directly to users. Should be on group",
178- "F34 FAIL RDS DB Cluster master user password must be Ref to NoEcho Parameter. Default credentials are not recommended",
179- "F26 FAIL RDS DBCluster should have StorageEncrypted enabled",
180- "F27 FAIL RDS DBInstance should have StorageEncrypted enabled",
181- "F23 FAIL RDS instance master user password must be Ref to NoEcho Parameter. Default credentials are not recommended",
182- "F24 FAIL RDS instance master username must be Ref to NoEcho Parameter. Default credentials are not recommended",
183- "F22 FAIL RDS instance should not be publicly accessible",
184- "F28 FAIL Redshift Cluster should have encryption enabled",
185- "F35 FAIL Redshift Cluster master user password must be Ref to NoEcho Parameter. Default credentials are not recommended",
186- "W28 WARN Resource found with an explicit name, this disallows updates that require replacement of this resource",
187- "W35 WARN S3 Bucket should have access logging configured",
188- "W20 WARN S3 Bucket policy should not allow Allow+NotAction",
189- "F9 FAIL S3 Bucket policy should not allow Allow+NotPrincipal",
190- "F15 FAIL S3 Bucket policy should not allow * action",
191- "F16 FAIL S3 Bucket policy should not allow * principal",
192- "W31 WARN S3 Bucket likely should not have a public read acl",
193- "F14 FAIL S3 Bucket should not have a public read-write acl",
194- "W5 WARN Security Groups found with cidr open to world on egress",
195- "W29 WARN Security Groups found egress with port range instead of just a single port",
196- "W9 WARN Security Groups found with ingress cidr that is not /32",
197- "W2 WARN Security Groups found with cidr open to world on ingress. This should never be true on instance. Permissible on ELB",
198- "W27 WARN Security Groups found ingress with port range instead of just a single port",
199- "F1000 FAIL Missing egress rule means all traffic is allowed outbound. Make this explicit if it is desired configuration",
200- "W19 WARN SNS Topic policy should not allow Allow+NotAction",
201- "F8 FAIL SNS Topic policy should not allow Allow+NotPrincipal",
202- "F18 FAIL SNS topic policy should not allow * principal",
203- "W18 WARN SQS Queue policy should not allow Allow+NotAction",
204- "F7 FAIL SQS Queue policy should not allow Allow+NotPrincipal",
205- "F20 FAIL SQS Queue policy should not allow * action",
206- "F21 FAIL SQS Queue policy should not allow * principal",
207- "F10 FAIL IAM user should not have any inline policies. Should be centralized Policy object on group",
208- "F2000 FAIL User is not assigned to a group",
209- "F665 FAIL WebAcl DefaultAction should not be ALLOW",
210- "F29 FAIL Workspace should have encryption enabled"
211- ]
212- }
213- ```
96+ The API exposed by the Docker endpoint is cfn_nag/v1/*
21497
21598### Verifying Signatures
21699
@@ -227,48 +110,26 @@ eyJmYWlsdXJlX2NvdW50IjoxLCJ2aW9sYXRpb25zIjpbeyJpZCI6IlczNSIsInR5cGUiOiJXQVJOIiwi
227110Signature is valid!
228111```
229112
230- ### Local Development
231-
232- #### Build dependencies
233- ```
234- sam build
235- ```
236-
237- #### Test Lambda
113+ ### Deployment
238114
239- ##### Local invoke
115+ To deploy the Lambda, run ` scripts/deploy_sam.sh ` and consult the outputs for the endpoints
240116
241- ```
242- sam local invoke -e event-json.json
243- sam local invoke -e event-yaml.json
244- ```
117+ To deploy the Docker container locally:
245118
246- ##### Local API testing
119+ docker build .
120+ docker run -p 4567:4567 -e 'private_key_override=<base64 signing_key >' -e use_https=self <image_id>
247121
248- ```
249- sam local start-api
250- file=~/git/cfn_nag/spec/test_templates/json/elasticsearch/elasticsearch_domain_without_explicit_name.json
251- curl -d "{\"template_body\": \"`base64 $file`\"}" -H "Content-Type: application/json" -X POST http://127.0.0.1:3000/scan
252- ```
122+ Then hit https://localhost:4567/cfn_nag/v1/status
253123
254- ### Deployment
124+ ### HTTPS
125+ The docker image observes env var use_https to determine whether to enable SSL.
255126
256- These are typically one time tasks:
257-
258- ```
259- ./scripts/create_signing_keys
260- ./scripts/extract_libsodium.sh
261- ```
262-
263- For each deployment:
264-
265- ```
266- sam build --use-container
267- sam package --template-file .aws-sam/build/template.yaml --s3-bucket stelligent-cfn-nag-service --output-template-file packaged-template.yaml
268- sam deploy --stack-name cfn-nag-service --template-file packaged-template.yaml --capabilities CAPABILITY_IAM
269- ```
127+ none means http
128+ self means https with a self-signed cert generated by the web container
129+ cert means a certificate of your own choosing that you must generate and map it. for example:
130+ -e use_https=cert -e cert_public_path=/certs/cert.pem -e cert_private_path=/certs/key.pem -v ~ /certs:/certs
270131
271- #### Testing
132+ #### Testing - Under development
272133
273134```
274135file=~/git/cfn_nag/spec/test_templates/json/elasticsearch/elasticsearch_domain_with_explicit_name.json
0 commit comments