Skip to content

feat: add enable_client_ip_attr_trust to stop trusting client-reported __client_ip - #60

Open
naughtyGitCat wants to merge 1 commit into
oceanbase:masterfrom
naughtyGitCat:fix/client-ip-attr-trust
Open

naughtyGitCat wants to merge 1 commit into
oceanbase:masterfrom
naughtyGitCat:fix/client-ip-attr-trust

Conversation

@naughtyGitCat

@naughtyGitCat naughtyGitCat commented Sep 11, 2026

Copy link
Copy Markdown

Problem

With enable_client_ip_checkout=true (default), ObMysqlPacketRewriter::rewrite_handshake_response_packet first stores the peer address detected by obproxy (write_client_addr_buf), then scans the client's connect attributes and lets a client-supplied __client_ip overwrite it unconditionally. The result is forwarded to observer as __client_ip and used there for ob_tcp_invited_nodes and the user@host match.

OceanBase Connector/J (every release on Maven Central, 2.4.0 through 2.4.19) sends socket.getLocalAddress().getHostAddress() as __client_ip on every login. When the application runs inside a container the reported address is the container address.

Observed on OceanBase CE 5.0.1.0 / obproxy 4.x:

# obproxy_error.log: TCP peer is the host, which is in the whitelist
OB_MYSQL_COM_LOGIN,,failed,1227,...,10.104.14.71:52400,,0,10.104.17.192:2881,Access denied,

# observer.log: observer checks the container address instead
MySQL LOGIN(direct_client_ip="10.104.17.190", client_ip=172.18.0.7, tenant_name=marketing,
            user_name=youdata_mid, host_name=xxx.xxx.xxx.xxx, from_proxy=true, ... proc_ret=-5036)

ob_tcp_invited_nodes was 10.0.0.0/8,... and the user was youdata_mid@10.104.14.71; both would have matched the detected peer. Beyond the container case, this also means any client can claim an arbitrary source address, so the tenant whitelist and per-user host restriction are only as strong as the client's honesty.

Turning enable_client_ip_checkout off is not a workaround: it stops sending __client_ip entirely, observer then falls back to its own peer (the obproxy address), and every user created with a specific host fails to log in.

Change

New config item enable_client_ip_attr_trust (CFG_NO_NEED_REBOOT, global level).

  • true (default): behaviour is unchanged.
  • false: obproxy forwards the peer address it detected. A client-supplied __client_ip is only honoured when the login packet carries __mysql_client_type=__ob_proxy, i.e. the client is an upstream obproxy, so proxy chaining keeps working. Ignored values are logged at DEBUG.

Only effective when enable_client_ip_checkout is true.

Files: ob_proxy_config.h, ob_mysql_config_processor.{h,cpp}, ob_mysql_packet_rewriter.{h,cpp}, ob_mysql_transact.cpp.

Notes

  • Default kept at true to avoid breaking deployments behind a NAT load balancer that rely on the driver-reported address. Maintainers may want to consider flipping the default in a future major release.
  • I could not build obproxy on my workstation (macOS). The change mirrors the existing enable_client_ip_checkout plumbing and uses only constants and helpers already referenced in the same function (OB_MYSQL_CLIENT_MODE, OB_MYSQL_CLIENT_OBPROXY_MODE, ObString::compare). Happy to adjust if CI reports anything.
  • The driver side can be worked around today with defaultConnectionAttributesBanList=__client_ip (available since Connector/J 2.4.1), but the proxy should not have to trust a client-chosen address for an access-control decision.

🤖 Generated with Claude Code

@CLAassistant

CLAassistant commented Sep 11, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

…d __client_ip

When enable_client_ip_checkout is on, rewrite_handshake_response_packet first
writes the peer address detected by obproxy into client_ip_buf_, then lets a
__client_ip connect attribute sent by the client overwrite it unconditionally.
OceanBase Connector/J (2.4.0 ~ 2.4.19) always reports socket.getLocalAddress()
in __client_ip. For an application running inside a container that is the
container address (e.g. 172.18.0.7), so observer applies ob_tcp_invited_nodes
and the user@host match against an address that never reaches the proxy, and
the login fails with ERROR 1227 Access denied although the TCP peer is in the
whitelist. It also means any client can claim an arbitrary source ip.

Add config item enable_client_ip_attr_trust (default true, behaviour unchanged).
When set to false, obproxy forwards the detected peer address and only accepts
__client_ip from an upstream obproxy, identified by
__mysql_client_type=__ob_proxy in the login packet, so proxy chaining keeps
working. Ignored self-reported values are logged at DEBUG level.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@naughtyGitCat
naughtyGitCat force-pushed the fix/client-ip-attr-trust branch from 4e55b5c to 941de2f Compare September 11, 2026 08:18
@naughtyGitCat naughtyGitCat changed the title feat: add enable_trust_client_ip_attr to stop trusting client-reported __client_ip feat: add enable_client_ip_attr_trust to stop trusting client-reported __client_ip Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants