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
호주 워홀중

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일

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

답글 달기