메뉴 건너뛰기

Bigdata, Semantic IoT, Hadoop, NoSQL

Bigdata, Hadoop ecosystem, Semantic IoT등의 프로젝트를 진행중에 습득한 내용을 정리하는 곳입니다.
필요한 분을 위해서 공개하고 있습니다. 문의사항은 gooper@gooper.com로 메일을 보내주세요.


*출처 : https://blog.lael.be/post/5107


웹은 계속 발전하고 있으며, 여러 새로운 기술이 끊임 없이 등장하고 있다.

이 글에서는 웹 기술 중 하나인 SSL (Secure Socket Layer) 에 대해서 이야기 해 보고자 한다.

ssl1

< 그림 : OSI Model 에서 SSL 의 위치 >

 

정확히 말해서 SSL 은 전송계층과 (Transport Layer) 응용계층 (Application Layer) 사이에서 동작한다. Transport 에서 패킷을 받으면 -> SSL 에서 패킷의 암호를 해독하고 -> Application 에게 전달하는 것이다.

SSL 을 세션계층(Layer 5), 표현계층(Layer 6)으로 분류하는 사람도 있고, 응용계층(Layer 7)으로 분류하는 사람도 있다. 나름대로 주장에 대한 근거가 일리 있으니 여기서는 따로 정확히 분류하지는 않겠다. 확실한건 Transport 와 Application 의 사이라는 것.

 


I) 어떻게 SSL 은 암호화 통신을 하는가?

- 쉽게 말하자면 SSL 은 “보안인증서” 라고 말할 수 있다.

- 사람으로 비유하자면 보안인증서 암호화코드가 내장된 주민등록증이라고 볼 수 있다.
요즘 대부분의 편의점이나 술집에서는 주민등록증 진위여부 판독기를 가지고 있다.

- 암호학에서 “비대칭키 암호화 방식” 이라는 것이 있다. 어떤 문자를 A 로 암호화하면 B 로만 해독할 수 있는 것이다.
일반적으로 암호화에 사용하는 것을 “암호화키” 라고 부르며 이것은 암호통신에서 공개되기 때문에 “공개키” 또는 “공개 암호화키”, “Public Key” 라고도 부른다.

참조 (RSA_암호) : https://ko.wikipedia.org/wiki/RSA_%EC%95%94%ED%98%B8

ssl2

[1] 클라이언트가 서버에 접속한다.

[2] 서버가 보안인증서를 제공한다.

[3] 클라이언트가 서버가 제출한 보안인증서의 유효성을 파악한다. 최상위 발급 기관과 통신하여 유효성을 확인한다. (최상위 발급기관은 운영체제 또는 웹브라우저에 미리 정의되어 있다.)

ssl-161024

< 그림 : 서버에서 제공한 인증서가 유효하지 않다면 클라이언트는 검증오류로 인해 통신을 중단한다 >

[4] 보안인증서가 유효하면 인증서에 쓰여져 있는 공개 암호화키 A 를 사용하여 클라이언트 자신의 공개 암호화키 C 를 암호화 하여 전송한다.

[5] 서버는 전송된 암호화 구문을 자신만 가지고 있는 해독키(개인 비밀키) B 를 통해서 해독한다.

[6] 해독한 메세지가 유효한 요청이고 클라이언트의 공개 암호화키 C 를 포함하고 있다면 암호화키 C 를 사용하여 잘 받았다는 메세지를 암호화해서 응답한다.

[7] 클라이언트는 자신만 가지고 있는 해독키(개인 비밀키) D 를 통해서 해독한다. 서버에서 받은 응답 메시지가 유효하다면 클라이언트는 A 를 통해 암호화해서 메세지를 보내고, 서버는 C 를 통해 암호화해서 메세지를 보낸다. A키로 암호화된 메세지는 B키로만 해독이 가능하고, C키로 암호화된 메세지는 D키로만 해독이 가능하므로 서로 종단간(End-to-End) 암호화 통신이 성립하는 것이다.

 

SSL이 적용된 사이트는 “종단간 암호화” 가 적용되기 때문에 중간 패킷 감청으로부터 안전하다. (해독키가 없으므로 메세지 해석이 불가능.)

 

보안인증서(SSL) 최상위 발급기관은 매우 많으며, 전세계 점유율은 다음 표와 같다.

참조 : https://en.wikipedia.org/wiki/Certificate_authority

market

< 그림 : World SSL Issuer Market Share >

참고로 이 블로그는 점유율 7위의 StartCom 보안인증서를 사용하고 있다.

mac-ssl

 


최상위 발급기관중 하나인 Let’s Encrypt 를 사용하여 SSL 을 발급받아 사이트에 적용하는 방법을 설명하겠다.

Let’s Encrypt 는 점유율 0.1% 미만의 인증기관이다.(점유율이 매우 낮음) 하지만 발급절차가 간단하고, 무료이기 때문에 점유율이 점차 늘어나지 않을까 싶다.

Let’s Encrypt의 점유율 (Market Share) : https://w3techs.com/technologies/details/sc-letsencrypt/all/all

 


II) SSL 발급 및 적용 방법

암호화 통신 이론에 대해서 알아보았으니 이제 실제로 적용을 해보도록 하자.

 

인증서 발급 프로그램을 서버에 설치해야한다.

Let’s Encrypt  Ubuntu 16.04 LTS 에서 기본패키지로 추가되었다. 따라서 쉽게 설치할 수 있다.
반면 Ubuntu 14.04 LTS 에서는 기본패키지가 아니기 때문에 몇 줄 더 입력해야 한다.

 

발급, 설치, 적용 방법은 다음과 같다.
모든 단계는 Linux root 계정으로 진행한다.

 

1. 인증서 발급 프로그램 설치하기

- Ubuntu 14.04 일 경우

# cd /root
# wget https://dl.eff.org/certbot-auto
# mv certbot-auto /usr/bin/letsencrypt
# chmod 755 /usr/bin/letsencrypt

start1

 

 

- Ubuntu 16.04 일 경우

# apt-get install letsencrypt

start2

 

2. 인증서 발급 프로그램을 사용하여 인증서 발급받기

인증서는 Domain Control Validation 을 거쳐야 발급받을 수 있다. 당신이 도메인이 없다면 인증서를 발급받을 수 없다.
Domain Control Validation 은 주로 다음의 3가지 방법으로 이루어진다.

참고 : Domain Control Validation 의 3가지 방법 (https://support.comodo.com/?/Knowledgebase/Article/View/791)

Let’s Encrypt 는 위의 도메인 인증방법 중 3번째 HTTP(HTTPS)-based DCV 를 사용하여 인증한다.

명령 실행시 1회에 한해 인증관련 프로그램이 추가설치될 수 있다.
*예제 1 :

# letsencrypt certonly --webroot --webroot-path=/home/ssl-demo-1404/www -d ssl-demo-1404.lael.be

*예제 2 :

# letsencrypt certonly --webroot --webroot-path=/home/ssl-demo-1604/www -d ssl-demo-1604.lael.be

*예제 3 :

# letsencrypt certonly --webroot --webroot-path=/home/banana/www -d banana.com -d www.banana.com

*예제 4 :

# letsencrypt certonly --webroot --webroot-path=/home/laelbe/blog -d lael.be -d www.lael.be -d blog.lael.be -d myhome.lael.be

 

* 명령어 설명

-d 는 도메인명을 지정하면 된다. 최대 100개의 도메인 이름을 지정할 수 있다. (한 인증서가 서로다른 100개의 도메인 인증을 할 수 있음) 일반적으로는 기본도메인과 www 도메인 두개를 지정한다.

-webroot 는 웹인증을 받을 것이라는 것이다. 외부 인증프로그램이 -d 에 지정된 도메인 사이트에 접속한다.

-webroot-path 는 웹루트의 경로이다. 보통 index 페이지가 위치하는 경로이다. 인증 프로그램이 이 경로에 임시 랜덤 파일을 생성하고, 외부 인증프로그램이 이 파일을 접근할 수 있다면 Domain Validation 이 되는 것이다.

 

명령이 실행되면 다음 화면이 표시된다.

비상연락처 : 인증에 문제가 생겼거나, 인증서 만료기간이 가까웠을때 갱신 알림 메일을 수신할 주소이다.

start3

약관에 동의하면 즉시 인증서가 발급된다.

발급에 실패했다면 외부 접속이 문제가 있거나 -webroot-path 를 올바르게 입력하지 않았을 것이다.

 


Let’s Encrypt 인증 오류 발생시 다음의 사항을 확인한다.

다음의 문서로 이동해서
# Allow Lets Encrypt Domain Validation Program
설정이 되어있는지 확인하여라.

Apache 사용자의 경우 : https://blog.lael.be/post/73#apache2.conf
Nginx 사용자의 경우 : https://blog.lael.be/post/2600#myuser1.conf


 

- Ubuntu 14.04 발급성공

start4

- Ubuntu 16.04 발급성공

start5

 

/etc/letsencrypt/live/[인증서명]/ 위치에 발급된다.
cert.pem - 인증서 파일
chain.pem - 인증서 발급자 파일
fullchain.pem - cert.pem 과 chain.pen 을 하나로 합쳐놓은 파일
privkey.pem - 인증암호를 해독하는 개인키


#TIP : 이때 발급된 인증서 파일은 웹서버 인증서(HTTPS), 메일서버 인증서(IMAPS, POP3S, SMTPS), VPN서버 인증서(SSTP), 윈도우 원격데스크톱 인증서(MSTSC), Gitlab, OwnCloud 등의 용도로 사용 할 수 있다. (인증서 만료시 갱신해야하는 번거로움이 생기겠지만..)

ssl5

Apache2 서버에서는 cert.pem, chain.pem, privkey.pem 을 사용합니다.
Nginx 서버에서는 fullchain.pem, privkey.pem 을 사용합니다.

 

Apache2 적용방법 https://blog.lael.be/post/73 13번 항목을 참조한다.

1
2
3
4
5
6
7
8
9
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
 
SSLHonorCipherOrder on
 
SSLCertificateFile "/etc/letsencrypt/live/ssl-demo-1404.lael.be/cert.pem"
SSLCertificateKeyFile "/etc/letsencrypt/live/ssl-demo-1404.lael.be/privkey.pem"
SSLCertificateChainFile "/etc/letsencrypt/live/ssl-demo-1404.lael.be/chain.pem"

 

Nginx 적용방법 : https://blog.lael.be/post/2600 16번 항목을 참조한다.

dhparam.pem 파일은 한번만 생성하면 된다.

# openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
1
2
3
4
5
6
7
8
9
10
11
listen       443 ssl http2;
server_name  ssl-demo-1604.lael.be;
root   /home/ssl-demo-1604/www;
client_max_body_size 10M;
 
ssl_certificate "/etc/letsencrypt/live/ssl-demo-1604.lael.be/fullchain.pem";
ssl_certificate_key "/etc/letsencrypt/live/ssl-demo-1604.lael.be/privkey.pem";
ssl_dhparam "/etc/ssl/certs/dhparam.pem";
 
# Enable HSTS. This forces SSL on clients that respect it, most modern browsers. The includeSubDomains flag is optional.
add_header Strict-Transport-Security "max-age=31536000";

 

3. 인증서 발급 프로그램을 통해 인증서 갱신하기

Let’s Encrypt 는 3개월짜리 인증서를 발급해준다.

즉 인증서를 3개월마다 주기적으로 갱신(renewal)해 주어야한다. 갱신은 만료일 기준 1개월전부터 할 수 있다.

# letsencrypt renew

갱신할 인증서가 있다면 자동으로 갱신 작업을 진행한다.

갱신 작업에는 인증서의 재발급이 이루어진다. (renew = reissue)
동일한 도메인에 대해서, 동일한 인증기관이 여러개의 인증서를 발급할 수도 있다. (모두 유효)

 

4. 인증서 갱신 프로그램 주기적으로 실행하기

큰 부하가 일어나는 것이 아니기 때문에 아무때나 실행해 주어도 큰 문제가 없다.

매주 월요일 새벽 5시 10분에 인증서 갱신을, 매주 월요일 새벽 5시 15분에 웹서버 프로그램 변경사항 적용을 실행하도록 설정한다.

# crontab -e

혹시나 에디터 선택문구가 출력된다면 3번을 누르세요. (재선택 명령어 : select-editor)

 

- Apache2 웹서버를 사용하는 경우

10 5 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log
15 5 * * 1 /usr/sbin/service apache2 reload

q1

 

- Nginx 웹서버를 사용하는 경우

10 5 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log
15 5 * * 1 /usr/sbin/service nginx reload

q2

 

참조 : https://www.ssl.com/article/dv-ov-and-ev-certificates/

참조 : https://community.letsencrypt.org/t/which-browsers-and-operating-systems-support-lets-encrypt/4394

참조 : https://www.bluecoat.com/documents/download/0485e335-7437-4c4e-bfc0-ca5ffc5bfd4d/16f27cf7-5d59-44b4-b17f-fb04acea369f

참조 : https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04

 


번호 제목 글쓴이 날짜 조회 수
608 [kudu]테이블 drop이 안되고 timeout이 걸리는 경우 조치 방법 총관리자 2020.06.08 195
607 [oozie] oozie shell action에서 shellscript수행결과의 2개 변수를 decision 액션에서 사용하기 총관리자 2020.06.05 101
606 [Sentry]HDFS의 ACL을 Sentry와 연동후 테스트 총관리자 2020.06.02 498
605 [sqoop] mapper를 2이상으로 설정하기 위한 split-by컬럼을 찾을때 유용하게 활용할 수 있는 쿼리 총관리자 2020.05.13 241
604 mysql sqoop작업을 위해서 mysql-connector-java.jar을 추가하는 경우 확실하게 인식시키는 방법 총관리자 2020.05.11 42
603 W/F수행후 Logs not available for 1. Aggregation may not to complete. 표시되며 로그내용이 보이지 않은 경우 총관리자 2020.05.08 2086
602 A Cluster의 HDFS 디렉토리및 파일을 사용자및 권한 유지 하여 다운 받아서 B Cluster에 넣기 총관리자 2020.05.06 42
601 impala external 테이블 생성시 컬럼과 라인 구분자를 지정하여 테이블 생성하는 예시 총관리자 2020.02.20 65
600 [Kerberos]Kerberos상태의 클러스터에 JDBC로 접근할때 케이스별 오류내용 총관리자 2020.02.14 419
599 cloudera서비스 중지및 기동순서 총관리자 2020.02.14 129
598 impala테이블 쿼리시 max_row_size 관련 오류가 발생할때 조치사항 총관리자 2020.02.12 128
597 hue.axes_accessattempt테이블 데이터 샘플 총관리자 2020.02.10 98
596 hue.desktop_document2의 type의 종류 총관리자 2020.02.10 603
595 hue db에서 사용자가 가지는 정보 확인 총관리자 2020.02.10 1586
594 Cloudera의 CMS각 컴포넌트의 역할 총관리자 2020.02.10 54
593 Namenode Metadata백업하는 방법 총관리자 2020.02.10 243
592 cloudera의 hue에서 사용자가 사용한 쿼리 목록 총관리자 2020.02.07 109
591 hive metadata(hive, impala, kudu 정보가 있음) 테이블에서 db, table, owner, location를 조회하는 쿼리 총관리자 2020.02.07 244
590 쿠버네티스(k8s) 설치 및 클러스터 구성하기 총관리자 2019.10.19 277
589 [kubernetes]우분투 Kubernetes 설치 방법 file 총관리자 2019.07.24 1184

A personal place to organize information learned during the development of such Hadoop, Hive, Hbase, Semantic IoT, etc.
We are open to the required minutes. Please send inquiries to gooper@gooper.com.

위로