为Windows客户端进行Kerberos配置

为Windows客户端进行Kerberos配置

您可以配置微软的Windows客户端应用程序来连接一个已配置Kerberos认证的Greenplum数据库系统。

有关在Greenplum数据库中启用Kerberos认证的信息,参阅使用Kerberos认证

在Windows上为Greenplum数据库客户端配置Kerberos

当一个Greenplum数据库系统被配置为启用Kerberos作认证后,您可以为微软Windows系统上的Greenplum数据库客户端工具gploadpsql配置Kerberos认证。 Greenplum数据库直接使用Kerberos认证,而不使用微软的活动目录(AD)。

本节包含以下信息。

这些主题假设Greenplum数据库系统已经被配置为启用Kerberos和微软的活动目录认证。参阅使用活动目录配置客户端身份认证

在Windows系统上安装Kerberos

要对Windows系统上的Greenplum数据库客户端使用Kerberos认证,该系统上必须安装MIT Kerberos Windows客户端。 可以从http://web.mit.edu/kerberos/dist/index.html下载安装MIT Kerberos for Windows 4.0.1 (for krb5)。

在Windows系统上,可以使用Kerberos的kinit工具管理Kerberos的票据。

Kerberos服务没有被设置为自启动。该服务不能被用来认证Greenplum数据库。

从Greenplum数据库master主机拷贝/etc/krb5.conf,并放置到Windows系统Kerberos默认路径C:\ProgramData\MIT\Kerberos5\krb5.ini。 在文件的[libdefaults]部分,移除Kerberos的票据缓冲的位置default_ccache_name

在Windows系统上,使用环境变量KRB5CCNAME指定Kerberos票据的位置。环境变量的值是一个文件而不是目录,并且它应该对服务器上的每个登录都是唯一的。

如下示例是配置文件,其中default_ccache_name被移除, [logging]部分也被移除。

[libdefaults]
 debug = true
 default_etypes = aes256-cts-hmac-sha1-96
 default_realm = EXAMPLE.LOCAL
 dns_lookup_realm = false
 dns_lookup_kdc = false
 ticket_lifetime = 24h
 renew_lifetime = 7d
 forwardable = true

[realms]
 EXAMPLE.LOCAL = {
  kdc =bocdc.example.local
  admin_server = bocdc.example.local
 }

[domain_realm]
 .example.local = EXAMPLE.LOCAL
 example.local = EXAMPLE.LOCAL

使用KRB5CCNAME指定Kerberos票据时, 可以在一个本地用户环境或者一个会话中指定该值。 如下命令设置KRB5CCNAME,然后运行kinit, 并且运行批处理文件来为Greenplum数据库的客户端设置环境变量。

set KRB5CCNAME=%USERPROFILE%\krb5cache
kinit

"c:\Program Files (x86)\Greenplum\greenplum-clients-<version>\greenplum_clients_path.bat"

运行psql工具

在Windows系统上安装并且配置Kerberos及其票据之后, 可以运行Greenplum数据库的命令行客户端psql

如果得到警告指出控制台代码页与Windows代码页不同, 可以运行Windows工具chcp来改变代码页。 如下示例展示了该警告及修正方法。

psql -h prod1.example.local warehouse
psql (9.4.20)
WARNING: Console code page (850) differs from Windows code page (1252)
 8-bit characters might not work correctly. See psql reference
 page "Notes for Windows users" for details.
Type "help" for help.

warehouse=# \q

chcp 1252
Active code page: 1252

psql -h prod1.example.local warehouse
psql (9.4.20)
Type "help" for help.

创建一个Kerberos的密钥表文件

在连接到Greenplum数据库系统时,可以创建并使用一个Kerberos的keytab文件来避免在命令行输入密码或者在脚本文件中列出密码。 可以用这些工具创建密钥表文件:
  • Windows Kerberos工具ktpass
  • Java JRE密钥表工具ktab

    如果使用AES256-CTS-HMAC-SHA1-96加密, 需要从Oracle下载并安装Java扩展Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for JDK/JRE。该命令创建密钥表文件 svcPostgresProd1.keytab

作为一个AD域管理员运行ktpass工具。 该工具需要一个包含服务主体名称(SPN)的用户账户作为AD用户属性的,该参数不是必需的。 可以设置它作为ktpass的一个参数并忽略未设置的警告。

Java JRE的ktab工具需要AD域名管理员,不需要SPN。

Note: 输入密码以创建密钥表文件时,屏幕上会显示密码。

该示例运行ktpass工具创建密钥表 dev1.keytab

ktpass -out dev1.keytab -princ dev1@EXAMPLE.LOCAL -mapUser dev1 -pass your_password -crypto all -ptype KRB5_NT_PRINCIPAL

尽管有警告信息Unable to set SPN mapping data仍然可用。

该示例运行Javaktab.exe创建密钥表文件(-a选项)并列出密钥表名称和条目(-l -e -t选项)。

C:\Users\dev1>"\Program Files\Java\jre1.8.0_77\bin"\ktab -a dev1
Password for dev1@EXAMPLE.LOCAL:your_password
Done!
Service key for dev1 is saved in C:\Users\dev1\krb5.keytab

C:\Users\dev1>"\Program Files\Java\jre1.8.0_77\bin"\ktab -l -e -t
Keytab name: C:\Users\dev1\krb5.keytab
KVNO Timestamp Principal
---- -------------- ------------------------------------------------------
 4 13/04/16 19:14 dev1@EXAMPLE.LOCAL (18:AES256 CTS mode with HMAC SHA1-96)
 4 13/04/16 19:14 dev1@EXAMPLE.LOCAL (17:AES128 CTS mode with HMAC SHA1-96)
 4 13/04/16 19:14 dev1@EXAMPLE.LOCAL (16:DES3 CBC mode with SHA1-KD)
 4 13/04/16 19:14 dev1@EXAMPLE.LOCAL (23:RC4 with HMAC)

然后,您可以使用该密钥表:

kinit -kt dev1.keytab dev1
or
kinit -kt %USERPROFILE%\krb5.keytab dev1

gpload示例YAML文件

该示例以dev1用户身份,运行gpload任务,用户通过AD域登录到Windows桌面。

示例中的test.yaml控制文件,其USER:行已经被移除。使用了Kerberos认证

---
VERSION: 1.0.0.1
DATABASE: warehouse
HOST: prod1.example.local
PORT: 5432

GPLOAD:
   INPUT:
    - SOURCE:
         PORT_RANGE: [18080,18080]
         FILE:
           - /Users/dev1/Downloads/test.csv
    - FORMAT: text
    - DELIMITER: ','
    - QUOTE: '"'
    - ERROR_LIMIT: 25
    - LOG_ERRORS: true
   OUTPUT:
    - TABLE: public.test
    - MODE: INSERT
   PRELOAD:
    - REUSE_TABLES: true

如下命令运行kinit,然后用test.yaml文件运行gpload,并成功显示gpload输出信息。

kinit -kt %USERPROFILE%\krb5.keytab dev1

gpload.py -f test.yaml
2016-04-10 16:54:12|INFO|gpload session started 2016-04-10 16:54:12
2016-04-10 16:54:12|INFO|started gpfdist -p 18080 -P 18080 -f "/Users/dev1/Downloads/test.csv" -t 30
2016-04-10 16:54:13|INFO|running time: 0.23 seconds
2016-04-10 16:54:13|INFO|rows Inserted = 3
2016-04-10 16:54:13|INFO|rows Updated = 0
2016-04-10 16:54:13|INFO|data formatting errors = 0
2016-04-10 16:54:13|INFO|gpload succeeded

问题及可能的解决方案

  • 这个消息表示Kerberos无法找到缓冲文件:
    Credentials cache I/O operation failed XXX
    (Kerberos error 193)
    krb5_cc_default() failed

    确保Kerberos能找到该文件,设置环境变量 KRB5CCNAME然后运行 kinit

    set KRB5CCNAME=%USERPROFILE%\krb5cache
    kinit
  • kinit消息表示kinit -k -t 命令无法找到密钥表文件。
    kinit: Generic preauthentication failure while getting initial credentials

    确认该Kerberos密钥表文件的完整路径和文件名是正确的。

使用活动目录配置客户端身份认证

可以使用微软活动目录(AD)帐户配置微软Windows用户,以便单点登录Greenplum数据库系统。

配置AD用户帐户以支持使用Kerberos身份认证登录。

通过AD单点登录,Windows用户可以将活动目录凭据与Windows客户端应用程序一起使用,以登录Greenplum数据库系统。 针对使用ODBC的Windows应用程序,ODBC驱动程序可以使用活动目录凭据连接到Greenplum数据库系统。

Note: Windows上运行的Greenplum数据库客户端,如gpload,接与Greenplum数据库连接,不要使用微软活动目录。有关将Windows上的Greenplum数据库客户端连接到启用Kerberos身份认证的Greenplum数据库系统的信息,请参阅在Windows上为Greenplum数据库客户端配置Kerberos

先决条件

这些项需要启用AD单点登录到Greenplum数据库系统。

  • 必须将Greenplum数据库系统配置为支持Kerberos身份认证。 有关使用Kerberos身份认证配置Greenplum数据库的信息,请参阅 为Windows客户端进行Kerberos配置
  • 必须知道Greenplum数据库master主机的完全限定域名(FQDN)。 同时,Greenplum数据库master主机名必须具有域部分。如果系统没有域,则必须将系统配置为使用域。

    该Linux的hostname命令显示FQDN信息。

    hostname --fqdn
  • 必须确认Greenplum数据库系统与活动目录域具有相同的日期和时间。 例如,您可以将Greenplum Database系统NTP时间源设置为AD域控制器,或配置master主机和AD域控制器使用相同的外部时间源。
  • 要支持单点登录,需要将一个AD作为AD的托管服务账号。如下是对于Kerberos认证的要求。
    • 需要添加增加服务主体名称(SPN)属性到用户账户信息中,因为Kerberos工具在Kerberos认证时需要这些信息。
    • 此外,由于Greenplum数据库需要无人值守启动,必须在一个Kerberos密钥表文件中提供账号登录细节。
    Note: 设置SPN和创建密钥表所需的AD管理权限。

设置活动目录

AD命名约定应支持多个Greenplum数据库系统。在此示例中,为Greenplum数据库系统master主机prod1创建了一个新的AD托管服务帐户svcPostresProd1

其活动目录的域为example.local

Greenplum数据库master主机的完全限定域名是prod1.example.local

添加SPN为postgres/prod1.example.local到这个帐户。 其他Greenplum数据库系统的服务帐户都是postgres/fully.qualified.hostname的形式。



在此示例中,AD的密码被设置为永不过期并且用户不能修改。只有在创建Kerberos密钥表文件时才需要AD账户的密码。不需要把它提供给数据库管理员。



AD管理员必须用Windows的setspn命令行,把服务主体名称属性添加到到账户中。该命令示例为AD用户svcPostgresProd1添加SPN属性postgres/prod1.example.local

setspn -A postgres/prod1.example.local svcPostgresProd1

如果设置了高级特性,可以在活动目录用户和计算机视图中,看到该SPN属性。 如果有必要,可以在属性编辑器标签页找到并编辑servicePrincipalName



下一步是创建Kerberos密钥表文件。

如果有安全性需要,可以选择特定的加密方法, 如果没有,最好先使其工作,然后删除您不需要的任何加密方法。

作为AD域管理员,您可以使用ktpass命令列出AD域控制器支持的加密类型:

ktpass /? 
作为AD域管理员,可以运行ktpass命令创建一个密钥表文件。该示例命令创建包含如下信息的文件svcPostgresProd1.keytab
  • 服务主体名称(SPN): postgres/prod1.example.local@EXAMPLE.LOCAL
  • AD用户:svcPostgresProd1
  • 加密方法: ALL available on AD
  • 主体类型:KRB5_NT_PRINCIPAL
ktpass -out svcPostgresProd1.keytab -princ postgres/prod1.example.local@EXAMPLE.LOCAL -mapUser svcPostgresProd1
   -pass your_password -crypto all -ptype KRB5_NT_PRINCIPAL
Note: AD域名@EXAMPLE.LOCAL被附加到SPN。

拷贝密钥表文件svcPostgresProd1.keytab到Greenplum数据库master主机。

作为AD域管理员运行ktpass的替代方案,如果桌面具有Java环境可以运行Java的ktab.exe 工具生成一个密钥表文件。不管使用ktpass或者ktab.exe,密码作为命令行参数,在屏幕上是可见的。

该命令示例创建一个密钥表文件 svcPostgresProd1.keytab
"c:\Program Files\Java\jre1.8.0_77\bin\ktab.exe" -a svcPostgresprod1 -k svcPostgresProd1.keytab
Password for svcPostgresprod1@EXAMPLE.LOCAL:your_password
Done!
Service key for svcPostgresprod1 is saved in svcPostgresProd1.keytab
Note: 如果使用AES256-CTS-HMAC-SHA1-96加密, 需要从Oracle下载并安装Java扩展Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for JDK/JRE

为活动目录设置Greenplum数据库

如下说明假定Kerberos工作站工具krb5-workstation已经安装在Greenplum数据库master主机上。

使用AD域名详细信息和AD域控制器的位置,更新/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 = EXAMPLE.LOCAL
 dns_lookup_realm = false
 dns_lookup_kdc = false
 ticket_lifetime = 24h
 renew_lifetime = 7d
 forwardable = true

[realms]
 EXAMPLE.LOCAL = {
 kdc = bocdc.example.local
 admin_server = bocdc.example.local
 }

[domain_realm]
 .example.local = EXAMPLE.LOCAL
 example.com = EXAMPLE.LOCAL

拷贝包含AD用户信息的Kerberos密钥表文件到Greenplum数据库master目录。该示例中复制了在 设置活动目录中创建的svcPostgresProd1.keytab

mv svcPostgresProd1.keytab $MASTER_DATA_DIRECTORY
chown gpadmin:gpadmin $MASTER_DATA_DIRECTORY/svcPostgresProd1.keytab
chmod 600 $MASTER_DATA_DIRECTORY/svcPostgresProd1.keytab

在Greenplum数据库pg_hba.conf最后一行添加如下配置。该内容配置Greenplum数据库使用活动目录授权之前行不匹配的连接请求。

host all all 0.0.0.0/0 gss include_realm=0

更新Greenplum数据库postgresql.conf文件中密钥表文件的位置详细信息要使用的主体名称。 完全限定名称和/etc/krb5.conf中的域名称,构成了完整的服务主体名称。

krb_server_keyfile = '/data/master/gpseg-1/svcPostgresProd1.keytab'
krb_srvname = 'postgres'

为AD用户创建数据库角色。该示例登录到默认数据库并运行CREATE ROLE命令。 用户dev1设置活动目录创建密钥表文件的指定用户。

psql
create role dev1 with login superuser;

重启数据库以使用最新的身份认证信息:

gpstop -a
gpstart  
Note: Greenplum数据库的依赖库可能与Kerberos工作站工具如kinit冲突。在Greenplum数据库master主机,可以不加载$GPHOME/greenplum_path.sh脚本使用gpadmin命令行,或者取消设置LD_LIBRARY_PATH类似于如下命令:
unset LD_LIBRARY_PATH
kinit
source $GPHOME/greenplum_path.sh

确认Greenplum数据库可以通过Kerberos认证访问

kinit dev1
psql -h prod1.example.local -U dev1

单点登录示例

如下使用AD和Kerberos的单点登录实例,假设使用单点登录AD用户dev1登入到Windows桌面。

该示例为Greenplum数据库配置Aginity Workbench。在使用单点登录时,启用了“使用集成的安全性”。



该示例配置一个ODBC源。设置该ODBC源时,请不要输入用户名或密码。该DSN可用作应用程序的ODBC数据源。



可以用R客户端使用DSN为testdata。该示例配置R以访问DSN。

library("RODBC")
conn <- odbcDriverConnect("testdata")
sql <- "select * from public.data1"
my_data <- sqlQuery(conn,sql)
print(my_data)

活动目录的问题及可能的解决方案

  • Kerberos票据含有的版本号必须匹配AD的版本号。

    要显示密钥表文件中的版本号,使用klist -ket命令,例如:

    klist -ket svcPostgresProd1.keytab

    要从AD域控制器得到相应的值,可作为一个AD管理员运行这个命令:

    kvno postgres/prod1.example.local@EXAMPLE.LOCAL
  • 当Windows ID和Greenplum数据库用户角色ID不匹配时,将会出现如下登录错误。 该日志文件项显示了登录错误。用户 dev22尝试从一个Windows桌面登录,而桌面上登录了一个不同的Windows用户。
    2016-03-29 14:30:54.041151 PDT,"dev22","gpadmin",p15370,th2040321824,
      "172.28.9.181","49283",2016-03-29 14:30:53 PDT,1917,con32,,seg-1,,,x1917,sx1,
      "FATAL","28000","authentication failed for user ""dev22"": valid 
      until timestamp expired",,,,,,,0,,"auth.c",628,

    当用户能被认证但没有对应Greenplum数据库用户角色时,也会发生这个错误。

    确保该用户是用的是正确的Windows ID并且为该用户ID配置了Greenplum数据库用户角色。

  • 当Kerberos密钥表不含有与正在尝试连接的客户端相匹配的加密类型时,会发生下面这种错误。
    psql -h 'hostname' postgres
    psql: GSSAPI continuation error: Unspecified GSS failure. Minor code may provide more information
    GSSAPI continuation error: Key version is not available

    解决方案是使用ktutil增加额外的加密类型到该密钥表,或者用来自AD中所有加密系统重新创建postgres的密钥表。