elb.tf 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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. ]
  44. #excluded_rules_AWSManagedRulesAmazonIpReputationList = []
  45. #excluded_rules_AWSManagedRulesKnownBadInputsRuleSet = []
  46. #excluded_rules_AWSManagedRulesSQLiRuleSet = [] # Module disabled
  47. #excluded_rules_AWSManagedRulesLinuxRuleSet = [] # Module disabled
  48. #excluded_rules_AWSManagedRulesUnixRuleSet = [] # Module disabled
  49. # Excluded Rulesets
  50. # There are too many hostnames, so we have to disable some
  51. excluded_set_AWSManagedRulesCommonRuleSet = false
  52. excluded_set_AWSManagedRulesAmazonIpReputationList = false
  53. excluded_set_AWSManagedRulesKnownBadInputsRuleSet = false
  54. excluded_set_AWSManagedRulesSQLiRuleSet = true
  55. excluded_set_AWSManagedRulesLinuxRuleSet = true
  56. excluded_set_AWSManagedRulesUnixRuleSet = true
  57. #additional_blocked_ips = []
  58. #allowed_ips = []
  59. admin_ips = local.trusted_ips
  60. # Optional Variables
  61. healthcheck_port = 443
  62. healthcheck_protocol = "HTTPS"
  63. healthcheck_path = "/status"
  64. healthcheck_matcher = "200"
  65. stickiness = false
  66. # Inherited Variables
  67. tags = merge(local.standard_tags, var.tags)
  68. dns_info = var.dns_info
  69. public_subnets = var.public_subnets
  70. environment = var.environment
  71. aws_partition = var.aws_partition
  72. aws_region = var.aws_region
  73. aws_account_id = var.aws_account_id
  74. vpc_id = var.vpc_id
  75. providers = {
  76. aws.mdr-common-services-commercial = aws.mdr-common-services-commercial
  77. aws.c2 = aws.c2
  78. }
  79. }
  80. # Github Needs a Wildcard Record
  81. module "public_dns_record_wildcard" {
  82. source = "../../submodules/dns/public_ALIAS_record"
  83. name = "*.github.${var.dns_info["public"]["zone"]}"
  84. target_dns_name = module.elb.nlb.dns_name
  85. target_zone_id = module.elb.nlb.zone_id
  86. dns_info = var.dns_info
  87. providers = {
  88. aws.mdr-common-services-commercial = aws.mdr-common-services-commercial
  89. }
  90. }
  91. #################################
  92. # Add port 80 to the ALB and NLB
  93. #
  94. # GHE uses LetsEncrypt, which needs access on port 80.
  95. # ALB side
  96. resource "aws_lb_target_group" "github_alb_80" {
  97. name_prefix = "gita80"
  98. port = 80
  99. protocol = "HTTP"
  100. vpc_id = var.vpc_id
  101. health_check {
  102. protocol = "HTTPS"
  103. port = 443
  104. path = "/status"
  105. matcher = "200"
  106. timeout = "4"
  107. interval = "5"
  108. }
  109. lifecycle {
  110. create_before_destroy = true
  111. }
  112. tags = merge(local.standard_tags, var.tags)
  113. }
  114. resource "aws_lb_target_group_attachment" "github_alb_80" {
  115. for_each = toset(aws_instance.ghe[*].id)
  116. target_group_arn = aws_lb_target_group.github_alb_80.arn
  117. target_id = each.value
  118. port = 80
  119. }
  120. resource "aws_lb_listener" "github_alb_80" {
  121. load_balancer_arn = module.elb.alb_id
  122. port = "80" # tfsec:ignore:aws-elb-http-not-used HTTP only used for letsencrypt and redirect
  123. protocol = "HTTP"
  124. default_action {
  125. type = "forward"
  126. target_group_arn = aws_lb_target_group.github_alb_80.arn
  127. }
  128. lifecycle {
  129. create_before_destroy = true
  130. }
  131. tags = merge(local.standard_tags, var.tags)
  132. }
  133. resource "aws_security_group_rule" "github_alb_80" {
  134. description = "Github - Allow 80 from any"
  135. type = "ingress"
  136. from_port = 80
  137. to_port = 80
  138. protocol = "tcp"
  139. cidr_blocks = ["0.0.0.0/0"] # tfsec:ignore:aws-vpc-no-public-ingress-sgr Intentionally Open
  140. security_group_id = module.elb.security_group_id
  141. }
  142. resource "aws_security_group_rule" "github_alb_80_out" {
  143. description = "Github - Allow 80 to the instances"
  144. type = "egress"
  145. from_port = 80
  146. to_port = 80
  147. protocol = "tcp"
  148. source_security_group_id = aws_security_group.ghe_server.id
  149. security_group_id = module.elb.security_group_id
  150. }
  151. # NLB Side
  152. resource "aws_lb_target_group" "github_nlb_80" {
  153. name_prefix = "gitn80"
  154. target_type = "alb"
  155. port = 80
  156. protocol = "TCP"
  157. vpc_id = var.vpc_id
  158. lifecycle {
  159. create_before_destroy = true
  160. }
  161. tags = merge(local.standard_tags, var.tags)
  162. }
  163. resource "aws_lb_target_group_attachment" "github_nlb_80" {
  164. target_group_arn = aws_lb_target_group.github_nlb_80.arn
  165. target_id = module.elb.alb_id
  166. port = 80
  167. }
  168. resource "aws_lb_listener" "github_nlb_80" {
  169. load_balancer_arn = module.elb.nlb_id
  170. port = "80"
  171. protocol = "TCP" # tfsec:ignore:aws-elb-http-not-used HTTP only for letsencrypt and redirects
  172. default_action {
  173. type = "forward"
  174. target_group_arn = aws_lb_target_group.github_nlb_80.arn
  175. }
  176. lifecycle {
  177. create_before_destroy = true
  178. }
  179. tags = merge(local.standard_tags, var.tags)
  180. }
  181. ##########################
  182. # Add port 22 to the NLB
  183. resource "aws_lb_target_group" "github_ssh" {
  184. name_prefix = "gitssh"
  185. port = 22
  186. protocol = "TCP"
  187. vpc_id = var.vpc_id
  188. lifecycle {
  189. create_before_destroy = true
  190. }
  191. tags = merge(local.standard_tags, var.tags)
  192. }
  193. resource "aws_lb_target_group_attachment" "github_ssh" {
  194. for_each = toset(aws_instance.ghe[*].id)
  195. target_group_arn = aws_lb_target_group.github_ssh.arn
  196. target_id = each.value
  197. port = 22
  198. }
  199. resource "aws_lb_listener" "github_ssh" {
  200. load_balancer_arn = module.elb.nlb_id
  201. port = "22"
  202. protocol = "TCP"
  203. default_action {
  204. type = "forward"
  205. target_group_arn = aws_lb_target_group.github_ssh.arn
  206. }
  207. lifecycle {
  208. create_before_destroy = true
  209. }
  210. tags = merge(local.standard_tags, var.tags)
  211. }