diff options
Diffstat (limited to '')
-rw-r--r-- | doc/dev/ceph_krb_auth.rst | 1094 |
1 files changed, 1094 insertions, 0 deletions
diff --git a/doc/dev/ceph_krb_auth.rst b/doc/dev/ceph_krb_auth.rst new file mode 100644 index 000000000..627b9bd8e --- /dev/null +++ b/doc/dev/ceph_krb_auth.rst @@ -0,0 +1,1094 @@ +=============================================================================== +A Detailed Documentation on How to Set up Ceph Kerberos Authentication +=============================================================================== + +This document provides details on the Kerberos authorization protocol. This is +the 1st draft and we will try to keep it updated along with code changes that +might take place. + +Several free implementations of this protocol are available (MIT, Heimdal, +MS...), covering a wide range of operating systems. The Massachusetts +Institute of Technology (MIT), where Kerberos was originally developed, +continues to develop their Kerberos package and it is the implementation we +chose to work with. `MIT Kerberos <http://web.mit.edu/Kerberos/>`_. + +Please, provide feedback to Daniel Oliveira (doliveira@suse.com) + +*Last update: Dec 3, 2018* + +| + +Background +---------- + +Before we get into *Kerberos details*, let us define a few terms so we can +understand what to expect from it, *what it can and can't do*: + +Directory Services + A directory service is a customizable information store that functions as + a single point from which users can locate resources and services + distributed throughout the network. This customizable information store + also gives administrators a single point for managing its objects and their + attributes. Although this information store appears as a single point to + the users of the network, it is actually most often stored in a distributed + form. A directory service consists of at least one *Directory Server and a + Directory Client* and are implemented based on *X.500 standards*. + + *OpenLDAP, 389 Directory Server, MS Active Directory, NetIQ eDirectory* are + some good examples. + + A directory service is often characterized as a *write-once-read-many-times + service*, meaning the data that would normally be stored in an directory + service would not be expected to change on every access. + + The database that forms a directory service *is not designed for + transactional data*. + +| + +LDAP (Lightweight Directory Access Protocol v3) + LDAP is a set of LDAP Protocol Exchanges *(not an implementation of a + server)* that defines the method by which data is accessed. LDAPv3 is a + standard defined by the IETF in RFC 2251 and describes how data is + represented in the Directory Service (the Data Model or DIT). + + Finally, it defines how data is loaded into (imported) and saved from + (exported) a directory service (using LDIF). LDAP does not define how data + is stored or manipulated. Data Store is an 'automagic' process as far as + the standard is concerned and is generally handled by back-end modules. + + No Directory Service implementation has all the features of LDAP v3 + protocol implemented. All Directory Server implementations have their + different problems and/or anomalies, and features that may not return + results as another Directory Server implementation would. + +| + +Authentication + Authentication is about validating credentials (like User Name/ID and + password) to verify the identity. The system determines whether one is what + they say they are using their credentials. + + Usually, authentication is done by a username and password, and sometimes + in conjunction with *(single, two, or multi) factors of authentication*, + which refers to the various ways to be authenticated. + +| + +Authorization + Authorization occurs after the identity is successfully authenticated by + the system, which ultimately gives one full permission to access the + resources such as information, files, databases, and so forth, almost + anything. It determines the ability to access the system and up to what + extent (what kind of permissions/rights are given and to where/what). + +| + +Auditing + Auditing takes the results from both *authentication and authorization* and + records them into an audit log. The audit log records records all actions + taking by/during the authentication and authorization for later review by + the administrators. While authentication and authorization are preventive + systems (in which unauthorized access is prevented), auditing is a reactive + system (in which it gives detailed log of how/when/where someone accessed + the environment). + +| + +Kerberos (KRB v5) + Kerberos is a network *authentication protocol*. It is designed to provide + strong authentication for client/server applications by using secret-key + cryptography (symmetric key). A free implementation of this protocol is + available from the MIT. However, Kerberos is available in many commercial + products as well. + + It was designed to provide secure authentication to services over an + insecure network. Kerberos uses tickets to authenticate a user, or service + application and never transmits passwords over the network in the clear. + So both client and server can prove their identity without sending any + unencrypted secrets over the network. + + Kerberos can be used for single sign-on (SSO). The idea behind SSO is + simple, we want to login just once and be able to use any service that we + are entitled to, without having to login on each of those services. + +| + +Simple Authentication and Security Layer (SASL) + SASL **(RFC 4422)** is a framework that helps developers to implement + different authentication mechanisms (implementing a series of challenges + and responses), allowing both clients and servers to negotiate a mutually + acceptable mechanism for each connection, instead of hard-coding them. + + Examples of SASL mechanisms: + + * ANONYMOUS **(RFC 4505)** + + - For guest access, meaning *unauthenticated* + + * CRAM-MD5 **(RFC 2195)** + + - Simple challenge-response scheme based on *HMAC-MD5*. + It does not establish any security layer. *Less secure than + DIGEST-MD5 and GSSAPI.* + + * DIGEST-MD5 **(RFC 2831)** + + - HTTP Digest compatible *(partially)* challenge-response scheme + based upon MD5, offering a *data security layer*. It is preferred + over PLAIN text passwords, protecting against plain text attacks. + It is a mandatory authentication method for LDAPv3 servers. + + * EXTERNAL **(RFCs 4422, 5246, 4301, 2119)** + + - Where *authentication is implicit* in the context (i.e; for + protocols using IPsec or TLS [TLS/SSL to performing certificate- + based authentication] already). This method uses public keys for + strong authentication. + + * GS2 **(RFC 5801)** + + - Family of mechanisms supports arbitrary GSS-API mechanisms in + SASL + + * NTLM (MS Proprietary) + + - MS Windows NT LAN Manager authentication mechanism + + * OAuth 1.0/2.0 **(RFCs 5849, 6749, 7628)** + + - Authentication protocol for delegated resource access + + * OTP **(RFC 2444)** + + - One-time password mechanism *(obsoletes the SKEY mechanism)* + + * PLAIN **(RFC 4616)** + + - Simple Cleartext password mechanism **(RFC 4616)**. This is not a + preferred mechanism for most applications because of its relative + lack of strength. + + * SCRAM **(RFCs 5802, 7677)** + + - Modern challenge-response scheme based mechanism with channel + binding support + +| + +Generic Security Services Application Program Interface (GSSAPI) + GSSAPI **(RFCs 2078, 2743, 2744, 4121, 4752)** is widely used by protocol + implementers as a way to implement Kerberos v5 support in their + applications. It provides a generic interface and message format that can + encapsulate authentication exchanges from any authentication method that + has a GSSAPI-compliant library. + + It does not define a protocol, authentication, or security mechanism + itself; it instead makes it easier for application programmers to support + multiple authentication mechanisms by providing a uniform, generic API for + security services. It is a set of functions that include both an API and a + methodology for approaching authentication, aiming to insulate application + protocols from the specifics of security protocols as much as possible. + + *Microsoft Windows Kerberos* implementation does not include GSSAPI support + but instead includes a *Microsoft-specific API*, the *Security Support + Provider Interface (SSPI)*. In Windows, an SSPI client can communicate with + a *GSSAPI server*. + + *Most applications that support GSSAPI also support Kerberos v5.* + +| + +Simple and Protected GSSAPI Negotiation Mechanism (SPNEGO) + As we can see, GSSAPI solves the problem of providing a single API to + different authentication mechanisms. However, it does not solve the problem + of negotiating which mechanism to use. In fact for GSSAPI to work, the two + applications communicating with each other must know in advance what + authentication mechanism they plan to use, which usually is not a problem + if only one mechanism is supported (meaning Kerberos v5). + + However, if there are multiple mechanisms to choose from, a method is + needed to securely negotiate an authentication mechanism that is mutually + supported between both client and server; which is where + *SPNEGO (RFC 2478, 4178)* makes a difference. + + *SPNEGO* provides a framework for two parties that are engaged in + authentication to select from a set of possible authentication mechanisms, + in a manner that preserves the opaque nature of the security protocols to + the application protocol that uses it. + + It is a security protocol that uses a *GSSAPI authentication mechanism* and + negotiates among several available authentication mechanisms in an + implementation, selecting one for use to satisfy the authentication needs + of the application protocol. + + It is a *meta protocol* that travels entirely in other application + protocols; it is never used directly without an application protocol. + +| + +*Why is this important and why do we care? Like, at all?* + + Having this background information in mind, we can easily describe things + like: + + 1. *Ceph Kerberos authentication* is based totally on MIT *Kerberos* + implementation using *GSSAPI*. + + 2. At the moment we are still using *Kerberos default backend + database*, however we plan on adding LDAP as a backend which would + provide us with *authentication with GSSAPI (KRB5)* and *authorization + with LDAP (LDAPv3)*, via *SASL mechanism*. + +| + +Before We Start +--------------- + +We assume the environment already has some external services up and running +properly: + + * Kerberos needs to be properly configured, which also means (for both + every server and KDC): + + - Time Synchronization (either using `NTP <http://www.ntp.org/>`_ or `chrony <https://chrony.tuxfamily.org/>`_). + + + Not only Kerberos, but also Ceph depends and relies on time + synchronization. + + - DNS resolution + + + Both *(forward and reverse)* zones, with *fully qualified domain + name (fqdn)* ``(hostname + domain.name)`` + + + KDC discover can be set up to use DNS ``(srv resources)`` as + service location protocol *(RFCs 2052, 2782)*, as well as *host + or domain* to the *appropriate realm* ``(txt record)``. + + + Even though these DNS entries/settings are not required to run a + ``Kerberos realm``, they certainly help to eliminate the need for + manual configuration on all clients. + + + This is extremely important, once most of the Kerberos issues are + usually related to name resolution. Kerberos is very picky when + checking on systems names and host lookups. + + * Whenever possible, in order to avoid a *single point of failure*, set up + a *backup, secondary, or slave*, for every piece/part in the + infrastructure ``(ntp, dns, and kdc servers)``. + + +Also, the following *Kerberos terminology* is important: + + * Ticket + + - Tickets or Credentials, are a set of information that can be used to + verify the client's identity. Kerberos tickets may be stored in a + file, or they may exist only in memory. + + - The first ticket obtained is a ticket-granting ticket (TGT), which + allows the clients to obtain additional tickets. These additional + tickets give the client permission for specific services. The + requesting and granting of these additional tickets happens + transparently. + + + The TGT, which expires at a specified time, permits the client to + obtain additional tickets, which give permission for specific + services. The requesting and granting of these additional tickets + is user-transparent. + + * Key Distribution Center (KDC). + + - The KDC creates a ticket-granting ticket (TGT) for the client, + encrypts it using the client's password as the key, and sends the + encrypted TGT back to the client. The client then attempts to decrypt + the TGT, using its password. If the client successfully decrypts the + TGT (i.e., if the client gave the correct password), it keeps the + decrypted TGT, which indicates proof of the client's identity. + + - The KDC is comprised of three components: + + + Kerberos database, which stores all the information about the + principals and the realm they belong to, among other things. + + Authentication service (AS) + + Ticket-granting service (TGS) + + * Client + + - Either a *user, host or a service* who sends a request for a ticket. + + * Principal + + - It is a unique identity to which Kerberos can assign tickets. + Principals can have an arbitrary number of components. Each component + is separated by a component separator, generally ``/``. The last + component is the *realm*, separated from the rest of the principal by + the realm separator, generally ``@``. + + - If there is no realm component in the principal, then it will be + assumed that the principal is in the default realm for the context in + which it is being used. + + - Usually, a principal is divided into three parts: + + + The ``primary``, the ``instance``, and the ``realm`` + + + The format of a typical Kerberos V5 principal is + ``primary/instance@REALM``. + + + The ``primary`` is the first part of the principal. In the case + of a user, it's the same as the ``username``. For a host, the + primary is the word ``host``. For Ceph, will use ``ceph`` as a + primary name which makes it easier to organize and identify Ceph + related principals. + + + The ``instance`` is an optional string that qualifies the + primary. The instance is separated from the primary by a slash + ``/``. In the case of a user, the instance is usually ``null``, + but a user might also have an additional principal, with an + instance called ``admin``, which one uses to administrate a + database. + + The principal ``johndoe@MYDOMAIN.COM`` is completely separate + from the principal ``johndoe/admin@MYDOMAIN.COM``, with a + separate password, and separate permissions. In the case of a + host, the instance is the fully qualified hostname, + i.e., ``osd1.MYDOMAIN.COM``. + + + The ``realm`` is the Kerberos realm. Usually, the Kerberos realm + is the domain name, in *upper-case letters*. For example, the + machine ``osd1.MYDOMAIN.COM`` would be in the realm + ``MYDOMAIN.COM``. + + * Keytab + + - A keytab file stores the actual encryption key that can be used in + lieu of a password challenge for a given principal. Creating keytab + files are useful for noninteractive principals, such as *Service + Principal Names*, which are often associated with long-running + processes like Ceph daemons. A keytab file does not have to be a + "1:1 mapping" to a single principal. Multiple different principal + keys can be stored in a single keytab file: + + + The keytab file allows a user/service to authenticate without + knowledge of the password. Due to this, *keytabs should be + protected* with appropriate controls to prevent unauthorized + users from authenticating with it. + + + The default client keytab file is ``/etc/krb5.keytab`` + +| + +The 'Ceph side' of the things +------------------------------ + +In order to configure connections (from Ceph nodes) to the KDC: + +1. Login to the Kerberos client (Ceph server nodes) and confirm it is properly + configured, by checking and editing ``/etc/krb5.conf`` file properly: :: + + /etc/krb5.conf + [libdefaults] + dns_canonicalize_hostname = false + rdns = false + forwardable = true + dns_lookup_realm = true + dns_lookup_kdc = true + allow_weak_crypto = false + default_realm = MYDOMAIN.COM + default_ccache_name = KEYRING:persistent:%{uid} + [realms] + MYDOMAIN.COM = { + kdc = kerberos.mydomain.com + admin_server = kerberos.mydomain.com + ... + } + ... + + +2. Login to the *KDC Server* and confirm it is properly configured to + authenticate to the Kerberos realm in question: + + a. Kerberos related DNS RRs: :: + + /var/lib/named/master/mydomain.com + kerberos IN A 192.168.10.21 + kerberos-slave IN A 192.168.10.22 + _kerberos IN TXT "MYDOMAIN.COM" + _kerberos._udp IN SRV 1 0 88 kerberos + _kerberos._tcp IN SRV 1 0 88 kerberos + _kerberos._udp IN SRV 20 0 88 kerberos-slave + _kerberos-master._udp IN SRV 0 0 88 kerberos + _kerberos-adm._tcp IN SRV 0 0 749 kerberos + _kpasswd._udp IN SRV 0 0 464 kerberos + ... + + + b. KDC configuration file: :: + + /var/lib/kerberos/krb5kdc/kdc.conf + [kdcdefaults] + kdc_ports = 750,88 + [realms] + MYDOMAIN.COM = { + acl_file = /var/lib/kerberos/krb5kdc/kadm5.acl + admin_keytab = FILE:/var/lib/kerberos/krb5kdc/kadm5.keytab + default_principal_flags = +postdateable +forwardable +renewable +proxiable + +dup-skey -preauth -hwauth +service + +tgt-based +allow-tickets -pwchange + -pwservice + dict_file = /var/lib/kerberos/krb5kdc/kadm5.dict + key_stash_file = /var/lib/kerberos/krb5kdc/.k5.MYDOMAIN.COM + kdc_ports = 750,88 + max_life = 0d 10h 0m 0s + max_renewable_life = 7d 0h 0m 0s + } + ... + + +3. Still on the KDC Server, run the Kerberos administration utility; + ``kadmin.local`` so we can list all the principals already created. :: + + kadmin.local: listprincs + K/M@MYDOMAIN.COM + krbtgt/MYDOMAIN.COM@MYDOMAIN.COM + kadmin/admin@MYDOMAIN.COM + kadmin/changepw@MYDOMAIN.COM + kadmin/history@MYDOMAIN.COM + kadmin/kerberos.mydomain.com@MYDOMAIN.COM + root/admin@MYDOMAIN.COM + ... + + +4. Add a *principal for each Ceph cluster node* we want to be authenticated by + Kerberos: + + a. Adding principals: :: + + kadmin.local: addprinc -randkey ceph/ceph-mon1 + Principal "ceph/ceph-mon1@MYDOMAIN.COM" created. + kadmin.local: addprinc -randkey ceph/ceph-osd1 + Principal "ceph/ceph-osd1@MYDOMAIN.COM" created. + kadmin.local: addprinc -randkey ceph/ceph-osd2 + Principal "ceph/ceph-osd2@MYDOMAIN.COM" created. + kadmin.local: addprinc -randkey ceph/ceph-osd3 + Principal "ceph/ceph-osd3@MYDOMAIN.COM" created. + kadmin.local: addprinc -randkey ceph/ceph-osd4 + Principal "ceph/ceph-osd4@MYDOMAIN.COM" created. + kadmin.local: listprincs + K/M@MYDOMAIN.COM + krbtgt/MYDOMAIN.COM@MYDOMAIN.COM + kadmin/admin@MYDOMAIN.COM + kadmin/changepw@MYDOMAIN.COM + kadmin/history@MYDOMAIN.COM + kadmin/kerberos.mydomain.com@MYDOMAIN.COM + root/admin@MYDOMAIN.COM + ceph/ceph-mon1@MYDOMAIN.COM + ceph/ceph-osd1@MYDOMAIN.COM + ceph/ceph-osd2@MYDOMAIN.COM + ceph/ceph-osd3@MYDOMAIN.COM + ceph/ceph-osd4@MYDOMAIN.COM + ... + + + b. This follows the same idea if we are creating a *user principal* :: + + kadmin.local: addprinc johndoe + WARNING: no policy specified for johndoe@MYDOMAIN.COM; defaulting to no policy + Enter password for principal "johndoe@MYDOMAIN.COM": + Re-enter password for principal "johndoe@MYDOMAIN.COM": + Principal "johndoe@MYDOMAIN.COM" created. + ... + + +5. Create a *keytab file* for each Ceph cluster node: + + As the default client keytab file is ``/etc/krb5.keytab``, we will want to + use a different file name, so we especify which *keytab file to create* and + which *principal to export keys* from: :: + + kadmin.local: ktadd -k /etc/gss_client_mon1.ktab ceph/ceph-mon1 + Entry for principal ceph/ceph-mon1 with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/gss_client_mon1.ktab. + Entry for principal ceph/ceph-mon1 with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:/etc/gss_client_mon1.ktab. + Entry for principal ceph/ceph-mon1 with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/gss_client_mon1.ktab. + Entry for principal ceph/ceph-mon1 with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/etc/gss_client_mon1.ktab. + kadmin.local: ktadd -k /etc/gss_client_osd1.ktab ceph/ceph-osd1 + Entry for principal ceph/ceph-osd1 with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/gss_client_osd1.ktab. + Entry for principal ceph/ceph-osd1 with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:/etc/gss_client_osd1.ktab. + Entry for principal ceph/ceph-osd1 with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/gss_client_osd1.ktab. + Entry for principal ceph/ceph-osd1 with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/etc/gss_client_osd1.ktab. + kadmin.local: ktadd -k /etc/gss_client_osd2.ktab ceph/ceph-osd2 + Entry for principal ceph/ceph-osd2 with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/gss_client_osd2.ktab. + Entry for principal ceph/ceph-osd2 with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:/etc/gss_client_osd2.ktab. + Entry for principal ceph/ceph-osd2 with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/gss_client_osd2.ktab. + Entry for principal ceph/ceph-osd2 with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/etc/gss_client_osd2.ktab. + kadmin.local: ktadd -k /etc/gss_client_osd3.ktab ceph/ceph-osd3 + Entry for principal ceph/ceph-osd3 with kvno 3, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/gss_client_osd3.ktab. + Entry for principal ceph/ceph-osd3 with kvno 3, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:/etc/gss_client_osd3.ktab. + Entry for principal ceph/ceph-osd3 with kvno 3, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/gss_client_osd3.ktab. + Entry for principal ceph/ceph-osd3 with kvno 3, encryption type arcfour-hmac added to keytab WRFILE:/etc/gss_client_osd3.ktab. + kadmin.local: ktadd -k /etc/gss_client_osd4.ktab ceph/ceph-osd4 + Entry for principal ceph/ceph-osd4 with kvno 4, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/gss_client_osd4.ktab. + Entry for principal ceph/ceph-osd4 with kvno 4, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:/etc/gss_client_osd4.ktab. + Entry for principal ceph/ceph-osd4 with kvno 4, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/gss_client_osd4.ktab. + Entry for principal ceph/ceph-osd4 with kvno 4, encryption type arcfour-hmac added to keytab WRFILE:/etc/gss_client_osd4.ktab. + + # ls -1 /etc/gss_client_* + /etc/gss_client_mon1.ktab + /etc/gss_client_osd1.ktab + /etc/gss_client_osd2.ktab + /etc/gss_client_osd3.ktab + /etc/gss_client_osd4.ktab + + + We can also check these newly created keytab client files by: :: + + # klist -kte /etc/gss_client_mon1.ktab + Keytab name: FILE:/etc/gss_client_mon1.ktab + KVNO Timestamp Principal + ---- ------------------- ------------------------------------------------------ + 2 10/8/2018 14:35:30 ceph/ceph-mon1@MYDOMAIN.COM (aes256-cts-hmac-sha1-96) + 2 10/8/2018 14:35:31 ceph/ceph-mon1@MYDOMAIN.COM (aes128-cts-hmac-sha1-96) + 2 10/8/2018 14:35:31 ceph/ceph-mon1@MYDOMAIN.COM (des3-cbc-sha1) + 2 10/8/2018 14:35:31 ceph/ceph-mon1@MYDOMAIN.COM (arcfour-hmac) + ... + + +6. A new *set parameter* was added in Ceph, ``gss ktab client file`` which + points to the keytab file related to the Ceph node *(or principal)* in + question. + + By default it points to ``/var/lib/ceph/$name/gss_client_$name.ktab``. So, + in the case of a Ceph server ``osd1.mydomain.com``, the location and name + of the keytab file should be: ``/var/lib/ceph/osd1/gss_client_osd1.ktab`` + + Therefore, we need to ``scp`` each of these newly created keytab files from + the KDC to their respective Ceph cluster nodes (i.e): + ``# for node in mon1 osd1 osd2 osd3 osd4; do scp /etc/gss_client_$node*.ktab root@ceph-$node:/var/lib/ceph/$node/; done`` + + Or whatever other way one feels comfortable with, as long as each keytab + client file gets copied over to the proper location. + + At this point, even *without using any keytab client file* we should be + already able to authenticate a *user principal*: :: + + # kdestroy -A && kinit -f johndoe && klist -f + Password for johndoe@MYDOMAIN.COM: + Ticket cache: KEYRING:persistent:0:0 + Default principal: johndoe@MYDOMAIN.COM + + Valid starting Expires Service principal + 10/10/2018 15:32:01 10/11/2018 07:32:01 krbtgt/MYDOMAIN.COM@MYDOMAIN.COM + renew until 10/11/2018 15:32:01, Flags: FRI + ... + + + Given that the *keytab client file* is/should already be copied and available at the + Kerberos client (Ceph cluster node), we should be able to athenticate using it before + going forward: :: + + # kdestroy -A && kinit -k -t /etc/gss_client_mon1.ktab -f 'ceph/ceph-mon1@MYDOMAIN.COM' && klist -f + Ticket cache: KEYRING:persistent:0:0 + Default principal: ceph/ceph-mon1@MYDOMAIN.COM + + Valid starting Expires Service principal + 10/10/2018 15:54:25 10/11/2018 07:54:25 krbtgt/MYDOMAIN.COM@MYDOMAIN.COM + renew until 10/11/2018 15:54:25, Flags: FRI + ... + + +7. The default client keytab is used, if it is present and readable, to + automatically obtain initial credentials for GSSAPI client applications. The + principal name of the first entry in the client keytab is used by default + when obtaining initial credentials: + + a. The ``KRB5_CLIENT_KTNAME environment`` variable. + b. The ``default_client_keytab_name`` profile variable in ``[libdefaults]``. + c. The hardcoded default, ``DEFCKTNAME``. + + So, what we do is to internally, set the environment variable + ``KRB5_CLIENT_KTNAME`` to the same location as ``gss_ktab_client_file``, + so ``/var/lib/ceph/osd1/gss_client_osd1.ktab``, and change the ``ceph.conf`` + file to add the new authentication method. :: + + /etc/ceph/ceph.conf + [global] + ... + auth cluster required = gss + auth service required = gss + auth client required = gss + gss ktab client file = /{$my_new_location}/{$my_new_ktab_client_file.keytab} + ... + + +8. With that the GSSAPIs will then be able to read the keytab file and using + the process of name and service resolution *(provided by the DNS)*, able to + request a *TGT* as follows: + + a. User/Client sends principal identity and credentials to the KDC Server + (TGT request). + b. KDC checks its internal database for the principal in question. + c. a TGT is created and wrapped by the KDC, using the principal's key + (TGT + Key). + d. The newly created TGT, is decrypted and stored in the credentials + cache. + e. At this point, Kerberos/GSSAPI aware applications (and/or services) are + able to check the list of active TGT in the keytab file. + +| +| + +** *For Ceph Developers Only* ** +================================= + +We certainly could have used straight native ``KRB5 APIs`` (instead of +``GSSAPIs``), but we wanted a more portable option as regards network security, +which is the hallmark of the ``GSS`` *(Generic Security Standard)* ``-API``. +It does not actually provide security services itself. + +Rather, it is a framework that provides security services to callers in a +generic way. :: + + +---------------------------------+ + | Application | + +---------------------------------+ + | Protocol (RPC, Etc. [Optional]) | + +---------------------------------+ + | GSS-API | + +---------------------------------+ + | Security Mechs (Krb v5, Etc) | + +---------------------------------+ + + +The GSS-API does two main things: + + 1. It creates a security context in which data can be passed between + applications. A context can be thought of as a sort of *"state of trust"* + between two applications. + + Applications that share a context know who each other are and thus can + permit data transfers between them as long as the context lasts. + + 2. It applies one or more types of protection, known as *"security services"*, + to the data to be transmitted. + + +GSS-API provides several types of portability for applications: + + a. **Mechanism independence.** GSS-API provides a generic interface to the + mechanisms for which it has been implemented. By specifying a default + security mechanism, an application does not need to know which mechanism + it is using (for example, Kerberos v5), or even what type of mechanism + it uses. As an example, when an application forwards a user's credential + to a server, it does not need to know if that credential has a Kerberos + format or the format used by some other mechanism, nor how the + credentials are stored by the mechanism and accessed by the application. + (If necessary, an application can specify a particular mechanism to use) + + b. **Protocol independence.** The GSS-API is independent of any + communications protocol or protocol suite. It can be used with + applications that use, for example, sockets, RCP, or TCP/IP. + RPCSEC_GSS "RPCSEC_GSS Layer" is an additional layer that smoothly + integrates GSS-API with RPC. + + c. **Platform independence.** The GSS-API is completely oblivious to the + type of operating system on which an application is running. + + d. **Quality of Protection independence.** Quality of Protection (QOP) is + the name given to the type of algorithm used in encrypting data or + generating cryptographic tags; the GSS-API allows a programmer to ignore + QOP, using a default provided by the GSS-API. + (On the other hand, an application can specify the QOP if necessary.) + + The basic security offered by the GSS-API is authentication. Authentication + is the verification of an identity: *if you are authenticated, it means + that you are recognized to be who you say you are.* + + The GSS-API provides for two additional security services, if supported by the + underlying mechanisms: + + 1. **Integrity:** It's not always sufficient to know that an application + sending you data is who it claims to be. The data itself could have + become corrupted or compromised. + + The GSS-API provides for data to be accompanied by a cryptographic tag, + known as an ``Message Integrity Code (MIC)``, to prove that the data + that arrives at your doorstep is the same as the data that the sender + transmitted. This verification of the data's validity is known as + *"integrity"*. + + 2. **Confidentiality:** Both authentication and integrity, however, leave + the data itself alone, so if it's somehow intercepted, others can read + it. + + The GSS-API therefore allows data to be encrypted, if underlying + mechanisms support it. This encryption of data is known as *"confidentiality"*. + +| + +Mechanisms Available With GSS-API: + + The current implementation of the GSS-API works only with the Kerberos v5 security + mechanism. :: + + Mechanism Name Object Identifier Shared Library Kernel Module + ---------------------- ---------------------- -------------- -------------- + diffie_hellman_640_0 1.3.6.4.1.42.2.26.2.4 dh640-0.so.1 + diffie_hellman_1024_0 1.3.6.4.1.42.2.26.2.5 dh1024-0.so.1 + SPNEGO 1.3.6.1.5.5.2 + iakerb 1.3.6.1.5.2.5 + SCRAM-SHA-1 1.3.6.1.5.5.14 + SCRAM-SHA-256 1.3.6.1.5.5.18 + GSS-EAP (arc) 1.3.6.1.5.5.15.1.1.* + kerberos_v5 1.2.840.113554.1.2.2 gl/mech_krb5.so gl_kmech_krb5 + + Therefore: + Kerberos Version 5 GSS-API Mechanism + OID {1.2.840.113554.1.2.2} + + Kerberos Version 5 GSS-API Mechanism + Simple and Protected GSS-API Negotiation Mechanism + OID {1.3.6.1.5.5.2} + + + There are two different formats: + + 1. The first, ``{ 1 2 3 4 }``, is officially mandated by the GSS-API + specs. ``gss_str_to_oid()`` expects this first format. + + 2. The second, ``1.2.3.4``, is more widely used but is not an official + standard format. + + Although the GSS-API makes protecting data simple, it does not do certain + things, in order to maximize its generic nature. These include: + + a. Provide security credentials for a user or application. These must + be provided by the underlying security mechanism(s). The GSS-API + does allow applications to acquire credentials, either automatically + or explicitly. + + b. Transfer data between applications. It is the application's + responsibility to handle the transfer of all data between peers, + whether it is security-related or "plain" data. + + c. Distinguish between different types of transmitted data (for + example, to know or determine that a data packet is plain data and + not GSS-API related). + + d. Indicate status due to remote (asynchronous) errors. + + e. Automatically protect information sent between processes of a + multiprocess program. + + f. Allocate string buffers ("Strings and Similar Data") to be passed to + GSS-API functions. + + g. Deallocate GSS-API data spaces. These must be explicitly deallocated + with functions such as ``gss_release_buffer()`` and + ``gss_delete_name()``. + +| + +These are the basic steps in using the GSS-API: + + 1. Each application, sender and recipient, acquires credentials explicitly, + if credentials have not been acquired automatically. + + 2. The sender initiates a security context and the recipient accepts it. + + 3. The sender applies security protection to the message (data) it wants to + transmit. This means that it either encrypts the message or stamps it + with an identification tag. The sender transmits the protected message. + (The sender can choose not to apply either security protection, in which + case the message has only the default GSS-API security service + associated with it. That is authentication, in which the recipient knows + that the sender is who it claims to be.) + + 4. The recipient decrypts the message (if needed) and verifies it + (if appropriate). + + 5. (Optional) The recipient returns an identification tag to the sender for + confirmation. + + 6. Both applications destroy the shared security context. If necessary, + they can also deallocate any *"leftover"* GSS-API data. + + Applications that use the GSS-API should include the file ``gssapi.h``. + + Good References: + - `rfc1964 <https://tools.ietf.org/html/rfc1964>`_. + - `rfc2743 <https://tools.ietf.org/html/rfc2743>`_. + - `rfc2744 <https://tools.ietf.org/html/rfc2744>`_. + - `rfc4178 <https://tools.ietf.org/html/rfc4178>`_. + - `rfc6649 <https://tools.ietf.org/html/rfc6649>`_. + - `MIT Kerberos Documentation <https://web.mit.edu/kerberos/krb5-latest/doc/appdev/gssapi.html>`_. + +| + +** *Kerberos Server Setup* ** +------------------------------ + +First and foremost, ``this is not a recommendation for a production +environment``. We are not covering ``Master/Slave replication cluster`` or +anything production environment related (*ntp/chrony, dns, pam/nss, sssd, etc*). + +Also, on the server side there might be different dependencies and/or +configuration steps needed, depending on which backend database will be used. +``LDAP as a backend database`` is a good example of that. + +On the client side there are different steps depending on which client backend +configuration will be used. For example ``PAM/NSS`` or ``SSSD`` (along with +LDAP for identity service, [and Kerberos for authentication service]) which is +the best suited option for joining ``MS Active Directory domains``, and doing +``User Logon Management``. + +By no means we intend to cover every possible scenario/combination here. These +steps are for a simple *get a (MIT) Kerberos Server up and running*. + +Please, note that *rpm packages might have slightly different names*, as well +as the locations for the binaries and/or configuration files, depending on +which Linux distro we are referring to. + +Finally, keep in mind that some Linux distros will have their own ``wizards``, +which can perform the basic needed configuration: :: + + SUSE: + Kerberos server: + yast2 auth-server + + Kerberos client: + pam/nss: yast2 ldapkrb + sssd: yast2 auth-client + + +However, we are going through the ``manual configuration``. + + +In order to get a new MIT KDC Server running: + +1. Install the KDC server by: + + a. Install the needed packages: :: + + SUSE: zypper install krb5 krb5-server krb5-client + Additionally: + for development: krb5-devel + if using 'sssd': sssd-krb5 sssd-krb5-common + + REDHAT: yum install krb5-server krb5-libs krb5-workstation + Additionally: 'Needs to be checked' + + + b. Edit the KDC Server configuration file: :: + + /var/lib/kerberos/krb5kdc/kdc.conf + [kdcdefaults] + kdc_ports = 750,88 + [realms] + MYDOMAIN.COM = { + acl_file = /var/lib/kerberos/krb5kdc/kadm5.acl + admin_keytab = FILE:/var/lib/kerberos/krb5kdc/kadm5.keytab + default_principal_flags = +postdateable +forwardable +renewable +proxiable + +dup-skey -preauth -hwauth +service + +tgt-based +allow-tickets -pwchange + -pwservice + dict_file = /var/lib/kerberos/krb5kdc/kadm5.dict + key_stash_file = /var/lib/kerberos/krb5kdc/.k5.MYDOMAIN.COM + kdc_ports = 750,88 + max_life = 0d 10h 0m 0s + max_renewable_life = 7d 0h 0m 0s + } + ... + + + c. Edit the Kerberos Client configuration file: :: + + /etc/krb5.conf + [libdefaults] + dns_canonicalize_hostname = false + rdns = false + forwardable = true + dns_lookup_realm = true //--> if using DNS/DNSMasq + dns_lookup_kdc = true //--> if using DNS/DNSMasq + allow_weak_crypto = false + default_realm = MYDOMAIN.COM + default_ccache_name = KEYRING:persistent:%{uid} + + [realms] + MYDOMAIN.COM = { + kdc = kerberos.mydomain.com + admin_server = kerberos.mydomain.com + ... + } + ... + + +2. Create the Kerberos database: :: + + SUSE: kdb5_util create -s + + REDHAT: kdb5_util create -s + + +3. Enable and Start both 'KDC and KDC admin' servers: :: + + SUSE: systemctl enable/start krb5kdc + systemctl enable/start kadmind + + REDHAT: systemctl enable/start krb5kdc + systemctl enable/start kadmin + + +4. Create a Kerberos Administrator + Kerberos principals can be created either locally on the KDC server itself + or through the network, using an 'admin principal'. On the KDC server, + using ``kadmin.local``: + + a. List the existing principals: :: + + kadmin.local: listprincs + K/M@MYDOMAIN.COM + krbtgt/MYDOMAIN.COM@MYDOMAIN.COM + kadmin/admin@MYDOMAIN.COM + kadmin/changepw@MYDOMAIN.COM + kadmin/history@MYDOMAIN.COM + kadmin/kerberos.mydomain.com@MYDOMAIN.COM + root/admin@MYDOMAIN.COM + ... + + + b. In case we don't have a built-in 'admin principal', we then create one + (whatever ``principal name``, we are using ``root``, once by default + ``kinit`` tries to authenticate using the same system login user name, + unless a ``principal`` is passed as an argument ``kinit principal``): :: + + # kadmin.local -q "addprinc root/admin" + Authenticating as principal root/admin@MYDOMAIN.COM with password. + WARNING: no policy specified for root/admin@MYDOMAIN.COM; defaulting to no policy + Enter password for principal "root/admin@MYDOMAIN.COM": + + + c. Confirm the newly created 'admin principal' has the needed permissions + in the KDC ACL (if ACLs are changed, ``kadmind`` needs to be restarted): :: + + SUSE: /var/lib/kerberos/krb5kdc/kadm5.acl + REDHAT: /var/kerberos/krb5kdc/kadm5.acl + + ############################################################################### + #Kerberos_principal permissions [target_principal] [restrictions] + ############################################################################### + # + */admin@MYDOMAIN.COM * + + + d. Create a simple 'user principal' (same steps as by *The 'Ceph side' of + the things*; 4a): :: + + kadmin.local: addprinc johndoe + WARNING: no policy specified for johndoe@MYDOMAIN.COM; defaulting to no policy + Enter password for principal "johndoe@MYDOMAIN.COM": + Re-enter password for principal "johndoe@MYDOMAIN.COM": + Principal "johndoe@MYDOMAIN.COM" created. + + + e. Confirm the newly created 'user principal' is able to authenticate (same + steps as by *The 'Ceph side' of the things*; 6): :: + + # kdestroy -A && kinit -f johndoe && klist -f + Password for johndoe@MYDOMAIN.COM: + Ticket cache: KEYRING:persistent:0:0 + Default principal: johndoe@MYDOMAIN.COM + + Valid starting Expires Service principal + 11/16/2018 13:11:16 11/16/2018 23:11:16 krbtgt/MYDOMAIN.COM@MYDOMAIN.COM + renew until 11/17/2018 13:11:16, Flags: FRI + ... + + +5. At this point, we should have a *simple (MIT) Kerberos Server up and running*: + + a. Considering we will want to work with keytab files, for both 'user and + service' principals, refer to The *'Ceph side' of the things* starting + at step 4. + + b. Make sure you are comfortable with following and their ``manpages``: :: + + krb5.conf -> Krb client config file + kdc.conf -> KDC server config file + + krb5kdc -> KDC server daemon + kadmind -> KDC administration daemon + + kadmin -> Krb administration tool + kdb5_util -> Krb low-level database administration tool + + kinit -> Obtain and cache Kerberos ticket-granting ticket tool + klist -> List cached Kerberos tickets tool + kdestroy -> Destroy Kerberos tickets tool + + +6. Name Resolution + As mentioned earlier, Kerberos *relies heavly on name resolution*. Most of + the Kerberos issues are usually related to name resolution, since Kerberos + is *very picky* on both *systems names* and *host lookups*. + + a. As described in *The 'Ceph side' of the things*; step 2a, DNS RRs + greatly improves service location and host/domain resolution, by using + ``(srv resources)`` and ``(txt record)`` respectively (as per + *Before We Start*; *DNS resolution*). :: + + /var/lib/named/master/mydomain.com + kerberos IN A 192.168.10.21 + kerberos-slave IN A 192.168.10.22 + _kerberos IN TXT "MYDOMAIN.COM" + _kerberos._udp IN SRV 1 0 88 kerberos + _kerberos._tcp IN SRV 1 0 88 kerberos + _kerberos._udp IN SRV 20 0 88 kerberos-slave + _kerberos-master._udp IN SRV 0 0 88 kerberos + _kerberos-adm._tcp IN SRV 0 0 749 kerberos + _kpasswd._udp IN SRV 0 0 464 kerberos + ... + + + b. For a small network or development environment, where a *DNS server is + not available*, we have the option to use ``DNSMasq``, an + ease-to-configure lightweight DNS server (along with some other + capabilities). + + These records can be added to ``/etc/dnsmasq.conf`` (in addition to the + needed 'host records'): :: + + /etc/dnsmasq.conf + ... + txt-record=_kerberos.mydomain.com,"MYDOMAIN.COM" + srv-host=_kerberos._udp.mydomain.com,kerberos.mydomain.com,88,1 + srv-host=_kerberos._udp.mydomain.com,kerberos-2.mydomain.com,88,20 + srv-host=_kerberos-master._udp.mydomain.com,kerberos.mydomain.com,88,0 + srv-host=_kerberos-adm._tcp.mydomain.com,kerberos.mydomain.com,749,0 + srv-host=_kpasswd._udp.mydomain.com,kerberos.mydomain.com,464,0 + srv-host=_kerberos._tcp.mydomain.com,kerberos.mydomain.com,88,1 + ... + + + c. After 'b)' is all set, and ``dnsmasq`` service up and running, we can + test it using: :: + + # nslookup kerberos + Server: 192.168.10.1 + Address: 192.168.10.1#53 + + Name: kerberos.mydomain.com + Address: 192.168.10.21 + + # host -t SRV _kerberos._tcp.mydomain.com + _kerberos._tcp.mydomain.com has SRV record 1 0 88 kerberos.mydomain.com. + + # host -t SRV {each srv-host record} + # host -t TXT _kerberos.mydomain.com + _kerberos.mydomain.com descriptive text "MYDOMAIN.COM" + ... + + + f. As long as ``name resolution`` is working properly, either ``dnsmasq`` + or ``named``, Kerberos should be able to find the needed service + records. |