= Configure Request Header Forwarding in AWS Application Load Balancer and Apache =
**Summary**: This wiki page shows how to configure both AWS Application Load Balancer and Apache to forward the request header to a backend container. \\
**Date**: 30 January 2026 \\
{{tag>aws apache}}
To start, this is the setup we're talking about:
[{{requestheaderforward01.drawio.png?800|Network layout}}] \\
As you can see, the application load balancer receives the request from clients and needs to forward the client IP address to the apache container, which then forwards it to the backend application container. To achieve this, we need to set the "X-Forwarded-For" header in both the load balancer and apache configurations.
== AWS Application Load Balancer Configuration ==
The [[https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html |AWS Application Load Balancer]] is the easiest part in this story. The load balancer has three options for handling the X-Forwarded-For header:
1. Append (default): If the value is append, the Application Load Balancer adds the client IP address (of the last hop) to the X-Forwarded-For header in the HTTP request before it sends it to targets.
1. Preserve: If the value is preserve, the Application Load Balancer preserves the X-Forwarded-For header in the HTTP request, and sends it to targets without any change.
1. Remove: If the value is remove, the Application Load Balancer removes the X-Forwarded-For header in the HTTP request before it sends it to targets.
For us, the append option will work best, and it should be the default. Quickly checking the settings confirms this:
[{{requestheaderforward02.png?800|ALB Settings}}] \\
== Apache Configuration ==
The [[https://httpd.apache.org/docs/2.0/mod/mod_headers.html#requestheader |apache requestheaders]] are a bit more work. Again, there are several options to choose from:
1. set: The request header is set, replacing any previous header with this name
1. append: The request header is appended to any existing header of the same name. When a new value is merged onto an existing header it is separated from the existing header with a comma. This is the HTTP standard way of giving a header multiple values.
1. add: The request header is added to the existing set of headers, even if this header already exists. This can result in two (or more) headers having the same name. This can lead to unforeseen consequences, and in general append should be used instead.
1. unset: The request header of this name is removed, if it exists. If there are multiple headers of the same name, all will be removed.
Again, the append option will work best for us. Besides that, we also need to enable [[https://httpd.apache.org/docs/current/mod/mod_headers.html#early |early processing]] to ensure the header is added before other modules process the request. To configure this, we find the section in our httpd-sites-enable file ({{{app-ssl.conf}}}) and locate the proxy pass section. We then add the request header line as follows:
ProxyRequests Off
Order deny,allow
Allow from all
ProxyVia On
ProxyErrorOverride On
ServerName getshifting.com
DocumentRoot /usr/local/apache2/htdocs
ErrorDocument 503 /custom_50x.html
ErrorDocument 403 /custom_50x.html
ErrorDocument 404 /custom_50x.html
ProxyPass /custom_50x.html !
ProxyPass /longpolling/ http://app_web:8080/longpolling/
ProxyPassReverse /longpolling/ http://app_web:8080/longpolling/
ProxyPass / http://app_web:8081/
ProxyPassReverse / http://app_web:8081/
RequestHeader append X-Forwarded-Proto "https" early
SetEnv proxy-nokeepalive 1
RewriteEngine on
== Testing the Configuration ==
To test the configuration, the easiest way is to add the client source IP address to the apache logs. We locate the apache config file ({{{httpd.conf}}}) and update the log format as follows:
#LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%h %{X-Forwarded-For}i %l %u %t \"%r\" %>s %b" common
== Restart the Apche container ==
I prefer starting the whole stack, so I know everything works as expected:
cd /data/app/docker
docker-compose -f docker-compose.yml down
docker-compose -f docker-compose.yml up -d
docker-compose logs -f
docker logs --follow --timestamps httpd_web
== Useful Links ==
* [[https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html |ALB Settings - routing.http.xff_header_processing.mode]]
* [[https://httpd.apache.org/docs/2.0/mod/mod_headers.html#requestheader |Apache Requestheader Settings]]
//This wiki has been made possible by://