为Windows客户端配置Kerberos
为Windows客户端配置Kerberos
可以配置微软的Windows客户端应用来连接一个配置为用Kerberos认证的Greenplum数据库系统。
有关在Greenplum数据库中配置Kerberos认证的信息请见使用Kerberos认证。
在Windows上为Greenplum数据库客户端配置Kerberos
当一个Greenplum数据库系统被配置为用Kerberos作认证后,可以为微软Windows系统上的Greenplum数据库客户端工具gpload和psql配置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的ticket。
Kerberos服务没有被设置为自动启动。该服务不能被用来认证Greenplum数据库。
为来自Greenplum数据库的Master的Kerberos配置文件/etc/krb5.conf创建一个拷贝并且把它放在Windows系统的默认Kerberos位置C:\ProgramData\MIT\Kerberos5\krb5.ini。在文件小节[libdefaults]中,移除Kerberos的ticket缓冲的位置default_ccache_name。
在Windows系统上,使用环境变量KRB5CCNAME指定Kerberos ticket的位置。这个环境变量的值是一个文件而不是目录,并且它应该对服务器上的每一个登录都是唯一的。
这是一个移除了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 ticket时,可以在一个本地用户环境或者一个会话中设置该值。这些命令设置KRB5CCNAME、运行kinit并且运行批处理文件来为Greenplum数据库的客户端设置环境变量。
set KRB5CCNAME=%USERPROFILE%\krb5cache kinit "c:\Program Files (x86)\Greenplum\greenplum-clients-<version>\greenplum_clients_path.bat"
运行psql工具
在Windows系统上安装并且配置Kerberos及其ticket之后,可以运行Greenplum数据库的命令行客户端psql。
如果得到警告指出控制台代码页与Windows代码页不同,可以运行Windows工具chcp来改变代码页。这是一个该警告的例子及修正。
psql -h prod1.example.local warehouse psql (8.3.23) 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 (8.3.23) Type "help" for help.
创建一个Kerberos的keytab文件
- Windows Kerberos工具ktpass
- Java JRE keytab工具ktab
如果使用AES256-CTS-HMAC-SHA1-96加密,需要从Oracle下载并安装Java扩展Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for JDK/JRE。这个命令创建keytab文件svcPostgresProd1.keytab。
作为一个AD域管理员运行ktpass工具。这个工具期望一个用户账户有一个被定义为AD用户属性的服务主体名称(SPN),不过这似乎并不是必需的。可以指定它作为ktpass的一个参数并且忽略它不能被设置的警告。
Java JRE的ktab工具不要求AD域管理员并且不要求SPN。
这个例子运行ktpass工具来创建keytab文件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工作下去。
这个例子运行Java的ktab.exe来创建一个keytab文件(-a选项)并且列出该keytab的名称和条目(-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)
You can then use a keytab with the following:
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命令不能找到keytab。
kinit: Generic preauthentication failure while getting initial credentials
确认该Kerberos keytab文件的完整路径和文件名是正确的。
用活动目录配置客户端认证
可以用一个微软活动目录(AD)账号配置一个微软Windows用户用于单点登录到Greenplum数据库系统。
可以配置一个AD用户账号来支持用Kerberos认证登录。
通过AD单点登录,一个Windows用户可以使用活动目录证书和一个Windows客户端应用来登入Greenplum数据库系统。对于使用ODBC的Windows应用,ODBC驱动能使用活动目录证书来连接到Greenplum数据库系统。
先决条件
启用对Greenplum数据库系统的AD单点登录要求这些项目。
- Greenplum数据库系统必须配置为支持Kerberos认证。有关配置Greenplum数据库支持Kerberos认证的信息,请见为Windows客户端配置Kerberos。
-
必须知道Greenplum数据库的Master主机的全称域名(FQDN)。还有,Greenplum数据库的Master主机名必须有一个域名部分。如果系统没有域,必须配置系统使用一个域。
这个Linux的hostname命令显示FQDN。
hostname --fqdn
- 必须把Greenplum数据库系统配置为与活动目录域具有相同的日期和时间。例如,可以把Greenplum数据库系统的NTP时间源设置为一个AD域控制器,或者把Master主机设置为使用和AD域控制器相同的外部时间源。
-
要支持单点登录,需要把一个AD用户账户配置为一个AD中的托管服务账号。对于Kerberos认证有这些要求。
- 需要对用户账户信息增加服务主体名称(SPN)属性,因为Kerberos工具在Kerberos认证期间会要求该信息。
- 还有,由于Greenplum数据库能够无人值守启动,还必须在一个Kerberos keytab文件中提供账号登录细节。
注意: 设置SPN和创建keytab要求AD的管理权限。
活动目录设置
AD命名习惯应该支持多个Greenplum数据库系统。在这个例子中,我们会为Greenplum数据库系统prod1的Master主机创建一个新的AD托管服务账户svcPostresProd1。
活动目录的域是example.local。
Greenplum数据库的Master主机的全称域名是prod1.example.local。
我们将把SPN postgres/prod1.example.local添加到这个账户。其他Greenplum数据库系统的服务账户都将是postgres/fully.qualified.hostname的形式。
在这个例子中,AD的密码被设置为永不过期并且用户不能更改。只有在创建Kerberos keytab文件时才需要AD账户的密码。不需要把它提供给数据库管理员。
AD管理员必须用Windows的setspn命令从命令行把服务主体名称属性添加到账户。这个示例命令把AD用户svcPostgresProd1的SPN属性值设置为postgres/prod1.example.local:
setspn -A postgres/prod1.example.local svcPostgresProd1
如果在活动目录的用户和计算机视图中设置了高级特性,用户可以看到这个SPN。如果有必要,可以在属性编辑器页面找到servicePrincipalName并且编辑它。
下一步是创建一个Kerberos keytab文件。
如果安全性需求要求一种特定的加密方法,可以选择它,但如果该方法不存在,最好是先让它能用然后再移除其他不想要的加密方法。
作为一个AD域管理员,可以用这个ktpass命令列出AD域控制器支持的加密类型:
ktpass /?
- ServicePrincipalName (SPN): postgres/prod1.example.local@EXAMPLE.LOCAL
- AD用户: svcPostgresProd1
- 加密方法: 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
复制keytab文件svcPostgresProd1.keytab到Greenplum数据库的Master主机。
另一种作为AD域管理员运行ktpass的方法是,如果在桌面机上安装了Java JRE,则可以运行Java的ktab.exe工具来生成一个keytab文件。当使用ktpass或者ktab.exe输入密码时,密码将会作为一个命令行参数被显示在屏幕上。
"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
活动目录的Greenplum数据库设置
这些指令假定在Greenplum数据库的Master主机上安装了Kerberos工作站工具krb5-workstation。
用一个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 keytab文件复制到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
用keytab文件的位置细节以及要使用的主体名称更新Greenplum数据库的postgresql.conf。全称主机名和来自/etc/krb5.conf的默认realm构成了完整的服务主体名称。
krb_server_keyfile = '/data/master/gpseg-1/svcPostgresProd1.keytab' krb_srvname = 'postgres'
为这个AD用户创建一个数据库角色。这个例子登入到默认数据库并且运行CREATE ROLE命令。用户dev1是活动目录设置中创建keytab文件时指定的用户。
psql create role dev1 with login superuser;
重启数据库以使用更新后的认证信息:
gpstop -a gpstart
unset LD_LIBRARY_PATH kinit source $GPHOME/greenplum_path.sh
用Kerberos认证确认Greenplum数据库访问:
kinit dev1 psql -h prod1.example.local -U dev1
单点登录实例
这些使用AD和Kerberos的单点登录实例假设配置为单点登录的AD用户dev1被登入到Windows桌面。
这个例子为Greenplum数据库配置Aginity Workbench。在使用单点登录时,请启用“Use Integrated 安全性”。
这个例子配置一个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的ticket含有的版本号必须匹配AD的版本号。
要显示keytab文件中的版本号,可使用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 keytab不含有一种与正在尝试连接的客户端相匹配的加密类型时,会发生下面这种错误。
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增加额外的加密类型到该keytab或者用来自AD的所有加密系统重新创建postgres的keytab。