[ https://issues.apache.org/jira/browse/HBASE-28317?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17807808#comment-17807808 ]
Bryan Beaudreault commented on HBASE-28317: ------------------------------------------- This sounds ok, but one comment for your consideration – I know you plan to inspect the certificate in the coprocessor. That might involve string manipulation/comparisons (cert parsing, username comparisons, etc) and math (for ip subnet checking). Since a certificate is tied to a connection and can't change for the lifetime of the connection, it will be far preferable to do this once per connection instead of for every request. A single client can send many requests/sec, and a RegionServer in aggregate will serve thousands of req/s or more. Doing this work on-connection instead of on-request would save a lot of cpu time. Given that TLS is a new native feature of hbase, I think we should consider this as a configurable auth plugin of some sort rather than just expose it on RpcCallContext. One good way to do that might be to add a pluggable interface for validating the certificate. We currently have HBaseTrustManager which delegates to the built-in X509ExtendedTrustManager and adds hostname verification via HBaseHostnameVerifier. We could add something pluggable in there for inspecting other fields. One problem with that approach is I'm not sure how we'd project the resulting "auth info" on to the NettyServerRpcConnection for usage elsewhere. Another option is something I experimented with in a super old POC I did for HBASE-27326: [https://github.com/HubSpot/hbase/commit/17d2db2f8a8fabcda9e36ecea826374f798c67f5#diff-3af1e2a33ec4dc8117718cddc9eafe8f99843e275cec7d0aada0995bbf2d9effR37.] This registers a listener to the SSL HandshakeFuture which allows us to fail the handshake if a specific CN field doesn't exist. In the impl of the linked class there, I have a comment about another approach we could take for injecting AuthInfo onto the Connection, which is probably the better idea. I'm imagining we have a pluggable interface (like other configuration-pluggable interfaces, i.e. RpcScheduler, etc.) which would get called there and users can return some sort of AuthInfo class or throw an auth exception. We could expose the AuthInfo object on RpcCallContext and inspect that in our coprocessor. For HubSpot's use-case we'd do something like the below, but this is flexible enough for many use-cases: {code:java} if (context.getAuthInfo() instanceof HubSpotAuthInfo && !((HubSpotAuthInfo)context.getAuthInfo()).isTrusted()) { AUDIT_LOG.log(request) }{code} A 3rd and final option I'd offer is if we can look into adding a preConnection and postConnection coprocessor hook. I think this would be tricky (but not impossible) to wire up because of how the RpcServer stuff is a step removed from the HRegionServer/HMaster stuff. The way to access it might be through the rpcServer.server field in NettyServerRpcConnection, which should be an instanceof HMaster or HRegionServer. > RpcCallContext should expose client's TLS certificate > ----------------------------------------------------- > > Key: HBASE-28317 > URL: https://issues.apache.org/jira/browse/HBASE-28317 > Project: HBase > Issue Type: Improvement > Reporter: Charles Connell > Assignee: Charles Connell > Priority: Minor > > At my employer we plan on using a coprocessor to log information about some > requests to HBase. For this to be useful to us, we need to know who each > request is coming from. We use HBase's TLS support with mutual authentication > to authenticate clients. I'd like a way to expose the client certificate used > on a request to coprocessors. For setups using Kerberos authentication, > RpcCall exposes the Kerberos principal shortname via {{getRequestUser()}}, so > this would be the TLS equivalent to that. -- This message was sent by Atlassian Jira (v8.20.10#820010)