自动生成Kerberos的keytab文件

2018-04-18  本文已影响450人  xuefly

隶属于文章系列:大数据安全实战 https://www.jianshu.com/p/76627fd8399c


场景:

根据服务请求,自动生成keytab文件
功能:
1、生成principle
2、生成keytab文件
2、接口返回principle 和 keytab

阅读并从ambari的源码中抽出来的Kerberos相关的代码

思路:

package kbds.auth.keytab;


import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
import org.apache.ambari.server.serveraction.kerberos
        .KerberosOperationException;
import org.apache.ambari.server.serveraction.kerberos.KerberosOperationHandler;
import org.apache.directory.server.kerberos.shared.keytab.Keytab;
import org.apache.directory.server.kerberos.shared.keytab.KeytabEntry;

import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class AuthMain {
    public static void main(String[] args) throws KerberosOperationException, IOException {
        KerberosOperationHandler handler = createHandler();
        File file = new File("D:\\am.keytab");
        final String principal1 = "a1@TT.COM";
        final String principal2 = "a1@TT.COM";
        Set<String> seenEntries = new HashSet<String>();

    handler.createKeytabFile(principal1, "some password", 0, file);
        handler.createKeytabFile(principal2, "some password", 0, file);

        // Attempt to add duplicate entries
    handler.createKeytabFile(principal2, "some password", 0, file);

        Keytab keytab = Keytab.read(file);
//      Assert.assertNotNull(keytab);

        List<KeytabEntry> entries = keytab.getEntries();
//      Assert.assertNotNull(entries);
//      Assert.assertFalse(entries.isEmpty());

        for (KeytabEntry entry : entries) {
            String seenEntry = String.format("%s|%s", entry.getPrincipalName(), entry.getKey().getKeyType().toString());
            //Assert.assertFalse(seenEntries.contains(seenEntry));
            seenEntries.add(seenEntry);
        }
    }

    public static  KerberosOperationHandler createHandler() throws KerberosOperationException {
        KerberosOperationHandler handler = new KerberosOperationHandler() {

            @Override
            public void open(PrincipalKeyCredential administratorCredentials, String defaultRealm, Map<String, String> kerberosConfiguration) throws KerberosOperationException {
                setAdministratorCredential(administratorCredentials);
                setDefaultRealm(defaultRealm);
                setExecutableSearchPaths("/usr/bin, /usr/kerberos/bin, /usr/sbin");
            }

            @Override
            public void close() throws KerberosOperationException {

            }

            @Override
            public boolean principalExists(String principal) throws KerberosOperationException {
                return false;
            }

            @Override
            public Integer createPrincipal(String principal, String password, boolean service) throws KerberosOperationException {
                return 0;
            }

            @Override
            public Integer setPrincipalPassword(String principal, String password) throws KerberosOperationException {
                return 0;
            }

            @Override
            public boolean removePrincipal(String principal) throws KerberosOperationException {
                return false;
            }
        };

        handler.open(new PrincipalKeyCredential("me/admin", "me"), "TT.COM", null);
        return handler;
    }

}

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>kbds</groupId>
    <artifactId>auth-keytab</artifactId>
    <version>1.0</version>
    <dependencies>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.2.2</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.6</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.5</version>
        </dependency>


        <!-- test start-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.easymock</groupId>
            <artifactId>easymock</artifactId>
            <scope>test</scope>
            <version>3.4</version>
        </dependency>

        <!-- kerberos-->
        <dependency>
            <groupId>org.apache.directory.server</groupId>
            <artifactId>apacheds-kerberos-codec</artifactId>
           <!-- <exclusions>
                <exclusion>
                    <groupId>net.sf.ehcache</groupId>
                    <artifactId>ehcache-core</artifactId>
                </exclusion>
            </exclusions>-->
            <version>2.0.0-M19</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.security.kerberos</groupId>
            <artifactId>spring-security-kerberos-core</artifactId>
            <version>1.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.kerberos</groupId>
            <artifactId>spring-security-kerberos-web</artifactId>
            <version>1.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.kerberos</groupId>
            <artifactId>spring-security-kerberos-client</artifactId>
            <version>1.0.1.RELEASE</version>
        </dependency>


        <dependency>
            <groupId>com.google.code.findbugs</groupId>
            <artifactId>jsr305</artifactId>
            <version>1.3.9</version>
        </dependency>
        <dependency>
            <groupId>com.google.inject</groupId>
            <artifactId>guice</artifactId>
            <version>3.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.inject.extensions</groupId>
            <artifactId>guice-persist</artifactId>
            <version>3.0</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.3</version>
        </dependency>
    </dependencies>


</project>

验证生成的keytab文件

 klist -ket xf@TT.COM1523956110379.keytab
Keytab name: FILE:xf@TT.COM1523956110379.keytab
KVNO Timestamp         Principal
---- ----------------- --------------------------------------------------------
   0 04/17/18 17:08:30 xf@TT.COM (des-cbc-md5)
   0 04/17/18 17:08:30 xf@TT.COM (des3-cbc-sha1)
   0 04/17/18 17:08:30 xf@TT.COM (aes128-cts-hmac-sha1-96)
   0 04/17/18 17:08:30 xf@TT.COM (arcfour-hmac)
# 销毁当前已有凭证
kdestroy

kinit  -kt xf@TT.COM1523956110379.keytab   xf
kinit: Client not found in Kerberos database while getting initial credentials

报错:在kdc上没有创建当前principal

kadmin.local:  addprinc xf
WARNING: no policy specified for xf@TT.COM; defaulting to no policy
Enter password for principal "xf@TT.COM":
Re-enter password for principal "xf@TT.COM":
Principal "xf@TT.COM" created.
 kinit  -kt xf@TT.COM1523956110379.keytab   xf
 klist -e
Ticket cache: FILE:/tmp/krb5cc_500
Default principal: xf@TT.COM

Valid starting     Expires            Service principal
04/17/18 17:13:35  04/18/18 17:13:35  krbtgt/TT.COM@TT.COM
        renew until 04/24/18 17:13:35, Etype (skey, tkt): aes128-cts-hmac-sha1-96, aes256-cts-hmac-sha1-96

发现创建keytab是可以跟kdc分离的.直接在kdc之外生成的keytab文件,也能通过kdc的验证。

上一篇 下一篇

猜你喜欢

热点阅读