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]#