Use MIT Kerberos KDC in ADB
- Step 1. Install and configure MIT Kerberos KDC
- Step 2. Create principals for ADB in MIT Kerberos KDC
- Step 3. Configure the ADB master and check authentication
- Step 4. Map Kerberos principals to ADB roles
- Step 5. Configure Kerberos authentication for client applications
- Step 6. Configure JDBC connections
Step 1. Install and configure MIT Kerberos KDC
TIP
For information on Kerberos authentication, see the MIT Kerberos documentation. |
Below you can find an example of installing and configuring MIT Kerberos KDC on the bds-kerberos.ru-central1.internal host with CentOS 7. The realm name is RU-CENTRAL1.INTERNAL
. Note that the Kerberos realm name should be uppercase:
-
Install Kerberos server and client packages:
$ sudo yum install krb5-libs krb5-server krb5-workstation
-
Edit the following Kerberos configuration files using the
vi
(orvim
) editor.-
In the /etc/krb5.conf file, fill in the
realms
,domain_realm
sections and thedefault_realm
field of thelibdefaults
section:$ sudo vi /etc/krb5.conf
The file example is given below. In the
kdc
andadmin_server
fields of therealms
section, specify the host where Kerberos KDC is being installed (with a port number). You can use IP addresses instead of host names:# Configuration snippets may be placed in this directory as well includedir /etc/krb5.conf.d/ [logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] default_realm = RU-CENTRAL1.INTERNAL dns_lookup_realm = false dns_lookup_kdc = false ticket_lifetime = 24h renew_lifetime = 7d forwardable = true default_tgs_enctypes = aes128-cts des3-hmac-sha1 des-cbc-crc des-cbc-md5 default_tkt_enctypes = aes128-cts des3-hmac-sha1 des-cbc-crc des-cbc-md5 permitted_enctypes = aes128-cts des3-hmac-sha1 des-cbc-crc des-cbc-md5 [realms] RU-CENTRAL1.INTERNAL = { kdc = bds-kerberos.ru-central1.internal:88 admin_server = bds-kerberos.ru-central1.internal:749 default_domain = ru-central1.internal } [domain_realm] .ru-central1.internal = RU-CENTRAL1.INTERNAL ru-central1.internal = RU-CENTRAL1.INTERNAL [appdefaults] pam = { debug = false ticket_lifetime = 36000 renew_lifetime = 36000 forwardable = true krb4_convert = false }
-
In the /var/kerberos/krb5kdc/kdc.conf file, update the realm name in the
realms
section:$ sudo vi /var/kerberos/krb5kdc/kdc.conf
The file example:
[kdcdefaults] kdc_ports = 88 kdc_tcp_ports = 88 [realms] RU-CENTRAL1.INTERNAL = { #master_key_type = aes256-cts acl_file = /var/kerberos/krb5kdc/kadm5.acl dict_file = /usr/share/dict/words admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal }
-
-
Use the kdb5_util utility to create a Kerberos KDC database. This database is used to store keys for the Kerberos realms that are managed by the current KDC server. Use the
-s
option to create a stash file: without that file, you will be requested a password every time the KDC server starts.$ sudo kdb5_util create -s
After running the command, enter and confirm a password:
Loading random data Initializing database '/var/kerberos/krb5kdc/principal' for realm 'RU-CENTRAL1.INTERNAL', master key name 'K/M@RU-CENTRAL1.INTERNAL' You will be prompted for the database Master Password. It is important that you NOT FORGET this password. Enter KDC database master key: Re-enter KDC database master key to verify:
-
Create the
gpadmin/admin
principal with administrative privileges in Kerberos KDC. To do this, use the kadmin.local utility:$ sudo kadmin.local -q "addprinc gpadmin/admin"
After running the command, enter and confirm a password:
Authenticating as principal root/admin@RU-CENTRAL1.INTERNAL with password. WARNING: no policy specified for gpadmin/admin@RU-CENTRAL1.INTERNAL; defaulting to no policy Enter password for principal "gpadmin/admin@RU-CENTRAL1.INTERNAL": Re-enter password for principal "gpadmin/admin@RU-CENTRAL1.INTERNAL": Principal "gpadmin/admin@RU-CENTRAL1.INTERNAL" created.
-
To grant the appropriate permissions to the created principal, edit the /var/kerberos/krb5kdc/kadm5.acl file:
$ sudo vi /var/kerberos/krb5kdc/kadm5.acl
For example, the following file record means that any principal in the
RU-CENTRAL1.INTERNAL
realm with a name ending with/admin
has all administrative privileges except key extraction:*/admin@RU-CENTRAL1.INTERNAL *
-
Start Kerberos services by running the following commands:
$ sudo systemctl start kadmin $ sudo systemctl start krb5kdc
-
To check the status of Kerberos services, you can use these commands:
$ systemctl status kadmin $ systemctl status krb5kdc
The result of the first command is shown below:
● kadmin.service - Kerberos 5 Password-changing and Administration Loaded: loaded (/usr/lib/systemd/system/kadmin.service; disabled; vendor preset: disabled) Active: active (running) since Thu 2024-05-23 10:02:07 UTC; 41s ago Process: 15825 ExecStart=/usr/sbin/_kadmind -P /var/run/kadmind.pid $KADMIND_ARGS (code=exited, status=0/SUCCESS) Main PID: 15826 (kadmind) CGroup: /system.slice/kadmin.service └─15826 /usr/sbin/kadmind -P /var/run/kadmind.pid
-
To make Kerberos start automatically upon the host restart, run the commands:
$ sudo systemctl enable krb5kdc.service $ sudo systemctl enable kadmin.service
The result of the first command is shown below:
Created symlink from /etc/systemd/system/multi-user.target.wants/krb5kdc.service to /usr/lib/systemd/system/krb5kdc.service.
Step 2. Create principals for ADB in MIT Kerberos KDC
In addition to the principal with administrative permissions (the creation of which is described above), you need to add Kerberos principals for all ADB users who will use Kerberos authentication. Since ordinary users do not need administrative access to the Kerberos server in most cases, you can use the kadmin utility to manage them (instead of kadmin.local
). Examples in the following sections will use only one principal for demonstration purposes — gpadmin/admin@RU-CENTRAL1.INTERNAL
(with one corresponding role in ADB — gpadmin/admin
).
You should also add a service principal to Kerberos KDC, which corresponds not to the role, but to the postgres
process on the ADB master host. This principal is required when using Kerberos authentication with ADB. A principal name is formed according to the following template:
postgres/<master_hostname>@<REALM>
where:
-
<master_hostname>
— a name of the ADB master host, which can be obtained via thehostname
command. If this command returns the fully qualified domain name (FQDN), use it as the parameter value. -
<REALM>
— a realm name in Kerberos.
Below is an example of adding a service principal:
$ sudo kadmin.local -q "addprinc postgres/bds-mdw@RU-CENTRAL1.INTERNAL"
The result:
Authenticating as principal root/admin@RU-CENTRAL1.INTERNAL with password. WARNING: no policy specified for postgres/bds-mdw@RU-CENTRAL1.INTERNAL; defaulting to no policy Enter password for principal "postgres/bds-mdw@RU-CENTRAL1.INTERNAL": Re-enter password for principal "postgres/bds-mdw@RU-CENTRAL1.INTERNAL": Principal "postgres/bds-mdw@RU-CENTRAL1.INTERNAL" created.
When all required principals (including the service principal) are created, add them to the keytab file using the following command. This keytab file should be copied to the master host of ADB later.
$ sudo kadmin.local -q "ktadd -k bds-kerberos.keytab postgres/bds-mdw@RU-CENTRAL1.INTERNAL gpadmin/admin@RU-CENTRAL1.INTERNAL"
The result:
Authenticating as principal root/admin@RU-CENTRAL1.INTERNAL with password. Entry for principal postgres/bds-mdw@RU-CENTRAL1.INTERNAL with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:bds-kerberos.keytab. Entry for principal postgres/bds-mdw@RU-CENTRAL1.INTERNAL with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:bds-kerberos.keytab. Entry for principal gpadmin/admin@RU-CENTRAL1.INTERNAL with kvno 3, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:bds-kerberos.keytab. Entry for principal gpadmin/admin@RU-CENTRAL1.INTERNAL with kvno 3, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:bds-kerberos.keytab.
Step 3. Configure the ADB master and check authentication
-
Install Kerberos client libraries on the ADB master host:
$ sudo yum install krb5-libs krb5-workstation
-
Copy the /etc/krb5.conf file contents from the Kerberos server to the /etc/krb5.conf file on the ADB master host.
-
Copy the keytab file that was generated on the Kerberos server (bds-kerberos.keytab in our example) to the /home/gpadmin/ directory on the ADB master host. Set the ownership and permissions of the keytab file you copied as follows:
$ sudo chown gpadmin:gpadmin /home/gpadmin/bds-kerberos.keytab $ sudo chmod 400 /home/gpadmin/bds-kerberos.keytab
-
Log in to the ADB master host under the
gpadmin
user and save a path to the keytab file in the server configuration parameter (GUC)krb_server_keyfile
:$ sudo su - gpadmin $ gpconfig -c krb_server_keyfile -v '/home/gpadmin/bds-kerberos.keytab'
The result:
20240523:10:50:32:008181 gpconfig:bds-mdw:gpadmin-[INFO]:-completed successfully with parameters '-c krb_server_keyfile -v /home/gpadmin/bds-kerberos.keytab'
-
Open the ADB service configuration page in ADCM. In the Custom pg_hba section field, add information about Kerberos authentication using the following format:
host all all 0.0.0.0/0 gss include_realm=0 krb_realm=RU-CENTRAL1.INTERNAL
For more information on the pg_hba.conf file format that is used for Kerberos authentication, see Step 4. Map Kerberos principals to ADB roles. The abovementioned entry allows connecting to all ADB databases from all hosts for those ADB roles whose names coincide with the principal names in the
RU-CENTRAL1.INTERNAL
realm. Theinclude_realm=0
option means the realm should be stripped from principal names before mapping with ADB role names.To apply changes, click Save and run the ADB service action Reconfigure.
Configure Kerberos authentication for ADB via ADCMNOTEThe0.0.0.0/0
address is used for test needs only. It is not recommended for production environments. -
Create the
gpadmin/admin
superuser role in ADB. This role will be mapped to the gpadmin/admin@RU-CENTRAL1.INTERNAL principal in Kerberos:$ createuser gpadmin/admin --superuser
-
Using the kinit command, create a ticket granting ticket (TGT) for the
gpadmin/admin@RU-CENTRAL1.INTERNAL
principal:$ kinit -k -t /home/gpadmin/bds-kerberos.keytab gpadmin/admin@RU-CENTRAL1.INTERNAL
NOTEIn this and the following examples, the previously created keytab file is used when a ticket is requested (see the-k
and-t
options). In practice, keytab files are most commonly used for service accounts. Ordinary users can callkinit
without arguments — in this case, they need to enter the password specified for the corresponding principals in Kerberos. The next steps are the same. -
Check the ticket existence in the ticket cache via the klist command:
$ klist
The result contains the obtained TGT:
Ticket cache: FILE:/tmp/krb5cc_2042 Default principal: gpadmin/admin@RU-CENTRAL1.INTERNAL Valid starting Expires Service principal 05/23/2024 15:23:38 05/24/2024 15:23:37 krbtgt/RU-CENTRAL1.INTERNAL@RU-CENTRAL1.INTERNAL
-
Log in to the
adb
database under thegpadmin/admin
role via psql:$ psql adb -U "gpadmin/admin" -h bds-mdw
-
Select the current user name to verify that authentication is successful:
SELECT current_user;
The result:
current_user --------------- gpadmin/admin
-
If you quit psql and run
klist
again, the command result will contain not only a TGT, but also a ticket granting service (TGS), which is needed to implement the Kerberos authentication protocol in ADB (see postgres/bds-mdw@RU-CENTRAL1.INTERNAL):Ticket cache: FILE:/tmp/krb5cc_2042 Default principal: gpadmin/admin@RU-CENTRAL1.INTERNAL Valid starting Expires Service principal 05/23/2024 15:23:38 05/24/2024 15:23:37 krbtgt/RU-CENTRAL1.INTERNAL@RU-CENTRAL1.INTERNAL 05/23/2024 15:24:03 05/24/2024 15:23:37 postgres/bds-mdw@ 05/23/2024 15:24:03 05/24/2024 15:23:37 postgres/bds-mdw@RU-CENTRAL1.INTERNAL
NOTEThe additional entry with the empty realm name (postgres/bds-mdw@
) is not an error. This is an artifact of the way how host referrals were introduced in krb5 later than 1.6.
Step 4. Map Kerberos principals to ADB roles
In the example listed above, the following template is used to add credentials for the Kerberos authentication to the pg_hba.conf file:
host <database> <user> <address> <auth-method> [<auth-options>]
For detailed information on each attribute of this entry, as well as for other possible attributes, see The pg_hba.conf File article in the PostgreSQL documentation. Below, we will focus only on the <auth-options>
specific for the GSSAPI protocol, which is used for Kerberos authentication. By combining these options, you can choose the most appropriate way to map Kerberos principals to ADB users:
-
include_realm
— if set to0
, a realm name is excluded from Kerberos principal names before being passed through the mapping with ADB role names; if set to1
— a realm name is included. The usage of0
is not secure in multi-realm environments (unless thekrb_realm
option is used). It is recommended to setinclude_realm=1
and use themap
option to convert Kerberos principal names to ADB role names based on the pg_ident.conf file. -
krb_realm
— a name of the Kerberos realm. If this parameter is set, only principals of that realm will be accepted. -
map
— a name of the custom mapping that allows you to explicitly map Kerberos principals to ADB roles in the pg_ident.conf file of the ADB master data directory. Each mapping requires the following format:# MAPNAME SYSTEM-USERNAME PG-USERNAME <map_name> <principal_name> <role_name>
where:
-
<map_name>
— a mapping name that should be specified in the pg_hba.conf file:map=<map_name>
. -
<principal_name>
— a name of the Kerberos principal. Should include the realm name (after@
) ifinclude_realm=1
. -
<role_name>
— a role name in ADB.
-
The following example shows how to map Kerberos principals to ADB roles via the map
option:
-
Connect to the master host under the
gpadmin
user and create a new usermyadmin
:$ createuser "myadmin" --superuser;
-
In the master data directory, open the pg_ident.conf file:
$ cd /data1/master/gpseg-1 $ vi pg_ident.conf
-
Add the
mymap
mapping to the file:# MAPNAME SYSTEM-USERNAME PG-USERNAME mymap gpadmin/admin@RU-CENTRAL1.INTERNAL myadmin
-
Open the ADB service configuration page in ADCM. In the Custom pg_hba section field, replace the previously added value of the Custom pg_hba section field by the following record:
host all all 0.0.0.0/0 gss include_realm=1 krb_realm=RU-CENTRAL1.INTERNAL map=mymap
Note that
include_realm=1
. If the option value is0
, the previous step would require to use another record:# MAPNAME SYSTEM-USERNAME PG-USERNAME mymap gpadmin/admin myadmin
-
Click Save to save changes and run the Reconfigure action of the ADB service.
CAUTIONYou should run the Reconfigure action each time you edit the pg_ident.conf file or the Custom pg_hba section value. -
Remove existing tickets (if any) via the kdestroy command:
$ kdestroy
-
Using the
kinit
command, create a TGT for thegpadmin/admin@RU-CENTRAL1.INTERNAL
principal:$ kinit -k -t /home/gpadmin/bds-kerberos.keytab gpadmin/admin@RU-CENTRAL1.INTERNAL
-
Ensure you can connect to the database using the
myadmin
role:$ psql adb -U "myadmin" -h bds-mdw
-
After you successfully connected to ADB, quit psql and run
klist
to ensure the service ticket is available:$ klist
The result:
Ticket cache: FILE:/tmp/krb5cc_2042 Default principal: gpadmin/admin@RU-CENTRAL1.INTERNAL Valid starting Expires Service principal 05/24/2024 07:21:57 05/25/2024 07:21:57 krbtgt/RU-CENTRAL1.INTERNAL@RU-CENTRAL1.INTERNAL 05/24/2024 07:22:15 05/25/2024 07:21:57 postgres/bds-mdw@ 05/24/2024 07:22:15 05/25/2024 07:21:57 postgres/bds-mdw@RU-CENTRAL1.INTERNAL
Step 5. Configure Kerberos authentication for client applications
After Kerberos authentication is configured, client applications need Kerberos tickets for connecting to ADB. On the client side, the kinit
utility is used to generate tickets. To make this utility work, you should copy the krb5-conf configuration file and the keytab file from the Kerberos side and install Kerberos client libraries on the host, where the ADB connection is being configured. The following is an example of configuring a host with CentOS 7 and connecting from that host to ADB via psql:
-
Install Kerberos client libraries on the host, from which you need to connect to the ADB database:
$ sudo yum install krb5-libs krb5-workstation
-
Copy the /etc/krb5.conf contents from Kerberos to the /etc/krb5.conf file on the client host.
-
Copy the keytab file previously created on the Kerberos server (bds-kerberos.keytab) to the home directory of the current user (/home/gpadmin/ in our example).
-
Connect to the host under the user, whose home directory contains the keytab file (
gpadmin
in our example).$ sudo su - gpadmin
-
Request a TGT for the
gpadmin/admin@RU-CENTRAL1.INTERNAL
principal via thekinit
command:$ kinit -k -t /home/gpadmin/bds-kerberos.keytab gpadmin/admin@RU-CENTRAL1.INTERNAL
-
Check that you can connect to the ADB database using the
myadmin
role, which creation was described in Step 4. Map Kerberos principals to ADB roles:$ psql adb -U "myadmin" -h bds-mdw
-
After you successfully connected to ADB, quit psql and run
klist
to ensure the service ticket is available:$ klist
The result:
Ticket cache: FILE:/tmp/krb5cc_2042 Default principal: gpadmin/admin@RU-CENTRAL1.INTERNAL Valid starting Expires Service principal 05/30/2024 13:07:02 05/31/2024 13:07:00 krbtgt/RU-CENTRAL1.INTERNAL@RU-CENTRAL1.INTERNAL 05/30/2024 13:07:15 05/31/2024 13:07:00 postgres/bds-mdw@ 05/30/2024 13:07:15 05/31/2024 13:07:00 postgres/bds-mdw@RU-CENTRAL1.INTERNAL
Step 6. Configure JDBC connections
The JDBC access from Java applications to ADB databases with Kerberos authentication is performed via the Java authentication and authorization service (JAAS). Below you can find how to configure and run a simple Java application on a host with the CentOS 7 operating system. The application selects table data from ADB. The PostgreSQL JDBC driver is used to connect to ADB:
-
Connect to the
adb
database on the master host and create a test table that will be used in your Java application:CREATE TABLE book_type(id INT PRIMARY KEY, name TEXT UNIQUE NOT NULL) DISTRIBUTED REPLICATED;
-
Add some data to the test table:
INSERT INTO book_type VALUES(1,'novel'),(2,'non-fiction'),(3,'fantastic');
-
On the host where you plan to run the Java application, follow all steps described in Step 5. Configure Kerberos authentication for client applications. At the end, check that you are log in under the user for whom the tickets were created (
gpadmin
in our example):$ sudo su - gpadmin
-
Ensure that Java is installed:
$ java -version
In our example, Java 11 is used:
openjdk version "11.0.23" 2024-04-16 LTS OpenJDK Runtime Environment (Red_Hat-11.0.23.0.9-2.el7_9) (build 11.0.23+9-LTS) OpenJDK 64-Bit Server VM (Red_Hat-11.0.23.0.9-2.el7_9) (build 11.0.23+9-LTS, mixed mode, sharing)
-
Create the .java.login.config file in the home directory of the current user (/home/gpadmin in our example):
$ vi .java.login.config
The file contents are listed below. The purpose of all file options can be found in the Class Krb5LoginModule documentation.
pgjdbc { com.sun.security.auth.module.Krb5LoginModule required doNotPrompt=true useTicketCache=true debug=true client=true; };
-
Create the application file:
$ vi test.java
The application code is shown below. This program connects to the
adb
database on thebds-mdw
master host using the PostgreSQL JDBC driver. Then, thename
column is read from all tuples of thebook_type
table:import java.sql.*; public class Test { public static void main(String []args) throws Exception { Class.forName("org.postgresql.Driver"); String url = "jdbc:postgresql://bds-mdw:5432/adb?kerberosServerName=postgres&jaasApplicationName=pgjdbc&user=myadmin"; try ( Connection conn = DriverManager.getConnection(url) ){ try ( Statement statement = conn.createStatement() ) { try (ResultSet rs = statement.executeQuery( "SELECT name FROM book_type") ){ while (rs.next()) System.out.println( "Get String: " + rs.getString(1)); } } } } }
-
Upload the JAR file of the PostgreSQL JDBC driver and specify its location in the
CLASSPATH
environment variable:$ export CLASSPATH=.:/home/gpadmin/postgresql-42.7.3.jar
-
Run the application:
$ java test.java
The successful result is shown below:
Debug is true storeKey false useTicketCache true useKeyTab false doNotPrompt true ticketCache is /tmp/krb5cc_2042 isInitiator true KeyTab is null refreshKrb5Config is false principal is null tryFirstPass is false useFirstPass is false storePass is false clearPass is false Acquire TGT from Cache Principal is gpadmin/admin@RU-CENTRAL1.INTERNAL Commit Succeeded Get String: novel Get String: non-fiction Get String: fantastic