Skip to content

Commit

Permalink
feat: Add support for XFF/TLS headers (#284)
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Strache authored Mar 24, 2023
1 parent f801a2d commit 2d7fcb9
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 52 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,9 @@ No modules.
| <a name="input_enable_cross_zone_load_balancing"></a> [enable\_cross\_zone\_load\_balancing](#input\_enable\_cross\_zone\_load\_balancing) | Indicates whether cross zone load balancing should be enabled in application load balancers. | `bool` | `false` | no |
| <a name="input_enable_deletion_protection"></a> [enable\_deletion\_protection](#input\_enable\_deletion\_protection) | If true, deletion of the load balancer will be disabled via the AWS API. This will prevent Terraform from deleting the load balancer. Defaults to false. | `bool` | `false` | no |
| <a name="input_enable_http2"></a> [enable\_http2](#input\_enable\_http2) | Indicates whether HTTP/2 is enabled in application load balancers. | `bool` | `true` | no |
| <a name="input_enable_tls_version_and_cipher_suite_headers"></a> [enable\_tls\_version\_and\_cipher\_suite\_headers](#input\_enable\_tls\_version\_and\_cipher\_suite\_headers) | Indicates whether the two headers (x-amzn-tls-version and x-amzn-tls-cipher-suite), which contain information about the negotiated TLS version and cipher suite, are added to the client request before sending it to the target. | `bool` | `false` | no |
| <a name="input_enable_waf_fail_open"></a> [enable\_waf\_fail\_open](#input\_enable\_waf\_fail\_open) | Indicates whether to route requests to targets if lb fails to forward the request to AWS WAF | `bool` | `false` | no |
| <a name="input_enable_xff_client_port"></a> [enable\_xff\_client\_port](#input\_enable\_xff\_client\_port) | Indicates whether the X-Forwarded-For header should preserve the source port that the client used to connect to the load balancer in application load balancers. | `bool` | `true` | no |
| <a name="input_extra_ssl_certs"></a> [extra\_ssl\_certs](#input\_extra\_ssl\_certs) | A list of maps describing any extra SSL certificates to apply to the HTTPS listeners. Required key/values: certificate\_arn, https\_listener\_index (the index of the listener within https\_listeners which the cert applies toward). | `list(map(string))` | `[]` | no |
| <a name="input_http_tcp_listener_rules"></a> [http\_tcp\_listener\_rules](#input\_http\_tcp\_listener\_rules) | A list of maps describing the Listener Rules for this ALB. Required key/values: actions, conditions. Optional key/values: priority, http\_tcp\_listener\_index (default to http\_tcp\_listeners[count.index]) | `any` | `[]` | no |
| <a name="input_http_tcp_listener_rules_tags"></a> [http\_tcp\_listener\_rules\_tags](#input\_http\_tcp\_listener\_rules\_tags) | A map of tags to add to all http listener rules | `map(string)` | `{}` | no |
Expand Down Expand Up @@ -370,6 +372,7 @@ No modules.
| <a name="input_target_group_tags"></a> [target\_group\_tags](#input\_target\_group\_tags) | A map of tags to add to all target groups | `map(string)` | `{}` | no |
| <a name="input_target_groups"></a> [target\_groups](#input\_target\_groups) | A list of maps containing key/value pairs that define the target groups to be created. Order of these maps is important and the index of these are to be referenced in listener definitions. Required key/values: name, backend\_protocol, backend\_port | `any` | `[]` | no |
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | VPC id where the load balancer and other resources will be deployed. | `string` | `null` | no |
| <a name="input_xff_header_processing_mode"></a> [xff\_header\_processing\_mode](#input\_xff\_header\_processing\_mode) | Determines how the load balancer modifies the X-Forwarded-For header in the HTTP request before sending the request to the target. | `string` | `"append"` | no |

## Outputs

Expand Down
21 changes: 12 additions & 9 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@ resource "aws_lb" "this" {
security_groups = var.create_security_group && var.load_balancer_type == "application" ? concat([aws_security_group.this[0].id], var.security_groups) : var.security_groups
subnets = var.subnets

idle_timeout = var.idle_timeout
enable_cross_zone_load_balancing = var.enable_cross_zone_load_balancing
enable_deletion_protection = var.enable_deletion_protection
enable_http2 = var.enable_http2
ip_address_type = var.ip_address_type
drop_invalid_header_fields = var.drop_invalid_header_fields
preserve_host_header = var.preserve_host_header
enable_waf_fail_open = var.enable_waf_fail_open
desync_mitigation_mode = var.desync_mitigation_mode
idle_timeout = var.idle_timeout
enable_cross_zone_load_balancing = var.enable_cross_zone_load_balancing
enable_deletion_protection = var.enable_deletion_protection
enable_http2 = var.enable_http2
enable_tls_version_and_cipher_suite_headers = var.enable_tls_version_and_cipher_suite_headers
enable_xff_client_port = var.enable_xff_client_port
ip_address_type = var.ip_address_type
drop_invalid_header_fields = var.drop_invalid_header_fields
preserve_host_header = var.preserve_host_header
enable_waf_fail_open = var.enable_waf_fail_open
desync_mitigation_mode = var.desync_mitigation_mode
xff_header_processing_mode = var.xff_header_processing_mode

dynamic "access_logs" {
for_each = length(var.access_logs) > 0 ? [var.access_logs] : []
Expand Down
18 changes: 18 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ variable "enable_cross_zone_load_balancing" {
default = false
}

variable "enable_tls_version_and_cipher_suite_headers" {
description = "Indicates whether the two headers (x-amzn-tls-version and x-amzn-tls-cipher-suite), which contain information about the negotiated TLS version and cipher suite, are added to the client request before sending it to the target."
type = bool
default = false
}

variable "enable_xff_client_port" {
description = "Indicates whether the X-Forwarded-For header should preserve the source port that the client used to connect to the load balancer in application load balancers."
type = bool
default = true
}

variable "extra_ssl_certs" {
description = "A list of maps describing any extra SSL certificates to apply to the HTTPS listeners. Required key/values: certificate_arn, https_listener_index (the index of the listener within https_listeners which the cert applies toward)."
type = list(map(string))
Expand Down Expand Up @@ -214,6 +226,12 @@ variable "desync_mitigation_mode" {
default = "defensive"
}

variable "xff_header_processing_mode" {
description = "Determines how the load balancer modifies the X-Forwarded-For header in the HTTP request before sending the request to the target."
type = string
default = "append"
}

variable "putin_khuylo" {
description = "Do you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo!"
type = bool
Expand Down
89 changes: 46 additions & 43 deletions wrappers/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,50 @@ module "wrapper" {

for_each = var.items

create_lb = try(each.value.create_lb, var.defaults.create_lb, true)
drop_invalid_header_fields = try(each.value.drop_invalid_header_fields, var.defaults.drop_invalid_header_fields, false)
preserve_host_header = try(each.value.preserve_host_header, var.defaults.preserve_host_header, false)
enable_deletion_protection = try(each.value.enable_deletion_protection, var.defaults.enable_deletion_protection, false)
enable_http2 = try(each.value.enable_http2, var.defaults.enable_http2, true)
enable_cross_zone_load_balancing = try(each.value.enable_cross_zone_load_balancing, var.defaults.enable_cross_zone_load_balancing, false)
extra_ssl_certs = try(each.value.extra_ssl_certs, var.defaults.extra_ssl_certs, [])
https_listeners = try(each.value.https_listeners, var.defaults.https_listeners, [])
http_tcp_listeners = try(each.value.http_tcp_listeners, var.defaults.http_tcp_listeners, [])
https_listener_rules = try(each.value.https_listener_rules, var.defaults.https_listener_rules, [])
http_tcp_listener_rules = try(each.value.http_tcp_listener_rules, var.defaults.http_tcp_listener_rules, [])
idle_timeout = try(each.value.idle_timeout, var.defaults.idle_timeout, 60)
ip_address_type = try(each.value.ip_address_type, var.defaults.ip_address_type, "ipv4")
listener_ssl_policy_default = try(each.value.listener_ssl_policy_default, var.defaults.listener_ssl_policy_default, "ELBSecurityPolicy-2016-08")
internal = try(each.value.internal, var.defaults.internal, false)
load_balancer_create_timeout = try(each.value.load_balancer_create_timeout, var.defaults.load_balancer_create_timeout, "10m")
load_balancer_delete_timeout = try(each.value.load_balancer_delete_timeout, var.defaults.load_balancer_delete_timeout, "10m")
name = try(each.value.name, var.defaults.name, null)
name_prefix = try(each.value.name_prefix, var.defaults.name_prefix, null)
load_balancer_type = try(each.value.load_balancer_type, var.defaults.load_balancer_type, "application")
load_balancer_update_timeout = try(each.value.load_balancer_update_timeout, var.defaults.load_balancer_update_timeout, "10m")
access_logs = try(each.value.access_logs, var.defaults.access_logs, {})
subnets = try(each.value.subnets, var.defaults.subnets, null)
subnet_mapping = try(each.value.subnet_mapping, var.defaults.subnet_mapping, [])
tags = try(each.value.tags, var.defaults.tags, {})
lb_tags = try(each.value.lb_tags, var.defaults.lb_tags, {})
target_group_tags = try(each.value.target_group_tags, var.defaults.target_group_tags, {})
https_listener_rules_tags = try(each.value.https_listener_rules_tags, var.defaults.https_listener_rules_tags, {})
http_tcp_listener_rules_tags = try(each.value.http_tcp_listener_rules_tags, var.defaults.http_tcp_listener_rules_tags, {})
https_listeners_tags = try(each.value.https_listeners_tags, var.defaults.https_listeners_tags, {})
http_tcp_listeners_tags = try(each.value.http_tcp_listeners_tags, var.defaults.http_tcp_listeners_tags, {})
security_groups = try(each.value.security_groups, var.defaults.security_groups, [])
target_groups = try(each.value.target_groups, var.defaults.target_groups, [])
vpc_id = try(each.value.vpc_id, var.defaults.vpc_id, null)
enable_waf_fail_open = try(each.value.enable_waf_fail_open, var.defaults.enable_waf_fail_open, false)
desync_mitigation_mode = try(each.value.desync_mitigation_mode, var.defaults.desync_mitigation_mode, "defensive")
putin_khuylo = try(each.value.putin_khuylo, var.defaults.putin_khuylo, true)
create_security_group = try(each.value.create_security_group, var.defaults.create_security_group, true)
security_group_name = try(each.value.security_group_name, var.defaults.security_group_name, null)
security_group_use_name_prefix = try(each.value.security_group_use_name_prefix, var.defaults.security_group_use_name_prefix, true)
security_group_description = try(each.value.security_group_description, var.defaults.security_group_description, null)
security_group_rules = try(each.value.security_group_rules, var.defaults.security_group_rules, {})
security_group_tags = try(each.value.security_group_tags, var.defaults.security_group_tags, {})
create_lb = try(each.value.create_lb, var.defaults.create_lb, true)
drop_invalid_header_fields = try(each.value.drop_invalid_header_fields, var.defaults.drop_invalid_header_fields, false)
preserve_host_header = try(each.value.preserve_host_header, var.defaults.preserve_host_header, false)
enable_deletion_protection = try(each.value.enable_deletion_protection, var.defaults.enable_deletion_protection, false)
enable_http2 = try(each.value.enable_http2, var.defaults.enable_http2, true)
enable_cross_zone_load_balancing = try(each.value.enable_cross_zone_load_balancing, var.defaults.enable_cross_zone_load_balancing, false)
enable_tls_version_and_cipher_suite_headers = try(each.value.enable_tls_version_and_cipher_suite_headers, var.defaults.enable_tls_version_and_cipher_suite_headers, false)
enable_xff_client_port = try(each.value.enable_xff_client_port, var.defaults.enable_xff_client_port, true)
extra_ssl_certs = try(each.value.extra_ssl_certs, var.defaults.extra_ssl_certs, [])
https_listeners = try(each.value.https_listeners, var.defaults.https_listeners, [])
http_tcp_listeners = try(each.value.http_tcp_listeners, var.defaults.http_tcp_listeners, [])
https_listener_rules = try(each.value.https_listener_rules, var.defaults.https_listener_rules, [])
http_tcp_listener_rules = try(each.value.http_tcp_listener_rules, var.defaults.http_tcp_listener_rules, [])
idle_timeout = try(each.value.idle_timeout, var.defaults.idle_timeout, 60)
ip_address_type = try(each.value.ip_address_type, var.defaults.ip_address_type, "ipv4")
listener_ssl_policy_default = try(each.value.listener_ssl_policy_default, var.defaults.listener_ssl_policy_default, "ELBSecurityPolicy-2016-08")
internal = try(each.value.internal, var.defaults.internal, false)
load_balancer_create_timeout = try(each.value.load_balancer_create_timeout, var.defaults.load_balancer_create_timeout, "10m")
load_balancer_delete_timeout = try(each.value.load_balancer_delete_timeout, var.defaults.load_balancer_delete_timeout, "10m")
name = try(each.value.name, var.defaults.name, null)
name_prefix = try(each.value.name_prefix, var.defaults.name_prefix, null)
load_balancer_type = try(each.value.load_balancer_type, var.defaults.load_balancer_type, "application")
load_balancer_update_timeout = try(each.value.load_balancer_update_timeout, var.defaults.load_balancer_update_timeout, "10m")
access_logs = try(each.value.access_logs, var.defaults.access_logs, {})
subnets = try(each.value.subnets, var.defaults.subnets, null)
subnet_mapping = try(each.value.subnet_mapping, var.defaults.subnet_mapping, [])
tags = try(each.value.tags, var.defaults.tags, {})
lb_tags = try(each.value.lb_tags, var.defaults.lb_tags, {})
target_group_tags = try(each.value.target_group_tags, var.defaults.target_group_tags, {})
https_listener_rules_tags = try(each.value.https_listener_rules_tags, var.defaults.https_listener_rules_tags, {})
http_tcp_listener_rules_tags = try(each.value.http_tcp_listener_rules_tags, var.defaults.http_tcp_listener_rules_tags, {})
https_listeners_tags = try(each.value.https_listeners_tags, var.defaults.https_listeners_tags, {})
http_tcp_listeners_tags = try(each.value.http_tcp_listeners_tags, var.defaults.http_tcp_listeners_tags, {})
security_groups = try(each.value.security_groups, var.defaults.security_groups, [])
target_groups = try(each.value.target_groups, var.defaults.target_groups, [])
vpc_id = try(each.value.vpc_id, var.defaults.vpc_id, null)
enable_waf_fail_open = try(each.value.enable_waf_fail_open, var.defaults.enable_waf_fail_open, false)
desync_mitigation_mode = try(each.value.desync_mitigation_mode, var.defaults.desync_mitigation_mode, "defensive")
xff_header_processing_mode = try(each.value.xff_header_processing_mode, var.defaults.xff_header_processing_mode, "append")
putin_khuylo = try(each.value.putin_khuylo, var.defaults.putin_khuylo, true)
create_security_group = try(each.value.create_security_group, var.defaults.create_security_group, true)
security_group_name = try(each.value.security_group_name, var.defaults.security_group_name, null)
security_group_use_name_prefix = try(each.value.security_group_use_name_prefix, var.defaults.security_group_use_name_prefix, true)
security_group_description = try(each.value.security_group_description, var.defaults.security_group_description, null)
security_group_rules = try(each.value.security_group_rules, var.defaults.security_group_rules, {})
security_group_tags = try(each.value.security_group_tags, var.defaults.security_group_tags, {})
}

0 comments on commit 2d7fcb9

Please sign in to comment.