elb.tf 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. # Architecture:
  2. # 1. DNS points to an NLB
  3. # 2. NLB:22 forwards to instance:22
  4. # 3. NLB:443 forward to an ALB, which forwards to the instance
  5. # 4. NLB:80 forwards to the same ALB, which forwards to the instance.
  6. #
  7. # The module "static_nlb_to_alb" takes care of #3, but the rest
  8. # we have to handle here.
  9. #
  10. # tfsec:ignore:aws-elb-alb-not-public Purposefully public
  11. module "elb" {
  12. source = "../../submodules/load_balancer/static_nlb_to_alb"
  13. name = "github"
  14. subject_alternative_names = ["*.github.${var.dns_info["public"]["zone"]}"]
  15. target_ids = aws_instance.ghe[*].id
  16. listener_port = 443
  17. target_port = 443
  18. target_protocol = "HTTPS"
  19. target_security_group = aws_security_group.ghe_server.id
  20. allow_from_any = true
  21. redirect_80 = false # GitHub handles port 80, and needs it for LetsEncrypt
  22. # WAF variables
  23. waf_enabled = true # TODO: Turn this on
  24. fqdns = local.hostnames
  25. # Set WAF to 'count' for now
  26. block_settings = {
  27. "default" = true # Default action. False = count
  28. "custom" = true # XDR Custom Rules. False = count
  29. "admin" = true # Block admin pages.
  30. "AWSManagedRulesCommonRuleSet" = true
  31. "AWSManagedRulesAmazonIpReputationList" = true
  32. "AWSManagedRulesKnownBadInputsRuleSet" = true
  33. "AWSManagedRulesSQLiRuleSet" = false # Irrelevant, module is disabled
  34. "AWSManagedRulesLinuxRuleSet" = false # Irrelevant, module is disabled
  35. "AWSManagedRulesUnixRuleSet" = false # Irrelevant, module is disabled
  36. }
  37. excluded_rules_AWSManagedRulesCommonRuleSet = [
  38. "SizeRestrictions_BODY", # SAML auth
  39. "RestrictedExtensions_URIPATH", # Lots of prohibited extensions, e.g. props.conf
  40. "RestrictedExtensions_QUERYARGUMENTS", # Again, prohibited extensions don't work here
  41. "CrossSiteScripting_BODY", # 2022-05-23 George Starcher's legit updates being blocked
  42. "EC2MetaDataSSRF_BODY", # 2022-05-23 George Starcher's legit updates being blocked
  43. "GenericLFI_BODY", # 2022-08-01 George Starcher's legit updates being blocked
  44. ]
  45. #excluded_rules_AWSManagedRulesAmazonIpReputationList = []
  46. #excluded_rules_AWSManagedRulesKnownBadInputsRuleSet = []
  47. #excluded_rules_AWSManagedRulesSQLiRuleSet = [] # Module disabled
  48. #excluded_rules_AWSManagedRulesLinuxRuleSet = [] # Module disabled
  49. #excluded_rules_AWSManagedRulesUnixRuleSet = [] # Module disabled
  50. # Excluded Rulesets
  51. # There are too many hostnames, so we have to disable some
  52. excluded_set_AWSManagedRulesCommonRuleSet = false
  53. excluded_set_AWSManagedRulesAmazonIpReputationList = false
  54. excluded_set_AWSManagedRulesKnownBadInputsRuleSet = false
  55. excluded_set_AWSManagedRulesSQLiRuleSet = true
  56. excluded_set_AWSManagedRulesLinuxRuleSet = true
  57. excluded_set_AWSManagedRulesUnixRuleSet = true
  58. #additional_blocked_ips = []
  59. #allowed_ips = []
  60. admin_ips = local.trusted_ips
  61. # Optional Variables
  62. healthcheck_port = 443
  63. healthcheck_protocol = "HTTPS"
  64. healthcheck_path = "/status"
  65. healthcheck_matcher = "200"
  66. stickiness = false
  67. # Inherited Variables
  68. tags = merge(local.standard_tags, var.tags)
  69. dns_info = var.dns_info
  70. public_subnets = var.public_subnets
  71. environment = var.environment
  72. aws_partition = var.aws_partition
  73. aws_region = var.aws_region
  74. aws_account_id = var.aws_account_id
  75. vpc_id = var.vpc_id
  76. providers = {
  77. aws.mdr-common-services-commercial = aws.mdr-common-services-commercial
  78. aws.c2 = aws.c2
  79. }
  80. }
  81. # Github Needs a Wildcard Record
  82. module "public_dns_record_wildcard" {
  83. source = "../../submodules/dns/public_ALIAS_record"
  84. name = "*.github.${var.dns_info["public"]["zone"]}"
  85. target_dns_name = module.elb.nlb.dns_name
  86. target_zone_id = module.elb.nlb.zone_id
  87. dns_info = var.dns_info
  88. providers = {
  89. aws.mdr-common-services-commercial = aws.mdr-common-services-commercial
  90. }
  91. }
  92. #################################
  93. # Add port 80 to the ALB and NLB
  94. #
  95. # GHE uses LetsEncrypt, which needs access on port 80.
  96. # ALB side
  97. resource "aws_lb_target_group" "github_alb_80" {
  98. name_prefix = "gita80"
  99. port = 80
  100. protocol = "HTTP"
  101. vpc_id = var.vpc_id
  102. health_check {
  103. protocol = "HTTPS"
  104. port = 443
  105. path = "/status"
  106. matcher = "200"
  107. timeout = "4"
  108. interval = "5"
  109. }
  110. lifecycle {
  111. create_before_destroy = true
  112. }
  113. tags = merge(local.standard_tags, var.tags)
  114. }
  115. resource "aws_lb_target_group_attachment" "github_alb_80" {
  116. for_each = toset(aws_instance.ghe[*].id)
  117. target_group_arn = aws_lb_target_group.github_alb_80.arn
  118. target_id = each.value
  119. port = 80
  120. }
  121. resource "aws_lb_listener" "github_alb_80" {
  122. load_balancer_arn = module.elb.alb_id
  123. port = "80" # tfsec:ignore:aws-elb-http-not-used HTTP only used for letsencrypt and redirect
  124. protocol = "HTTP"
  125. default_action {
  126. type = "forward"
  127. target_group_arn = aws_lb_target_group.github_alb_80.arn
  128. }
  129. lifecycle {
  130. create_before_destroy = true
  131. }
  132. tags = merge(local.standard_tags, var.tags)
  133. }
  134. resource "aws_security_group_rule" "github_alb_80" {
  135. description = "Github - Allow 80 from any"
  136. type = "ingress"
  137. from_port = 80
  138. to_port = 80
  139. protocol = "tcp"
  140. cidr_blocks = ["0.0.0.0/0"] # tfsec:ignore:aws-vpc-no-public-ingress-sgr Intentionally Open
  141. security_group_id = module.elb.security_group_id
  142. }
  143. resource "aws_security_group_rule" "github_alb_80_out" {
  144. description = "Github - Allow 80 to the instances"
  145. type = "egress"
  146. from_port = 80
  147. to_port = 80
  148. protocol = "tcp"
  149. source_security_group_id = aws_security_group.ghe_server.id
  150. security_group_id = module.elb.security_group_id
  151. }
  152. # NLB Side
  153. resource "aws_lb_target_group" "github_nlb_80" {
  154. name_prefix = "gitn80"
  155. target_type = "alb"
  156. port = 80
  157. protocol = "TCP"
  158. vpc_id = var.vpc_id
  159. lifecycle {
  160. create_before_destroy = true
  161. }
  162. tags = merge(local.standard_tags, var.tags)
  163. }
  164. resource "aws_lb_target_group_attachment" "github_nlb_80" {
  165. target_group_arn = aws_lb_target_group.github_nlb_80.arn
  166. target_id = module.elb.alb_id
  167. port = 80
  168. }
  169. resource "aws_lb_listener" "github_nlb_80" {
  170. load_balancer_arn = module.elb.nlb_id
  171. port = "80"
  172. protocol = "TCP" # tfsec:ignore:aws-elb-http-not-used HTTP only for letsencrypt and redirects
  173. default_action {
  174. type = "forward"
  175. target_group_arn = aws_lb_target_group.github_nlb_80.arn
  176. }
  177. lifecycle {
  178. create_before_destroy = true
  179. }
  180. tags = merge(local.standard_tags, var.tags)
  181. }
  182. ##########################
  183. # Add port 22 to the NLB
  184. resource "aws_lb_target_group" "github_ssh" {
  185. name_prefix = "gitssh"
  186. port = 22
  187. protocol = "TCP"
  188. vpc_id = var.vpc_id
  189. lifecycle {
  190. create_before_destroy = true
  191. }
  192. tags = merge(local.standard_tags, var.tags)
  193. }
  194. resource "aws_lb_target_group_attachment" "github_ssh" {
  195. for_each = toset(aws_instance.ghe[*].id)
  196. target_group_arn = aws_lb_target_group.github_ssh.arn
  197. target_id = each.value
  198. port = 22
  199. }
  200. resource "aws_lb_listener" "github_ssh" {
  201. load_balancer_arn = module.elb.nlb_id
  202. port = "22"
  203. protocol = "TCP"
  204. default_action {
  205. type = "forward"
  206. target_group_arn = aws_lb_target_group.github_ssh.arn
  207. }
  208. lifecycle {
  209. create_before_destroy = true
  210. }
  211. tags = merge(local.standard_tags, var.tags)
  212. }