인증을 위해 Search Guard 플러그인을 적용한 ELK 구성
-
install 명령
$ bin/elasticsearch-plugin install -b com.floragunn:search-guard-5:5.5.0-14
- 버전은 아래 버전표 참고
-
tools 디렉토리로 이동
$ cd <Elasticsearch directory>/plugins/search-guard-<version>/tools
-
install_demo_configuration.sh 실행
$ ./install_demo_configuration.sh
- 실행권한이 없는 경우
chmod +x install_demo_configuration.sh
- 실행 후 truststore, keystore, kirk 인증서 파일이 생성됨
<Elasticsearch directory>/config
디렉토리에 생성됨- truststore.jks : root CA와 intermediate/signing CA
- keystore.jks : 노드 인증서(node certificate)
- install_demo_configuration.sh를 통해 생성된 인증서 파일들은 미리 생성해놓은 키값을 사용하기 때문에 보안에 취약하므로 production 서비스에서 사용할 경우에는 keystore와 truststore를 생성하여 사용할 것을 권장.
- 실행권한이 없는 경우
-
elasticsearch 실행
$ <Elasticsearch directory>/bin/elasticsearch
- elasticsearch가 실행 된 후 아래 sgadmin 스크립트를 실행 시켜주어야 Search Guard를 사용하기 위해 필요한 데이터들이 elasticsearch에 생성된다.
-
sgadmin_demo.sh 실행
$ cd <Elasticsearch directory>/plugins/search-guard-<version>/tools $ ./sgadmin_demo.sh
-
권한 설정이나 SearchGuard에 대한 설정 파일들은
plugins/search-guard-<version>/sgconfig
디렉토리에 생성됨 -
elasticsearch의 설정에 따라 ip와 port가 localhost의 9300이 아닌 경우에는 sgadmin_demo.sh 파일을 수정하여 호스트와 포트를 지정한다.'
$ <Elasticsearch directory>/plugins/search-guard-5/tools/sgadmin.sh -cn searchguard_demo -h localhost -p 9300 -cd <Elasticsearch directory>/plugins/search-guard-5/sgconfig -ks <Elasticsearch directory>/config/kirk.jks -ts <Elasticsearch directory>/config/truststore.jks -nhnv
-
-
https://localhost:9200 으로 접속 확인
-
인증 요청 팝업이 출력됨. (이 계정 정보는 sgconfig/sg_internal_user.xml에 정의)
-
인증에 성공하면 아래와 같은 정보가 출력됨
{ "name" : "9t6GokQ", "cluster_name" : "searchguard_demo", "cluster_uuid" : "itfKNEpHTZGSnbMuhj8ZrA", "version" : { "number" : "5.5.0", "build_hash" : "260387d", "build_date" : "2017-06-30T23:16:05.735Z", "build_snapshot" : false, "lucene_version" : "6.6.0" }, "tagline" : "You Know, for Search" }
-
-
플러그인 다운로드
$ wget https://github.com/floragunncom/search-guard-kibana-plugin/releases/download/v5.4.2-3/searchguard-kibana-5.4.2-3.zip
-
플러그인 설치
$ bin/kibana-plugin install file:///usr/share/kibana/temp/searchguard-kibana-5.4.2-3.zip
-
/etc/kibana/kibana.yml 설정
elasticsearch.url: "https://localhost:9200" ... 생략 ... elasticsearch.username: "kibanaserver" elasticsearch.password: "kibanaserver" ... 생략 ... elasticsearch.ssl.verificationMode: none ... 생략 ...
- elasticsearch URL은 이제 https를 사용
- username과 password는 elasticsearch 쪽에 sgconfig/sg_internal_user.xml 파일에 지정된 계정을 사용
- 사설 인증서를 사용하지 않으므로 verificationMode는 none으로 설정
-
http://localhost:5601 (키바나)로 접속
-
브랜드 이미지를 변경하고 싶은 경우에는 config/kibana.yml에서 아래와 같이 설정
searchguard.basicauth.login.showbrandimage: true searchguard.basicauth.login.brandimage: "이미지 경로" searchguard.basicauth.login.title: "로그인을 해주세요." searchguard.basicauth.login.subtitle: "서브 타이틀입니다."
-
키바나 재시작 후 접속
-
logstash.conf 파일 작성
input { stdin {} } output { elasticsearch { hosts => "localhost:9200" user => logstash password => logstash ssl => true ssl_certificate_verification => false truststore => "<logstash path>/config/truststore.jks" truststore_password => changeit index => "test" document_type => "test_doc" } stdout{ codec => rubydebug } }
- user와 password는 elasticsearch의 Search Guard 플러그인에 등록된 유저 정보
- 기본적으로 logstash 용으로 계정이 정의되어 있음.
- ssl 설정을 true로 한 경우 ssl을 사용한다.
- 인증서 파일을 사용하여 인증 절차를 수행하는 경우 ssl_certificate_verification을 true로 설정한다.
- 여기서는 인증 절차를 수행하지 않기 때문에 false로 설정
- true인 경우 truststore에 대한 설정을 해주어야 한다.
- user와 password는 elasticsearch의 Search Guard 플러그인에 등록된 유저 정보
http.host: 0.0.0.0
logger._root: DEBUG
######## 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
######## End Search Guard Demo Configuration ########
-
keystore/truststore 를 직접 생성하지 않고 이미 생성되어 있는 것을 사용하는 경우 아래 명령으로 인증 정보 확인
$ keytool -list -v -keystore kirk.jks
- install_demo_configuration.sh를 통해 생성된 kirk.jks 파일의 패스워드는
changeit
- install_demo_configuration.sh를 통해 생성된 kirk.jks 파일의 패스워드는
-
이 설정 값은 install_demo_configuration.sh 쉘스크립트를 실행하면 자동으로 추가된다.
자바에 포함된 보완관련 어플리케이션인 keytool을 사용
-
keystore 생성 (인증서)
$ keytool -genkey -alias hive-key -keyalg RSA -keypass changeit -storepass changeit -keystore keystore.jks
-
위에서 생성한 keystore.jks 인증서를 server.cer 파일로 내보냄
$ keytool -export -alias hive-key -storepass changeit -file server.cer -keystore keystore.jks
-
truststore 파일을 만들고 인증서를 truststore에 추가
$ keytool -import -v -trustcacerts -file server.cer -keystore truststore.jks -keypass changeit
-
keystore.jks와 trusstore.jks 생성 완료
Owner: CN=yongho, OU=vinus, O=server, L=Seoul, ST=Samsung, C=16201 Issuer: CN=yongho, OU=vinus, O=server, L=Seoul, ST=Samsung, C=16201 Serial number: 3ee66345 Valid from: Thu Jul 13 05:27:44 UTC 2017 until: Wed Oct 11 05:27:44 UTC 2017 Certificate fingerprints: MD5: 58:DD:2D:D2:11:93:8C:E4:EF:96:4C:0F:8D:04:52:96 SHA1: 93:5F:BD:68:04:6C:E6:CC:7A:DC:08:79:0D:EB:B4:C3:69:38:EF:A1 SHA256: 57:FB:66:40:47:A0:6B:1A:96:4B:91:31:60:6C:51:F7:7E:2B:04:29:9A:EE:EE:8E:AB:5A:23:43:F3:4B:E4:83 Signature algorithm name: SHA1withDSA Version: 3 Extensions: #1: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: 33 4D 88 F3 C9 AC 12 DF 3F 92 1D 96 50 9C 36 2E 3M......?...P.6. 0010: E4 11 2E 51 ...Q ] ]
아래에서 사용되는 설정 파일들은 <elasticsearch path>/plugins/search-guard-5/
하위에 위치함.
-
sgconfig/sg_internal_users.yml 파일에 유저 추가
guest: hash: #password is: guest
-
tools/hash.sh를 사용하여 패스워드 생성
$ sh hash.sh [Password:] $2a$12$izzerIN4R.m6nCDNuCPtWOR/6n/LBudgjPLBS1naNptyF2VuUPwfe
-
생성된 해쉬코드를 복사하여 sgconfig/sg_internal_users.yml 파일에 추가
guest: hash: $2a$12$izzerIN4R.m6nCDNuCPtWOR/6n/LBudgjPLBS1naNptyF2VuUPwfe #password is: guest
-
tools/sgadmin_demo.sh 파일을 실행하여 변경된 사항 적용
$ ./sgadmin_demo.sh
-
사용자에 대한 권한 role 이름을 sgconfig/sg_roles_mapping.xml 파일에 설정 하고, role 이름을 기반으로 사용자들을 해당 role에 추가시켜서 다수의 사용자들에게 동일한 role을 지정할 수 있다.
-
기본적으로 prefix로 sg_가 붙음
-
위에서 추가한 guest의 경우 sg_guest로 지정
sg_guest: uesrs: - guest
-
-
sgconfig/sg_roles.xml 파일 수정
-
위에서 설정한 role 이름에 대한 권한을 지정한다.
-
여기서는 guest로 들어온 경우 read only 권한을 부여
sg_guest: cluster: - UNLIMITED indices: '*': '*': - READ
-
대문자로 표시되어 있는 값들은 sgconfig/sg_action_groups.yml 파일에 정의되어 있다.
-
위에 설정한 READ의 경우 아래와 같이 설정됨
READ: - "indices:data/read*" - "indices:admin/mappings/fields/get*"
-
-
-
변경된 사항을 적용하기 위해 tools/sgadmin_demo.sh 실행
$ ./sgadmin_demo.sh
[2017-07-13T06:04:03,175][ERROR][c.f.s.t.SearchGuardRequestHandler] Error validating headers
[2017-07-13T06:04:03,191][WARN ][o.e.d.z.UnicastZenPing ] [vOvmwD5] [1] failed send ping to {#zen_unicast_127.0.0.1:9300_0#}{UV7v4BgFTaSO3E3F6Ng2DQ}{127.0.0.1}{127.0.0.1:9300}
java.lang.IllegalStateException: handshake failed with {#zen_unicast_127.0.0.1:9300_0#}{UV7v4BgFTaSO3E3F6Ng2DQ}{127.0.0.1}{127.0.0.1:9300}
at org.elasticsearch.transport.TransportService.handshake(TransportService.java:386) ~[elasticsearch-5.4.3.jar:5.4.3]
at org.elasticsearch.transport.TransportService.handshake(TransportService.java:353) ~[elasticsearch-5.4.3.jar:5.4.3]
at org.elasticsearch.discovery.zen.UnicastZenPing$PingingRound.getOrConnect(UnicastZenPing.java:401) ~[elasticsearch-5.4.3.jar:5.4.3]
at org.elasticsearch.discovery.zen.UnicastZenPing$3.doRun(UnicastZenPing.java:508) [elasticsearch-5.4.3.jar:5.4.3]
at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:638) [elasticsearch-5.4.3.jar:5.4.3]
at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) [elasticsearch-5.4.3.jar:5.4.3]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_131]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_131]
-
conf/elasticsearch.yml 설정에서 network.publish_host와 network.bind_host가 모두 설정되어 있는 경우 network.publish_host 설정을 제거하면 해결됨
cluster.name: mycluster node.master: true node.data: true discovery.zen.ping.multicast.enabled: false number_of_nodes : 1 minimum_master_nodes: 1 path.logs: . node.name: ElasticStack.0.0.0.0 # network.publish_host: 0.0.0.0 network.bind_host: "0.0.0.0" ... 생략 ...
-
참고
-
Search Guard 사용 시 http 통신 또한 ssl로 사용하도록 설정해둔 경우 기존에 http를 사용하여 logstash나 kibana를 사용하고 있었기 때문에 이 통신이 https가 아니라는 오류가 출력된다.
-
logstash나 kibana에 https로 통신을 하도록 설정하던가 https 통신을 사용하지 않도록 설정하도록 함.
-
여기서는 https 통신을 사용하지 않는 것으로 설정
-
conf/elasticsearch.yml 파일 수정
... 생략 ... searchguard.ssl.http.enabled: false searchguard.ssl.http.keystore_filepath: /usr/share/elasticsearch/config/keystore.jks searchguard.ssl.http.keystore_password: changeit searchguard.ssl.http.truststore_filepath: /usr/share/elasticsearch/config/truststore.jks searchguard.ssl.http.truststore_password: changeit ... 생략 ...
- searchguard.ssl.http.enabled을 false로 설정
[2017-07-14T10:23:06,639][INFO ][c.f.s.c.IndexBaseConfigurationRepository] searchguard index does not exist yet, so no need to load config on node startup. Use sgadmin to initialize cluster
[2017-07-14T10:23:06,639][INFO ][o.e.g.GatewayService ] [9t6GokQ] recovered [0] indices into cluster_state
[2017-07-14T10:23:08,171][ERROR][c.f.s.a.BackendRegistry ] Not yet initialized (you may need to run sgadmin)
[2017-07-14T10:23:08,200][ERROR][c.f.s.a.BackendRegistry ] Not yet initialized (you may need to run sgadmin)
[2017-07-14T10:23:10,708][ERROR][c.f.s.a.BackendRegistry ] Not yet initialized (you may need to run sgadmin)
[2017-07-14T10:23:13,212][ERROR][c.f.s.a.BackendRegistry ] Not yet initialized (you may need to run sgadmin)
[2017-07-14T10:23:15,714][ERROR][c.f.s.a.BackendRegistry ] Not yet initialized (you may need to run sgadmin)
-
키바나에서 연결 요청을 하는 경우 위와 같은 에러 발생
-
Search Guard 플러그인에 대한 초기 설정이 제대로 이루어지지 않아서 발생하는 에러이다.
-
이는 sgadmin_demo.sh 실행이 실패했다는 것을 의미한다.
-
실패한 경우를 보면 아래와 같다.
$ ./sgadmin_demo.sh Search Guard Admin v5 Will connect to localhost:9300 ERR: Seems there is no elasticsearch running on localhost:9300 - Will exit
- 여기서는 elasticsearch에 접속하지 못해서 발생하는 에러였는데 실제로 elasticsearch가 구동 중이지 않거나 host 또는 port가 맞지 않았기 때문에 발생하였다.
- host와 port가 맞지 않은 경우 sgadmin_demo.sh 파일을 수정하여 호스트와 포트를 지정
-
정상적인 경우에는 아래와 같은 메시지가 출력된다.
Search Guard Admin v5 Will connect to 192.168.10.211:9300 ... done ### LICENSE NOTICE Search Guard ### If you use one or more of the following features in production make sure you have a valid Search Guard license (See https://floragunn.com/searchguard-validate-license) * Kibana Multitenancy * LDAP authentication/authorization * Active Directory authentication/authorization * REST Management API * JSON Web Token (JWT) authentication/authorization * Kerberos authentication/authorization * Document- and Fieldlevel Security (DLS/FLS) * Auditlogging In case of any doubt mail to <[email protected]> ################################### Contacting elasticsearch cluster 'searchguard_demo' and wait for YELLOW clusterstate ... Clustername: searchguard_demo Clusterstate: GREEN Number of nodes: 1 Number of data nodes: 1 searchguard index does not exists, attempt to create it ... done (auto expand replicas is on) Populate config from /home/hive/elk-test/elasticsearch-5.5.0/plugins/search-guard-5/sgconfig/ Will update 'config' with /home/hive/elk-test/elasticsearch-5.5.0/plugins/search-guard-5/sgconfig/sg_config.yml SUCC: Configuration for 'config' created or updated Will update 'roles' with /home/hive/elk-test/elasticsearch-5.5.0/plugins/search-guard-5/sgconfig/sg_roles.yml SUCC: Configuration for 'roles' created or updated Will update 'rolesmapping' with /home/hive/elk-test/elasticsearch-5.5.0/plugins/search-guard-5/sgconfig/sg_roles_mapping.yml SUCC: Configuration for 'rolesmapping' created or updated Will update 'internalusers' with /home/hive/elk-test/elasticsearch-5.5.0/plugins/search-guard-5/sgconfig/sg_internal_users.yml SUCC: Configuration for 'internalusers' created or updated Will update 'actiongroups' with /home/hive/elk-test/elasticsearch-5.5.0/plugins/search-guard-5/sgconfig/sg_action_groups.yml SUCC: Configuration for 'actiongroups' created or updated Done with success