Skip to content

Add docs for rewrite client IP settings #2701

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 21, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions site/content/how-to/data-plane-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,45 @@ as arguments and add `/bin/sh` as the command. The deployment manifest should lo
- /bin/sh
...
```

## Configure PROXY protocol and RewriteClientIP settings

When the request is passed through multiple proxies or load balancers, the client IP is set to the IP address of the server that last handled the request. To preserve the original client IP address, you can configure `RewriteClientIP` settings in the `NginxProxy` resource. `RewriteClientIP` has the fields: _mode_, _trustedAddresses_ and _setIPRecursively_.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"When a request" not "When the request"


**Mode** determines how the original client IP is passed through multiple proxies and the way the load balancer is set to receive it. It can have two values:

1. `ProxyProtocol` is a protocol that carries connection information from the source requesting the connection to the destination for which the connection was requested.
2. `XForwardedFor` is a multi-value HTTP header that is used by proxies to append IP addresses of the hosts that passed the request.

The choice of mode depends on how the load balancer fronting NGINX Gateway Fabric receives information.

**TrustedAddresses** are used to specify the IP addresses of the trusted proxies that pass the request. These can be in the form of CIDRs, IPs, or hostnames. For example, if a load balancer is forwarding the request to NGINX Gateway Fabric, the IP address of the load balancer should be specified in the `trustedAddresses` list to inform NGINX that the forwarded request is from a known source.

**SetIPRecursively** is a boolean field used to enable recursive search when selecting the client's address from a multi-value header. It is applicable in cases where we have a multi-value header containing client IPs to select from, i.e., when using `XForwardedFor` mode.

The following command creates an `NginxProxy` resource with `RewriteClientIP` settings that set the mode to XForwardedFor, enables recursive search for finding the client IP and sets a CIDR, IPAddress and Hostname in the list of trusted addresses to find the original client IP address.

```yaml
kubectl apply -f - <<EOF
apiVersion: gateway.nginx.org/v1alpha1
kind: NginxProxy
metadata:
name: ngf-proxy-config
spec:
config:
rewriteClientIP:
mode: XForwardedFor
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Part of me wonders if it makes more sense to use ProxyProtocol as the example, since that was the main use case we were targeting with this feature.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a little confused about that as well. I wanted to mention setIPrecursively field since it only applies to XForwardedFor

But at this point, its causing a lot of confusion so I can include both.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to provide every field in our example. Nor do we need to provide examples of both modes. Our API covers all cases, I think we just provide a basic example of the most common use case.

setIPRecursively: true
trustedAddresses:
- type: CIDR
value: ":1/28"
- type: IPAddress
value: "192.68.74.28"
- type: Hostname
value: "cafe.com"
Comment on lines +189 to +195
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought, I'm not sure we need to specify all three examples here. One should be enough to get the point across. A realistic CIDR would be fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just added this for user convenience to not go refer the spec and figure out types. I think we can have all fields for one example and simply it for our second example of ProxyProtocol

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment above, this resource should ideally be something that a user could probably just plug in and use, maybe just altering the single CIDR value for their case. They shouldn't have to go in and delete every field they aren't using.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the way we are thinking about this is a little different. I agree to your point too for it to be a plugin, but there would still be some editing needed to change the field value. I don't know how much of an effort difference would it be edit a field and delete two. I mentioned all types just so we could bring out most of the information in one page for the user without having to check out the spec.

But maybe that's not the right way to think about this and I'll change it to one example.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get where you're coming from. We just have a pattern of our examples being realistic and not just a showcase of all of the options. And our API reference is there to specifically showcase all the options.

EOF
```

For more information, see the `NginxProxy spec` in the [API reference]({{< relref "reference/api.md" >}}).
Copy link
Collaborator

@sjberman sjberman Oct 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of "For more information", I'd say "For the full configuration API".


{{< note >}} When sending curl requests to a server expecting proxy information, use the flag `--harproxy-protocol` to avoid broken header errors. {{< /note >}}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--haproxy-protocol is misspelled

Loading