<commit_before>// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

== Kerberos

=== Overview

Kerberos is a network authentication protocol that provides a secure way for
peers to prove their identity over an unsecure network in a client-server model.
A centralized key-distribution center (KDC) is the service that coordinates
authentication between a client and a server. Clients and servers use "tickets",
obtained from the KDC via a password or a special file called a "keytab", to
communicate with the KDC and prove their identity. A KDC administrator must
create the principal (name for the client/server identiy) and the password
or keytab, securely passing the necessary information to the actual user/service.
Properly securing the KDC and generated ticket material is central to the security
model and is mentioned only as a warning to administrators running their own KDC.

To interact with Kerberos programmatically, GSSAPI and SASL are two standards
which allow cross-language integration with Kerberos for authentication. GSSAPI,
the generic security service application program interface, is a standard which
Kerberos implements. In the Java programming language, the language itself also implements
GSSAPI which is leveraged by other applications, like Apache Hadoop and Apache Thrift.
SASL, simple authentication and security layer, is a framework for authentication and
and security over the network. SASL provides a number of mechanisms for authentication,
one of which is GSSAPI. Thus, SASL provides the transport which authenticates 
using GSSAPI that Kerberos implements.

Kerberos is a very complicated software application and is deserving of much
more description than can be provided here. An http://www.roguelynn.com/words/explain-like-im-5-kerberos/[explain like
I'm 5] blog post is very good at distilling the basics, while http://web.mit.edu/kerberos/[MIT Kerberos's project page]
contains lots of documentation for users or administrators. Various Hadoop "vendors"
also provide free documentation that includes step-by-step instructions for
configuring Hadoop and ZooKeeper (which will be henceforth considered as prerequisites).

=== Within Hadoop

Out of the box, HDFS and YARN have no ability to enforce that a user is who
they claim they are. Thus, any basic Hadoop installation should be treated as
unsecure: any user with access to the cluster has the ability to access any data.
Using Kerberos to provide authentication, users can be strongly identified, delegating
to Kerberos to determine who a user is and enforce that a user is who they claim to be.
As such, Kerberos is widely used across the entire Hadoop ecosystem for strong
authentication. Since server processes accessing HDFS or YARN are required
to use Kerberos to authenticate with HDFS, it makes sense that they also require
Kerberos authentication from their clients, in addition to other features provided
by SASL.

A typical deployment involves the creation of Kerberos principals for all server
processes (Hadoop datanodes and namenode(s), ZooKeepers), the creation of a keytab
file for each principal and then proper configuration for the Hadoop site xml files.
Users also need Kerberos principals created for them; however, a user typically
uses a password to identify themselves instead of a keytab. Users can obtain a
ticket granting ticket (TGT) from the KDC using their password which allows them
to authenticate for the lifetime of the TGT (typically one day by default) and alleviates
the need for further password authentication.

For client server applications, like web servers, a keytab can be created which
allow for fully-automated Kerberos identification removing the need to enter any
password, at the cost of needing to protect the keytab file. These principals
will apply directly to authentication for clients accessing Accumulo and the
Accumulo processes accessing HDFS.

=== Delegation Tokens

MapReduce, a common way that clients interact with Accumulo, does not map well to the
client-server model that Kerberos was originally designed to support. Specifically, the parallelization
of tasks across many nodes introduces the problem of securely sharing the user credentials across
these tasks in as safe a manner as possible. To address this problem, Hadoop introduced the notion
of a delegation token to be used in distributed execution settings.

A delegation token is nothing more than a short-term, on-the-fly password generated after authenticating with the user's
credentials.  In Hadoop itself, the Namenode and ResourceManager, for HDFS and YARN respectively, act as the gateway for
delegation tokens requests. For example, before a YARN job is submitted, the implementation will request delegation
tokens from the NameNode and ResourceManager so the YARN tasks can communicate with HDFS and YARN. In the same manner,
support has been added in the Accumulo Master to generate delegation tokens to enable interaction with Accumulo via
MapReduce when Kerberos authentication is enabled in a manner similar to HDFS and YARN.

Generating an expiring password is, arguably, more secure than distributing the user's
credentials across the cluster as only access to HDFS, YARN and Accumulo would be
compromised in the case of the token being compromised as opposed to the entire
Kerberos credential. Additional details for clients and servers will be covered
in subsequent sections.

=== Configuring Accumulo

To configure Accumulo for use with Kerberos, both client-facing and server-facing
changes must be made for a functional system on secured Hadoop. As previously mentioned,
numerous guidelines already exist on the subject of configuring Hadoop and ZooKeeper for
use with Kerberos and won't be covered here. It is assumed that you have functional
Hadoop and ZooKeeper already installed.

==== Servers

The first step is to obtain a Kerberos identity for the Accumulo server processes.
When running Accumulo with Kerberos enabled, a valid Kerberos identity will be required
to initiate any RPC between Accumulo processes (e.g. Master and TabletServer) in addition
to any HDFS action (e.g. client to HDFS or TabletServer to HDFS).

===== Generate Principal and Keytab

In the +kadmin.local+ shell or using the +-q+ option on +kadmin.local+, create a
principal for Accumulo for all hosts that are running Accumulo processes. A Kerberos
principal is of the form "primary/instance@REALM". "accumulo" is commonly the "primary"
(although not required) and the "instance" is the fully-qualified domain name for
the host that will be running the Accumulo process -- this is required.

----
kadmin.local -q "addprinc -randkey accumulo/host.domain.com"
----

Perform the above for each node running Accumulo processes in the instance, modifying
"host.domain.com" for your network. The +randkey+ option generates a random password
because we will use a keytab for authentication, not a password, since the Accumulo
server processes don't have an interactive console to enter a password into.

----
kadmin.local -q "xst -k accumulo.hostname.keytab accumulo/host.domain.com"
----

To simplify deployments, at thet cost of security, all Accumulo principals could
be globbed into a single keytab

----
kadmin.local -q "xst -k accumulo.service.keytab -glob accumulo*"
----

To ensure that the SASL handshake can occur from clients to servers and servers to servers,
all Accumulo servers must share the same instance and realm principal components as the
"client" needs to know these to set up the connection with the "server".

===== Server Configuration

A number of properties need to be changed to account to properly configure servers
in +accumulo-site.xml+.

* *general.kerberos.keytab*=_/etc/security/keytabs/accumulo.service.keytab_
** The path to the keytab for Accumulo on local filesystem.
** Change the value to the actual path on your system.
* *general.kerberos.principal*=_accumulo/_HOST@REALM_
** The Kerberos principal for Accumulo, needs to match the keytab.
** "_HOST" can be used instead of the actual hostname in the principal and will be
automatically expanded to the current FQDN which reduces the configuration file burden.
* *instance.rpc.sasl.enabled*=_true_
** Enables SASL for the Thrift Servers (supports GSSAPI)
* *instance.security.authenticator*=_org.apache.accumulo.server.security.handler.KerberosAuthenticator_
** Configures Accumulo to use the Kerberos principal as the Accumulo username/principal
* *instance.security.authorizor*=_org.apache.accumulo.server.security.handler.KerberosAuthorizor_
** Configures Accumulo to use the Kerberos principal for authorization purposes
* *instance.security.permissionHandler*=_org.apache.accumulo.server.security.handler.KerberosPermissionHandler_
** Configures Accumulo to use the Kerberos principal for permission purposes
* *trace.token.type*=_org.apache.accumulo.core.client.security.tokens.KerberosToken_
** Configures the Accumulo Tracer to use the KerberosToken for authentication when
serializing traces to the trace table.
* *trace.user*=_accumulo/_HOST@REALM_
** The tracer process needs valid credentials to serialize traces to Accumulo.
** While the other server processes are creating a SystemToken from the provided keytab and principal, we can
still use a normal KerberosToken and the same keytab/principal to serialize traces. Like
non-Kerberized instances, the table must be created and permissions granted to the trace.user.
** The same +_HOST+ replacement is performed on this value, substituted the FQDN for +_HOST+.
* *general.delegation.token.lifetime*=_7d_
** The length of time that the server-side secret used to create delegation tokens is valid.
   After a server-side secret expires, a delegation token created with that secret is no longer valid.
* *general.delegation.token.update.interval*=_1d_
** The frequency in which new server-side secrets should be generated to create delegation
   tokens for clients. Generating new secrets reduces the likelihood of cryptographic attacks.<commit_msg>ACCUMULO-3816 Add in rpc.sasl.qop to kerberos chapter.<commit_after>// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

== Kerberos

=== Overview

Kerberos is a network authentication protocol that provides a secure way for
peers to prove their identity over an unsecure network in a client-server model.
A centralized key-distribution center (KDC) is the service that coordinates
authentication between a client and a server. Clients and servers use "tickets",
obtained from the KDC via a password or a special file called a "keytab", to
communicate with the KDC and prove their identity. A KDC administrator must
create the principal (name for the client/server identiy) and the password
or keytab, securely passing the necessary information to the actual user/service.
Properly securing the KDC and generated ticket material is central to the security
model and is mentioned only as a warning to administrators running their own KDC.

To interact with Kerberos programmatically, GSSAPI and SASL are two standards
which allow cross-language integration with Kerberos for authentication. GSSAPI,
the generic security service application program interface, is a standard which
Kerberos implements. In the Java programming language, the language itself also implements
GSSAPI which is leveraged by other applications, like Apache Hadoop and Apache Thrift.
SASL, simple authentication and security layer, is a framework for authentication and
and security over the network. SASL provides a number of mechanisms for authentication,
one of which is GSSAPI. Thus, SASL provides the transport which authenticates 
using GSSAPI that Kerberos implements.

Kerberos is a very complicated software application and is deserving of much
more description than can be provided here. An http://www.roguelynn.com/words/explain-like-im-5-kerberos/[explain like
I'm 5] blog post is very good at distilling the basics, while http://web.mit.edu/kerberos/[MIT Kerberos's project page]
contains lots of documentation for users or administrators. Various Hadoop "vendors"
also provide free documentation that includes step-by-step instructions for
configuring Hadoop and ZooKeeper (which will be henceforth considered as prerequisites).

=== Within Hadoop

Out of the box, HDFS and YARN have no ability to enforce that a user is who
they claim they are. Thus, any basic Hadoop installation should be treated as
unsecure: any user with access to the cluster has the ability to access any data.
Using Kerberos to provide authentication, users can be strongly identified, delegating
to Kerberos to determine who a user is and enforce that a user is who they claim to be.
As such, Kerberos is widely used across the entire Hadoop ecosystem for strong
authentication. Since server processes accessing HDFS or YARN are required
to use Kerberos to authenticate with HDFS, it makes sense that they also require
Kerberos authentication from their clients, in addition to other features provided
by SASL.

A typical deployment involves the creation of Kerberos principals for all server
processes (Hadoop datanodes and namenode(s), ZooKeepers), the creation of a keytab
file for each principal and then proper configuration for the Hadoop site xml files.
Users also need Kerberos principals created for them; however, a user typically
uses a password to identify themselves instead of a keytab. Users can obtain a
ticket granting ticket (TGT) from the KDC using their password which allows them
to authenticate for the lifetime of the TGT (typically one day by default) and alleviates
the need for further password authentication.

For client server applications, like web servers, a keytab can be created which
allow for fully-automated Kerberos identification removing the need to enter any
password, at the cost of needing to protect the keytab file. These principals
will apply directly to authentication for clients accessing Accumulo and the
Accumulo processes accessing HDFS.

=== Delegation Tokens

MapReduce, a common way that clients interact with Accumulo, does not map well to the
client-server model that Kerberos was originally designed to support. Specifically, the parallelization
of tasks across many nodes introduces the problem of securely sharing the user credentials across
these tasks in as safe a manner as possible. To address this problem, Hadoop introduced the notion
of a delegation token to be used in distributed execution settings.

A delegation token is nothing more than a short-term, on-the-fly password generated after authenticating with the user's
credentials.  In Hadoop itself, the Namenode and ResourceManager, for HDFS and YARN respectively, act as the gateway for
delegation tokens requests. For example, before a YARN job is submitted, the implementation will request delegation
tokens from the NameNode and ResourceManager so the YARN tasks can communicate with HDFS and YARN. In the same manner,
support has been added in the Accumulo Master to generate delegation tokens to enable interaction with Accumulo via
MapReduce when Kerberos authentication is enabled in a manner similar to HDFS and YARN.

Generating an expiring password is, arguably, more secure than distributing the user's
credentials across the cluster as only access to HDFS, YARN and Accumulo would be
compromised in the case of the token being compromised as opposed to the entire
Kerberos credential. Additional details for clients and servers will be covered
in subsequent sections.

=== Configuring Accumulo

To configure Accumulo for use with Kerberos, both client-facing and server-facing
changes must be made for a functional system on secured Hadoop. As previously mentioned,
numerous guidelines already exist on the subject of configuring Hadoop and ZooKeeper for
use with Kerberos and won't be covered here. It is assumed that you have functional
Hadoop and ZooKeeper already installed.

==== Servers

The first step is to obtain a Kerberos identity for the Accumulo server processes.
When running Accumulo with Kerberos enabled, a valid Kerberos identity will be required
to initiate any RPC between Accumulo processes (e.g. Master and TabletServer) in addition
to any HDFS action (e.g. client to HDFS or TabletServer to HDFS).

===== Generate Principal and Keytab

In the +kadmin.local+ shell or using the +-q+ option on +kadmin.local+, create a
principal for Accumulo for all hosts that are running Accumulo processes. A Kerberos
principal is of the form "primary/instance@REALM". "accumulo" is commonly the "primary"
(although not required) and the "instance" is the fully-qualified domain name for
the host that will be running the Accumulo process -- this is required.

----
kadmin.local -q "addprinc -randkey accumulo/host.domain.com"
----

Perform the above for each node running Accumulo processes in the instance, modifying
"host.domain.com" for your network. The +randkey+ option generates a random password
because we will use a keytab for authentication, not a password, since the Accumulo
server processes don't have an interactive console to enter a password into.

----
kadmin.local -q "xst -k accumulo.hostname.keytab accumulo/host.domain.com"
----

To simplify deployments, at thet cost of security, all Accumulo principals could
be globbed into a single keytab

----
kadmin.local -q "xst -k accumulo.service.keytab -glob accumulo*"
----

To ensure that the SASL handshake can occur from clients to servers and servers to servers,
all Accumulo servers must share the same instance and realm principal components as the
"client" needs to know these to set up the connection with the "server".

===== Server Configuration

A number of properties need to be changed to account to properly configure servers
in +accumulo-site.xml+.

[options="header"]
|=================================================================
|Key | Default Value | Description
|general.kerberos.keytab                 |/etc/security/keytabs/accumulo.service.keytab |
The path to the keytab for Accumulo on local filesystem. Change the value to the actual path on your system.

|general.kerberos.principal              |accumulo/_HOST@REALM |
The Kerberos principal for Accumulo, needs to match the keytab. "_HOST" can be used instead of the actual hostname in the principal and will be automatically expanded to the current FQDN which reduces the configuration file burden.

|instance.rpc.sasl.enabled               |true |
Enables SASL for the Thrift Servers (supports GSSAPI)

|rpc.sasl.qop                            |auth |
One of "auth", "auth-int", or "auth-conf". These map to the SASL defined properties for
quality of protection. "auth" is authentication only. "auth-int" is authentication and data
integrity. "auth-conf" is authentication, data integrity and confidentiality.


|instance.security.authenticator         |
org.apache.accumulo.server.security.
handler.KerberosAuthenticator |
Configures Accumulo to use the Kerberos principal as the Accumulo username/principal

|instance.security.authorizor            |
org.apache.accumulo.server.security.
handler.KerberosAuthorizor |
Configures Accumulo to use the Kerberos principal for authorization purposes

|instance.security.permissionHandler     |
org.apache.accumulo.server.security.
handler.KerberosPermissionHandler|
Configures Accumulo to use the Kerberos principal for permission purposes

|trace.token.type                        |
org.apache.accumulo.core.client.
security.tokens.KerberosToken |
Configures the Accumulo Tracer to use the KerberosToken for authentication when serializing traces to the trace table.

|trace.user                              |accumulo/_HOST@REALM |
The tracer process needs valid credentials to serialize traces to Accumulo. While the other server processes are
creating a SystemToken from the provided keytab and principal, we can still use a normal KerberosToken and the same
keytab/principal to serialize traces. Like non-Kerberized instances, the table must be created and permissions granted
to the trace.user. The same +_HOST+ replacement is performed on this value, substituted the FQDN for +_HOST+.

|general.delegation.token.lifetime       |7d |
The length of time that the server-side secret used to create delegation tokens is valid. After a server-side secret
expires, a delegation token created with that secret is no longer valid.

|general.delegation.token.update.interval|1d |
The frequency in which new server-side secrets should be generated to create delegation tokens for clients. Generating
new secrets reduces the likelihood of cryptographic attacks.

|=================================================================
{'fraction_non_alphanumeric': 0.05155431050063257, 'fraction_numerical': 0.0009036688957166094, 'mean_word_length': 4.699974246716456, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5207010', 'n_tokens_mistral': 5610, 'n_tokens_neox': 5375, 'n_words': 3023}