SearchGuard 實踐

weixin_34116110發表於2018-09-28
3239635-52d26a847f155f3b.jpg
searchguard.jpg

SearchGuard 安裝

  1. searchguard 必須與所選版本一致

線上安裝

bin/elasticsearch-plugin install -b com.floragunn:search-guard-6:6.3.2-23.0

離線安裝

bin/elasticsearch-plugin install -b file:../search-guard-6-6.3.2-23.0.zip

證照生成

線上生成方式

https://search-guard.com/tls-certificate-generator/

線上生成的配置稍顯不同生成完裡面有文件教你怎麼配置

離線工具生成

離線工具下載

https://repo1.maven.org/maven2/com/floragunn/search-guard-tlstool/1.5/

根據以上鍊接下載所需要的工具解壓

  • 目錄結構

config 配置檔案目錄,工具可以根據配置檔案模板為你生成證照

dep 工具所依賴的jar包

tools 生成證照的指令碼

生成模板配置

在config資料夾中建立tlsconfig.yml檔案

 ca:
     root:
         # The distinguished name of this CA. You must specify a distinguished name.   
         dn: CN=root.ca.xxx.com,OU=CA,O=xxx Com\, Inc.,DC=xxx,DC=com

         # The size of the generated key in bits
         keysize: 2048

         # The validity of the generated certificate in days from now
         validityDays: 3650
         
         # Password for private key
         #   Possible values: 
         #   - auto: automatically generated password, returned in config output; 
         #   - none: unencrypted private key; 
         #   - other values: other values are used directly as password   
         pkPassword: auto 
         
         # The name of the generated files can be changed here
         file: root-ca.pem
     
 ### 
 ### Default values and global settings
 ###
 defaults:

     # The validity of the generated certificate in days from now
     validityDays: 3650 
     
     # Password for private key
     #   Possible values: 
     #   - auto: automatically generated password, returned in config output; 
     #   - none: unencrypted private key; 
     #   - other values: other values are used directly as password   
     pkPassword: auto      
     
     # Specifies to recognize legitimate nodes by the distinguished names
     # of the certificates. This can be a list of DNs, which can contain wildcards.
     # Furthermore, it is possible to specify regular expressions by
     # enclosing the DN in //. 
     # Specification of this is optional. The tool will always include
     # the DNs of the nodes specified in the nodes section.            
     #nodesDn:
     #- "CN=*.example.com,OU=Ops,O=Example Com\\, Inc.,DC=example,DC=com"
     # - 'CN=node.other.com,OU=SSL,O=Test,L=Test,C=DE'
     # - 'CN=*.example.com,OU=SSL,O=Test,L=Test,C=DE'
     # - 'CN=elk-devcluster*'
     # - '/CN=.*regex/' 

     # If you want to use OIDs to mark legitimate node certificates, 
     # the OID can be included in the certificates by specifying the following
     # attribute
     
     # nodeOid: "1.2.3.4.5.5"

     # The length of auto generated passwords            
     generatedPasswordLength: 12
     
     # Set this to true in order to generate config and certificates for 
     # the HTTP interface of nodes
     httpsEnabled: true
     
     # Set this to true in order to re-use the node transport certificates
     # for the HTTP interfaces. Only recognized if httpsEnabled is true
     
     # reuseTransportCertificatesForHttp: false
     
     # Set this to true to enable hostname verification
     #verifyHostnames: false
     
     # Set this to true to resolve hostnames
     #resolveHostnames: false
     
     
 ###
 ### Nodes
 ###
 # 
 # Specify the nodes of your ES cluster here
 #      
 nodes:
     - name: node-01
         dn: CN=node-01.xxx.com,OU=Ops,O=xxx Com\, Inc.,DC=xxx,DC=com
         dns: node-01.xxx.com
         ip: 111.111.111.11
     - name: node-02
         dn: CN=node-02.xxx.com,OU=Ops,O=xxx Com\, Inc.,DC=xxx,DC=com
         dns: 
           - node-02.xxx.com
         ip: 
           - 111.111.111.12
     - name: node-03
         dn: CN=node-03.xxx.com,OU=Ops,O=xxx Com\, Inc.,DC=xxx,DC=com
         dns: node-03.xxx.com
         ip: 
           - 111.111.111.13

 ###
 ### Clients
 ###
 #
 # Specify the clients that shall access your ES cluster with certificate authentication here
 #
 # At least one client must be an admin user (i.e., a super-user). Admin users can
 # be specified with the attribute admin: true    
 #        
 clients:
     - name: ppb
         dn: CN=ppb.xxx.com,OU=Ops,O=xxx Com\, Inc.,DC=xxx,DC=com
     - name: backend
         dn: CN=backend.xxx.com,OU=Ops,O=xxx Com\, Inc.,DC=xxx,DC=com
         admin: true

node配置說明

  • node-01 node-02 node-03 可以對應ES叢集中的node節點名稱

  • dns: 此項注意後面會用上。

  • ip 與es叢集ip對應

client配置

  • 上面的配置是client端證照生成用於client端訪問es用的

xxx 替換成公司域名 xxx.com baidu.com xxx即 baidu

證照生成

進入工具的tools資料夾

  • 執行命令生成證照

    ./sgtlstool.sh -c ../config/tlsconfig.yml  -ca -crt
    
  • 證照在installation directory/tools/out目錄下存放

    • 根證照
      • root-ca.pem Root certificate
      • root-ca.key Private key of the Root CA
      • root-ca.readme Passwords of the root and intermediate CAs
    • node節點證照
      • [nodename].pem Node certificate
      • [nodename].key Private key of the node certificate
      • [nodename]_http.pem REST certificate, only generated if reuseTransportCertificatesForHttp is false
      • [nodename]_http.key Private key of the REST certificate, only generated if reuseTransportCertificatesForHttp is false
      • [nodename]_elasticsearch_config_snippet.yml Search Guard configuration snippet for this node, add this to elasticsearch.yml
    • 客戶端證照
      • [name].pem Client certificate
      • [name].key Private key of the client certificate
      • client-certificates.readme Contains the auto-generated passwords for the certificates
  • 說明:

    • 根據配置檔案

      • 客戶端: 會生成5個檔案 2個客戶端配置,每個客戶端2個檔案,外加一個readme檔案
      • node: 配置了3個節點,會生成3*5個檔案
      • 根證照:唯一的,生成3個檔案
      • 證照密碼獲取:當然在生成的時候你可以自己在配置檔案配置密碼,我這裡是自動生成的
        • root-ca.readme 裡面找到root證照的密碼
        • client-certificates.readme 裡面獲取客戶端證照密碼
        • [nodename]_elasticsearch_config_snippet.yml存放著配置es節點的模板,裡面存在證照密碼

證照配置

複製證照

  • 配置ES

    • 複製 root-ca.pem 到 elasticsearch的config目錄下

    • 複製 [nodename].pem elasticsearch的config目錄下

    • 複製 [nodename].key elasticsearch的config目錄下

    • 複製 [nodename]_http.pem elasticsearch的config目錄下

    • 複製 [nodename]_http.key elasticsearch的config目錄下

      sudo cp out/[nodename]*.key /[espath]/config/
      sudo cp out/[nodename]*.pem /[espath]/config/
      sudo cp out/root-ca.pem /[espath]/config/
      
      
    • 複製 root-ca.pem 到 elasticsearch的plugins/search-guard-[version]/tools目錄下

      • 複製 [username].pem elasticsearch的config目錄下
      • 複製 [username].key elasticsearch的config目錄下
      sudo cp out/[username].key /opt/apps/elasticsearch-6.3.2/plugins/search-guard-6/tools/
      
      sudo cp out/[username].pem /opt/apps/elasticsearch-6.3.2/plugins/search-guard-6/tools/
      
      sudo cp out/root-ca.pem /opt/apps/elasticsearch-6.3.2/plugins/search-guard-6/tools/
      
      
  • 配置ES(所有節點配置上)

    • 配置如下:

      cluster.name: PPB-CLUSTER
      node.name: node-01
      network.host: 0.0.0.0
      http.cors.enabled: true
      http.cors.allow-origin: "*"
      http.cors.allow-headers: "Authorization,X-Requested-With,Content-Length,Content-Type"
      searchguard.ssl.transport.pemcert_filepath: node-01.pem
      searchguard.ssl.transport.pemkey_filepath: node-01.key
      searchguard.ssl.transport.pemkey_password: ******
      searchguard.ssl.transport.pemtrustedcas_filepath: root-ca.pem
      searchguard.ssl.transport.enforce_hostname_verification: false
      searchguard.ssl.transport.resolve_hostname: false
      searchguard.ssl.http.enabled: true
      searchguard.ssl.http.pemcert_filepath: node-01_http.pem
      searchguard.ssl.http.pemkey_filepath: node-01_http.key
      searchguard.ssl.http.pemkey_password: ********
      searchguard.ssl.http.pemtrustedcas_filepath: root-ca.pem
      searchguard.nodes_dn:
          - CN=node-01.xxx.com,OU=Ops,O=xxx Com\, Inc.,DC=xxx,DC=com
          - CN=node-02.xxx.com,OU=Ops,O=xxx Com\, Inc.,DC=xxx,DC=com
          - CN=node-03.xxx.com,OU=Ops,O=xxx Com\, Inc.,DC=xxx,DC=com
      searchguard.authcz.admin_dn:
          - CN=ppb.xxx.com,OU=Ops,O=xxx Com\, Inc.,DC=xxx,DC=com
      searchguard.allow_unsafe_democertificates: true
      xpack.security.enabled: false
      searchguard.enterprise_modules_enabled: false
      
      • 配置提示(避坑)
        • network.host: 0.0.0.0 避免執行sgadmin命令時報錯
        • xpack.security.enabled: false 禁用xpack
        • es-head支援
          • http.cors.enabled: true
          • http.cors.allow-origin: "*"
          • http.cors.allow-headers: "Authorization,X-Requested-With,- Content-Length,Content-Type"
  • 啟動ES節點

    /[espath]/bin/elasticsearch -d
    
  • 啟用searchguard

    • 進入/[espath]/plugins/search-guard-6/tools

          ./sgadmin.sh -cacert root-ca.pem -cert ppb.pem -key pbb.key -keypass gb1bbJEWO5lW -nhnv -icl -cd ../sgconfig
      
    • ppb.pem ppb.key 即你後面在Spring裡面整合時需要的客戶端證照

    • 如果提示沒有許可權則增加sgadmin.sh的許可權重新執行即可

  • 按如上方式把所有節點啟動起來

  • 驗證:

    瀏覽器輸入 https://es-node:9200,某一節點讓輸入使用者名稱密碼說明安裝成功

SpringBoot整合

通過TransportClient方式訪問ES

依賴pom.xml

          <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>com.floragunn</groupId>
            <artifactId>search-guard-ssl</artifactId>
            <version>5.6.4-23</version>
        </dependency>
        <dependency>
            <groupId> org.elasticsearch.plugin</groupId>
            <artifactId> transport-netty3-client</artifactId>
            <version> 5.1.1</version>
      </dependency>

配置檔案配置application.properties

search_guard.elasticsearch.nodes = node-01.xxx.com,node-02.xxx.com,node-03.xxx.com
search_guard.elasticsearch.transclient.port = 9300
search_guard.elasticsearch.clustername = PPB-CLUSTER
search_guard.ssl_transport_pemkey_password = ******
search_guard.ssl_transport_pemkey_filepath = /ssl/ppb.key
search_guard.ssl_transport_pemcert_filepath = /ssl/ppb.pem
search_guard.ssl_transport_pemtrustedcas_filepath = ssl/root-ca.pem

javaConfig

@Configuration
@Profile("test")
public class ElasticSearchConfig {
    private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchConfig.class);
    @Value("${search_guard.elasticsearch.clustername}")
    private String clusterName;
    @Value("${search_guard.ssl_transport_pemkey_filepath}")
    private String pemKeyFilePath;
    @Value("${search_guard.ssl_transport_pemcert_filepath}")
    private String pemCertFilePath;
    @Value("${search_guard.ssl_transport_pemtrustedcas_filepath}")
    private String pemTrustedCasFilePath;
    @Value("${search_guard.ssl_transport_pemkey_password}")
    private String pemkeyPassword;
    @Value("#{'${search_guard.elasticsearch.nodes}'.split(',')}")
    private List<String> clusterNodes;
    @Value("${search_guard.elasticsearch.transclient.port}")
    private int transportPort;

    @Bean
    public Client client() throws Exception {
        LOGGER.info("載入配置" + transportPort);
        Settings.Builder settingsBuilder =
                Settings.builder()
                        .put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMKEY_FILEPATH, pemKeyFilePath)
                        .put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMCERT_FILEPATH, pemCertFilePath)
                        .put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH, pemTrustedCasFilePath)
                        .put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMKEY_PASSWORD, pemkeyPassword)
                        .put("cluster.name", clusterName)
                        .put("client.transport.sniff", false);
        Settings settings = settingsBuilder.build();
        TransportClient client = new PreBuiltTransportClient(settings, SearchGuardSSLPlugin.class);
        for (String node : clusterNodes) {
            LOGGER.info("載入配置 " + node);
            client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(node), transportPort));
        }
        return client;
    }

    @Bean
    public ElasticsearchTemplate elasticsearchTemplate() throws Exception {
        return new ElasticsearchTemplate(client());
    }

}

避坑指南

  • search_guard.elasticsearch.nodes 配置一定要與節點證照的dns一致node-01.xxx.com
  • 在釋出伺服器上修改host檔案,把es節點與對應的ip配置進去
  • client.transport.sniff 配置成false。
  • 證照檔案放到對應的目錄下 所需要的證照:
    • root-ca.pem
    • [username].key
    • [username].pem
    • 使用者證照一定要使用你執行sgadmin命令時使用的證照

es-head外掛如何訪問獲取es資訊

預設使用者名稱密碼是admin

http://[es-head]:9100/?base_uri=https://[es-node]:9200&auth_user=admin&auth_password=admin

總結

最後就可以開啟許可權配置了。