1.1安装kerberos服务端
先更新yum
yum update
安装依赖包
yum -y install krb5-libs krb5-server
1.2.配置/etc/krb5.conf
# 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]
dns_lookup_realm = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = false
pkinit_anchors = /etc/pki/tls/certs/ca-bundle.crt
default_realm = EXAMPLE.COM
default_ccache_name = KEYRING:persistent:%{uid}
[realms]
EXAMPLE.COM = {
kdc = liuqi1212.xyz:88 #kdc服务运行在88端口,前面的域名测试可以/etc/hosts文件中配置
admin_server = liuqi1212.xyz:749
default_domain = example.com
}
[domain_realm]
.example.com = EXAMPLE.COM
example.com = EXAMPLE.COM
在默认配置的基础上修改一下即可
1.3配置/var/kerberos/krb5kdc/kdc.conf
[kdcdefaults]
kdc_ports = 88
kdc_tcp_ports = 88
[realms]
EXAMPLE.COM = {
#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
kadmin_port = 749
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
}
1.4初始化kerberos database
/usr/sbin/kdb5_util create -s
database初始化之后会多出一些文件
-rw------- 1 root root 22 Sep 14 00:40 kadm5.acl
-rw------- 1 root root 470 Dec 12 16:22 kdc.conf
-rw------- 1 root root 16384 Dec 12 16:36 principal
-rw------- 1 root root 8192 Dec 12 14:46 principal.kadm5
-rw------- 1 root root 0 Dec 12 14:46 principal.kadm5.lock
-rw------- 1 root root 0 Dec 12 16:36 principal.ok
1.5为database administrator设置ACL权限,编辑/var/kerberos/krb5kdc/kadm5.acl
*/[email protected] *
1.6启动kdc和server
/bin/systemctl start krb5kdc.service
/bin/systemctl start kadmin.service
1.7 添加 principals
kadmin.local: addprinc [email protected]
WARNING: no policy specified for [email protected]; defaulting to no policy
Enter password for principal "[email protected]":
Re-enter password for principal "[email protected]":
Principal "[email protected]" created.
这就相当于令牌,在客户端用这里设置的用户名密码就可以通过认证
2.1安装kerberos 客户端
yum install krb5-workstation krb5-libs
2.2配置/etc/krb5.conf,跟server的krb5.conf一样
2.3测试
2.3.1通过kinit测试,没有提示就表示认证通过,错误的时候会有错误信息提示
[root@VM_0_8_centos data]# kinit [email protected]
Password for [email protected]:
[root@VM_0_8_centos data]#
[root@VM_0_8_centos data]# kinit [email protected]
Password for [email protected]:
kinit: Password incorrect while getting initial credentials
[root@VM_0_8_centos data]#
代码测试,这段代码是oracle官网上的
import javax.security.auth.*;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import com.sun.security.auth.callback.TextCallbackHandler;
public class JaasAcn {
public static void main(String[] args) {
String path = "/data/";
System.setProperty("java.security.auth.login.config", path + "jaas.conf");
System.setProperty("java.security.krb5.realm", "EXAMPLE.COM");
System.setProperty("java.security.krb5.kdc", "liuqi1212.xyz:88");
System.setProperty("sun.security.krb5.debug", "true");
LoginContext lc = null;
try {
lc = new LoginContext("JaasSample", new TextCallbackHandler());
try {
lc.login();
} catch (LoginException le) {
le.printStackTrace();
System.err.println("Authentication failed:");
System.err.println(" " + le.getMessage());
System.exit(-1);
}
} catch (LoginException le) {
System.err.println("Cannot create LoginContext. " + le.getMessage());
} catch (SecurityException se) {
System.err.println("Cannot create LoginContext. " + se.getMessage());
System.exit(-1);
}
System.out.println("Authentication succeeded!");
}
}
jaas.conf
JaasSample {
com.sun.security.auth.module.Krb5LoginModule required debug=true refreshKrb5Config=true;
};
[root@VM_0_8_centos data]# ls -l
total 24
-rw-r--r-- 1 root root 1733 Dec 12 17:37 JaasAcn.class
-rw-r--r-- 1 root root 1361 Dec 12 17:36 JaasAcn.java
-rw-r--r-- 1 root root 108 Dec 12 17:37 jaas.conf
drwxr-xr-x 2 root root 4096 Oct 17 13:02 java
drwxr-xr-x 7 root root 4096 Oct 17 13:09 java_pids
-rw-r--r-- 1 root root 658 Dec 12 16:43 krb5.conf
编译运行
[root@VM_0_8_centos data]# java JaasAcn
Debug is true storeKey false useTicketCache false useKeyTab false doNotPrompt false ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is true principal is null tryFirstPass is false useFirs
tPass is false storePass is false clearPass is false
Refreshing Kerberos configuration
Java config name: null
Native config name: /etc/krb5.conf
Loaded from native config
>>> KdcAccessibility: reset
>>> KdcAccessibility: reset
Kerberos username [root]: test
Kerberos password for test:
[Krb5LoginModule] user entered username: test
Using builtin default etypes for default_tkt_enctypes
default etypes for default_tkt_enctypes: 18 17 16 23.
>>> KrbAsReq creating message
>>> KrbKdcReq send: kdc=liuqi1212.xyz UDP:88, timeout=30000, number of retries =3, #bytes=140
>>> KDCCommunication: kdc=liuqi1212.xyz UDP:88, timeout=30000,Attempt =1, #bytes=140
>>> KrbKdcReq send: #bytes read=647
>>> KdcAccessibility: remove liuqi1212.xyz
>>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType
>>> KrbAsRep cons in KrbAsReq.getReply test
principal is [email protected]
Commit Succeeded
Authentication succeeded!
[root@VM_0_8_centos data]#
认证成功
上面的LoginContext的第二个参数是一个回调,让我们在控制台输入用户名,密码。实际我们显然不能用这种方式,每次都输入密码显得有点愚
这个时候keytab文件应运而生
什么是keytab文件呢?
A keytab is a file containing pairs of Kerberos principals and encrypted keys (which are derived from the Kerberos password). ... Keytab files are commonly used to allow scripts to automatically authenticate using Kerberos, without requiring human interaction or access to password stored in a plain-text file
生成keytab文件,client端都可以用这个命令
> ktutil
ktutil: addent -password -p [email protected] -k 1 -e aes256-cts
Password for [email protected]: [enter your password]
ktutil: wkt test.keytab
ktutil: quit
改动一下上面的JaasAnc.java
import javax.security.auth.*;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import com.sun.security.auth.callback.TextCallbackHandler;
public class JaasAcn {
public static void main(String[] args) {
LoginContext lc = null;
try {
lc = new LoginContext("client", new Subject(), null, new Configuration() {
@Override
public AppConfigurationEntry[] getAppConfigurationEntry(String s) {
Map<String, String> options = new HashMap<>();
options.put("useKeyTab", "true");
options.put("useTicketCache", "true");
options.put("renewTGT", "true");
options.put("debug", "true");
options.put("keyTab", "test.keytab");
options.put("principal", "[email protected]");
return new AppConfigurationEntry[]{
new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule",
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
options)};
}
});
try {
lc.login();
} catch (LoginException le) {
le.printStackTrace();
System.err.println("Authentication failed:");
System.err.println(" " + le.getMessage());
System.exit(-1);
}
} catch (LoginException le) {
System.err.println("Cannot create LoginContext. " + le.getMessage());
} catch (SecurityException se) {
System.err.println("Cannot create LoginContext. " + se.getMessage());
System.exit(-1);
}
System.out.println("Authentication succeeded!");
}
}
JaasSample {
com.sun.security.auth.module.Krb5LoginModule
required useKeyTab=true useTicketCache=false storeKey=true principal="[email protected]" keyTabName="/data/test.keytab";
};
编译运行
[root@VM_0_8_centos data]# java JaasAcnDebug is true storeKey false useTicketCache true useKeyTab true doNotPrompt false ticketCache is null isInitiator true KeyTab is test.keytab refreshKrb5Config is false principal is [email protected] tryFirstPas
s is false useFirstPass is false storePass is false clearPass is false
Acquire TGT from Cache
Principal is [email protected]
null credentials from Ticket Cache
principal is [email protected]
Will use keytab
Commit Succeeded
Authentication succeeded!
[root@VM_0_8_centos data]#