Elasticsearch curl: (52) Empty reply from server 에러

이준석·2022년 5월 11일
3

Elastic

목록 보기
1/1
post-thumbnail

서론

최근에 Elasticsearch를 사용해야 할 일이 있어서 도커로 간단하게 설치해서 사용법을 학습하고 있었다. 최신버전이 좋겠거니 생각하고 오늘 기준으로 가장 최신 버전인 8.2.0 버전을 도커 이미지로 다운받아서 실행하고 curl 명령어를 날려보았더니 이게 왠걸!! curl: (52) Empty reply from server 가 발생하면서 아무것도 나오지 않는다.

다른 블로그와 책을 찾아봤지만 설치 후 바로 curl 명령을 날리면 아무 문제없이 응답이 오고 있었다. 그래서 7.12 버전으로 낮춰서 실행해보니 curl 명령이 잘 먹히는걸 확인할 수 있었다. 그렇게 끙끙 앓다가 우연찮게 elastic 커뮤니티에서 한 유저가 사용한 curl 명령을 보고 해결할 수 있었다.

본론

진짜 curl이 안되는지 테스트

우선 가장 최신 버전인 8.2.0을 로컬에 실행시켜보기 위해 다음 명령을 터미널에 입력합니다.

docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:8.2.0

그 후에 curl 명령을 날리면 다음과 같이 에러가 발생한다.

$ curl localhost:9200
curl: (52) Empty reply from server

원인은 아직 잘 모르지만 Elasticsearch는 https 통신으로 주고 받도록 설정이 되어있는 것 같다. 그래서 찾다보면 xpack.security.enabled 값을 false 로 하라는 글들을 볼 수 있는데 보안 설정 값을 함부로 건드려서는 안될 것 같아서 원론적인 해결 방법이라고 생각하지 않았다. (xpack이 플러그인으로 제공되다가 디폴트로 탑재가 되었는데 다 이유가 있어서 한거라고 생각했다.)

curl 테스트가 되도록 해결하기

elasticsearch 도커 컨테이너 내부 접속

그럼 curl 명령을 어떻게 날려야지 정상적으로 응답을 받을 수 있을까? 먼저 도커 컨테이너 내부로 접속해야 된다. 그러기 위해서는 컨테이너 아이디를 먼저 조회해야 하는데 다음 명령어로 조회할 수 있다.

$ docker ps -a
CONTAINER ID   IMAGE                      COMMAND                  CREATED             STATUS                        PORTS                                              NAMES
0fc2c0bd8454   elasticsearch:8.2.0        "/bin/tini -- /usr/l…"   About an hour ago   Up 41 minutes                 0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp     elasticsearch

그리고 해당 컨테이너 내부를 루트 권한이 있는 계정(root)로 접속한다.

$ docker exec -it --user root 0fc2 /bin/bash

cert 파일 복사하기

접속한 뒤에 다음 경로로 들어가서 인증서 하나를 살펴볼 수 있도록 한다.

$ cat /config/certs/http_ca.crt

-----BEGIN CERTIFICATE-----
MIIFWjCCA0KgAwIBAgIVANbY7UwEMnridEDNqkp08iwRurKlMA0GCSqGSIb3DQEB
CwUAMDwxOjA4BgNVBAMTMUVsYXN0aWNzZWFyY2ggc2VjdXJpdHkgYXV0by1jb25m
aWd1cmF0aW9uIEhUVFAgQ0EwHhcNMjIwNTExMDc0MjU5WhcNMjUwNTEwMDc0MjU5
WjA8MTowOAYDVQQDEzFFbGFzdGljc2VhcmNoIHNlY3VyaXR5IGF1dG8tY29uZmln

...생략

yERrZjNJ16xrtCL/145vCUuuRJrs/Zqu0yy3jyeWeiC/Jhf/gycIia1KuxfpAde2
XyRto6N/zZ62lWP60KBeWfZaQ5y1809A9fXdn8hcrL1jbtgdKrRemugXZ+zZT6hA
WzEKCtVqqfSqIcLe6gtXLGdz7Hp1G1lsFNjT5sPrSPYsN8lQtwik71Gb9zr6+sds
/l+3QfPYwrPzSrJBm+gyFH+m0v60VaopIkG1ZbgF
-----END CERTIFICATE-----

해당 내용을 복사해서 로컬 컴퓨터에 파일을 하나 만들 수 있도록 한다.

curl 명령에 cert 파일 넣어서 해보기

그 다음 curl 명령을 다음과 같이 입력한다.

$ curl --cacert <인증서 경류>/http_ca.crt  https://localhost:9200
ex) curl --cacert /Users/junsugi/Desktop/http_ca.crt  https://localhost:9200

{"error":{"root_cause":[{"type":"security_exception","reason":"missing authentication credentials for REST request [/]","header":{"WWW-Authenticate":["Basic realm=\"security\" charset=\"UTF-8\"","Bearer realm=\"security\"","ApiKey"]}}],"type":"security_exception","reason":"missing authentication credentials for REST request [/]","header":{"WWW-Authenticate":["Basic realm=\"security\" charset=\"UTF-8\"","Bearer realm=\"security\"","ApiKey"]}},"status":401}%

입력하면 401 에러가 발생하는데 이는 아이디 패스워드를 입력하지 않아서 발생한 문제이다.
일단 여기까지 봤을때 아까는 Empty reply from server가 발생했는데 우선 통신은 되었다는걸 확인할 수 있다.

curl 테스트를 위한 계정 찾기

기본적으로 Elastic 서비스에는 elastic 이라는 아이디가 존재한다. 그리고 비밀번호는 재발급 받는게 편한거 같아서 재발급해서 인증하는 방식으로 해보겠다.

다시 elasticsearch 컨테이너 내부로 접속한 뒤 bin 폴더로 접속한다. 접속하면 다음 배치 파일 리스트를 볼 수 있다.

$ docker exec -it --user root 0fc2 /bin/bash
$ root@0fc2c0bd8454:/usr/share/elasticsearch# cd bin
$ root@0fc2c0bd8454:/usr/share/elasticsearch# ls -al
total 2964
drwxrwxr-x 1 elasticsearch root    4096 May 11 07:52 .
drwxrwxr-x 1 root          root    4096 May 11 07:59 ..
-r-xr-xr-x 1 root          root    5398 Apr 20 10:34 elasticsearch
-r-xr-xr-x 1 root          root     501 Apr 20 10:37 elasticsearch-certgen
-r-xr-xr-x 1 root          root     493 Apr 20 10:37 elasticsearch-certutil
-r-xr-xr-x 1 root          root     996 Apr 20 10:34 elasticsearch-cli
-r-xr-xr-x 1 root          root     452 Apr 20 10:37 elasticsearch-create-enrollment-token
-r-xr-xr-x 1 root          root     443 Apr 20 10:37 elasticsearch-croneval
-r-xr-xr-x 1 root          root    5897 Apr 20 13:36 elasticsearch-env
-r-xr-xr-x 1 root          root    2595 Apr 20 10:34 elasticsearch-env-from-file
-r-xr-xr-x 1 root          root     168 Apr 20 10:34 elasticsearch-geoip
-r-xr-xr-x 1 root          root     181 Apr 20 10:34 elasticsearch-keystore
-r-xr-xr-x 1 root          root     126 Apr 20 10:34 elasticsearch-node
-r-xr-xr-x 1 root          root     265 Apr 20 10:34 elasticsearch-plugin
-r-xr-xr-x 1 root          root     509 Apr 20 10:37 elasticsearch-reconfigure-node
-r-xr-xr-x 1 root          root     448 Apr 20 10:37 elasticsearch-reset-password
-r-xr-xr-x 1 root          root     441 Apr 20 10:37 elasticsearch-saml-metadata
-r-xr-xr-x 1 root          root     439 Apr 20 10:37 elasticsearch-service-tokens
-r-xr-xr-x 1 root          root     448 Apr 20 10:37 elasticsearch-setup-passwords
-r-xr-xr-x 1 root          root     118 Apr 20 10:34 elasticsearch-shard
-r-xr-xr-x 1 root          root     483 Apr 20 10:37 elasticsearch-sql-cli
-r-xr-xr-x 1 root          root 2915354 Apr 20 10:37 elasticsearch-sql-cli-8.2.0.jar
-r-xr-xr-x 1 root          root     436 Apr 20 10:37 elasticsearch-syskeygen
-r-xr-xr-x 1 root          root     436 Apr 20 10:37 elasticsearch-users
-r-xr-xr-x 1 root          root     356 Apr 20 10:37 x-pack-env
-r-xr-xr-x 1 root          root     364 Apr 20 10:37 x-pack-security-env
-r-xr-xr-x 1 root          root     363 Apr 20 10:37 x-pack-watcher-env

여기서 reset-password 배치 파일을 사용할 건데 다음과 같이 입력할 수 있도록 한다.

# bin 폴더까지 접속한 경우
elasticsearch-reset-password -u elastic

# 그 외의 상황
./bin/elasticsearch-reset-password -u elastic

This tool will reset the password of the [elastic] user to an autogenerated value.
The password will be printed in the console.
Please confirm that you would like to continue [y/N]y


Password for the [elastic] user successfully reset.
New value: eUp1Lde3Y*rWa0t9crEN  << 비밀번호

최종 curl 테스트 해보기

따라서 출력된 비밀번호를 복사해놓고 curl을 다음과 같이 입력할 수 있도록 한다.

$ curl --cacert /Users/junsugi/Desktop/http_ca.crt -u elastic https://localhost:9200
Enter host password for user 'elastic': eUp1Lde3Y*rWa0t9crEN (실제로는 안보임, 복붙하고 엔터치면됨)
{
  "name" : "0fc2c0bd8454",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "DMLiHQ_NSNGIgPusg4Apyg",
  "version" : {
    "number" : "8.2.0",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "b174af62e8dd9f4ac4d25875e9381ffe2b9282c5",
    "build_date" : "2022-04-20T10:35:10.180408517Z",
    "build_snapshot" : false,
    "lucene_version" : "9.1.0",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

이렇게하면 8.2.0 버전에서도 curl을 이용해서 Elasticsearch 상태를 확인할 수 있다.

결론

어떻게보면 중요하지 않은 부분일수도 있는데 다른 사람은 다 되는데 나만 안되니까 괜히 찝찝해서 찾아보았고 나같은 사람들도 있을꺼 같아서 적어보았습니다. 앞으로 Elastic 관련 글들을 많이 적을꺼 같아서 한번 짧게 운을 띄워보았습니다.

그럼 이만 총총.

profile
호주 워홀중 https://blog.naver.com/wnstjrl96

6개의 댓글

comment-user-thumbnail
2022년 8월 10일

이야 잘 보고갑니당

답글 달기
comment-user-thumbnail
2022년 9월 22일

감사합니다~~!

답글 달기
comment-user-thumbnail
2023년 2월 21일

안녕하세요. 독학하고 있는 유저입니다.
elasticsearch 컨테이너 내부로 접속, bin 폴더로 접속
어떻게 하는건가요 ㅠㅠㅠ

1개의 답글
comment-user-thumbnail
2023년 3월 29일

오와 잘 됩니다. 감사합니다!!

답글 달기
comment-user-thumbnail
2024년 3월 27일

큰 도움이 되었습니다. 감사합니다!!

답글 달기