Skip to content

Enforce internal_port gating of builtin services in pb protocols - #3511

Open
chenBright wants to merge 1 commit into
apache:masterfrom
chenBright:fix_pb_builtin
Open

Enforce internal_port gating of builtin services in pb protocols#3511
chenBright wants to merge 1 commit into
apache:masterfrom
chenBright:fix_pb_builtin

Conversation

@chenBright

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: resolve

Problem Summary:

ServerOptions.internal_port is documented to make builtin services (and
Tabbed services, see the comment on internal_port) reachable only from the
internal port. ServerOptions::security_mode() returns true once it is set.

Only the http/h2 dispatch path actually enforced this. Every pb protocol
computed the same security_mode flag but used it just for address obfuscation
in AppendServerIdentiy(), and had no check at all between method resolution
and CallMethod(). Since builtin services share _method_map with user
services, they can be addressed by name over pb.

With internal_port configured, a client on the public port can therefore reach builtin
services that the http path returns 403 Forbidden for on the very same server. For
example, brpc.vars dumps the full metrics set, andhotspots is reachable the same
way.

Affected dispatch paths: baidu_std, hulu_pbrpc, sofa_pbrpc, and all
nshead-based pb protocols (public_pbrpc, nshead_mcpack, nova_pbrpc,
ubrpc2pb), which share NsheadPbServiceAdaptor::ProcessNsheadRequest.

What is changed and the side effects?

Changed:

Side effects:

  • Performance effects:

  • Breaking backward compatibility:


Check List:

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to make ServerOptions.internal_port enforcement consistent across bRPC protocols by rejecting access to builtin (and tabbed) services on the public port when the server is in “security mode”, extending the behavior that previously only the HTTP/H2 dispatch path reliably enforced.

Changes:

  • Adds a shared RejectBuiltinAccess(...) helper and wires it into multiple pb-protocol dispatch paths (baidu_std, hulu_pbrpc, sofa_pbrpc, and nshead-based pb adaptor).
  • Refactors the HTTP dispatch path to use the shared helper for builtin/tabbed gating.
  • Adds unit tests to validate builtin service reachability via pb protocols vs HTTP, with and without internal_port.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/brpc_server_unittest.cpp Adds tests covering builtin gating behavior for pb protocols and HTTP with/without internal_port.
src/brpc/policy/sofa_pbrpc_protocol.cpp Invokes builtin/tabbed gating during Sofa pb request dispatch.
src/brpc/policy/hulu_pbrpc_protocol.cpp Invokes builtin/tabbed gating during Hulu pb request dispatch.
src/brpc/policy/http_rpc_protocol.cpp Switches HTTP dispatch to use the shared builtin/tabbed gating helper.
src/brpc/policy/baidu_rpc_protocol.cpp Invokes builtin/tabbed gating during baidu_std request dispatch.
src/brpc/nshead_pb_service_adaptor.cpp Invokes builtin/tabbed gating for nshead-based pb adaptors.
src/brpc/details/server_private_accessor.h Introduces RejectBuiltinAccess(...) helper shared by protocols.
src/brpc/details/controller_private_accessor.h Minor signature/style cleanup (no functional change intended).

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/brpc/details/server_private_accessor.h
Comment on lines 770 to +784
if (nullptr == mp) {
cntl->SetFailed(ENOMETHOD, "Fail to find method=%s/%s",
request_meta.service_name().c_str(),
request_meta.method_name().c_str());
break;
} else if (mp->service->GetDescriptor() == BadMethodService::descriptor()) {
BadMethodRequest breq;
BadMethodResponse bres;
breq.set_service_name(request_meta.service_name());
mp->service->CallMethod(mp->method, cntl.get(), &breq, &bres, nullptr);
break;
}
if (RejectBuiltinAccess(cntl.get(), *server, mp)) {
break;
}
Comment on lines 448 to +462
if (nullptr == sp) {
cntl->SetFailed(ENOMETHOD, "Fail to find method=%d of service=%s",
meta.method_index(), meta.service_name().c_str());
break;
} else if (sp->service->GetDescriptor()
== BadMethodService::descriptor()) {
BadMethodRequest breq;
BadMethodResponse bres;
breq.set_service_name(meta.service_name());
sp->service->CallMethod(sp->method, cntl.get(), &breq, &bres, nullptr);
break;
}
if (RejectBuiltinAccess(cntl.get(), *server, sp)) {
break;
}
Comment on lines 1620 to 1625
if (!server->AcceptRequest(cntl)) {
return;
}
} else if (security_mode) {
cntl->SetFailed(EPERM, "Not allowed to access builtin services, try "
"ServerOptions.internal_port=%d instead if you're in"
" internal network", server->options().internal_port);
} else if (RejectBuiltinAccess(cntl, *server, mp)) {
return;
}
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