톰캣에 SSL을 적용하는 방법에 대해 알아보겠습니다.

( SSL에 대한 개념은 여기를 참고해주세요 ! )

원래 SSL 인증서는 인증된 기관( CA )으로부터 발급 받아야 하는데, Let's Encrypt을 이용하면 무료로 인증서를 발급 받을 수 있습니다.

단, 90일 동안만 인증서가 유효하므로 서버에서 cron을 이용하여 주기적으로 인증서를 갱신해야 합니다.



톰캣에 SSL을 적용하는 과정은 크게 나누면 다음과 같습니다.

1) Let's Encrypt로 인증서( .pem 파일 )를 발급 받기

2) pem파일을 Tomcat에서 사용 할 수 있도록 PKCS12로 변환

2) Tomcat의 server.xml 파일에서 인증서 적용



실습 환경은 다음과 같습니다.

1) CentOS 7 , JDK1.8 , Tomcat8.0.52

( JDK1.8 설치는 여기를, Tomcat8.0.52 설치는 여기를 참고해주세요 ! )


2) Let's Encrypt로 부터 인증서를 발급 받으려면 유효한 도메인인지 확인하는 작업이 필요합니다.

도메인이 있으시다면 문제될 것이 없지만, 여기서는 도메인이 없어도 적용 할 수 있도록 ngrok을 사용할 것입니다.

ngrok은 localhost를 공공IP로 포워딩 해주는 툴인데, 세션이 8시간 동안 유효하므로 테스트용으로 적합합니다.

( ngrok에 대한 정보는 여기를 참고해주세요 ! )


3) 톰캣에 SSL을 적용하는 이 글은, 웹 서버를 사용하지 않고 톰캣에서 정적 자원을 처리하는 상황을 가정한 것입니다.





1. Let's Encrypt로 인증서 ( .pem 파일 ) 발급 받기

우선 톰캣에 SSL을 적용하기 위해서는 공인된 인증서가 필요합니다.

원래는 CA로부터 인증서를 발급받아야 하는데, 돈이 들기 때문에 무료로 인증서를 발급 받을 수 있는 Let's Encrypt를 사용할 것입니다.



1) 의존성 설치

# yum install -y gcc

# yum install -y gcc-c++ # yum install -y wget

# yum install -y perl-devel # yum install -y curl-devel



2) 준비 작업

Let's Encrypt 인증서를 발급 받기 위해서 github으로부터 끌어와야 합니다.

따라서 서버에 Git이 설치되어 있어야 하는데, Git 설치되어 있다면 " 준비 작업 "과정은 생략하셔도 됩니다.


이 방법은 컴파일 설치 방법을 소개한 것이며, 간단하게 yum install -y git 으로 설치하셔도 됩니다.


zlib 설치

Git을 설치하기 위해서 Zlib을 먼저 설치해야 합니다.

# wget http://www.zlib.net/fossils/zlib-1.2.8.tar.gz # tar xvfz zlib-1.2.8.tar.gz # cd zlib-1.2.8 # ./configure --prefix=/usr/local

# make # make install


Git 설치

# cd # wget https://www.kernel.org/pub/software/scm/git/git-2.6.4.tar.gz # tar xvfz git-2.6.4.tar.gz # cd git-2.6.4 # ./configure --prefix=/usr/local

# make # make install


# git --version



3) Let's Encrypt 인증서 발급

# cd

# git clone https://github.com/letsencrypt/letsencrypt # cd letsencrypt


Github으로부터 letsencrypt을 clone한 후, 인증서를 발급 받는 명령어를 작성합니다.

명령어 형식은 다음과 같으며, Let's encrypt를 사용하기 위한 의존 라이브러리들을 자동으로 설치합니다.


./letsencrypt-auto certonly --manual --email [이메일 주소] -d [사용할 도메인주소]


우선은 이메일 주소와, 도메인 주소를 아무렇게나 작성해보겠습니다.

# ./letsencrypt-auto certonly --manual --email foo@example.ocm -d test-001.com


이어서 이메일 주소를 작성하고, Agree -> N -> Y 를 순서대로 입력합니다.

그러면 마지막에 다음과 같은 메시지가 출력됩니다.

위에서 작성한 도메인이 유효한 도메인인지 확인하기 위해, 두 번째 네모 박스인 파일 경로에 첫 번째 네모 박스의 내용이 작성되어 있는지 확인합니다.

이 과정이 완료되면 인증서( .pem 파일 )를 발급 받을 수 있습니다.


도메인이 있으시다면, 8단계로 넘어가서 바로 인증서를 발급 받으시면 됩니다.

4 ~ 7 단계는 도메인이 없는 경우를 위해 필요한 단계입니다.


저는 공공 IP가 없으므로, 공공 IP를 생성하여 localhost로 포워딩 해주는 툴인 ngrok을 사용할 것입니다.

우선은 엔터를 누르고 Let's Encrypt 발급을 중지합니다.




4) ngork

ngrok 사용법은 매우 간단하기 때문에 부담 갖지 않으셔도 됩니다.

먼저 ngrok을 다운 받으신 후( 링크 ), ngrok http test-001.com:9090 명령어를 입력해주세요.

이 프로그램은 브라우저에서 http://41c40b60.ngrok.io으로 요청하면, test-001.com:9090으로 포워딩 해줍니다.
9090 포트는 아직 설치하지 않은 Nginx가 사용 할 포트입니다.

ngrok은 이렇게 켜놓기만 하면 됩니다. 

 


지금까지 과정을 정리하면, 인증서를 발급 받기 위해서 공공 IP가 필요했습니다.
그래서 ngrok으로 도메인을 하나 받았고, 브라우저에서 http://41c40b60.ngrok.io 으로 요청을 하면, ngrok은 test-001.com:9090으로 포워딩 할 것입니다.
test-001.com:9090은 ( 아직 설치하지 않은 )웹 서버가 사용하는 포트입니다. ( 80포트의 중복을 피하기 위해 임의로 9090포트를 사용했습니다. )
웹 서버가 필요한 이유는 .well-known/acme-challenge/~~~ 디렉터리가 필요하기 때문입니다.
추가적으로 웹 서버와 윈도우에서 test-001.com 도메인을 알 수 있도록 hosts 파일을 수정해야 하는데, 우선 Nginx를 먼저 설치하도록 하겠습니다.




5) Nginx 설치

Nginx 설치는 여기를 참고해주세요 !

( 물론 아파치를 설치하셔도 됩니다. 어차피 웹 서버는 Let's Encrypt로부터 인증서만 발급 받고 사용하지 않을 것이기 때문입니다. )


다음으로 Nginx 설정 파일 nginx.conf을 열어서 기본 포트를 바꾸고 도메인을 추가합니다.

# vi /usr/local/victolee/nginx1.6.2/conf/nginx.conf

( 기본 포트인 80을 9090으로, 도메인을 다음과 같이 수정합니다. - line 36, 37 )

listen 9090; server_name test-001.com;


 

 

6) hosts 파일 수정

다음으로 서버에서 test-001.com URL을 알 수 있도록 hosts 파일을 수정해야 합니다.

IP주소는 ifconfig 명령어로 확인해주세요.

# vi /etc/hosts

192.168.245.134   test-001.com


뿐만 아니라 브라우저를 실행하는 것은 호스트이기 때문에 호스트인 윈도우에서도 hosts 파일을 수정해야 합니다.

C:\Windows\System32\drivers\etc 경로에서 hosts 파일을 열어서 아래의 내용을 추가해주세요.

192.168.245.134   test-001.com




7) 접속 테스트

nginx 재실행하여, 브라우저에서 test-001.com:9090으로 접속이 되는지 확인합니다.

그리고 ngrok에서 제공하는 http://41c40b60.ngrok.io 으로 요청해도 접속이 잘 되는지 확인해주세요.




8) 인증서 발급받기

이제 유효한 도메인이 생겼으니 인증서를 발급 받아보도록 하겠습니다.


2)번 과정에서 명령했던 내용을 명령하는데, 끝에 -d 이후의 도메인 부분이 ngrok에서 제공하는 도메인으로 바뀌었습니다.

# ./letsencrypt-auto certonly --manual --email foo@example.com -d 41c40b60.ngrok.io


 

아직 엔터를 누르면 안됩니다.

쉘을 하나 더 열어서 위 경로의 파일에서 내용을 작성하고 저장합니다.

# mkdir -p /usr/local/victolee/nginx1.6.2/html/.well-known/acme-challenge

# vi /usr/local/victolee/nginx1.6.2/html/.well-known/acme-challenge/jqR5OyWKw0JgFpu_hAuh8wTpy2vXP6HAFghq7i6wI9I jqR5OyWKw0JgFpu_hAuh8wTpy2vXP6HAFghq7i6wI9I.5DPbC1pY_idF8dcmwbEwjmjY0XieoeVLuck5MlkaS-Q


원래 쉘로 돌아와서 엔터를 누르면 아래와 같이 pem 파일이 생성되었다고 합니다.

이 과정이 끝나면 Let's Encrypt 인증키를 발급 받은 것입니다.

( ngrok이 제공하는 URL은 이제 더 이상 필요 없습니다. ngrok은 Let's Encrypt 인증서를 발급 받기 위한 역할을 할 뿐입니다. )





2. PKCS12 포맷의 키 저장소 ( keystore ) 파일 생성

Tomcat은 JKS, PKCS11 혹은 PKCS12 포맷의 Keystore를 지원합니다.

JKS 포맷은 Java Standard Keystore 포맷이며, JDK에 포함되어 있는 Keytool 명령어를 사용하여 생성할 수 있고,

PKCS12 포맷은 인터넷 표준 포맷이며, OpenSSL를 사용하여 생성할 수 있습니다.


여기서는 PICKS12 포맷의 Keystore를 생성할 것입니다.

( 41c40b60.ngrok.io는 Let's Encrypt 인증서를 발급 받을 때 사용했던 도메인인데, 각자 도메인에 맞게 작성하시면 됩니다. )

# cd /etc/letsencrypt/live/41c40b60.ngrok.io

# openssl rsa -in privkey.pem -text > devbit.key # openssl x509 -inform PEM -in fullchain.pem -out devbit.crt # openssl pkcs12 -export -in devbit.crt -inkey devbit.key -out devbit.p12 -name tomcat # keytool -list -v -keystore devbit.p12 -storetype pkcs12

openssl rsa -in privkey.pem -text > devbit.key

privkey.pem 파일을 .key 파일로 변환


openssl x509 -inform PEM -in fullchain.pem -out devbit.crt

fullchain.pem 파일로 .crt파일로 변환


openssl pkcs12 -export -in devbit.crt -inkey devbit.key -out devbit.p12 -name tomcat

pkcs12 형식으로 변환

비밀번호를 입력하라고 하는데, 이 비밀번호는 톰캣 설정파일에서 사용됩니다.


keytool -list -v -keystore devbit.p12 -storetype pkcs12

keystore 생성 




 

3. 톰캣 설정

마지막 단계입니다.

server.xml 파일을 열어서 설정 내용을 작성하면 됩니다.

# vi /usr/local/victolee/tomcat8.0.52/conf/server.xml ( <Connector>가 있는 곳에 아래의 내용을 추가 ) <Connector port="443" maxHttpHeaderSize="8192" maxThreads="150" enableLookups="false" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" protocol=”org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="" keystoreType="PKCS12" keystorePass="" />

 

keystoreFile은 keystore가 저장되어 있는 디렉터리 경로를,

keystorePass는 설정한 비밀번호를 작성합니다.

 

톰캣 설정 파일을 수정했으니 톰캣을 재실행 해주세요.


 


 

4. 테스트

이제 브라우저에서 https프로토콜로 8443 포트에 접속해봅니다.

https://test-001.com:8443

 

접속은 잘 되지만, 아마 자물쇠가 채워지지 않을 것입니다.

( 접속이 잘 안되시면 방화벽을 확인해주세요 ! )

그 이유는, Let's Encrypt를 인증할 때 사용한 도메인 주소( 41c40b60.ngrok.io )와 접속한 도메인 test-001.com이 다르기 때문입니다.


 

보시는 바와 같이 인증서는 Let's Encrypt로부터 받은 인증서이므로 인증서에는 문제가 없습니다.

이 문제는 실서버를 운영하면 해결될 문제입니다.



 

이상으로 톰캣에 SSL을 적용해보았습니다.

이 글에서 사용한 방법은 웹 서버를 두지 않고, 톰캣이 웹 서버 역할도 하는 상황에서 SSL을 적용해야 할 때 필요한 방식입니다.

댓글 펼치기 👇
  1. ㅎㅇ 2019.01.18 20:14

    포스팅 잘보고 갑니다. 혹시갱신 하는 포스팅도 해주실수 있을까요?

    • Favicon of https://victorydntmd.tistory.com victolee 우르르응 2019.01.23 07:47 신고

      안녕하세요~ 감사합니다^^
      인증서를 갱신하는 부분 말씀하시는거죠??

      http://victorydntmd.tistory.com/255
      이와 관련된 부분은 위 링크의 하단부에 있으니, 참고하시면 좋을 것 같습니다!

  2. cdi0720@naver.com 2020.09.08 13:30

    안녕하세요 이 방법을 적용해서 인증서를 적용했는데

    혹시 갱신은 letsencrypt-auto renew 만 하면 되는것인지

    PKCS12 포맷의 키 저장소 ( keystore ) 파일 생성 작업을

    다시 해주어야 되는건지 궁금해요