###################################
High-level steps:
###################################
1. Setup the required test users and service accounts in the AD and the DB
2. Get our Linux OS to talk Kerberos with the KDC and test it using Kinit
3. Get the Oracle client(on the server) to talk Kerberos with the KDC using OKinit
4. Create a Keytab file and move it to the Database Server
5. Edit sqlnet.ora
6. Correct database parameters
7. Test the setup locally on the DB server using kinit and sqlplus
8. Create ticket for service account now
9. Client Windows Setup
10. Script to refresh ticket
Схема взаимодействия:
#-----------------------------------------------------------------------------------
# 1. Setup the required test users and service accounts in the AD and the DB
#-----------------------------------------------------------------------------------
===> We need the following user accounts in the AD:
-> A Domain test User that will be used during login to Windows Client Machine: testuser@DATABASE.COM
-> A Service Account used by the DB during Kerberos communication: sso@DATABASE.COM
!!!
!!! Ensure that you:
!!! - Deselect Setup option "Use DES Encryption"
!!! - Select option "Do not require Kerberos PreAuthentication" for this user
!!! - Select option "Password never expires"
!!!
===> We need the following account in the DB:
-> A test user that that will be used by SQLplus: TESTUSER@DATABASE.COM
SQL> create user "TESTUSER@DATABASE.COM" identified externally;
OR
SQL> create user TESTUSER identified externally as 'testuser@DATABASE.COM';
!!!
!!! Notice: The database username needs to be all capital letters if you go with option 1. In option 2 the case of tester@MYDOMAIN.TEST must match whats in the AD
!!!
#-----------------------------------------------------------------------------------
# 2. Get our Linux OS to talk Kerberos with the KDC and test it using Kinit
#-----------------------------------------------------------------------------------
>>> root
cat /etc/krb5.conf
+++++++++++++++++++++++++++++++++++++++++
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
default_realm = DATABASE.COM
[realms]
DATABASE.COM = {
kdc = SRV-DC1.DATABASE.COM:88
}
[domain_realm]
.database.com = DATABASE.COM
database.com = DATABASE.COM
+++++++++++++++++++++++++++++++++++++++++
//
// To test the Kerberos configuration we will used the kinit OS command.
//
>>> root
kinit testuser
+++++
Password for testuser@DATABASE.COM: ***
+++++
klist
+++++
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: testuser@DATABASE.COM
Valid starting Expires Service principal
06/21/19 09:43:27 06/21/19 19:43:24 krbtgt/DATABASE.COM@DATABASE.COM
renew until 06/28/19 09:43:27
+++++
!!!
!!! The above result shows that we received a valid TGT from the KDC
!!!
Убедились, что связь на уровне OS до KDC, с использованием конфиг файла "/etc/krb5.conf", успешно работает, значит конфиг файл нормальный).
#-----------------------------------------------------------------------------------
# 3. Get the Oracle client(on the server) to talk Kerberos with the KDC using OKinit
#-----------------------------------------------------------------------------------
//
// The okinit command is the Oracle equivalent of kinit but it uses configuration from the Oracle home.
// So we use this command to verify that the configuration from an Oracle point of view is correct.
//
На данном этапе, чтобы проверить функциональность между Oracle и KDC достаточно добавить следующие строки:
cat $ORACLE_HOME/network/admin/sqlnet.ora
+++++++++++++++++++++++++++++++++++++++++
NAMES.DIRECTORY_PATH=(TNSNAMES, HOSTNAME)
SQLNET.KERBEROS5_CONF_MIT=TRUE
SQLNET.AUTHENTICATION_SERVICES=(BEQ,KERBEROS5)
SQLNET.KERBEROS5_CONF=/etc/krb5.conf
+++++++++++++++++++++++++++++++++++++++++
//
// Now the okinit command can be tested
//
okinit -e 23 testuser@DATABASE.COM
+++++++++++++++++++++++++++++++++++++++++
Kerberos Utilities for Linux: Version 11.2.0.4.0 - Production on 26-JUN-2019 09:36:52
Copyright (c) 1996, 2013 Oracle. All rights reserved.
Password for testuser@DATABASE.COM:
+++++++++++++++++++++++++++++++++++++++++
oklist
+++++++++++++++++++++++++++++++++++++++++
Kerberos Utilities for Linux: Version 11.2.0.4.0 - Production on 26-JUN-2019 09:36:59
Copyright (c) 1996, 2013 Oracle. All rights reserved.
Ticket cache: /tmp/krb5cc_54321
Default principal: testuser@DATABASE.COM
Valid Starting Expires Principal
26-Jun-2019 09:36:55 26-Jun-2019 17:36:52 krbtgt/DATABASE.COM@DATABASE.COM
+++++++++++++++++++++++++++++++++++++++++
Based on the above we can see that a TGT has been placed in the default Kerberos cache.
#-----------------------------------------------------------------------------------
# 4. Create a Keytab file and move it to the Database Server
#-----------------------------------------------------------------------------------
The Database Service will use the keytab file instead of using username/password when interacting with the KDC.
В нашем случае это "sso" = "orcl/node01.database.com@DATABASE.COM"
!!!
!!! On the Domain Controller you need to use the ktpass tool to generate a keytab file and also associate an SPN(Service Principal) entry to the "sso" AD User.
!!!
>>> В командной строке на KDC
### setspn -A orcl/node01.database.com@DATABASE.COM sso # Необязательный шаг, потому что при выполнении команды ниже SPN сам создастся, который будет указан, если такой еще не существует для данного пользователя
ktpass -princ orcl/node01.database.com@DATABASE.COM -mapuser sso@DATABASE.COM -crypto all -ptype KRB5_NT_PRINCIPAL -out C:\krb5.keytab -pass ***
!!!
!!! ВНИМАНИЕ: Очень важно, чтобы SPN содержал в нижнем регистре буквы, то есть именно так: orcl/node01.database.com@DATABASE.COM моя ошибка была в том что делал так (НЕПРАВИЛЬНО): orcl/NODE01.DATABASE.COM@DATABASE.COM
!!!
!!! Объяснение: Because on Linux side, when user uses the file to login to server, klist or oklist shows service principals are always transferred to lower case. If use upper case we'll fail to get authenticated.
!!!
!!! Источник: http://tomdu.github.io/2018/06/20/Configure-Kerberos-Authentication-for-Oracle-12c/
!!!
!!!
!!! Note: Так же интересный механизм работы кербероса. Если вы сделали изменения в настройках сервис пользователя (sso в нашем случае) на стороне AD (сняли какую-то галочку, сменили пароль и т.п.) то необходимо пересоздать keytab через утилиту ktpass выше.
!!! При этом все предыдущие (старые) keytab файлы станут неактуальными, нужно будет использовать только этот и скопировать его на сервер с БД.
!!!
//
// Скопировать файл на сервер БД
//
$ ls -ltr /etc/krb5.keytab
-rw-r--r--. 1 root root 427 Jun 26 09:10 /etc/krb5.keytab
//
// Протестировать валидность данного keytab с помощью утилиты oklist
//
$ oklist -k /etc/krb5.keytab
+++++++++++++++++++++++++++++++++++++++++
Kerberos Utilities for Linux: Version 11.2.0.4.0 - Production on 26-JUN-2019 09:49:09
Copyright (c) 1996, 2013 Oracle. All rights reserved.
Service Key Table: /etc/krb5.keytab
Ver Timestamp Principal
6 01-Jan-1970 03:00:00 orcl/node01.database.com@DATABASE.COM
6 01-Jan-1970 03:00:00 orcl/node01.database.com@DATABASE.COM
6 01-Jan-1970 03:00:00 orcl/node01.database.com@DATABASE.COM
6 01-Jan-1970 03:00:00 orcl/node01.database.com@DATABASE.COM
6 01-Jan-1970 03:00:00 orcl/node01.database.com@DATABASE.COM
+++++++++++++++++++++++++++++++++++++++++
Такое количество записей (5 штук), поскольку при создании кетаб файла, был указан ключ -crypto all , поэтому он(кейтаб) содержит 5 записей для каждого метода шифрования. Можно было указать какой-то конкретный метод шифрования, тогда была бы одна запись.
#-----------------------------------------------------------------------------------
# 5. Edit sqlnet.ora
#-----------------------------------------------------------------------------------
Итоговый вариант файла:
cat $ORACLE_HOME/network/admin/sqlnet.ora
+++++++++++++++++++++++++++++++++++++++++
NAMES.DIRECTORY_PATH=(TNSNAMES, HOSTNAME)
SQLNET.KERBEROS5_CONF=/etc/krb5.conf
SQLNET.KERBEROS5_KEYTAB=/etc/krb5.keytab
SQLNET.KERBEROS5_CONF_MIT=TRUE
SQLNET.AUTHENTICATION_SERVICES=(BEQ,KERBEROS5)
SQLNET.AUTHENTICATION_KERBEROS5_SERVICE=orcl
+++++++++++++++++++++++++++++++++++++++++
#-----------------------------------------------------------------------------------
# 6. Correct database parameters
#-----------------------------------------------------------------------------------
>>> oracle
sqlplus / as sysdba
SQL> show parameter os_auth
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
os_authent_prefix string ops$
remote_os_authent boolean FALSE
SQL> alter system set os_authent_prefix='' scope=spfile;
SQL> alter system set remote_os_authent=false scope=spfile;
SQL> shu immediate;
SQL> startup;
#-----------------------------------------------------------------------------------
# 7. Test the setup locally on the DB server using kinit and sqlplus
#-----------------------------------------------------------------------------------
>>> oracle
$ okdstry
$ okinit -e 23 testuser@DATABASE.COM
+++++++++++++++++++++++++++++++++++++++++
Kerberos Utilities for Linux: Version 11.2.0.4.0 - Production on 26-JUN-2019 09:55:12
Copyright (c) 1996, 2013 Oracle. All rights reserved.
Password for testuser@DATABASE.COM:
+++++++++++++++++++++++++++++++++++++++++
$ oklist
+++++++++++++++++++++++++++++++++++++++++
Kerberos Utilities for Linux: Version 11.2.0.4.0 - Production on 26-JUN-2019 09:55:48
Copyright (c) 1996, 2013 Oracle. All rights reserved.
Ticket cache: /tmp/krb5cc_54321
Default principal: testuser@DATABASE.COM
Valid Starting Expires Principal
26-Jun-2019 09:55:16 26-Jun-2019 17:55:12 krbtgt/DATABASE.COM@DATABASE.COM
+++++++++++++++++++++++++++++++++++++++++
$ sqlplus /@orcl
+++++++++++++++++++++++++++++++++++++++++
SQL*Plus: Release 11.2.0.4.0 Production on Wed Jun 26 09:56:15 2019
Copyright (c) 1982, 2013, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> show user;
USER is "TESTUSER@DATABASE.COM"
+++++++++++++++++++++++++++++++++++++++++
#-----------------------------------------------------------------------------------
# 8. Create ticket for service account now:
#-----------------------------------------------------------------------------------
>>> oracle
$ okdstry
$ okinit -e 23 orcl/node01.database.com@DATABASE.COM
$ oklist
+++++++++++++++++++++++++++++++++++++++++
Kerberos Utilities for Linux: Version 11.2.0.4.0 - Production on 26-JUN-2019 10:06:30
Copyright (c) 1996, 2013 Oracle. All rights reserved.
Ticket cache: /tmp/krb5cc_54321
Default principal: orcl/node01.database.com@DATABASE.COM
Valid Starting Expires Principal
26-Jun-2019 10:06:19 26-Jun-2019 18:06:17 krbtgt/DATABASE.COM@DATABASE.COM
+++++++++++++++++++++++++++++++++++++++++
#-----------------------------------------------------------------------------------
# 9. Client Windows Setup:
#-----------------------------------------------------------------------------------
===> 1) Создать директорию и конфиг файл в ней (содержимое должно быть таким же как на сервере с БД):
C:\Windows\system32>more C:\krb\krb5.conf
[libdefaults]
default_realm = DATABASE.COM
[realms]
DATABASE.COM = {
kdc = SRV-DC1.DATABASE.COM:88
}
[domain_realm]
.database.com = DATABASE.COM
database.com = DATABASE.COM
===> 2) Установить Oracle Client (вместе с ним будет установлена утилита sqlplus) и в директорию $ORACLE_HOME/network/admin прописать в файлы ниже следующие значения:
tnsnames.ora
+++++++++++++++++++++++++++++++++++++++++
orcl =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = node01.database.com)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)
)
)
+++++++++++++++++++++++++++++++++++++++++
sqlnet.ora
+++++++++++++++++++++++++++++++++++++++++
NAMES.DIRECTORY_PATH = (TNSNAMES)
SQLNET.KERBEROS5_CC_NAME = OSMSFT://
SQLNET.KERBEROS5_CONF = c:\krb\krb5.conf
SQLNET.KERBEROS5_CONF_MIT = TRUE
SQLNET.AUTHENTICATION_SERVICES=(BEQ,KERBEROS5PRE,KERBEROS5) <===== В моем случае клиент версии 12c, поэтому нужно еще добавить KERBEROS5PRE, тоже самое качается и базы 12c, но в моем случае БД 11g. При апгрейде нужно не забыть подкорректировать sqlnet.ora на стороне сервера БД иначе войти без пароля не получится
SQLNET.AUTHENTICATION_KERBEROS5_SERVICE = orcl
+++++++++++++++++++++++++++++++++++++++++
IMPORTANT:
-> For 11.x clients authentication service KERBEROS5 is used, with Credential Cache (CC_NAME) OSMSFT:
-> For 12.x client 12.x in theory, KERBROS5 service should be used with MSLSA: for the CC_NAME (however due to bug 18895651, KERBEROS5PRE is required with CC_NAME OSMSFT
===> Edit C:\Windows\System32\drivers\etc\services
kerberos 88/tcp kerberos5 krb5 kerberos-sec #Kerberos
kerberos 88/udp kerberos5 krb5 kerberos-sec #Kerberos
#-----------------------------------------------------------------------------------
# 10. Script to refresh ticket
#-----------------------------------------------------------------------------------
На стороне сервера БД нужно периодически обновлять тикет, поскольку, если этого не делать, то он просрочится и со стороны базы не сможет происходить проверка валидности клиентских тикетов.
Поэтому, написал небольшой скрипт для автоматизации этого процесса.
В кронтабе, под пользователем, из под которого установлена БД (бегает каждые 6 часов):
##
## Kerberos ticket refresh ---> /home/oracle/dba/logs/krk5_ticket_refresh.log
##
0 */6 * * * /home/oracle/dba/scripts/krk5_ticket_refresh.sh
Сам скрипт:
/home/oracle/dba/scripts/krk5_ticket_refresh.sh
#!/bin/bash
##
## Name:
## krk5_ticket_refresh.sh
##
## Version:
## 1.0 --- Initial --- dr.oracle
##
## Description:
## Script for kerberos ticket refresh.
##
## Usage:
## /home/oracle/dba/scripts/krk5_ticket_refresh.sh
##
#----------------------------
# Variables:
#----------------------------
ORACLE_HOME=/oracle/app/oracle/product/11204/db_1
PATH=/usr/sbin:$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:/usr/sbin:$PATH
TMPDIR=/home/oracle/tmp
LOG_DIR=/home/oracle/dba/logs
REALM="@DATABASE.COM"
SPN="orcl/node1.database.com"
SRVACCPWD="pwd"
#----------------------------
# Functions:
#----------------------------
############################
___checks() {
if [[ ! -d $LOG_DIR ]];
then
echo "`date`" >> /tmp/krk5_ticket_refresh.log
echo "ERROR: Directory LOG_DIR=${LOG_DIR} doesn't exist." >> /tmp/krk5_ticket_refresh.log
return 1;
elif [[ ! -d $ORACLE_HOME ]];
then
echo "`date`" >> ${LOG_DIR}/krk5_ticket_refresh.log
echo "ERROR: Directory ORACLE_HOME=${ORACLE_HOME} doesn't exist." >> ${LOG_DIR}/krk5_ticket_refresh.log
return 1;
elif [[ ! -d $TMPDIR ]];
then
echo "`date`" >> ${LOG_DIR}/krk5_ticket_refresh.log
echo "ERROR: Directory TMPDIR=${TMPDIR} doesn't exist." >> ${LOG_DIR}/krk5_ticket_refresh.log
return 1;
else
return 0;
fi
}
############################
___krb_ticket_refresh () {
echo "${SRVACCPWD}" | okinit ${SPN}${REALM} > /dev/null
if [[ $? == 0 ]];
then
return 0;
else
echo "`date`" >> ${LOG_DIR}/krk5_ticket_refresh.log
echo "ERROR: okinit failed. Try to run manually to identify the issue." >> ${LOG_DIR}/krk5_ticket_refresh.log
return 1;
fi
}
#----------------------------
# Main:
#----------------------------
export ORACLE_HOME
export PATH
export TMPDIR
if ___checks
then
if ___krb_ticket_refresh
then
echo "`date`" >> ${LOG_DIR}/krk5_ticket_refresh.log
echo "SUCCESS: Ticket has been refreshed." >> ${LOG_DIR}/krk5_ticket_refresh.log
exit 0;
else
exit -10;
fi
else
exit -10;
fi
#-----------------------------------------------------------------------------------
# Источники:
#-----------------------------------------------------------------------------------
1) http://www.ateam-oracle.com/configuring-your-oracle-database-for-kerberos-authentication
2) https://bjornnaessens.wordpress.com/2012/12/21/configuring-kerberos-for-oracle-databases-11-2-with-win2008r2-ad/
3) http://tomdu.github.io/2018/06/20/Configure-Kerberos-Authentication-for-Oracle-12c/
4) How To Check if Oracle Advanced Security Option is Installed ? (Doc ID 549989.1)