• solr集成kerberos认证


    1. 概述

      solr使用kerberos principal和keytab文件来认证zookeeper和solr集群。kerberos认证插件仅仅在solrcloud模式下有用。

      当设置solr使用kerberos的时候,一个在KDC中注册认证的服务principal或者kerberos用户名的配置是需要的。这个配置定义了服务主体的名称和keytab文件的位置。solr的认证模式是用security.json这个文件,如果更改这个文件,需要重启整个solr集群。此外认证插件可以通过系统启动参数制定:-DauthenticationPlugin=org.apache.solr.security.KerberosPlugin。这个参数可以用在solrcloud或者单独模式下,在单独模式下这是唯一的方式。

    1. 软件版本

      Solr版本 8.8

      环境:

    ip

    主机名

    角色

    192.168.1.105

    node1

    zookeeper、solr、kdc、kadmin、kclient

    192.168.1.109

    node2

    zookeeper、solr、kclient

    192.168.1.103

    node3

    zookeeper、solr、kclient

      kdc、kadmin为kerberos的服务器节点,kclient为kerberos的客户端节点

    2. solr集成kerberos

    2.1. 添加solr用户

      在kdc中为solr添加主体并生成用于验证HTTP请求的keytab文件,为每个要运行solr的主机创建一个keytab文件,并将主体名称与主机一起使用:

    root@kdc:/# kadmin.local
    kadmin.local: addprinc -randkey HTTP/<hostname>@EXAMPLE.COM
    kadmin.local: ktadd -k /tmp/solr.keytab HTTP/<hostname>@EXAMPLE.COM
    kadmin.local: quit

      注:

        addprinc -randkey HTTP/${HOST1}@EXAMPLE.COM,将${HOST1}替换为实际的主机名。

        上述操作需要每个solr节点都重复一遍,为每台solr节点创建kerberos HTTP用户主体,并生成/tmp/solr.keytab文件,最后复制到solr节点的/keytabs/solr.keytab路径。

      如上,solr节点分布在三台机器上,则需要执行如下命令添加:

    root@kdc:/# kadmin.local
    kadmin.local: addprinc -randkey HTTP/node1@EXAMPLE.COM
    kadmin.local: ktadd -k /tmp/node1.keytab HTTP/node1@EXAMPLE.COM
    
    kadmin.local: addprinc -randkey HTTP/node2@EXAMPLE.COM
    kadmin.local: ktadd -k /tmp/node2.keytab HTTP/node2@EXAMPLE.COM
    
    kadmin.local: addprinc -randkey HTTP/node3@EXAMPLE.COM
    kadmin.local: ktadd -k /tmp/node3.keytab HTTP/node3@EXAMPLE.COM

      需要把node1.keytab、node2.keytab,node3.keytab分别放置在各自节点的/keytabs/路径下,并重命名为solr.keytab

    2.2. zookeeper配置(如果已配置kerberos则跳过)

      zookeeper管理solrcloud集群中的节点通信,它必须要与集群各节点中认证。配置要求为zookeeper设置服务principal,定义JAAS配置文件。

      第一步是在zookeeper的conf目录创建java.env文件,并且添加如下内容:

    export JVMFLAGS="-Djava.security.auth.login.config=/etc/zookeeper/conf/jaas-client.conf"

      在kdc为zookeeper创建用户主体并生成keytab文件,如下:

    [root@node1 conf]# kadmin.local
    kadmin.local:  addprinc -randkey zookeeper/node1@EXAMPLE.COM
    kadmin.local:  addprinc -randkey zookeeper/node2@EXAMPLE.COM
    kadmin.local:  addprinc -randkey zookeeper/node3@EXAMPLE.COM
    kadmin.local:  ktadd -k /keytabs/zoo105.keytab zookeeper/node1@EXAMPLE.COM
    kadmin.local:  ktadd -k /keytabs/zoo109.keytab zookeeper/node2@EXAMPLE.COM
    kadmin.local:  ktadd -k /keytabs/zoo103.keytab zookeeper/node3@EXAMPLE.COM

      把生成的zoo105.keytab、zoo109.keytab、zoo103.keytab分别放置105、109、103服务器的同一路径/keytabs下,并重名为zoo.keytab

      JAAS配置文件应该包含下面的参数,确保改变principal和keytab的路径。jaas-client.conf配置内容如下:

    Server {
     com.sun.security.auth.module.Krb5LoginModule required
      useKeyTab=true
      keyTab="/keytabs/zkhost1.keytab"
      storeKey=true
      doNotPrompt=true
      useTicketCache=false
      debug=true
      principal="zookeeper/host1@EXAMPLE.COM";
    };

      最后,在zookeeper配置文件zoo.cfg添加如下内容:

    authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
    jaasLoginRenew=3600000

      启动zookeeper,如下:

    bin/zkServer.sh start

    2.3. 创建security.json

      在solrcloud模式中,设置solr通过上传security.json到zookeeper来使用kerberos插件

    server/scripts/cloud-scripts/zkcli.sh -zkhost node1:2181,node2:2181,node3:2181 -cmd put /solr/security.json '{"authentication":{"class":"org.apache.solr.security.KerberosPlugin"}}'

      如果你使用solr的standalone模式,需要创建security.json文件,然后放置在$SOLR_HOME目录下方。

      注:

        /solr/security.json这里的/solr为solr在zookeeper的chroot路径,放错路径,solr的kerberos认证不生效。可以查看2.6节点的solr启动命令会带有

    bin/solr -c -z node1:2181,node2:2181,node3:2181/solr

      zookeeper后面会带有/solr路径,即是solr在zookeeper的根路径。

    2.4. 创建jaas文件

      JAAS配置文件定义认证属性使用,例如服务principal和keytab路径。在下面的例子中,我们创建JAAS配置文件/home/foo/jaas-client.conf。当我们启动solr的时候,我们将会使用该名字和路径。确保使用正确principal和keytab文件路径。

    Client {
        com.sun.security.auth.module.Krb5LoginModule required
        useKeyTab=true
        keyTab="/keytabs/solr.keytab"
        storeKey=true
        useTicketCache=true
        debug=true
        principal="HTTP/${hostname}@EXAMPLE.COM";
    };

      注:

      每个solr节点都需要执行这一步,${hostname}为对应solr节点的主机名。principal="HTTP/${hostname}@EXAMPLE.COM"后面需要加分号,不然会报错

    2.5. 在solr.in.sh中添加以下内容

      当启动solr的时候,需要配置solr的start命令中属性参数,示例如下:

    SOLR_AUTH_TYPE="kerberos"
    SOLR_JAAS_FILE=/home/redpeak/app/ranger-solr-8.3.0-cloud/ranger_audit_server/conf/jaas-client.conf
    SOLR_HOST=`hostname -f`
    SOLR_KERB_PRINCIPAL=HTTP/node1@EXAMPLE.COM
    SOLR_KERB_KEYTAB=/keytabs/solr.keytab
    
    SOLR_AUTHENTICATION_OPTS=" -Dsun.security.krb5.debug=true -Dsolr.authentication.type=kerberos -Djava.security.auth.login.config=${SOLR_JAAS_FILE} -Dsolr.kerberos.cookie.domain=${SOLR_HOST} -Dsolr.kerberos.name.rules=DEFAULT -Dsolr.kerberos.cookie.portaware=true -Dsolr.kerberos.principal=${SOLR_KERB_PRINCIPAL} -Dsolr.kerberos.keytab=${SOLR_KERB_KEYTAB}"

      注:

      SOLR_KERB_PRINCIPAL=HTTP/node1@EXAMPLE.COM中的node1,每台节点不一样,需要切换。

    2.6. 启动solr

    bin/solr -c -z server1:2181,server2:2181,server3:2181/solr

    2.7. 测试配置

      第一步执行如下命令:

    kinit user@EXAMPLE.COM

      第二步执行如下命令,curl,会得到成功的反应:

    curl --negotiate -u : "http://node1:6083/solr/"

    3. solrJ的认证

    3.1. 基础配置

       在solrJ应用中使用kerberos认证,需要在创建solr客户端之前执行下面两步:

    System.setProperty("java.security.auth.login.config", "/home/foo/jaas-client.conf");
    HttpClientUtil.setConfigurer(new Krb5HttpClientConfigurer());

      你需要为JAAS客户端配置jaas-client.conf指定kerberos服务principal和keytab,如下:

    SolrJClient {
        com.sun.security.auth.module.Krb5LoginModule required
        useKeyTab=true
        keyTab="/keytabs/foo.keytab"
        storeKey=true
        useTicketCache=true
        debug=true
        principal="foo@EXAMPLE.COM";
    };

      注:  

        principal="foo@EXAMPLE.COM"后面需要加分号。

    3.2. solr.5.5版本demo

    3.2.1. pom.xml配置 

            <dependency>
                <groupId>org.apache.solr</groupId>
                <artifactId>solr-solrj</artifactId>
                <version>5.5.4</version>
            </dependency>
    
            <dependency>
                <groupId>commons-codec</groupId>
                <artifactId>commons-codec</artifactId>
                <version>1.9</version>
            </dependency>
    
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.30</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.30</version>
            </dependency>

      注意:

        低版本的solrJ需要配置slf4j日志jar包,否则会莫名报错,如下:

        org.apache.solr.common.SolrException: java.util.concurrent.TimeoutException: Could not connect to ZooKeeper host1:2181,host2:2181,host3:2181/infra-solr within 10000 ms

    3.2.2. java代码 

    import org.apache.solr.client.solrj.SolrQuery;
    import org.apache.solr.client.solrj.impl.*;
    import org.apache.solr.client.solrj.response.QueryResponse;
    
    public class solrTest {
        public static void main(String[] args) {
            try {
                //System.setProperty("java.security.krb5.conf", "/etc/krb5.conf");
                System.setProperty("java.security.krb5.conf", "D:\krb5.conf");
    
                System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
                System.setProperty("sun.security.krb5.debug", "true");
    
                //System.setProperty("java.security.auth.login.config", "/home/redpeak/ranger_solr_jaas_test.conf");
                System.setProperty("java.security.auth.login.config", "D:\ranger_solr_jaas_test.conf");
    
    
                Krb5HttpClientConfigurer krb5 = new Krb5HttpClientConfigurer();
                HttpClientUtil.setConfigurer(krb5);
                System.out.println(HttpClientUtil.getConfigurer().toString());
    
                /**
                 * the first method:  用于集群solrCloud模式,通过zookeeper访问,
                 * 注意:当solr开启kerberos后,不能直接通过ip访问zookeeper,会报错401没有认证,需要改为hostname,并在hosts里面配置ip和hostname映射关系
                 */
                //CloudSolrClient solrCloudClient = new CloudSolrClient("192.168.1.165:2181,192.168.1.166:2181,192.168.1.167:2181/infra-solr");
                CloudSolrClient solrCloudClient = new CloudSolrClient("host1:2181,host2:2181,host3:2181/infra-solr");
                solrCloudClient.setDefaultCollection("ranger_audits");
                solrCloudClient.setZkClientTimeout(10000);
                solrCloudClient.setZkClientTimeout(20000);
                solrCloudClient.connect();
                SolrQuery params = new SolrQuery("*:*");
                QueryResponse qr = solrCloudClient.query(params);
                System.out.println(qr.getResults());
    
                /**
                 * the second method:  用于standalone模式或者集群solrCloud模式,通过http访问
                 * 注意:当solr开启kerberos后,不能直接通过ip访问web ui,会报错zookeeper连接超时,需要改为hostname,并在hosts里面配置ip和hostname映射关系
                 */
                //String solrURL = "http://192.168.1.165:8886/solr/ranger_audits";
                String solrURL = "http://host1:8886/solr/ranger_audits";
                HttpSolrClient solrClient = new HttpSolrClient(solrURL);
                solrClient.setAllowCompression(true);
                solrClient.setConnectionTimeout(1000);
                solrClient.setRequestWriter(new BinaryRequestWriter());
                SolrQuery params2 = new SolrQuery("*:*");
                QueryResponse qr2 = solrClient.query(params2);
                System.out.println(qr2.getResults());
    
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }

      注意:

        无论是CloudSolrClient还是HttpSolrClient,当solr开启kerberos后,不能直接通过ip访问,只能通过hostname访问,并在hosts里面配置ip和hostname映射关系。

    3.3. solr.7.7.0版本demo

    3.3.1. pom.xml配置 

            <dependency>
                <groupId>org.apache.solr</groupId>
                <artifactId>solr-solrj</artifactId>
                <version>7.7.0</version>
            </dependency>
            <dependency>
                <groupId>commons-codec</groupId>
                <artifactId>commons-codec</artifactId>
                <version>1.9</version>
            </dependency>

    3.3.2. java代码 

    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.solr.client.solrj.SolrClient;
    import org.apache.solr.client.solrj.SolrQuery;
    import org.apache.solr.client.solrj.impl.*;
    import org.apache.solr.client.solrj.response.QueryResponse;
    import org.apache.solr.common.params.ModifiableSolrParams;
    
    public class solrTest2 {
        public static void main(String[] args) {
            try {
                //System.setProperty("java.security.krb5.conf", "/etc/krb5.conf");
                System.setProperty("java.security.krb5.conf", "D:\krb5.conf");
                
                System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
                System.setProperty("sun.security.krb5.debug", "true");
                
                //System.setProperty("java.security.auth.login.config", "/home/redpeak/ranger_solr_jaas_test.conf");
                System.setProperty("java.security.auth.login.config", "D:\ranger_solr_jaas_test.conf");
    
                /**
                 * 用于standalone模式或者集群solrCloud模式,通过http访问
                 * 注意:当solr开启kerberos后,不能直接通过ip访问web ui,会报错401没有认证,需要改为hostname,并在hosts里面配置ip和hostname映射关系
                 */
                //HttpSolrClient.Builder solrClientBuilder = new HttpSolrClient.Builder("http://192.168.1.165:8886/solr/ranger_audits");
                HttpSolrClient.Builder solrClientBuilder = new HttpSolrClient.Builder("http://host1:8886/solr/ranger_audits");
                SolrHttpClientBuilder solrHttpClientBuilder = new Krb5HttpClientBuilder().getHttpClientBuilder(java.util.Optional.empty());
                HttpClientUtil.setHttpClientBuilder(solrHttpClientBuilder);
    
                ModifiableSolrParams params = new ModifiableSolrParams();
                params.set(HttpClientUtil.PROP_FOLLOW_REDIRECTS, false);
    
                CloseableHttpClient httpClient = HttpClientUtil.createClient(params);
                SolrClient client = solrClientBuilder.withHttpClient(httpClient).build();
    
                SolrQuery params2 = new SolrQuery("*:*");
                QueryResponse qr = client.query(params2);
    
                System.out.println(qr.getResults());
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }

      注意:

        当solr开启kerberos后,不能直接通过ip访问,只能通过hostname访问,并在hosts里面配置ip和hostname映射关系。

    4. 参考资料

    https://solr.apache.org/guide/8_8/kerberos-authentication-plugin.html

  • 相关阅读:
    由全能悖论而引发的思考
    Prism4文档翻译(第五章 第二部分)
    Windows Phone 7
    软件行业畅想
    第十章 还需要编辑
    Prism4文档翻译(第五章 第三部分)
    我的编程之路——从零到面向过程
    mongodb指南(翻译)(二十五) developer zone 插入对象(二)模式设计(Schema Design)
    在MongoDB中一起使用$or和sort()时,查询性能差的一种解决方案
    google纪念牛顿特效
  • 原文地址:https://www.cnblogs.com/swordfall/p/14699660.html
Copyright © 2020-2023  润新知