/
vpc.sp
1927 lines (1815 loc) · 66.4 KB
/
vpc.sp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
locals {
conformance_pack_vpc_common_tags = merge(local.aws_compliance_common_tags, {
service = "AWS/VPC"
})
}
control "vpc_flow_logs_enabled" {
title = "VPC flow logs should be enabled"
description = "The VPC flow logs provide detailed records for information about the IP traffic going to and from network interfaces in your AWS Virtual Private Cloud (AWS VPC."
query = query.vpc_flow_logs_enabled
tags = merge(local.conformance_pack_vpc_common_tags, {
cis_controls_v8_ig1 = "true"
cisa_cyber_essentials = "true"
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gdpr = "true"
gxp_21_cfr_part_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_4 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
rbi_cyber_security = "true"
soc_2 = "true"
})
}
control "vpc_security_group_remote_administration" {
title = "Ensure no security groups allow ingress from 0.0.0.0/0 to remote server administration ports"
description = "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port 22 and RDP to port 3389."
query = query.vpc_security_group_remote_administration
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_security_group_remote_administration_ipv4" {
title = "Ensure no security groups allow ingress from 0.0.0.0/0 to remote server administration ports"
description = "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port 22 and RDP to port 3389, using either the TCP (6), UDP (17) or ALL (-1) protocols."
query = query.vpc_security_group_remote_administration_ipv4
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_security_group_restrict_ingress_rdp_all" {
title = "Ensure no security groups allow ingress from 0.0.0.0/0 to port 3389"
description = "Security groups provide stateful filtering of ingress/egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to port 3389."
query = query.vpc_security_group_restrict_ingress_rdp_all
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_security_group_remote_administration_ipv6" {
title = "Ensure no security groups allow ingress from ::/0 to remote server administration ports"
description = "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port 22 and RDP to port 3389."
query = query.vpc_security_group_remote_administration_ipv6
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_security_group_unused" {
title = "Unused EC2 security groups should be removed"
description = "This AWS control checks that security groups are attached to AWS Elastic Compute Cloud (AWS EC2) instances or to an elastic network interface. The control will fail if the security group is not associated with an AWS EC2 instance or an elastic network interface."
query = query.vpc_security_group_unused
tags = local.conformance_pack_ec2_common_tags
}
control "vpc_igw_attached_to_authorized_vpc" {
title = "VPC internet gateways should be attached to authorized vpc"
description = "Manage access to resources in the AWS Cloud by ensuring that internet gateways are only attached to authorized AWS Virtual Private Cloud (AWS VPC)."
query = query.vpc_igw_attached_to_authorized_vpc
tags = merge(local.conformance_pack_vpc_common_tags, {
gxp_21_cfr_part_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_4 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
rbi_cyber_security = "true"
soc_2 = "true"
})
}
control "vpc_network_acl_remote_administration" {
title = "Network ACLs should not allow ingress from 0.0.0.0/0 to port 22 or port 3389"
description = "This control checks if default ports for SSH/RDP ingress traffic for network access control lists (NACLs) is unrestricted. The rule fails if a NACL inbound entry allows a source CIDR block of '0.0.0.0/0' or '::/0' for ports 22 or 3389."
query = query.vpc_network_acl_remote_administration
tags = merge(local.conformance_pack_vpc_common_tags, {
nist_csf = "true"
pci_dss_v321 = "true"
})
}
control "vpc_security_group_restrict_ingress_tcp_udp_all" {
title = "VPC security groups should restrict ingress TCP and UDP access from 0.0.0.0/0"
description = "Manage access to resources in the AWS Cloud by ensuring common ports are restricted on AWS Elastic Compute Cloud (AWS EC2) Security Groups."
query = query.vpc_security_group_restrict_ingress_tcp_udp_all
tags = merge(local.conformance_pack_vpc_common_tags, {
cisa_cyber_essentials = "true"
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gxp_21_cfr_part_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_4 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
rbi_cyber_security = "true"
soc_2 = "true"
})
}
control "vpc_security_group_restrict_ingress_common_ports_all" {
title = "VPC security groups should restrict ingress access on ports 20, 21, 22, 3306, 3389, 4333 from 0.0.0.0/0"
description = "Manage access to resources in the AWS Cloud by ensuring common ports are restricted on AWS Elastic Compute Cloud (AWS EC2) security groups."
query = query.vpc_security_group_restrict_ingress_common_ports_all
tags = merge(local.conformance_pack_vpc_common_tags, {
audit_manager_control_tower = "true"
cisa_cyber_essentials = "true"
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gxp_21_cfr_part_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_4 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
rbi_cyber_security = "true"
soc_2 = "true"
})
}
control "vpc_security_group_restrict_ingress_ssh_all" {
title = "VPC security groups should restrict ingress SSH access from 0.0.0.0/0"
description = "AWS Elastic Compute Cloud (AWS EC2) Security Groups can help manage network access by providing stateful filtering of ingress and egress network traffic to AWS resources."
query = query.vpc_security_group_restrict_ingress_ssh_all
tags = merge(local.conformance_pack_vpc_common_tags, {
audit_manager_control_tower = "true"
cis_controls_v8_ig1 = "true"
cisa_cyber_essentials = "true"
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gxp_21_cfr_part_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_4 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
rbi_cyber_security = "true"
soc_2 = "true"
})
}
control "vpc_default_security_group_restricts_all_traffic" {
title = "VPC default security group should not allow inbound and outbound traffic"
description = "AWS Elastic Compute Cloud (AWS EC2) security groups can help in the management of network access by providing stateful filtering of ingress and egress network traffic to AWS resources."
query = query.vpc_default_security_group_restricts_all_traffic
tags = merge(local.conformance_pack_vpc_common_tags, {
cis_controls_v8_ig1 = "true"
cisa_cyber_essentials = "true"
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gxp_21_cfr_part_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_4 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
rbi_cyber_security = "true"
soc_2 = "true"
})
}
control "vpc_vpn_tunnel_up" {
title = "Both VPN tunnels provided by AWS Site-to-Site VPN should be in UP status"
description = "Redundant Site-to-Site VPN tunnels can be implemented to achieve resilience requirements."
query = query.vpc_vpn_tunnel_up
tags = merge(local.conformance_pack_vpc_common_tags, {
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gxp_21_cfr_part_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_53_rev_4 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
})
}
control "vpc_eip_associated" {
title = "VPC EIPs should be associated with an EC2 instance or ENI"
description = "This rule ensures Elastic IPs allocated to a AWS Virtual Private Cloud (AWS VPC) are attached to AWS Elastic Compute Cloud (AWS EC2) instances or in-use Elastic Network Interfaces."
query = query.vpc_eip_associated
tags = merge(local.conformance_pack_vpc_common_tags, {
cis_controls_v8_ig1 = "true"
cisa_cyber_essentials = "true"
ffiec = "true"
nist_800_171_rev_2 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
soc_2 = "true"
})
}
control "vpc_security_group_associated_to_eni" {
title = "VPC security groups should be associated with at least one ENI"
description = "This rule ensures the security groups are attached to an AWS Elastic Compute Cloud (AWS EC2) instance or to an ENI. This rule helps monitoring unused security groups in the inventory and the management of your environment."
query = query.vpc_security_group_associated_to_eni
tags = merge(local.conformance_pack_vpc_common_tags, {
cis_controls_v8_ig1 = "true"
nist_800_171_rev_2 = "true"
soc_2 = "true"
})
}
control "vpc_subnet_auto_assign_public_ip_disabled" {
title = "VPC subnet auto assign public IP should be disabled"
description = "Ensure that AWS Virtual Private Cloud (AWS VPC) subnets are assigned a public IP address. The control is compliant if AWS VPC does not have subnets that are assigned a public IP address. The control is non-compliant if AWS VPC has subnets that are assigned a public IP address."
query = query.vpc_subnet_auto_assign_public_ip_disabled
tags = merge(local.conformance_pack_vpc_common_tags, {
cis_controls_v8_ig1 = "true"
cisa_cyber_essentials = "true"
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gxp_21_cfr_part_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
rbi_cyber_security = "true"
})
}
control "vpc_route_table_restrict_public_access_to_igw" {
title = "VPC route table should restrict public access to IGW"
description = "Ensure that there are public routes in the route table to an Internet Gateway (IGW). The rule is non-compliant if a route to an IGW has a destination CIDR block of '0.0.0.0/0' or '::/0'."
query = query.vpc_route_table_restrict_public_access_to_igw
tags = merge(local.conformance_pack_vpc_common_tags, {
cisa_cyber_essentials = "true"
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gxp_21_cfr_part_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
rbi_cyber_security = "true"
})
}
control "vpc_security_group_restrict_ingress_redis_port" {
title = "VPC security groups should restrict ingress redis access from 0.0.0.0/0"
description = "AWS VPC security groups can help in managing network access by providing stateful filtering of ingress and egress network traffic to AWS resources."
query = query.vpc_security_group_restrict_ingress_redis_port
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_security_group_restrict_ingress_kafka_port" {
title = "VPC security groups should restrict ingress Kafka port access from 0.0.0.0/0"
description = "AWS VPC security groups can help in managing network access by providing stateful filtering of ingress and egress network traffic to AWS resources."
query = query.vpc_security_group_restrict_ingress_kafka_port
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_security_group_restrict_ingress_kibana_port" {
title = "VPC security groups should restrict ingress kibana port access from 0.0.0.0/0"
description = "AWS VPC security groups can help in managing network access by providing stateful filtering of ingress and egress network traffic to AWS resources."
query = query.vpc_security_group_restrict_ingress_kibana_port
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_security_group_not_uses_launch_wizard_sg" {
title = "VPC security groups should restrict uses of 'launch-wizard' security groups."
description = "Ensure the launch-wizard security group in your AWS account is not being used."
query = query.vpc_security_group_not_uses_launch_wizard_sg
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_endpoint_service_acceptance_required_enabled" {
title = "VPC endpoint services should have acceptance required enabled"
description = "Ensure VPC endpoints connection requests to the service are accepted by the service owner."
query = query.vpc_endpoint_service_acceptance_required_enabled
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_network_acl_unused" {
title = "VPC network access control lists (network ACLs) should be associated with a subnet."
description = "Ensure there are no unused network access control lists (network ACLs). The rule is compliant if each network ACL is associated with a subnet. The rule is non-compliant if a network ACL is not associated with a subnet."
query = query.vpc_network_acl_unused
tags = merge(local.conformance_pack_vpc_common_tags, {
cis_controls_v8_ig1 = "true"
cisa_cyber_essentials = "true"
nist_csf = "true"
})
}
control "vpc_configured_to_use_vpc_endpoints" {
title = "VPC should be configured to use VPC endpoints"
description = "Checks if Service Endpoint for the service provided in rule parameter is created for each AWS Virtual Private Cloud (AWS VPC). The rule is non-compliant if an AWS VPC doesn't have an AWS VPC endpoint created for the service."
query = query.vpc_configured_to_use_vpc_endpoints
tags = merge(local.conformance_pack_vpc_common_tags, {
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
})
}
control "vpc_security_group_restricted_common_ports" {
title = "Security groups should not allow unrestricted access to ports with high risk"
description = "This control checks whether unrestricted incoming traffic for the security groups is accessible to the specified ports that have the highest risk. This control passes when none of the rules in a security group allow ingress traffic from 0.0.0.0/0 for those ports."
query = query.vpc_security_group_restricted_common_ports
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_security_group_allows_ingress_authorized_ports" {
title = "VPC Security groups should only allow unrestricted incoming traffic for authorized ports"
description = "This control checks whether the VPC security groups that are in use allow unrestricted incoming traffic. Optionally the rule checks whether the port numbers are listed in the authorizedTcpPorts parameter. The default values for authorizedTcpPorts are 80 and 443."
query = query.vpc_security_group_allows_ingress_authorized_ports
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_security_group_allows_ingress_to_cassandra_ports" {
title = "VPC security groups should restrict ingress from 0.0.0.0/0 or ::/0 to cassandra ports 7199 or 9160 or 8888"
description = "This control checks whether the VPC security groups allow ingress from 0.0.0.0/0 or ::/0 to cassandra ports 7199 or 9160 or 8888. This control passes when none of the rules in a security group allow ingress traffic from 0.0.0.0/0 from ports 7199 or 9160 or 8888."
query = query.vpc_security_group_allows_ingress_to_cassandra_ports
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_security_group_allows_ingress_to_memcached_port" {
title = "VPC security groups should restrict ingress from 0.0.0.0/0 or ::/0 to memcached port 11211"
description = "This control checks whether the VPC security groups that are in use allow allow ingress from 0.0.0.0/0 or ::/0 to memcached port 11211. Optionally the rule checks whether the port numbers are listed in the authorizedTcpPorts parameter. This control passes when none of the rules in a security group allow ingress traffic from 0.0.0.0/0 from port 11211."
query = query.vpc_security_group_allows_ingress_to_memcached_port
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_security_group_allows_ingress_to_mongodb_ports" {
title = "VPC security groups should restrict ingress from 0.0.0.0/0 or ::/0 to mongoDB ports 27017 and 27018"
description = "This control checks whether the VPC security groups that are in use allow ingress from 0.0.0.0/0 or ::/0 to mongoDB ports 27017 and 27018. Optionally the rule checks whether the port numbers are listed in the authorizedTcpPorts parameter. This control passes when none of the rules in a security group allow ingress traffic from 0.0.0.0/0 from ports 27017 and 27018."
query = query.vpc_security_group_allows_ingress_to_mongodb_ports
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_security_group_allows_ingress_to_oracle_ports" {
title = "VPC security groups should restrict ingress from 0.0.0.0/0 or ::/0 to oracle ports 1521 or 2483"
description = "This control checks whether the VPC security groups that are in use allow ingress from 0.0.0.0/0 or ::/0 to oracle ports 1521 or 2483. Optionally the rule checks whether the port numbers are listed in the authorizedTcpPorts parameter. This control passes when none of the rules in a security group allow ingress traffic from 0.0.0.0/0 from ports 1521 or 2483."
query = query.vpc_security_group_allows_ingress_to_oracle_ports
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_in_more_than_one_region" {
title = "VPCs should exist in multiple regions"
description = "This control checks whether there are VPCs present in multiple regions."
query = query.vpc_in_more_than_one_region
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_subnet_multi_az_enabled" {
title = "VPCs subnets should exist in multiple availability zones"
description = "Ensure that each VPC has subnets spread across multiple availability zones."
query = query.vpc_subnet_multi_az_enabled
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_subnet_public_and_private" {
title = "VPCs should have both public and private subnets configured"
description = "Ensure that all VPCs have both public and private subnets configured."
query = query.vpc_subnet_public_and_private
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_peering_connection_route_table_least_privilege" {
title = "VPCs peering connection route tables should have least privilege"
description = "Ensure that all VPCs peering connection route tables have least privilege."
query = query.vpc_peering_connection_route_table_least_privilege
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_not_in_use" {
title = "VPCs should be in use"
description = "This control checks whether there are any unused VPCs."
query = query.vpc_not_in_use
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_peering_connection_no_cross_account_access" {
title = "VPCs peering connection should not be allowed in cross account"
description = "Ensure that all VPCs peering connection are not having cross account access."
query = query.vpc_peering_connection_no_cross_account_access
tags = local.conformance_pack_vpc_common_tags
}
control "vpc_gateway_endpoint_restrict_public_access" {
title = "VPC gateway endpoints should restrict public access"
description = "Manage access to resources in the AWS Cloud by ensuring VPC gateway endpoints cannot be publicly accessed."
query = query.vpc_gateway_endpoint_restrict_public_access
tags = local.conformance_pack_vpc_common_tags
}
query "vpc_flow_logs_enabled" {
sql = <<-EOQ
select
distinct arn as resource,
case
when v.account_id <> v.owner_id then 'skip'
when f.resource_id is not null then 'ok'
else 'alarm'
end as status,
case
when v.account_id <> v.owner_id then vpc_id || ' is a shared VPC.'
when f.resource_id is not null then vpc_id || ' flow logging enabled.'
else vpc_id || ' flow logging disabled.'
end as reason
${replace(local.tag_dimensions_qualifier_sql, "__QUALIFIER__", "v.")}
${replace(local.common_dimensions_qualifier_sql, "__QUALIFIER__", "v.")}
from
aws_vpc as v
left join aws_vpc_flow_log as f on v.vpc_id = f.resource_id;
EOQ
}
query "vpc_igw_attached_to_authorized_vpc" {
sql = <<-EOQ
select
'arn:' || partition || ':ec2:' || region || ':' || account_id || ':internet-gateway/' || title as resource,
case
when jsonb_array_length(attachments) = 0 then 'alarm'
else 'ok'
end as status,
case
when jsonb_array_length(attachments) = 0 then title || ' not attached to VPC.'
else title || ' attached to ' || split_part(
substring(attachments :: text, 3, length(attachments :: text) -6),
'"VpcId": "',
2
) || '.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_vpc_internet_gateway;
EOQ
}
query "vpc_network_acl_remote_administration" {
sql = <<-EOQ
with bad_rules as (
select
network_acl_id,
count(*) as num_bad_rules
from
aws_vpc_network_acl,
jsonb_array_elements(entries) as att
where
att ->> 'Egress' = 'false' -- as per aws egress = false indicates the ingress
and (
att ->> 'CidrBlock' = '0.0.0.0/0'
or att ->> 'Ipv6CidrBlock' = '::/0'
)
and att ->> 'RuleAction' = 'allow'
and (
(
att ->> 'Protocol' = '-1' -- all traffic
and att ->> 'PortRange' is null
)
or (
(att -> 'PortRange' ->> 'From') :: int <= 22
and (att -> 'PortRange' ->> 'To') :: int >= 22
and att ->> 'Protocol' in('6', '17') -- TCP or UDP
)
or (
(att -> 'PortRange' ->> 'From') :: int <= 3389
and (att -> 'PortRange' ->> 'To') :: int >= 3389
and att ->> 'Protocol' in('6', '17') -- TCP or UDP
)
)
group by
network_acl_id
)
select
'arn:' || acl.partition || ':ec2:' || acl.region || ':' || acl.account_id || ':network-acl/' || acl.network_acl_id as resource,
case
when bad_rules.network_acl_id is null then 'ok'
else 'alarm'
end as status,
case
when bad_rules.network_acl_id is null then acl.network_acl_id || ' does not allow ingress to port 22 or 3389 from 0.0.0.0/0 or ::/0.'
else acl.network_acl_id || ' contains ' || bad_rules.num_bad_rules || ' rule(s) allowing ingress to port 22 or 3389 from 0.0.0.0/0 or ::/0.'
end as reason
${local.tag_dimensions_sql}
${replace(local.common_dimensions_qualifier_sql, "__QUALIFIER__", "acl.")}
from
aws_vpc_network_acl as acl
left join bad_rules on bad_rules.network_acl_id = acl.network_acl_id;
EOQ
}
query "vpc_security_group_restrict_ingress_tcp_udp_all" {
sql = <<-EOQ
with bad_rules as (
select
group_id,
count(*) as num_bad_rules
from
aws_vpc_security_group_rule
where
type = 'ingress'
and cidr_ipv4 = '0.0.0.0/0'
and (
ip_protocol in ('tcp', 'udp')
or (
ip_protocol = '-1'
and from_port is null
)
)
group by
group_id
)
select
arn as resource,
case
when bad_rules.group_id is null then 'ok'
else 'alarm'
end as status,
case
when bad_rules.group_id is null then sg.group_id || ' does not allow ingress to TCP or UDP ports from 0.0.0.0/0.'
else sg.group_id || ' contains ' || bad_rules.num_bad_rules || ' rule(s) that allow ingress to TCP or UDP ports from 0.0.0.0/0.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_vpc_security_group as sg
left join bad_rules on bad_rules.group_id = sg.group_id;
EOQ
}
query "vpc_security_group_restrict_ingress_common_ports_all" {
sql = <<-EOQ
with ingress_ssh_rules as (
select
group_id,
count(*) as num_ssh_rules
from
aws_vpc_security_group_rule
where
type = 'ingress'
and cidr_ipv4 = '0.0.0.0/0'
and (
( ip_protocol = '-1'
and from_port is null
)
or (
from_port >= 22
and to_port <= 22
)
or (
from_port >= 3389
and to_port <= 3389
)
or (
from_port >= 21
and to_port <= 21
)
or (
from_port >= 20
and to_port <= 20
)
or (
from_port >= 3306
and to_port <= 3306
)
or (
from_port >= 4333
and to_port <= 4333
)
)
group by
group_id
)
select
arn as resource,
case
when ingress_ssh_rules.group_id is null then 'ok'
else 'alarm'
end as status,
case
when ingress_ssh_rules.group_id is null then sg.group_id || ' ingress restricted for ports 20, 21, 22, 3306, 3389, 4333 from 0.0.0.0/0.'
else sg.group_id || ' contains ' || ingress_ssh_rules.num_ssh_rules || ' ingress rule(s) allowing access on ports 20, 21, 22, 3306, 3389, 4333 from 0.0.0.0/0.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_vpc_security_group as sg
left join ingress_ssh_rules on ingress_ssh_rules.group_id = sg.group_id;
EOQ
}
query "vpc_security_group_restrict_ingress_ssh_all" {
sql = <<-EOQ
with ingress_ssh_rules as (
select
group_id,
count(*) as num_ssh_rules
from
aws_vpc_security_group_rule
where
type = 'ingress'
and cidr_ipv4 = '0.0.0.0/0'
and (
( ip_protocol = '-1'
and from_port is null
)
or (
from_port >= 22
and to_port <= 22
)
)
group by
group_id
)
select
arn as resource,
case
when ingress_ssh_rules.group_id is null then 'ok'
else 'alarm'
end as status,
case
when ingress_ssh_rules.group_id is null then sg.group_id || ' ingress restricted for SSH from 0.0.0.0/0.'
else sg.group_id || ' contains ' || ingress_ssh_rules.num_ssh_rules || ' ingress rule(s) allowing SSH from 0.0.0.0/0.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_vpc_security_group as sg
left join ingress_ssh_rules on ingress_ssh_rules.group_id = sg.group_id;
EOQ
}
query "vpc_default_security_group_restricts_all_traffic" {
sql = <<-EOQ
select
arn resource,
case
when jsonb_array_length(ip_permissions) = 0 and jsonb_array_length(ip_permissions_egress) = 0 then 'ok'
else 'alarm'
end status,
case
when jsonb_array_length(ip_permissions) > 0 and jsonb_array_length(ip_permissions_egress) > 0
then 'Default security group ' || group_id || ' has inbound and outbound rules.'
when jsonb_array_length(ip_permissions) > 0 and jsonb_array_length(ip_permissions_egress) = 0
then 'Default security group ' || group_id || ' has inbound rules.'
when jsonb_array_length(ip_permissions) = 0 and jsonb_array_length(ip_permissions_egress) > 0
then 'Default security group ' || group_id || ' has outbound rules.'
else 'Default security group ' || group_id || ' has no inbound or outbound rules.'
end reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_vpc_security_group
where
group_name = 'default';
EOQ
}
query "vpc_vpn_tunnel_up" {
sql = <<-EOQ
with filter_data as (
select
arn,
count(t ->> 'Status')
from
aws_vpc_vpn_connection,
jsonb_array_elements(vgw_telemetry) as t
where t ->> 'Status' = 'UP'
group by arn
)
select
a.arn as resource,
case
when b.count is null or b.count < 2 then 'alarm'
else 'ok'
end as status,
case
when b.count is null then a.title || ' has both tunnels offline.'
when b.count = 1 then a.title || ' has one tunnel offline.'
else a.title || ' has both tunnels online.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_vpc_vpn_connection as a
left join filter_data as b on a.arn = b.arn;
EOQ
}
query "vpc_eip_associated" {
sql = <<-EOQ
select
'arn:' || partition || ':ec2:' || region || ':' || account_id || ':eip/' || allocation_id as resource,
case
when association_id is null then 'alarm'
else 'ok'
end status,
case
when association_id is null then title || ' is not associated with any resource.'
else title || ' is associated with a resource.'
end reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_vpc_eip;
EOQ
}
query "vpc_security_group_associated_to_eni" {
sql = <<-EOQ
with associated_sg as (
select
count(sg ->> 'GroupId'),
sg ->> 'GroupId' as secgrp_id
from
aws_ec2_network_interface,
jsonb_array_elements(groups) as sg
group by sg ->> 'GroupId'
)
select
distinct s.arn as resource,
case
when a.secgrp_id = s.group_id then 'ok'
else 'alarm'
end as status,
case
when a.secgrp_id = s.group_id then s.title || ' is associated with ' || a.count || ' ENI(s).'
else s.title || ' not associated to any ENI.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_vpc_security_group as s
left join associated_sg as a on s.group_id = a.secgrp_id;
EOQ
}
query "vpc_subnet_auto_assign_public_ip_disabled" {
sql = <<-EOQ
select
subnet_id as resource,
case
when map_public_ip_on_launch = 'false' then 'ok'
else 'alarm'
end as status,
case
when map_public_ip_on_launch = 'false' then title || ' auto assign public IP disabled.'
else title || ' auto assign public IP enabled.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_vpc_subnet;
EOQ
}
query "vpc_route_table_restrict_public_access_to_igw" {
sql = <<-EOQ
with route_with_public_access as (
select
route_table_id,
count(*) as num
from
aws_vpc_route_table,
jsonb_array_elements(routes) as r
where
( r ->> 'DestinationCidrBlock' = '0.0.0.0/0'
or r ->> 'DestinationCidrBlock' = '::/0'
)
and r ->> 'GatewayId' like 'igw%'
group by
route_table_id
)
select
a.route_table_id as resource,
case
when b.route_table_id is null then 'ok'
else 'alarm'
end as status,
case
when b.route_table_id is null then a.title || ' does not have public routes to an Internet Gateway (IGW)'
else a.title || ' contains ' || b.num || ' rule(s) which have public routes to an Internet Gateway (IGW)'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_vpc_route_table as a
left join route_with_public_access as b on b.route_table_id = a.route_table_id;
EOQ
}
query "vpc_security_group_restrict_ingress_redis_port" {
sql = <<-EOQ
with ingress_redis_port as (
select
group_id,
count(*) as num_redis_rules
from
aws_vpc_security_group_rule
where
type = 'ingress'
and
(cidr_ipv4 = '0.0.0.0/0'
or cidr_ipv6 = '::/0')
and
(
( ip_protocol = '-1'
and from_port is null
)
or (
from_port >= 6379
and to_port <= 6379
)
)
group by
group_id
)
select
arn as resource,
case
when ingress_redis_port.group_id is null then 'ok'
else 'alarm'
end as status,
case
when ingress_redis_port.group_id is null then sg.group_id || ' restricted ingress from 0.0.0.0/0 or ::/0 to Redis port 6379.'
else sg.group_id || ' contains ' || ingress_redis_port.num_redis_rules || ' ingress rule(s) from 0.0.0.0/0 or ::/0 to Redis port 6379.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_vpc_security_group as sg
left join ingress_redis_port on ingress_redis_port.group_id = sg.group_id;
EOQ
}
query "vpc_security_group_restrict_ingress_kafka_port" {
sql = <<-EOQ
with ingress_kafka_port as (
select
group_id,
count(*) as num_ssh_rules
from
aws_vpc_security_group_rule
where
type = 'ingress'
and (
cidr_ipv4 = '0.0.0.0/0'
or cidr_ipv6 = '::/0'
)
and (
( ip_protocol = '-1'
and from_port is null
)
or (
from_port >= 9092
and to_port <= 9092
)
)
group by
group_id
)
select
arn as resource,
case
when k.group_id is null then 'ok'
else 'alarm'
end as status,
case
when k.group_id is null then sg.group_id || ' ingress restricted for kafka port from 0.0.0.0/0.'
else sg.group_id || ' contains ' || k.num_ssh_rules || ' ingress rule(s) allowing kafka port from 0.0.0.0/0.'
end as reason
${local.tag_dimensions_sql}
${replace(local.common_dimensions_qualifier_sql, "__QUALIFIER__", "sg.")}
from
aws_vpc_security_group as sg
left join ingress_kafka_port as k on k.group_id = sg.group_id;
EOQ
}
query "vpc_security_group_restrict_ingress_kibana_port" {
sql = <<-EOQ
with ingress_kibana_port as (
select
group_id,
count(*) as num_ssh_rules
from
aws_vpc_security_group_rule
where
type = 'ingress'
and (
cidr_ipv4 = '0.0.0.0/0'
or cidr_ipv6 = '::/0'
)
and (
( ip_protocol = '-1'
and from_port is null
)
or (
from_port >= 9200
and to_port <= 9200
)
or (
from_port >= 5601
and to_port <= 5601
)
)
group by
group_id
)
select
arn as resource,
case
when k.group_id is null then 'ok'
else 'alarm'
end as status,
case
when k.group_id is null then sg.group_id || ' ingress restricted for kibana port from 0.0.0.0/0.'
else sg.group_id || ' contains ' || k.num_ssh_rules || ' ingress rule(s) allowing kibana port from 0.0.0.0/0.'
end as reason
${local.tag_dimensions_sql}
${replace(local.common_dimensions_qualifier_sql, "__QUALIFIER__", "sg.")}
from
aws_vpc_security_group as sg
left join ingress_kibana_port as k on k.group_id = sg.group_id;
EOQ
}
query "vpc_security_group_not_uses_launch_wizard_sg" {
sql = <<-EOQ
with associated_sg as (
select
distinct (sg ->> 'GroupName') as sg_name
from
aws_ec2_network_interface,
jsonb_array_elements(groups) as sg
where
(sg ->> 'GroupName') like 'launch-wizard%'
)
select
arn as resource,
case
when a.sg_name is null then 'ok'
else 'alarm'
end as status,