Tagged: 인증서

Elasticsearch 보안 – 인증서

Elasticsearch 가 버전이 높아짐에 따라 인증서에 대한 이해가 필요하게 되었다. 사실 이 인증서가 필요한 이유가 Elastic 에서 배포하는 X-Pack 중에 Security 플러그인 때문인데, 이 Security 를 활성화 하게 되면 TCP, HTTP 통신을 TLS 통신을 하도록 강제하고 있다.

문제는 Elasticsearch 자바 기반이며, 따라서 생성하는 파일이 여느 다른 인증서와는 다른 면도 있다. ‘다른 면도 있다’ 라고 표현한 이유는 일반적인 PEM 형식의 보안키와 인증서를 모두 지원하지만 여전히 자바 세계에서만 통용되는 방법을 여전히 고수하고 있기 때문이다.

keystore 파일

최신 버전의 Elasticsearch 7 을 설치하게 되면 /etc/elasticsearch/elasticsearch.keystore 파일 하나만 생성되게 된다.

이 파일은 key/value 형식으로 계정 정보가 들어가 있다. 이 내용을 적는 이유는 Java Keystore 파일과는 다르다는 것을 말하기 위함이다. Elasticsearch 을 설치하고 나서 Security 를 활성한 후에 계정에 대한 패스워드를 작성하는 절차를 밟는다.

계정에 대한 패스워드를 자동 생성하도록 한 것인데, 이렇게 생성된 내용들은 elasticsearch.keystore 파일에 key/value 형식으로 저장된다.

이렇게 저장된 key 값들은 elasticsearch-keystore 명령어를 통해서 볼 수 있다.

PKCS#12(확장자 p12) 파일

확장자가 p12 파일을 보게 된다. 이 파일은 PKCS#12 형식의 파일인데, 인증서와 개인키를 포함한 형태의 데이터 파일이다. Elasticsearch 7 에서는 루트 인증서(CA 인증서) 와 서버 인증서를 다음과 같이 제작해 사용 한다.

elastic-stack-ca.p12 은 CA 인증서 인데, openssl 을 이용해서 PKCS12 파일을 읽어볼 수 있다.

패스워드를 입력하지 않았기 때문에 패스워드 입력 문구에서는 그냥 Enter 를 치면 된다. 그러면 위와같이 Private Key, Certificate 내용이 나온다. Certificate 부분을 따로 때어내서 파일로 저장하고 Openssl 명령어를 이용해 인증서를 읽으면 다음과 같다.

CA:TRUE 라고 명백하게 나오고 있다.

그러면 CA 인증서를 가지고 만들어진 /usr/share/elasticsearch/elastic-certificates.p12 파일도 내용을 확인해 보자.

위 내용을 보면, Private Key 1개, Certificate 2개 로 나온다. 이건 인증서 체인 파일인게 분명하다. Certificate 부분만 따로 때어서 보면 다음과 같다.

확인 결과, 하나는 인증서이고 하나는 CA 인증서인 것으로 확인된다. 그러니까 elastic-certificate.p12 파일은 Private Key, CA 인증서, 서버 인증서 이렇게 3가지를 모두 가지는 파일이다.

PEM 형식 파일

Elasticsearch 에서는 PEM 형식의 파일도 함께 지원 한다. PEM 형식은 가장 흔하게, 널리 사용되는 인증서 파일 포맷 형식이다. elasticsearch-certutil 명령어를 이용해서 작성할 수 있다.

위와같이 zip 파일 형태로 생성된다. 압축을 해제하면 다음과 같이 파일이 생성된다.

ca 디렉토리가 생성되는데, 보면 Private Key 파일과 CA 파일이 별도로 생성된 것을 알 수 있다.

이렇게 작성된 파일을 가지고 서버 인증서를 다음과 같이 생성할 수 있다.

역시나 압축된 형태의 파일로 출력이 된다. 압축을 해제해 보자.

instance.crt 인증서 파일의 내용을 살펴보자

서버 인증서임을 알수 있다.

인증서 활용

PKCS#12 형식과 PEM 형식의 인증서를 활용하는 방법은 다르다.

PKCS#12 형식은 다음과 같이 설정 한다.

PEM 형식은 다음과 같다.

SAN 인증서

지금까지 설명한 방법으로 인증서를 작성할 경우에 한가지 문제가 있을 수 있다. 이 인증서들은 SAN 인증서가 아니기 때문에 모든 도메인에서 통용될 수 있다. 앞에 인증서 내용을 보면 SAN 이 없다. 하지만 SAN 인증서라야만 하는 보안성을 요구된다면 SAN 인증서를 만들어 사용해야 한다.

SAN 인증서를 작성할때에 주의 사항은 Elasticsearch Stack 에서 사용할 모든 도메인, 혹은 IP 주소를 기재해야 한다. 그렇지 않으면 절대로 통신을 할 수가 없게 된다.

먼저, CA 인증서가 필요하다. 이 CA 인증서는 앞에 PEM 형식의 CA 인증서를 만들고 압축을 해제해 놓는다. 그리고 다음과 같이 instance.yml 파일을 작성한다.

이 파일에서 ip, dns 항목이 보이는데, 둘 중 하나만 있어도 된다. 어짜피 인증서에서 SAN 항목에서 IP Address, DNS 둘중하나가 들어가 있고 매칭이되면 인증서를 쓸 수 있다.

이제 다음과 같이 인증서를 작성해 생성한다.

정상적으로 생성이 되었을 것이다. 압축을 해제해 보자

instance.yml 파일에서 이름부분이 디렉토리로 생성되면서 각각 인증서와 key 값이 생성되어 있다. 이 인증서들은 SAN 부분이 instance.yml 에 따라서 하나의 IP, 하나의 DNS 만 들어가 있다.

SAN 이 뭔지를 안다면 굳이 이렇게 다 분리할 필요는 없다는 생각을 하게 된다. 멀티도메인 인증서를 사용하면 도메인에 *.systemv.local 처럼 생성하면 될 것이고, 그러면 하나의 인증서를 가지고 여러곳에서 함께 사용이 가능해 진다. 위 예제에서는 각각의 용도에 맞게 딱 1개의 도메인과 IP 에 한해서 허용하도록 작성되었을 뿐이다.

PEM 형식의 Key 는 PKCS#12 형식으로 사용해야할 때가 있다. 이때는 다음과 같이 openssl 명령어를 이용해서 변환할 수 있다.

letsencrypt 인증서 발급/갱신

letencrypt 는 무료로 발급 받을 수 있는 도메인 인증서이다. 도메인 인증서는 서버와 클라이언트간에 HTTP 통신을 암호화하는데 필요한 것이다. 원래는 돈을 주고 구매해야 하지만 letsencrypt 는 무료로 사용할 수 있게 해준다.

대부분의 발급 절차를 서버의 CLI 를 통해서 이루어진다. 따라서 서버가 있어야 하며 터미널 접속이 가능해야 한다. 또, Python 을 필요로 한다. 인증서를 발급 받기위해서 프로그램을 사용하는데 이것이 Python 을 필요로 한다.

certbot 설치

certbot 은 letsencrypt 인증서를 발급받기 위한 CLI 명령어 세트다. 다음과 같이 다운로드 할 수 있다.

복제된 디렉토리에는 letsencrypt 인증서를 위한 모든 내용이 포함되어 있다.

주도메인, 멀티도메인

발급 받기전에 한가지 생각해봐야 할게 있다. 인증서는 주도메인 인증서와 멀티도메인 인증서로 크게 나뉜다. 예를들면 다음과 같다.

  • systemv.pe.kr – 주도메인 인증서
  • *.systemv.pe.kr – 멀티도메인 인증서

많은 사람들이 실수하는 것이 멀티도메인 인증서를 발급받고 systemv.pe.kr 도메인으로 접속할려고 한다는 것이다. 멀티도메인 인증서의 *. 이것이 주도메인을 포함하지 않는다. 따라서 반드시 따로 도메인 인증서를 발급 받아야 한다.

수동 도메인 인증서 발급

도메인 인증서를 발급 받를때에 해줘야 하는 거이 Validation 이다. 이것이 실제로 인증서를 사용 가능한 발급요청인지를 체크한다. 이 체크를 위한 방법은 두가지가 있다.

  1. DNS TXT 레코드를 이용.
  2. HTTP 를 이용한 특정 디렉토리에 파일 접근.

멀티 도메인 인증서를 발급 받을때는 DNS TXT 레코드를 이용하는 방법이 좋다. 주도메인(단일도메인) 을 발급 받을때는 HTTP 를 이용한 파일 접근으로 유요한 요청인지를 인증하면 된다.

발급을 위해서 시스템의 슈퍼유저 계정으로 실행 한다.

위와같이 특정 디렉토리에 외부에서 접근 가능한 파일을 작성해 위에서 출력한 데이터를 작성하고 저장한다. 이렇게 한 후에 진행을 하면 Letsencrypt 에서 파일에 접근해 유요한 요청인지를 확인하고 인증서를 발급해 준다.

멀티도메인처럼 하나의 인증서로 여러 도메인을 인증하기 위해선 DNS TXT 레코드 인증을 이용하는 것이 편하다.

위와같이 하면 화면에 TXT 레코드를 입력하라는 메시지가 나온다. 그것을 다음과 같이 DNS 에 입력해 준다.

_acme-challenge.systemv.pe.kr 도메인으로 하는 TXT 를 입력해 주는 것이다. 그리고 반드시 DNS 서버를 재시작해 적용해 준다.

정상적으로 발급이 되었다면 /etc/letsencrypt/live 디렉토리에 도메인으로 디렉토리가 생성되고 인증서가 발급된다.

2022-02 내용추가

Lets Encrypt 관련해 내용이 변경되었다. 인증서를 적용하기 위한 절차는 다음과 같다.

letsencrypt 업데이트

git 로 소스를 복제했다면 시간이 지남에 따라 최신 소스가 달라진다. 다음과 같이 최신판으로 업데이트를 해준다.

한번에 멀티 도메인 인증서 발급

나는 DNS 서버를 별도로 운영하고 있다. 따라서 DNS TXT 필드를 이용해서 인증서 설정이 가능하다. 다음과 같이 하면 된다.

대상 도메인에 대해서, 위 경우에는 두개(systemv.pe.kr, *.systemv.pe.kr), DNS TXT 를 발급해 준다. 그러면 그것을 zone 파일에서 DNS TXT 에 적용해주고 DNS 서버를 재시작 해준다.

그리고 letsencrypt 의 Verify 를 해주면 적용 된다.