Opened 17 months ago
Closed 17 months ago
#2524 closed enhancement (duplicate)
ngx_http_realip_module cannot read CloudFront-Viewer-Address IPV6 header
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | nginx-module | Version: | 1.25.x |
Keywords: | ngx_http_realip_module, ipv6, cloudfront-viewer-address | Cc: | |
uname -a: | Linux wordpress-deployment-6bd9bdb7b8-hjqdm 5.10.184-175.731.amzn2.aarch64 #1 SMP Tue Jun 27 21:48:49 UTC 2023 aarch64 GNU/Linux | ||
nginx -V: |
nginx version: nginx/1.25.1
built by gcc 12.2.0 (Debian 12.2.0-14) built with OpenSSL 3.0.9 30 May 2023 |
Description
We have problem that nginx cannot read CloudFront-Viewer-Address if the client is coming with IPV6 address.
Manually tampering the CloudFront-Viewer-Address I have come to the following conclusion which works and which not:
ipv6 with or without brackets and no port - fine
ipv6 with brackets and port - fine
ipv6 without brackets and port - broken
Problem is that it's not customizable on Cloudfront side on which format to send this header. It can only send you the IP without brackets and port in the following format:
"cloudfront-viewer-address": "2001:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:60776",
Any ideas how to solve this problem?
Documentation about this header is here:
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/adding-cloudfront-headers.html
Change History (1)
comment:1 by , 17 months ago
Priority: | major → minor |
---|---|
Resolution: | → duplicate |
Status: | new → closed |
Type: | defect → enhancement |
In IPv6 addresses, text representation can contain varying number of components separated by colons due to zero compression, and simply adding
:<port>
to an IPv6 address is not going to work: the result is not distinguishable from a bare IPv6 address. For example, consider the2001:db8::1
address and port8080
: combined, they will lead to the2001:db8::1:8080
string, which is a perfectly valid IPv6 address by itself. See Wikipedia and RFC 5952 for details.As such, when combining IPv6 addresses with port numbers it is important to provide additional syntax constructs, such as square brackets in
[2001:db8::1]:8080
. For example, this what usually done for X-Fowarded-For headers when ports are used.On the linked page, description of the
CloudFront-Viewer-Address
header is as follows:Unfortunately, from the description it looks like the header was designed for IPv4, without IPv6 in mind, and it is completely unclear how IPv6 is expected to be handled in this header, if at all. You may want to report this to Cloudfront team, it looks like they have something to fix here.
The only approach I can think of is to strictly assume
<address>:<port>
format, and parse everything after the last colon in the header as a port, and everything before it as an address. This is not something nginx supports natively though: instead, it expects and address, and tolerates an optional port if there is one.On nginx side, the easiest solution would be to use the
X-Forwarded-For
header instead, with appropriate settings (you'll have to use real_ip_recursive and appropriate IP address blocks in set_real_ip_from).Alternatively, you can alter the header to something nginx accepts by using an additional proxying, as recommended as a workaround in #2350.
Closing this as a duplicate of #2350 - the expected enhancement should make it possible to do arbitrary modifications to headers before they are used by the realip module, including custom parsing of headers.