NLBPreserveClientIP

Forward the real client source IP to targets behind the public NLB. When No (default), the NLB source-NATs incoming connections to its VPC-internal IP — applications see the NLB's address rather than the client's. When Yes, target tasks observe the real client IP.

| Default value | No | | Allowed values | Yes, No |

Prerequisites

This parameter is incompatible with a Rack that sets a customer-supplied InstanceSecurityGroup. Convox cannot add the required ingress rule to an SG it does not own. If your Rack uses a custom instance SG, add the ingress rule yourself (sourced from ${Rack}:NLBSecurityGroup) before enabling this parameter — see Incompatibility with customer InstanceSecurityGroup below. Per-port preserve_client_ip: true on a Service is blocked on the same Racks.

Use Cases

  • Compliance requirements for real client IPs in application logs (HIPAA §164.312(b), PCI-DSS 10.2.1)
  • Application-layer rate limiting or abuse mitigation keyed on client IP
  • GeoIP-based routing or analytics
  • Any workload where the NLB's internal IP in logs is operationally unhelpful

Additional Information

$ convox rack params set NLBPreserveClientIP=Yes

When enabled, Convox attaches an ingress rule on the ECS instances' security group (InstancesSecurity) sourced from the NLB security group (NLBSecurity), allowing the real-IP forwarded traffic to reach targets. For Fargate and Isolate Services, the equivalent rule is added to each Service's Security security group so ip-type target groups (used by awsvpc-mode tasks) work correctly.

The setting applies to every existing and future listener on the public NLB. Per-port preserve_client_ip: overrides the rack default for a single listener.

Incompatibility with customer InstanceSecurityGroup

Racks that set InstanceSecurityGroup to a customer-managed security group cannot enable NLBPreserveClientIP=Yes through Convox — the CloudFormation stack cannot attach ingress rules to an SG Convox does not own. The validator rejects the change:

cannot enable NLBPreserveClientIP on a rack with a customer-supplied
InstanceSecurityGroup; your instance SG must add an ingress rule from the
NLB security group (exported as ${Rack}:NLBSecurityGroup) for the NLB
listener ports before this feature can be enabled safely

The fix on customer-SG Racks is to add the ingress rule to your SG manually — sourced from the Rack's exported ${Rack}:NLBSecurityGroup, one rule per NLB listener port you expose — before attempting to enable preserve-client-IP. Example:

$ aws ec2 authorize-security-group-ingress \
    --group-id sg-customer-instance \
    --source-group $(aws cloudformation describe-stacks \
      --stack-name <rack> \
      --query 'Stacks[0].Outputs[?OutputKey==`NLBSecurityGroup`].OutputValue' \
      --output text) \
    --protocol tcp --port <listener-port>

Repeat the command for each NLB listener port declared in your Apps' convox.yml.

The inverse direction is also blocked. Setting InstanceSecurityGroup to a non-empty value while NLBPreserveClientIP=Yes is already in force is rejected unless the same rack params set call also disables preserve-client-IP — preventing a silent-breakage transition where the SG swap leaves the old ingress rule behind but the new SG does not allow the real-IP traffic.

Per-port enforcement

If the Rack parameter is No but a Service declares preserve_client_ip: true on an nlb: entry, release promote runs the same interlock on that scheme and rejects the Release on customer-SG Racks with a parallel error.

See Also