You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by "iloveeyjafjalla (via GitHub)" <gi...@apache.org> on 2026/10/12 06:44:56 UTC
[I] [Bug] Proxy Admin ACL evaluates the source IP against the transport peer, ignoring the PROXY protocol client address [rocketmq]
iloveeyjafjalla opened a new issue, #11362:
URL: https://github.com/apache/rocketmq/issues/11362
### Before Creating the Bug Report
- [x] I found a bug, not just asking a question, which should be created in [GitHub Discussions](https://github.com/apache/rocketmq/discussions).
- [x] I have searched the [GitHub Issues](https://github.com/apache/rocketmq/issues) and [GitHub Discussions](https://github.com/apache/rocketmq/discussions) of this repository and believe that this is not a duplicate.
- [x] I have confirmed that this bug belongs to the current repository, not other repositories of RocketMQ.
### Runtime platform environment
OS: any (proxy module; the affected path needs a PROXY-protocol ingress — HAProxy / NLB / any proxy-protocol load balancer — in front of the admin port)
### RocketMQ version
branch: develop
Git commit id: 9ea2ccdc2b41445aee5e177e14e501d606f5a1ed (2026-10-08)
### JDK Version
Compiler: Temurin 1.8.0_504 (target 1.8, same as CI)
### Describe the Bug
The Proxy Admin ACL evaluates the source IP against the transport peer instead of the client address.
`ProxyAdminAuthInterceptor#resolveSourceIp` reads the raw transport address:
```java
InetSocketAddress remoteAddress = (InetSocketAddress) call.getAttributes()
.get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR);
```
The admin server shares the data plane's negotiator (`ProxyAndTlsProtocolNegotiator`), so it accepts PROXY protocol connections, and its interceptor chain contains `HeaderInterceptor`, which resolves the real client address — the PROXY protocol address when present, the transport peer otherwise — and puts it into the metadata:
```java
String remoteAddress = getProxyProtocolAddress(call.getAttributes());
if (StringUtils.isBlank(remoteAddress)) {
remoteAddress = parseSocketAddress(call.getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR));
}
GrpcUtils.putHeader(headers, GrpcConstants.REMOTE_ADDRESS, remoteAddress);
```
The data plane authorizes against exactly that value (`DefaultAuthorizationContextBuilder` derives the source IP with
`StringUtils.substringBeforeLast(metadata.get(GrpcConstants.REMOTE_ADDRESS), ":")`), while the admin surface bypasses it.
Behind a proxy-protocol load balancer the transport peer is the balancer, so:
- an ACL entry that whitelists the operator range (`-i <client-range>`) is evaluated against the balancer's address: operators are denied if the balancer is outside the range, and every client that can reach the balancer is accepted if it is inside the range (the `-i` restriction silently stops restricting);
- the `sourceIp` field of every `[PROXY-ADMIN-AUDIT]` audit line records the balancer instead of the caller;
- data plane and admin plane disagree about the source IP of the same client.
### Steps to Reproduce
1. Run a proxy with `grpcAdminServerEnable=true` behind a load balancer that sends PROXY protocol to the admin port.
2. Enable cluster authentication + authorization and add a policy for a `proxy.admin.*` resource with an `-i <client-range>` restriction.
3. Call any admin RPC from a client inside the range: the decision is made against the load balancer's address, not the client's (the `RemoteAddress` seen by the ACL evaluator is the balancer).
Unit level (see the pull request): build a `ServerCall` whose attributes carry the PROXY protocol client address while the
transport peer is the balancer, and resolve the source IP — the peer address is used.
### Expected behavior
The admin ACL subject uses the client address `HeaderInterceptor` resolved (the same value the data plane authorizes
against), so `-i` restrictions and the audit log refer to the real caller.
### Actual behavior
The transport peer (the load balancer) is used as the ACL source IP and in the audit log.
### Additional context
Minimal fix: prefer the normalized `GrpcConstants.REMOTE_ADDRESS` header, keep the transport peer as the fallback for the
case where the interceptor runs without the standard pipeline.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@rocketmq.apache.org.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [I] [Bug] Proxy Admin ACL evaluates the source IP against the transport peer, ignoring the PROXY protocol client address [rocketmq]
Posted by "RockteMQ-AI (via GitHub)" <gi...@apache.org>.
RockteMQ-AI commented on issue #11362:
URL: https://github.com/apache/rocketmq/issues/11362#issuecomment-6119413801
**Issue Evaluation**
Category: `type/bug` | Status: **Confirmed**
The reported issue has been verified against the current codebase (develop branch, commit b764205).
**Root Cause:** `ProxyAdminAuthInterceptor#resolveSourceIp` reads the raw transport peer address via `Grpc.TRANSPORT_ATTR_REMOTE_ADDR`, bypassing the PROXY protocol client address that `HeaderInterceptor` correctly resolves and stores in `GrpcConstants.REMOTE_ADDRESS`. The data plane authorizes against the resolved address, while the admin surface uses the transport peer — causing ACL mis-evaluation behind proxy-protocol load balancers.
**Impact:** Admin ACL silently stops restricting by client IP when the Proxy admin port is behind a PROXY-protocol LB. Audit logs record the LB address instead of the real caller.
**Severity:** High — security control bypass in admin plane
**Suggested Fix:** `resolveSourceIp()` should reuse the same resolution logic as `HeaderInterceptor`: check for PROXY protocol address first (`AttributeKeys.PROXY_PROTOCOL_ADDR` + `PROXY_PROTOCOL_PORT`), fall back to transport peer address.
---
*Automated evaluation by github-manager-bot*
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@rocketmq.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org