[WAS]Tomcat SSL 적용
- -
보안과 관련된 공부를 하던 중 SSL에 대해 알아보았습니다.
아주 깊이 있게 공부한 것은 아니지만 정리하며 메모해놓은 내용들을 포스팅하여 공유하고자 합니다.
아직도 한참 부족하고 개발자는 공부할 것이 참 많다는 것을 느끼네요.
※ 테스트 환경입니다.
- Tomcat 7.0
- jdk 1.7
- Eclipse 2019-06
- Spring Security 3.1.0
- Windows 10
SSL(Secure Socket Layer)과 TLS(Transport Layer Security)
SSL을 이해하기 위해서는 https의 개념을 짚고갈 필요가 있습니다.
아마 대부분의 사이트에서 사진과 같이 자물쇠 모양의 주소를 확인할 수 있을 것입니다. 이것은 https가 적용되었다는 의미로 https는 HTTP over Secure Socket Layer의 약자입니다.
https는 SSL을 이용한 http 통신 방식을 의미합니다.
기존 http는 암호화되지 않은 방식으로 데이터를 주고 받기 때문에 제 3자에 의한 악의적인 해킹에 취약했습니다. 이에 https는 제 3자인 CA(인증기관)가 보증하는 문서를 통해 보안 통신을 제공합니다. 이 문서를 SSL 인증서라 합니다.
먼저, 웹에서 https 통신 방식을 제공하기 위한 과정을 살펴보겠습니다.(우측 순서)
① : https 통신 방식을 위해 CA로부터 인증서를 구입합니다. 이 때 웹은 서비스의 도메인과 서버 공개키 정보를 제출합니다.
② : CA는 서비스의 정보를 비공개키를 이용하여 암호화합니다.
③,④ : 웹은 CA로부터 암호화된 SSL 인증서를 제공받습니다.
다음으로 브라우저가 https 통신을 하는 과정을 살펴보겠습니다.(좌측 순서)
① : 브라우저는 웹과 데이터를 주고 받기 전, 가장 먼저 웹으로부터 SSL 인증서를 받게 됩니다. 여기서 알아야할 것은 브라우저는 내부적으로 CA의 리스트를 파악하고 있으며 CA의 공개키에 대한 정보도 알고 있다는 것입니다.
② : 브라우저는 웹 서버로부터 받은 인증서를 CA의 공개키를 이용해 복호화합니다.
③ : 성공한다면 인증서가 CA의 비공개키에 의해 암호화된 것을 의미하며, 이 사이트는 신뢰할 수 있다는 것으로 생각하면 됩니다.
실패한다면 신뢰할 수 없는 사이트이므로 아래와 같이 사용자에게 경고 메세지를 출력합니다.
SSL은 2.0과 3.0 버전을 거쳐 현재는 SSL 3.0을 기반으로한 TLS가 도입되어 사용 중입니다.(SSL 2.0 / SSL 3.0 은 2015년을 마지막으로 사용 중지 되었습니다)
TLS는 현재 TLS 1.0 / TLS 1.1 / TLS 1.2 / TLS 1.3의 버전이 존재합니다.
2020년부터는 크롬과 사파리, IE, Edge 등 주요 브라우저에서 TLS 1.0 / TLS 1.1 버전의 지원이 중단될 것이라고 발표되었습니다. 이에 모든 기술 회사는 TLS 1.2 이상으로 업그레이드하기를 권장하고 있습니다.
SSL과 TLS는 같은 말이며, SSL이라는 이름이 오래 사용된 탓인지 TLS에 비해 SSL이라는 이름으로 많이 사용되고 있습니다.
테스트를 해보기 위해 사설 인증서를 발급받아 프로젝트에 https를 적용해 보겠습니다.
앞서 언급됐듯이 실제 운영중인 서비스에서 SSL을 이용하기 위해서는 신뢰할 수 있는 인증서 발급기관(CA)으로부터 SSL 서버용 인증서를 발급받아 서버에 설치해야 합니다.
구글링 결과, 인증서를 생성할 수 있는 방법은 크게 두 가지로 나누어졌습니다.
Keytool과 Openssl이다.
본 포스팅에서는 Keytool을 이용한 방법을 소개하려고 합니다.
Keytool은 Java Key Store(JKS)를 생성 및 관리하는 응용 프로그램입니다. 공개키(public key), 개인키(private key)를 생성할 수 있으며 인증서 발급이 가능합니다.
자바 환경 변수 셋팅이 되어있다면 커맨드창을 이용해 Keytool을 쉽게 실행할 수 있습니다.(프로그램 경로 JAVAHOME/bin에서 확인 가능)
1. 인증서 생성
1) Keystore 생성
Keystore란 키를 저장하는 파일입니다. keystore의 파일 확장자는 .jks와 .keystore가 있습니다. 확장자만 다를 뿐 똑같은 keystore 파일입니다. 참고로 keystore의 기본값은 jks입니다.
(아래 예제를 보고 원하는 확장자로 진행해주시면 됩니다)
keytool -genkey -alias jksSSL -keyalg RSA -keystore shleeSSL.jks
keytool -genkey -alias shlee -keyalg RSA -keystore .keystore
명령어가 뜻하는 바는 다음과 같습니다.
- -genkey : 개인키(Private key)와 자체서명 인증서를 생성하는 명령어
- -alias : 키 별칭
- -keyalg RSA : 키 생성 알고리즘
- -keystore : 키가 저장될 jks를 지정한다.
이름과 성을 입력하는 부분에는 사용하고자 하는 도메인 또는 IP를 입력합니다.
2) 생성한 Keystore로부터 인증서 추출하기
keytool -export -alias jksSSL -file shleeSSL.cer -keystore shleeSSL.jks
keytool -export -alias shlee -file shleeKey.crt -keystore .keystore
+ list 명령어로 keystore 내용을 출력해볼 수 있습니다.
keytool -list -v -keystore shleeSSL.jks
(생성된 인증서 파일)
2. Tomcat server.xml 설정
<Connector connectionTimeout="20000" port="8099" protocol="HTTP/1.1" redirectPort="443" />
<Connector port="443"
protocol="org.apache.coyote.http11.Http11Protocol"
clientAuth="false"
SSLEnabled="true"
maxThreads="150"
scheme="https"
secure="true"
ciphers="TTLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_RSA_WITH_RC4_128_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_256_CBC_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA,
SSL_RSA_WITH_RC4_128_SHA"
keystoreFile="C:\OpenSSL\jks\shleeSSL.jks" keystorePass="123456"
keyAlias="jksssl" keystoreType="JKS"
sslProtocol="TLS"
URIEncoding="UTF-8"
/>
- keystoreFile : 생성된 인증서가 있는 경로
- keystorePass : 인증서 비밀번호
- keyAlias : 인증서 별칭
- ciphers : 보안 문자열
기본 포트로 8099를 사용중이었는데 해당 포트에서 redirect가 되도록 했습니다.
SSL의 기본포트는 443이다.
3. 스프링 시큐리티 설정
스프링 시큐리티를 사용하지 않는다면 2번 단계까지만 해서 테스트를 해도 될 것입니다. 하지만 스프링 시큐리티를 사용하는 경우 추가로 설정해줘야할 것이 있습니다.
security-context.xml
<http auto-config='true' use-expressions="true">
<intercept-url pattern="/favicon.ico" access="hasRole('ROLE_ANONYMOUS')" />
<intercept-url pattern="/resources/**" access="permitAll" />
<intercept-url pattern="/login/**" access="permitAll" requires-channel="https" />
<intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')" requires-channel="https" />
<form-login login-page="/login/loginPage.do"
login-processing-url="/login.do"
authentication-failure-url="/login/loginPage.do?err=true"
default-target-url="/"
username-parameter="userid"
password-parameter="userpw" />
<session-management>
<concurrency-control max-sessions="1" expired-url="/" />
</session-management>
<access-denied-handler error-page="/login/accessDenied.do" />
</http>
Tomcat 설정에 따라 이제 https를 사용하게 되었는데 그것을 시큐리티에도 적용하는 작업입니다.
requires-channel="https"를 <intercept> 태그에 추가합니다.
web.xml
<security-constraint>
<web-resource-collection>
<web-resource-name>SSL Redirect</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
이 설정을 해주면 http로 호출시 https로 자동 리다이렉트됩니다.
4. 테스트
이제 http://shlee:8099(본인의 아이피 또는 도메인:포트번호) 로 접속하게 되면 https로 자동 접속됩니다. ssl의 기본 포트인 443으로 url은 https://shlee 로 확인할 수 있습니다.
개발용으로 인증서를 생성해서 입혀놓았기 때문에 아래와 같이 뜬다면 성공한 것입니다.
[ie]
[chrome]
Tomcat에 SSL을 입히는 작업을 하면서 기존에 정상적으로 작동하던 기능이 되지 않았습니다.
원인 파악을 해보니 jquery를 url로 임포트해서 사용 중이었는데 해당 url이 http였다. url을 https로 수정하니 해결됐습니다.
<!-- jQUery Latest Ver -->
<script type="text/javascript" src="https://code.jquery.com/jquery-latest.min.js"></script>
기타 라이브러리를 url 타입으로 사용 중이라면 체크해봐야합니다.
참고문서
https://www.mobiinside.co.kr/2019/02/13/buzzvil-tls/
http://btsweet.blogspot.com/2014/06/tls-ssl.htm
http://trandent.com/article/etc/detail/741
https://offbyone.tistory.com/262
http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html
https://opentutorials.org/course/1334/4894
+ 피드백은 언제나 환영입니다 :)
'Server' 카테고리의 다른 글
[WAS]POST 방식에서 파라미터 개수 제한 (0) | 2020.05.26 |
---|---|
아파치 SSL 설정 (5) | 2020.02.05 |
아파치 톰캣 연동(Apache + Tomcat) (5) | 2020.02.03 |
hosts 파일 (0) | 2018.12.02 |
WAS 그리고 Tomcat(+웹 서버와 차이점) (0) | 2018.05.04 |
소중한 공감 감사합니다.