[ 
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)

Reply via email to