集中式日志分析平臺(tái) - ELK Stack - 開源安全套件 SearchGuard 的整合 - 1

前言

在之前的一篇 集中式日志分析平臺(tái) - ELK Stack - 安全解決方案 X-Pack 里講解了官方收費(fèi)安全套件,官方套件很強(qiáng)大啊,但是完全收費(fèi)。業(yè)界比較有名的一款開源產(chǎn)品 SearchGuard 卻是部分收費(fèi),專注于 ES 的安全加固以及順帶做做 ELK 棧的 security,功能包括:

認(rèn)證授權(quán)有關(guān)的:

  • 支持基礎(chǔ) Http 認(rèn)證;
  • 支持 LDAP 和 AD,可以用于認(rèn)證和授權(quán)的用戶角色信息元數(shù)據(jù)集中式存儲(chǔ);(收費(fèi))
  • 支持 Kerberos 雙邊認(rèn)證;(收費(fèi))
  • 支持 JWT;(收費(fèi))
  • 支持代理認(rèn)證,可以很方便的實(shí)現(xiàn) SSO 系統(tǒng)對(duì)接;

ES 行(document)和列(field)級(jí)別的安全訪問控制;

日志審計(jì)功能;(收費(fèi))

ELK 棧其他組件有關(guān)的:

  • 和 Kibana 完美整合,包括添加了 x-pack 插件的情況下,支持 Kerberos 認(rèn)證、代理認(rèn)證、JWT、用戶名/密碼登錄認(rèn)證、Https 加密、對(duì) ES 訪問的 ACL 等,并且可以自定義登錄首頁(yè)樣式;
  • 支持 Kibana 的 visualization、dashboard 的多租戶模式;(收費(fèi))
  • 和 logstash 完美整合,支持 logstash 可以通過 Https 訪問 ES;
  • 和 x-pack monitoring 整合;
  • 支持 Tribe nodes 模式,也就是說支持多個(gè) ES 集群的級(jí)聯(lián)查詢;
  • 支持 indices 的快照和恢復(fù)操作,默認(rèn)只有 admin 用戶具備權(quán)限;
  • 可以和開源 ES 報(bào)警組件 ElastAlert 整合;

本文描述的是如何把關(guān)鍵性的幾個(gè)免費(fèi)功能整合到我們的 ELK 棧里去,涵蓋了

  • 如何以腳本的形式 quickstart 整合 search guard 至 elasticsearch (Https & indices 粒度 ACL);
  • 如何讓 kibana 訪問安全 elasticsearch 集群;
  • 如何讓 logstash 訪問安全 elasticsearch 集群;
  • 一個(gè)簡(jiǎn)單的鏈路調(diào)試?yán)樱?/li>

Integration with ES(Https & indices 粒度 ACL)

假設(shè)我們已經(jīng)有一個(gè) ELK 集群(部署方式請(qǐng)參考我之前的文章),它的節(jié)點(diǎn)分布是這樣的(版本統(tǒng)一為 5.2.1):

IP Role
172.16.134.34 ES/Logstash/Kibana
172.16.134.37 ES/Logstash/Zookeeper/Kafka/Filebeat

服務(wù)的安裝路徑統(tǒng)一為 /home/admin/server/${SERVICE_NAME} ,日志的統(tǒng)一路徑為 /home/admin/logs/${SERVICE_NAME}

互聯(lián)網(wǎng)聯(lián)通情況下的安裝:

/home/admin/server/elasticsearch-current/bin/elasticsearch-plugin install -b com.floragunn:search-guard-5:5.2.1-12

請(qǐng)按照您自己的 es 版本進(jìn)行版本選擇:https://github.com/floragunncom/search-guard/wiki

離線環(huán)境下的安裝:

在可以訪問互聯(lián)網(wǎng)的機(jī)器上下載 https://oss.sonatype.org/content/repositories/releases/com/floragunn/search-guard-5/5.2.1-12/search-guard-5-5.2.1-12.zip,然后上傳至內(nèi)網(wǎng)環(huán)境。

/home/admin/server/elasticsearch-current/bin/elasticsearch-plugin install -b file:///home/admin/soft/search-guard-5-5.2.1-12.zip

運(yùn)行命令進(jìn)行腳本式初始化:

cd /home/admin/server/elasticsearch-current/plugins/search-guard-5/tools
chmod +x install_demo_configuration.sh
./install_demo_configuration.sh

完成后會(huì)在 config 目錄下生成測(cè)試用的 3 個(gè) jks 文件:

  • truststore.jks—根 CA;
  • keystore.jks—節(jié)點(diǎn)證書;
  • kirk.jks—運(yùn)行 sgadmin 必備的管理員證書;

完成后也會(huì)自動(dòng)設(shè)置一些默認(rèn)配置至 elasticsearch.yml 中:

######## Start Search Guard Demo Configuration ########
searchguard.ssl.transport.keystore_filepath: keystore.jks
searchguard.ssl.transport.truststore_filepath: truststore.jks
searchguard.ssl.transport.enforce_hostname_verification: false
searchguard.ssl.http.enabled: true
searchguard.ssl.http.keystore_filepath: keystore.jks
searchguard.ssl.http.truststore_filepath: truststore.jks
searchguard.authcz.admin_dn:
  - CN=kirk,OU=client,O=client,L=test, C=de
cluster.name: searchguard_demo
network.host: 0.0.0.0

但是如果現(xiàn)在重新啟動(dòng) es 可能會(huì)報(bào)錯(cuò),因?yàn)樵鹊呐渲美锖w了 cluster.name network.host 等配置,報(bào)錯(cuò)可能如下:

Exception in thread "main" ElasticsearchParseException[duplicate settings key [cluster.name] found at line number [21], column number [15], previous value [lw-daily], current value [search
guard_demo]]

這里 lw-daily 是我們默認(rèn)的集群名稱。

我們需要?jiǎng)h除相應(yīng)報(bào)錯(cuò)配置項(xiàng),然后重啟 es:

######## Start Search Guard Demo Configuration ########
searchguard.ssl.transport.keystore_filepath: keystore.jks
searchguard.ssl.transport.truststore_filepath: truststore.jks
searchguard.ssl.transport.enforce_hostname_verification: false
searchguard.ssl.http.enabled: true
searchguard.ssl.http.keystore_filepath: keystore.jks
searchguard.ssl.http.truststore_filepath: truststore.jks
searchguard.authcz.admin_dn:
  - CN=kirk,OU=client,O=client,L=test, C=de
network.host: 0.0.0.0

如果重啟過程中還遇到如下報(bào)錯(cuò)說明 openssl 運(yùn)行缺少 jar:

[2017-07-12T12:56:23,987][INFO ][c.f.s.s.DefaultSearchGuardKeyStore] Open SSL not available (this is not an error, we simply fallback to built-in JDK SSL) because of java.lang.ClassNotFoundException: org.apache.tomcat.jni.SSL

該情況需要去官方下載對(duì)應(yīng)版本的 jar 包(https://github.com/floragunncom/search-guard-docs/blob/master/tls_openssl.md),比如我們的版本對(duì)應(yīng)的是 http://repo1.maven.org/maven2/io/netty/netty-tcnative/1.1.33.Fork25,然后放置到 plugins/search-guard-5/

mv netty-tcnative-1.1.33.Fork25-linux-x86_64.jar /home/admin/server/elasticsearch-current/plugin/search-gurad-5/

修改 tools/sgadmin_demo.sh ,使其中一行匹配我們默認(rèn)的集群名稱:

/home/admin/server/elasticsearch-current/plugins/search-guard-5/tools/sgadmin.sh -cd /home/admin/server/elasticsearch-current/plugins/search-guard-5/sgconfig -cn lw-daily -ks /home/admin/server/elasticsearch-current/config/kirk.jks -ts /home/admin/server/elasticsearch-current/config/truststore.jks -nhnv

我們把 -cn 參數(shù)修改為了 lw-daily。

然后我們執(zhí)行腳本:

./sgadmin_demo.sh

執(zhí)行腳本之后會(huì)根據(jù) plugins/search-guard-5-5.2.1-12/sgconfig 的配置初始化 search guard index,初始化的包括內(nèi)部用戶、角色、用戶和角色的映射、權(quán)限組等等。

到這一步之后安裝就算完成了,我們可以通過接口觀察是否配置正確:

https://172.16.134.34:9200/_searchguard/authinfo

這里默認(rèn)的用戶名和密碼可以選擇 adminadmin,如果通過認(rèn)證,那么就會(huì)返回如下結(jié)果:

{
    user: "User [name=admin, roles=[]]",
    user_name: "admin",
    user_requested_tenant: null,
    remote_address: "172.16.129.61:50317",
    sg_roles: [
        "sg_all_access",
        "sg_own_index",
        "sg_public"
    ],
    sg_tenants: {
        test_tenant_ro: true,
        admin: true,
        adm_tenant: true
    },
    principal: null,
    peer_certificates: "0"
}

Integration with Kibana

ES 做了加固,原先的普通訪問方式就歇菜了,首先是 Https 然后是 ACL,那么就會(huì)沒通過認(rèn)證和得到相應(yīng)的權(quán)限訪問資源。我們需要對(duì) Kibana 做相應(yīng)的配置:

下載 plugin:

https://github.com/floragunncom/search-guard-kibana-plugin/releases/download/v5.2.1-3/searchguard-kibana-5.2.1-3.zip

安裝 plugin:

/home/admin/server/kibana-current/bin/kibana-plugin install file:///home/admin/soft/searchguard-kibana-5.2.1-3.zip

修改 kibana.yml

elasticsearch.url: "https://v134034.yn1.lwsite.net:9200"
server.host: "v134034.yn1.lwsite.net"

searchguard.basicauth.enabled: true
searchguard.cookie.secure: false
searchguard.cookie.name: 'searchguard_authentication'
searchguard.cookie.password: 'searchguard_cookie_default_password'
searchguard.cookie.ttl: 3600000
searchguard.session.ttl: 3600000
searchguard.session.keepalive: true

elasticsearch.username: "kibanaserver"
elasticsearch.password: "kibanaserver"

elasticsearch.ssl.verify: false

console.proxyConfig:
  - match:
      protocol: "https"
    ssl:
      verify: false

重啟 kibana:

sudo kill -9 $(sudo lsof -i:5601 | awk '{print$2}' | tail -1 )
/home/admin/server/kibana-current/bin/kibana >> /home/admin/logs/kibana/kibana.log 2>&1 &

使用 kibanaserver 查看是否可以登錄,密碼默認(rèn)為 kibanaserver。(該用戶是在整合 searchguard 至 es 之后在運(yùn)行 demo 腳本中生成的,同樣的 logstash 用戶也是)

Integration with Logstash

同樣,我們需要修改 logstash ,以使其可以訪問 es。以下是一個(gè)簡(jiǎn)單的示例配置,數(shù)據(jù)來自 kafka 的 stdin_test:

input {
  kafka {
    bootstrap_servers => 'v134037.yn1.lwsite.net:9092'
    consumer_threads => 1
    topics => ["stdin_test"]
    type => "stdin_test"
    codec => "json"
  }
}

output {
  elasticsearch {
    hosts => ["v134034.yn1.lwsite.net:9200","v134037.yn1.lwsite.net:9200"]
    manage_template => false
    index => "stdin_test-%{+YYYY.MM.dd}"
    document_type => "stdin_test"
    ssl => true
    ssl_certificate_verification => false
    truststore => "/home/admin/server/elasticsearch-current/config/truststore.jks"
    truststore_password => changeit
    user => logstash
    password => logstash
  }
}

其中,/home/admin/server/elasticsearch-current/config/truststore.jks 也是由之前的 demo 腳本生成的。

重啟 logstash 之后可以正確訪問。

即使 ssl_certificate_verification 設(shè)置為 false,也必須配置 truststore ,否則會(huì)報(bào)錯(cuò):

logstash unable to find valid certification path to requested target,參考 issue 鏈接:https://github.com/logstash-plugins/logstash-output-http/issues/21,我們必須保證 truststore 文件存在可讀。

一個(gè)簡(jiǎn)單的例子

上一節(jié)我們介紹了如何整合 logstash 至 searchguard,現(xiàn)在我們要在 stdin_test 這個(gè) topic 里面造些數(shù)據(jù)進(jìn)行集成測(cè)試,我們當(dāng)然用 filebeat 推送數(shù)據(jù)至 kafka,filebeat 部署在 172.16.134.37,配置如下:

首先是主配置文件 /home/admin/server/filebeat-current/filebeat.yml

filebeat:
  config_dir: /home/admin/server/filebeat-current/conf.d

output.kafka:
  hosts: ["v134037.yn1.lwsite.net:9092"]
  topic: '%{[type]}'
  partition.round_robin:
    reachable_only: false
  required_acks: 1
  compression: gzip
  max_message_bytes: 10485760

然后是對(duì)應(yīng)的采集 stdin_test 的配置文件 /home/admin/server/filebeat-current/conf.d/stdin_test.yml

filebeat.prospectors:
- input_type: log
  paths:
  - /tmp/stdin_test.log
  document_type: stdin_test

OK,接下來我們灌簡(jiǎn)單數(shù)據(jù)至文件:

echo "1" >> /tmp/stdin_test.log

在 Kibana 添加 index 的時(shí)候發(fā)現(xiàn)無法獲取,排查了一下可以得知 Kafka 是有 topic 新建并且有數(shù)據(jù)的:

/home/admin/server/kafka-current/bin/kafka-topics.sh --list --zookeeper 172.16.134.37:2181
/home/admin/server/kafka-current/bin/kafka-console-consumer.sh --zookeeper 127.0.0.1:2181 --topic stdin_test --from-beginning

然后排查下 logstash DEBUG 日志:

[2017-07-13T15:06:14,376][WARN ][logstash.outputs.elasticsearch] Failed action. {:status=>403, :action=>["index", {:_id=>nil, :_index=>"stdin_test-2017.07.13", :_type=>"stdin_test", :_routing=>nil}, 2017-07-13T07:06:14.280Z %{host} {
"@timestamp":"2017-07-13T07:06:13.054Z","beat":{"hostname":"v134037.yn1","name":"v134037.yn1","version":"5.2.1"},"input_type":"log","message":"1","offset":6,"source":"/tmp/stdin_test.log","type":"stdin_test"}], :response=>{"index"=>{
"_index"=>"stdin_test-2017.07.13", "_type"=>"stdin_test", "_id"=>nil, "status"=>403, "error"=>{"type"=>"security_exception", "reason"=>"no permissions for indices:admin/create"}}}}

注意最后的報(bào)錯(cuò) no permissions for indices:admin/create,可以得知 logstash 沒有對(duì)應(yīng)權(quán)限進(jìn)行 indices 新建。按照官方的建議,對(duì) searchguard 的配置文件進(jìn)行修改 /home/admin/server/elasticsearch-5.2.1/plugins/search-guard-5/sgconfig/sg_roles.yml,注意只修改 sg_logstash 這個(gè)角色的配置:

...
sg_logstash:
  cluster:
    - indices:admin/template/get
    - indices:admin/template/put
    - CLUSTER_MONITOR
    - CLUSTER_COMPOSITE_OPS
  indices:
    'logstash-*':
      '*':
        - CRUD
        - CREATE_INDEX
    'stdin_test-*': # 修改這里,添加對(duì)應(yīng)權(quán)限
      '*':
        - CRUD
        - CREATE_INDEX
    '*beat*':
      '*':
        - CRUD
        - CREATE_INDEX
...

發(fā)現(xiàn)修改后重啟沒有卵用,看到了官方的建議說需要用腳本刷下配置:

/home/admin/server/elasticsearch-current/plugins/search-guard-5/tools/sgadmin.sh -cd /home/admin/server/elasticsearch-current/plugins/search-guard-5/sgconfig -cn lw-daily -ks /home/admin/server/elasticsearch-current/config/kirk.jks -ts /home/admin/server/elasticsearch-current/config/truststore.jks -nhnv

官方說只要一個(gè)節(jié)點(diǎn)刷就可以全局生效,但是我發(fā)現(xiàn)不行,所以我是全局所有節(jié)點(diǎn)都進(jìn)行了這個(gè)操作的。重啟試下是否數(shù)據(jù)可以被 Kibana 識(shí)別,發(fā)現(xiàn)還是不行,這個(gè)時(shí)候看了下 Kibana 的日志發(fā)現(xiàn)如下報(bào)錯(cuò):

[2017-07-13T15:49:28,591][INFO ][c.f.s.c.PrivilegesEvaluator] No index-level perm match for User [name=kibanaserver, roles=[]] [IndexType [index=stdin_test-2017.07.13, type=*]] [Action [indices:admin/mappings/fields/get]] [RolesCheck
ed [sg_kibana_server, sg_own_index, sg_public]]
[2017-07-13T15:49:28,591][INFO ][c.f.s.c.PrivilegesEvaluator] No permissions for {sg_public=[IndexType [index=stdin_test-2017.07.13, type=*]], sg_own_index=[IndexType [index=stdin_test-2017.07.13, type=*]], sg_kibana_server=[IndexTyp
e [index=stdin_test-2017.07.13, type=*]]}

也是權(quán)限的問題,按照和之前一樣的方式修改權(quán)限:

...
sg_kibana:
  cluster:
    - CLUSTER_COMPOSITE_OPS_RO
  indices:
    '*':
      '*':
        - READ
        - indices:admin/mappings/fields/get*
    '?kibana':
      '*':
        - ALL
...

并且刷新后,重啟 Kibana,以 kibanaro 角色登錄(默認(rèn)密碼 kibanaro),再灌入測(cè)試數(shù)據(jù)至日志文件后,就可以正確獲取 indices 數(shù)據(jù)。

小結(jié)

本文介紹了如何使用 searchguard 對(duì) ES 進(jìn)行 https 和 indices 粒度 ACL 的安全賦能,以及一個(gè)短小的例子。下一篇我將寫一下如何整合 Kerberos 雙邊認(rèn)證進(jìn)行進(jìn)一步加固,以及如何使用 restful API 對(duì) ES 進(jìn)行訪問。

參考文獻(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容