Elastic Stack 또는 ELK에 Search Guard 적용하기
by 뚜부니Search Guard는 Elastic Stack을 위한 보안 및 알림 플러그인입니다. TLS 암호화, Elasticsearch 인덱스에 대한 역할 기반 액세스 제어, document 및 Field 수준 보안 제어, 감사 로깅 및 알림 기능을 제공합니다. 또한, 저장된 데이터에 대한 액세스를 암호화, 보호 및 모니터링 하는 데 필요한 도구를 제공합니다. Search Guard는 Community Edition, Enterprise Edition, Compliance Edition이 존재하며, 여기서는 무료로 제공되는 Community Edition을 사용하여 Elastic Stack의 보안 기능을 강화하는 실습을 진행하도록 하겠습니다.
00. 실습 환경
Apache 2.0 License 내에서 사용할 수 있는 기능만 포함된 OSS 버전을 활용하여 실습하였습니다.
- CentOS 7.9
- Elasticsearch 7.10.2
- Logstash 7.10.2
- Kibana 7.10.2
- Search Guard 53.5.0
- Search Guard Kibana Plugin 53.0.0
- Java 11
본 게시글에는 Elastic Stack 구축 방법에 대한 설명은 포함되어 있지 않습니다. Search Guard 설치 버전은 공식 홈페이지에서 확인해주세요. 여기서는 windows 환경에서 다운로드 받은 파일을 CentOS 서버에 업로드 하여 사용하였습니다.
01. Elasticsaerch에 적용하기
Java 설치하기
Search Guard
를 사용하기 위해서는 java가 설치되어 있어야 합니다. 해당 과정은 sudo -i
를 통해 관리자 모드로 변경하여 진행해주세요.
먼저, 설치할 수 있는 java 버전을 확인합니다.
yum list java*jdk-devel
그러면 다음과 같이 설치 가능한 목록이 화면에 표출됩니다.
이 중 java 11 버전을 설치합니다.
yum install -y java-11-openjdk-devel.x86_64
설치가 완료되면 java --version
명령어를 통해 정상적으로 설치되었는지 한 번 더 확인해주세요. 정상 설치되었다면 다음과 같은 문구가 화면에 뜹니다.
openjdk 11.0.8 2020-07-14 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.8+10-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.8+10-LTS, mixed mode, sharing)
그 다음 JAVA_HOME
으로 환경 변수를 설정해줍니다.
먼저, java의 실행 파일 경로를 확인합니다.
which java
그러면 다음과 같은 링크가 뜹니다.
/usr/bin/java
해당 링크는 심볼릭 링크이므로 아래 명령어를 통해 원본 링크를 찾아줍니다.
readlink -f /bin/java
명령을 통해 찾은 원본 링크는 다음과 같습니다.
/usr/lib/jvm/java-11-openjdk-11.0.8.10-1.el7.x86_64/bin/java
원본 링크를 사용해 JAVA_HOME
환경 변수를 등록합니다.
echo "export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.8.10-1.el7.x86_64" >> /etc/profile && source /etc/profile
JAVA-HOME
환경 변수가 등록이 잘 되었는지 확인해봅시다.
echo $JAVA_HOME
설정한 path가 화면에 뜨면 정상적으로 설정이 된 것입니다. 설정이 완료되었으니, exit
을 통해 관리자 모드를 종료합니다.
Search Guard TLS Tool로 인증서 생성하기
::: tip
인증서 생성은 하나의 서버에서 진행하면 됩니다. 동일한 인증서를 가지고 있어야 하기 때문에, 하나의 서버에서 생성한 다음 다른 서버에 복사해야 합니다.
저는 Elasticsearch node-1
서버에 생성하였습니다.
:::
이제 Search Guard TLS Tool
를 설치 및 설정해보겠습니다.
먼저, Search Guard TLS Tool
을 다운로드 받습니다. 저는 Windows 10 서버에서 공식 홈페이지에서 Search Guard TLS Tool
을 클릭하여 다운로드 받은 후, CentOS 서버의 /etc/elasticsearch
내로 업로드 하였습니다.
/etc/elasticsearch
에 추가한 이유는, 인증서를 elasticsearch.yml
이 있는 위치에서 상대 경로로 접근하기 쉬운 위치에 두기 위해서 입니다. SearchGuard
설정을 elasticsearch.yml
에 추가할 때 상대 경로로 해야 하기 때문입니다.
sudo -i
를 통해 관리자 모드로 변경한 다음, CentOS 서버에 접속하여 /etc/elasticsearch
로 이동합니다.
cd /etc/elasticsearch
그 다음 zip 파일을 압축 해제합니다.
unzip -d ./search-guard-tlstool search-guard-tlstool-1.9.1.zip
이 때, unzip: command not found
가 발생하면 unzip
을 설치한 다음 진행해주세요.
yum install unzip
설치가 완료되면, search-guard-tlstool
의 config
디렉터리로 이동합니다.
cd ./search-guard-tlstool/config
config
디렉터리를 살펴보면,
그 다음 기본적으로 제공되는 template.yml
을 복사하여 TLS Tool 설정 파일을 생성합니다.
cp template.yml tlsconfig.yml
이제 tlsconfig.yml
파일을 열고 공식 홈페이지를 참고하여 내용을 수정합니다.
공식 문서에서 intermediate ca
에 대해 다음과 같이 설명합니다. 그렇기에 여기서는 intermediate ca
설정은 제외하고 구성하였습니다.
In addition to the root CA you optionally also specify an intermediate CA.
수정한 tlsconfig.yml
내용은 다음과 같습니다.
ca:
root:
dn: CN=root, OU=monitoring, O=monitoring
keyzise: 2048
validitDays: 3650
pkPassword: root-monitoring
file: root-ca.pem
defaults:
validitDays: 3650
pkPassword: monitoring
httpsEnabled: true
reuseTransportCertificatesForHttp: true
nodes:
- name: node-1
dn: CN=node-1, OU=monitoring, O=monitoring
ip: 10.0.0.1
- name: node-2
dn: CN=node-2, OU=monitoring, O=monitoring
ip: 10.0.0.2
- name: node-3
dn: CN=node-3, OU=monitoring, O=monitoring
ip: 10.0.0.3
- name: node-4
dn: CN=node-4, OU=monitoring, O=monitoring
ip: 10.0.0.4
- name: node-5
dn: CN=node-5, OU=monitoring, O=monitoring
ip: 10.0.0.5
clients:
- name: admin
dn: CN=admin, OU=monitoring, O=monitoring
admin: true
httpsEnabled
는 REST 계층에서 TLS를 활성화할지 입력합니다. 그리고 reuseTransportCertificatesForHttp
는 REST 와 Transport에 대해 동일한 인증서를 생성할지를 입력하며, false로 설정할 경우 transport와 rest에 대한 인증서가 각각 생성됩니다.
dn
을 설정할 때, CN
은 중복되지 않은 고유한 이름으로 설정합니다. nodes
설정은 Elasticsearch 노드 설정에 맞게 입력하면 됩니다. 그리고 clients
의 name
에 입력한 admin
은 admin 권한을 가진 Kibana 사용자로 생성해야 합니다. Kibana 사용자 생성 관련 내용은 Kibana 설정 부분에서 다루도록 하겠습니다.
이제 인증서를 생성해보겠습니다. 참고로, 현재 위치는 /etc/elasticsearc/search-guard-tlstool/config
입니다.
# 인증서 보관할 디렉터리 생성
mkdir ../../certs
# 인증서 생성
../tools/sgtlstool.sh -c ./tlsconfig.yml -ca -crt -t ../../certs
인증서를 생성 및 저장할 디렉터리로 certs
를 생성한 다음 인증서를 생성하였습니다. 만약 -t ../certs
를 명령어에 입력하지 않는다면, 보관할 디렉터리를 생성하지 않아도 됩니다. 왜냐하면, default로 out
이라는 디렉터리에 인증서를 생성 및 저장하기 때문입니다.
-c
:-config
, 뒤에 설정 파일 경로 입력 필수-ca
:-create-ca
, CA 생성-crt
:-create-cert
, 로컬 인증 기관을 통해 인증서 생성-t
:-target
, 인증서 생성 위치 지정. (default : out)
정상적으로 생성되었는지 확인해봅시다.
# 인증서 생성한 디렉터리로 이동
cd /etc/elasticsearch/certs
# 목록 보기
ls
그러면 다음과 같이 인증서들이 생성된 것을 확인할 수 있습니다.
인증서가 제대로 생성되었는지 확인해봅시다.
저는 실수로 ip 필드 앞에 주석(#)을 입력하여 일부 인증서가 정상적으로 생성되어 있지 않았습니다.
../search-guard-tlstool/tools/sgtlsdiag.sh -ca ./root-ca.pem -crt ./node-1.pem
node-1.pem
인증서를 확인했을 때, 다음과 같이 표출되면 정상적으로 생성된 것입니다.
이제 인증서 생성이 완료되었으므로 exit
명령어를 통해 관리자 모드를 종료합니다.
그 다음 생성한 certs를 각 Elasticsearch 서버에 옮겨줍니다.
Search Guard 플러그인 설정
Elasticsearch에 Search Guard를 설치하기 전, 엘라스틱서치의 모든 노드를 중지합니다. 만약, 대규모 클러스터로 구성되어 있고 샤드 할당이 되어 있다면 노드 중지 전에 비활성화 해주세요.
sudo -i service elasticsearch stop
그 다음, 엘라스틱서치 각 노드에 Search Guard 플러그인을 설치합니다.
sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install file:///home/monitoring/search-guard-suite-plugin-7.10.2-53.5.0.zip
여기서 /usr/share/elasticsearch/bin
은 일반적으로 CentOS에서 elasticsearch-plugin
이 존재하는 위치이며, file://
뒤에 있는 /home/monitoring/search-guard-suite-plugin-7.10.2-53.5.0.zip
은 설치하려는 Search Guard 파일의 위치 및 zip 파일입니다.
명령어를 입력하면 다음 그림과 같은 문구를 확인할 수 있으며, Continue with installation? [y/N]
에 대해 y
를 입력하면 됩니다.
-> Installed search-guard-7
과 같은 문구가 뜨면 설치가 완료된 것입니다.
설치가 완료되었다면, /etc/elasticsearch/elasticsearch.yml
파일에 Search Guard 설정을 추가합니다.
아래 내용은 node-1
서버에서 설정한 내용이며, /etc/elasticsearch/certs/node-1_elasticsearch_config_snippet.yml
을 참고하여 작성했습니다.
# Disable enterprise settings to use only the community version that is free.
searchguard.enterprise_modules_enabled: false
#
# SSL/TLS
searchguard.ssl.transport.pemcert_filepath: certs/node-1.pem
searchguard.ssl.transport.pemkey_filepath: certs/node-1.key
searchguard.ssl.transport.pemkey_password: monitoring
searchguard.ssl.transport.pemtrustedcas_filepath: certs/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: certs/node-1.pem
searchguard.ssl.http.pemkey_filepath: certs/node-1.key
searchguard.ssl.http.pemkey_password: monitoring
searchguard.ssl.http.pemtrustedcas_filepath: certs/root-ca.pem
searchguard.nodes_dn:
- "CN=node-1,OU=monitoring,O=monitoring"
- "CN=node-2,OU=monitoring,O=monitoring"
- "CN=node-3,OU=monitoring,O=monitoring"
- "CN=node-4,OU=monitoring,O=monitoring"
- "CN=node-5,OU=monitoring,O=monitoring"
searchguard.authcz.admin_dn:
- "CN=admin,OU=monitoring,O=monitoring"
searchguard.enterprise_modules_enabled: false
설정은 SearchGuard Enterprise를 비활성화 한 것입니다. 무료 버전인 Community Edition
만을 사용하기 위해서는 반드시 비활성화 해야 합니다. searchguard.ssl.transport
는 SearchGuard의 SSL/TLS
설정입니다.
현재 사용하는 Elasticsearch가 OSS 버전이 아닌 경우, xpack.security.enabled: false
설정도 해야 합니다.
모든 경로는 반드시 상대 경로로 입력해주세요. 그러지 않으면, access denied
이 발생합니다.
설정이 완료되었으므로 Elasticsearch를 재시작합니다.
sudo -i service elasticsearch start
sgconfig 알아보기
사용자 생성 및 권한을 부여하기 전, sgconfig
디렉터리에 존재하는 파일에 대해 간단히 살펴보도록 하겠습니다. 참고로 제가 살펴볼 sgconfig
전체 경로는 /usr/share/elasticsearch/plugins/search-guard-7/sgconfig
입니다.
sg_action_groups.yml
sg_action_groups.yml
은 action group에 대한 설정 파일입니다. 그리고 action group은 permission(권한)의 모음이라고 이해하면 됩니다.
MY_ACTION_GROUP: # action group name
reserved: false # optional. 예약어 설정 여부. (default: false)
allowed_actions:
- "<permission or action group>"
- ...
type: "index" # optional. action group 타입. index 외에 cluster, kibana 등 존재.
description: "..." # optional. action group에 대한 설명
sg_blocks.yml
sg_blocks.yml
은 화이트 리스트(verdict: allow
) 또는 블랙 리스트(verdict: disallow
)에 대한 설정 파일입니다.
sg_config.yml
sg_config.yml
은 Search Guard 기본 설정입니다.
sg_config:
dynamic:
http:
anonymous_auth_enable: false
...
authc: ...
authz: ...
여기서 dynamic.http.anonymous_auth_enable: false
는 익명 인증 설정이며, 기본 설정은 false
입니다. 상세한 내용은 공식 문서를 참고하시길 바랍니다.
기본적으로 제공되는 설정 중 현재 사용하려는 community 버전에서 미지원하는 항목은 다음과 같습니다.
dynamic.kibana
dynamic.http.auth_token_provider
dynamic.http.authc
일부 타입 : ldap, kerberos, jwt, openid, saml, sg_auth_tokendynamic.http.authz
일부 타입 : ldap
그리고 필수가 아닌 필드는 다음과 같습니다.
dynamic.http.xff
dynamic.http.auth_failure_listeners
: 무차별 암호 입력 방지를 위한 설정
더 자세한 설명은 공식 문서와 마이그레이션 관련 글 참고하시길 바랍니다.
sg_internal_users.yml
sg_internal_users.yml
은 internal user database에 사용자 및 해시로 변환한 비밀번호를 설정하는 파일입니다. Search Guard에서는 BCrypt를 사용하여 비밀번호를 해시합니다. 더 상세한 내용은 공식 문서를 참고하시길 바랍니다.
username: # user name
hash : <hashed password> # BCrypt를 사용하여 해시된 비밀번호
search_guard_roles:
- <rolename> # search guard role과 직접 연결
backend_roles:
- <backend rolename> # sg_roles_mapping.yml에서 설정한 backend_roles와 연결됨
attributes: # Optional. 사용자에 대한 추가 정보 설정
key: value
description: "..." # Optional. user에 대한 설명
search_guard_roles
와 backend_roles
둘 중 하나만 사용해도 되며, 사용하려는 시스템에 맞춰 설정하면 됩니다.
attributes
를 사용하려면 sg_config.yml
의 map_db_attrs_to_user_attrs
에 추가해야 합니다. 아래 설정 외 다른 설정이 궁금하시다면, 공식 문서를 참고하시길 바랍니다.
basic_internal_auth_domain:
http_enabled: true
order: 1
http_authenticator:
type: basic
challenge: true
authentication_backend:
type: internal
config:
map_db_attrs_to_user_attrs:
dbfield: mappingfield # <실제 DB에 저장될 필드명> : <매핑할 필드명> 순서로 입력.
map_db_attrs_to_user_attrs
를 작성할 때, 매핑할 필드명인 mappingfield는 위에서 입력한 attributes의 key와 동일해야 합니다.
sg_roles.yml
sg_roles.yml
은 역할 및 관련 권한에 대한 설정 파일입니다. 상세한 내용은 공식 문서를 참고하시길 바랍니다.
ROLE_NAME: # role name
cluster_permissions: # cluster 수준에서 적용되는 권한
- '<action group or single permission>'
- ...
index_permissions: # index 수준에서 적용되는 권한
- index_patterns: # index 패턴 정의. 와일트 카드와 정규식 표현 사용 가능
- <index pattern the allowed actions should be applied to>
- ...
allowed_actions: # 설정한 패턴에 대해 허용할 action
- '<action group or single permission>'
- ...
dls: # Community 지원 X
fls: # Community 지원 X
- index_patterns:
- ...
tenant_permissions: # Community 지원 X
sg_roles_mapping.yml
sg_roles_mapping.yml
은 사용자, 호스트 등을 역할에 매핑하기 위한 파일입니다. 상세한 내용은 공식 문서를 참고하시길 바랍니다.
ROLE_NAME: # search guard role name
users:
- <username>
- ...
backend_roles:
- <backend rolename>
- ...
hosts:
- <hostname>
- ...
만약 users
필드에서 사용자를 설정하였다면, sg_internal_users.yml
에 추가하지 않아도 됩니다.
sg_tenants.yml
sg_tenants.yml
은 Kibana Access 구성을 위한 tenats를 정의하는 파일입니다. Community 버전을 지원하지 않기에 상세한 설명은 넘어가도록 하겠습니다.
role 관계 이해하기
role
에 대한 개념을 좀 더 이해하기 쉽도록 다음과 같이 그림으로 정리해두었습니다.
sg_internal_user.yml
의 backend_roles
는 sg_role_mapping.yml
과 연결됩니다.
그리고 sg_role_mapping.yml
은 sg_role.yml
과 연결됩니다.
다음과 같이 sg_role_mapping.yml
과 sg_internal_user.yml
을 작성한 경우, devadmin
이라는 이름을 가진 사용자는 admin
이라는 backend_roles
에 연결된 SGS_ALL_ACCESS
라는 역할에 대한 권한을 가지게 됩니다.
# sg_role_mapping.yml
SGS_ALL_ACCESS:
backend_roles:
- "admin"
# sg_internal_user.yml
devadmin:
hash: <password>
backend_roles:
- "admin"
만약, backend_roles
를 거치지 않고 바로 Search Guard Role과 연결하려면 다음과 같이 sg_internal_user.yml
을 설정해도 됩니다.
devadmin:
hash: <password>
search_guard:
- SGS_ALL_ACCESS
user 내에서 이러한 권한에 대한 설정을 주고 싶지 않은 경우, sg_role_mapping.yml
과 sg_internal_user.yml
을 다음과 같이 설정할 수도 있습니다.
# sg_role_mapping.yml
SGS_ALL_ACCESS:
users:
- "devadmin"
# sg_internal_user.yml
devadmin:
hash: <password>
사용자 생성 및 권한 부여하기
이제 admin
이라는 이름의 사용자를 생성해보도록 하겠습니다. 관리자 모드(sudo -i
)로 접속해주세요.
그 전에 sgconfig.yml
을 설정하도록 하겠습니다.
먼저 파일 내용 중 community 버전에서 지원하지 않는 모듈 관련 필드를 삭제하겠습니다.
dynamic.kibana
dynamic.http.auth_token_provider
dynamic.http.authc
일부 타입 : ldap, kerberos, jwt, openid, saml, sg_auth_tokendynamic.http.authz
일부 타입 : ldap
참고로, community 버전임에도 sg_auth_token
과 관련된 설정이 있으면 아래와 같은 내용이 로그 파일에 계속 쌓이게 됩니다.
Unable to initialize auth domain sg_issued_jwt_auth_domain=AuthcDomain [http_enabled=false, transport_enabled=true, order=1, http_authenticator=HttpAuthenticator [challenge=false, type=sg_auth_token, config={}], authentication_backend=AuthcBackend [type=sg_auth_token, config={}], description=Authenticate via Json Web Tokens issued by Search Guard, skip_users=[]] due to ElasticsearchException[Can not load 'sg_auth_token' because enterprise modules are disabled]
org.elasticsearch.ElasticsearchException: Can not load 'sg_auth_token' because enterprise modules are disabled
지원하지 않는 필드를 삭제하면 다음과 같이 정리됩니다.
_sg_meta:
type: "config"
config_version: 2
sg_config:
dynamic:
http:
anonymous_auth_enabled: false
xff:
enabled: false
internalProxies: '192\.168\.0\.10|192\.168\.0\.11' # regex pattern
#internalProxies: '.*' # trust all internal proxies, regex pattern
#remoteIpHeader: 'x-forwarded-for'
authc:
basic_internal_auth_domain:
description: "Authenticate via HTTP Basic against internal users database"
http_enabled: true
transport_enabled: true
order: 4
http_authenticator:
type: basic
challenge: true
authentication_backend:
type: internal
proxy_auth_domain:
description: "Authenticate via proxy"
http_enabled: false
transport_enabled: false
order: 3
http_authenticator:
type: proxy
challenge: false
config:
user_header: "x-proxy-user"
roles_header: "x-proxy-roles"
authentication_backend:
type: noop
clientcert_auth_domain:
description: "Authenticate via SSL client certificates"
http_enabled: false
transport_enabled: false
order: 2
http_authenticator:
type: clientcert
config:
username_attribute: cn #optional, if omitted DN becomes username
challenge: false
authentication_backend:
type: noop
# auth_failure_listeners:
# ip_rate_limiting:
# type: ip
# allowed_tries: 10
# time_window_seconds: 3600
# block_expiry_seconds: 600
# max_blocked_clients: 100000
# max_tracked_clients: 100000
# internal_authentication_backend_limiting:
# type: username
# authentication_backend: intern
# allowed_tries: 10
# time_window_seconds: 3600
# block_expiry_seconds: 600
# max_blocked_clients: 100000
# max_tracked_clients: 100000
그리고 tenants 설정도 community 버전에서 지원하지 않으므로 sg_tenants.yml
파일의 내용은 모두 지워줍니다.
사용자 생성을 하기 전, 사용자에게 부여할 역할을 생성해야 합니다. Search Guard에서 기본적으로 제공되는 role을 최대한 활용하려고 합니다. 그러나 SGS_LOGSTASH
역할만으로는 logstash에서 elasticsearch에 데이터를 저장할 수 없기 때문에, sg_roles.yml
파일에 logstash를 위한 역할을 생성하도록 하겠습니다.
sg_logstash:
cluster_permissions:
- SGS_CLUSTER_MONITOR
- SGS_CLUSTER_COMPOSITE_OPS
- SGS_CLUSTER_MANAGE_INDEX_TEMPLATES
- SGS_CLUSTER_MANAGE_ILM
- SGS_CLUSTER_MANAGE_PIPELINES
index_permissions:
- index_patterns:
- '*'
allowed_actions:
- "indices:admin/get" # 추가: 인덱스 정보 조회 권한
- "indices:admin/auto_create" # 추가: 인덱스 자동 생성 권한
- "indices:data/write/index" # 추가: 데이터 쓰기(index)
- "indices:data/write/bulk[s]" # 추가: 데이터 쓰기(bulk)
- "indices:admin/mapping/auto_put" # 추가: 인덱스 매핑 자동 생성 권한
- index_patterns:
- 'logstash-*'
allowed_actions:
- SGS_CRUD
- SGS_CREATE_INDEX
- SGS_MANAGE
- index_patterns:
- '*beat*'
allowed_actions:
- SGS_CRUD
- SGS_CREATE_INDEX
- SGS_MANAGE
그 외 역할을 Search Guard에서 기본적으로 제공하는 role을 그대로 활용하여 sg_role_mapping.yml
을 작성하였습니다.
SGS_ALL_ACCESS:
reserved: true
backend_roles:
- "admin"
SGS_OWN_INDEX:
reserved: false
users:
- "*"
sg_logstash:
users:
- logstash
SGS_KIBANA_USER:
reserved: false
backend_roles:
- "kibanauser"
SGS_READALL:
reserved: true
backend_roles:
- "readall"
SGS_MANAGE_SNAPSHOTS:
reserved: true
backend_roles:
- "snapshotrestore"
SGS_KIBANA_SERVER:
reserved: true
users:
- "kibanaserver"
SGS_ALL_ACCESS
: 모든 인덱스와 모든 클러스터에 대한 권한을 부여함.SGS_OWN_INDEX
: 인증된 사용자의 사용자 이름을 따른 인덱스에 대한 전체 권한을 부여함.SGS_KIBANA_USER
: 일반 Kibana 사용자에 대한 최소 권한을 가지며, 인덱스에 대한 READ 권한은 따로 부여해주어야 함SGS_READALL
: 모든 인덱스에 대한 읽기 권한은 있지만 쓰기 권한은 없음SGS_MANAGE_SNAPSHOTS
: 스냅샷, 복원 및 리포지토리 작업에 대한 전체 권한을 부여함.SGS_KIBANA_SERVER
: 모든 인덱스에 대한 읽기 권한 뿐만 아니라 Kibana 대시보드, 시각화, 검색 등의 권한을 부여함.
마지막으로 sg_internal_user.yml
을 작성하도록 하겠습니다. 이 때,{password}
는 실제로 입력할 password를 BCrypt 변환 사이트를 통해 해시한 값으로 작성해야 합니다.
admin:
hash: "{password}"
reserved: true
backend_roles:
- "admin"
description: "admin user"
kibanaserver:
hash: "{password}"
reserved: true
description: "kibanaserver user"
logstash:
hash: "{password}"
reserved: false
description: "logstash user"
설정한 내용이 적용되도록 sgadmin.sh
를 실행하기 위해 tools
디렉터리로 이동합니다.
그 다음, sgadmin.sh
를 실행할 수 있도록 권한을 변경합니다.
chmod +x sgadmin.sh
권한을 변경하였으면, sgadmin.sh
를 실행하여 아래와 같이 PEM 인증서로 기본 구성을 적용합니다.
./sgadmin.sh -cd ../sgconfig/ -cacert /etc/elasticsearch/certs/root-ca.pem -cert /etc/elasticsearch/certs/admin.pem -key /etc/elasticsearch/certs/admin.key -keypass monitoring -nhnv -icl
cacert
: root PEM 파일 입력cert
: Client의admin
권한을 가진 PEM 파일 입력key
: Client의admin
권한을 가진 KEY 파일 입력keypass
: Client의admin
권한의 파일에 대한 비밀번호 입력
실행이 성공적으로 완료되면 다음과 같은 마지막에 success
가 화면에 표출됩니다.
모든 설정이 완료되었으므로 exit
명령어를 통해 관리자 모드를 종료합니다.
정상적으로 동작하는지 curl
호출을 통해 확인해보도록 하겠습니다.
curl -k -u admin -X GET "https://localhost:9200"
위와 같이 명령어를 입력하면 admin
사용자에 대한 password를 입력하라고 뜹니다.
Enter host password for user 'admin':
password를 입력하면 다음과 같이 엘라스틱서치 정보가 화면에 표출됩니다.
{
"name" : "node-1",
"cluster_name" : "monitoring",
"cluster_uuid" : "cluster_uuid",
"version" : {
"number" : "7.10.2",
"build_flavor" : "oss",
"build_type" : "rpm",
"build_hash" : "build_hash",
"build_date" : "2021-01-13T00:42:12.435326Z",
"build_snapshot" : false,
"lucene_version" : "8.7.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
02. Kibana에 적용하기
Search Guard 적용 전, Kibana를 종료합니다.
sudo systemctl stop kibana
그리고 Kibana optimization process is shaky 관련 이슈가 발생하지 않도록 node.options
파일을 수정합니다. 이 때, 메모리의 50% ~ 60% 정도로 설정합니다. 현재 사용 중인 서버의 Memory가 32GB여서 16GB(8192MB)를 할당해주었습니다.
## max size of old space in megabytes
--max-old-space-size=8192
Search Guard 적용을 위해 키바나에 Search Guard 플러그인을 설치합니다. 저는 미리 zip 파일을 서버에 업로드하여 사용하였습니다.
sudo /usr/share/kibana/bin/kibana-plugin install file:///home/monitoring/search-guard-kibana-plugin-7.10.2-53.0.0.zip --allow-root
그리고 이전에 만들었던 cert
중 admin
(client) 관련 파일과 root-ca
관련 파일을 kibana.yml
이 존재하는 디렉터리에 추가합니다. 파일 구조는 다음과 같습니다.
etc
├─ certs
│ ├─ admin.key
│ ├─ admin.pem
│ ├─ root-ca.key
│ └─ root-ca.pem
├─ kibana.yml
└─ node.options
이 중 kibana.yml
을 다음과 같이 수정하여 Search Guard를 적용하도록 하겠습니다.
elasticsearch.hosts: ["https://10.0.0.1:9200", "https://10.0.0.2:9200", "https://10.0.0.3:9200", "https://10.0.0.4:9200", "https://10.0.0.5:9200"]
elasticsearch.username: "kibanaserver"
elasticsearch.password: "password"
elasticsearch.ssl.verificationMode: none
elasticsearch.hosts
: Elasticsearch에 TLS/SSL이 적용되었으므로https
라고 작성elasticsearch.username
:SGS_KIBANA_SERVER
권한을 가진 사용자에 대한 이름elasticsearch.password
:SGS_KIBANA_SERVER
권한을 가진 사용자에 대한 passwordelasticsearch.ssl.verificationMode: none
: 인증서 유효성 검사를 하지 않도록none
으로 설정
설정 변경이 완료되었으면, kibana를 실행합니다.
sudo systemctl start kibana
아래 명령어를 통해 정상 실행 되었는지 확인해봅시다.
sudo systemctl status kibana
정상 실행되면 다음과 같이 표출됩니다.
그리고 5601 포트로 접속해보면 아래와 같이 로그인 페이지가 화면에 뜹니다.
공식 문서를 참고하여 로그인 페이지를 커스텀해보도록 하겠습니다. kibana.yml
에 다음 설정을 추가하여 Search Guard
의 로고를 삭제해봅시다.
searchguard.basicauth.login.showbrandimage: false
그 다음 kibana를 재실행하면, 아래와 같이 로고가 삭제된 것을 확인할 수 있습니다.
03. Logstash 설정하기
먼저 logstash 설정 파일을 불러올 수 있도록 pipelines.yml
을 설정합니다.
- pipeline.id: main
path.config: "/etc/logstash/conf.d/main.conf"
그 다음 main.conf
를 생성하고 다음과 같이 logstash를 설정합니다. input.log
는 테스트를 위해 임의로 구성한 파일입니다.
input {
file {
path => "/etc/logstash/test/input.log"
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
output {
elasticsearch {
hosts => ["https://10.0.0.1:9200", "https://10.0.0.2:9200", "https://10.0.0.3:9200", "https://10.0.0.4:9200", "https://10.0.0.5:9200"]
index => "test"
user => "logstash"
password => "logstash_password"
ssl => true
cacert => "/etc/logstash/root-ca.pem" # Elasticsearch path
}
}
logstash의 각 설정에 대한 내용은 다음과 같습니다.
input
: 입력 설정file
: 파일을 입력 받음 명시path
: 입력 받을 파일 경로start_position
: 파일을 불러들이는 위치sincedb_path => "/dev/null"
: 파일을 어디까지 읽었는지 기록하는 파일 경로이며,dev/null
로 설정 시 파일을 어디까지 읽었는지 기록하지 않음
output
: 출력 설정elasticsearch
: elasticsearch로 출력함을 병시hosts
: elasticsearch host 목록index
: logstash에서 elasticsearch로 출력할 때 저장할 인덱스 명user
: searchguard에 설정한 logstash 사용자 명password
: searchguard에 설정한 logstash 사용자의 패스워드ssl => true
: elasticsearch와의 통신을https
로 하기 위해true
로 설정cacert
:root-ca.pem
이 위치하는 경로 (root-ca.pem
은 이전에 생성한 파일 업로드)
설정을 완료한 다음 logstash를 실행합니다.
sudo systemctl start logstash
그 다음 Kibana > DevTools
에 접속하여 인덱스가 생성되었는지 확인해보기 위해 아래 명령어를 입력합니다.
GET _cat/indices
참고
- https://docs.search-guard.com/7.x-53/search-guard-installation
- https://docs.search-guard.com/7.x-53/search-guard-community-edition
- https://docs.search-guard.com/7.x-53/offline-tls-tool
- https://gomsg.tistory.com/30
- https://ye5ni.tistory.com/152
- https://www.infracody.com/2022/05/centos-7-yum-install-java-openjdk-11.html
- https://forum.search-guard.com/t/tls-configuration-error-in-elasticsearch/1951/3
- https://docs.search-guard.com/7.x-53/configuring-tls
- https://search-guard.com/generating-certificates-tls-tool/
- https://gryzli.info/2018/12/01/elasticsearchelk-stack-security-howto/#3_Stop_ElasticSearch_server_on_your_cluster_nodes
- https://docs.search-guard.com/7.x-53/sgadmin-basic-usage#prerequisites
- https://docs.search-guard.com/7.x-53/search-guard-index
- https://docs.search-guard.com/7.x-53/action-groups
- https://docs.search-guard.com/7.x-53/authentication-authorization
- https://docs.search-guard.com/latest/config-migration-feature-map
- https://docs.search-guard.com/7.x-53/internal-users-database
- https://docs.search-guard.com/7.x-53/roles-permissions
- https://docs.search-guard.com/7.x-53/mapping-users-roles
- https://docs.search-guard.com/7.x-53/kibana-plugin-installation
- https://yongho1037.tistory.com/737
- https://docs.search-guard.com/7.x-53/kibana-login-customizing
- https://search-guard.com/beats-logstash-searchguard/
'Elastic Stack (ELK)' 카테고리의 다른 글
Elastic Stack 또는 ELK에 OpenDistro Security 적용하기 (0) | 2024.11.13 |
---|---|
Logstash에서 Elasticsearch 인덱스 한국 시간(KST) 추가해서 생성하기 (0) | 2024.11.11 |
CentOS에서 Elasticsearch 운영 환경 설정하기 (0) | 2024.11.09 |
Elasticsearch Cluster 설정하기 (0) | 2023.06.11 |
CentOS 환경에 Elastic Stack 구축하기 (0) | 2023.05.09 |
블로그의 정보
개발하는 두부
뚜부니