스프링부트 HTTPS 적용

To-Do project를 하면서 window의 notification api를 사용하게 되었다. 로컬에서 테스트를 했을때는 잘 돌아갔지만 ec2에 배포를 한 후부터 제대로 동작하지 않는다는 것을 알게되었다. 이유를 보아하니 notification api 특징이 Https와 로컬에서만 작동한다는 것이었다. 그래서 spring boot에 https를 적용하기를 시도해보았다.

SSL 증명서 생성하기

1) 키가 없을 때

가장 먼저 키를 생성해야 한다. 아래의 명령어를 통해서 키를 생성하도록 한다

keytool -genkeypair -alias tomcat -keyalg RSA -keysize 2048 -keystore keystore.jks -validity 3650

각각의 옵션은 아래와 같다.

-alias : 처리할 항목의 별칭 이름

-keyalg : 알고리즘

-keysize : 키의 비트 크기 (2048이 제일 적당하다고 한다. 1024는 너무 작고 4096은 너무 과하다.)

-keystore : 키 저장소 이름

-validity : 유효 기간 일 수

후에 키 저장소 비밀번호, 이름과 성, 조직 단위와 이름 등을 적절하게 입력한 후 생성한다.

2) 키가 이미 있을 때

keytool -import -alias tomcat -file [키 파일] -keystore keystore.p12 -storepass [비밀번호]

Spring Boot에서 HTTPS 설정하기

키를 생성했다면 이제 인증서를 이용하여 HTTP 대신 HTTPS를 이용해서 요청을 받을수 있도록 설정해야한다. 일단 생성한 키를 스프링 부트 프로젝트 안에 넣도록한다.

후에 application.properties파일을 열어 아래와 같이 설정한다.

# 키 형식
server.ssl.enabled=true
server.ssl.key-store-type=PKCS12
server.ssl.key-sotre=keystore.p12
server.ssl.key-store-password=본인의 패스워드 
server.ssl.key-alias=tomcat

# 만약 스프링 시큐리티를 사용중이라면 아래 설정도 포함
security.require-ssl=true

이제 설정을 마치고 나면 우리의 프로젝트에서는 이제 HTTPS가 가능하게 된다. 접속을 하여 확인을 하도록 한다.

먼저 http로 접속을 했을 때 나는 다음과 같은 페이지를 마주칠수 있었다.

Bad Request

This combination of host and port requires TLS.

https로 접속을 해보자. 그러면 연결이 비공개로 설정되어 있지 않습니다. 라는 문구가 나올것이다.

당연히 내가 만든 인증서는 공식적으로 인정이 되지 않기 때문에 다음과 같은 문구가 뜨는 것이다.

고급에서 안전하지않음을 클릭하여 들어가도록 한다.

여기서 잠깐!

안전하지않음을 클릭했을 때 들어가지지 않고, 실행 로그를 보았을 때 java.lang.UnsatisfiedLinkError tomcat.jni.SSL.renegotiatePending 에러가 뜨는 분들만 아래를 이어서 보도록한다.

일단 무엇이 문제인지 몰라서 검색을 했었는데, 이와 같은 글을 보게 되었다.

답변을 보니 다음과 같이 설명하고 있다. Spring boot 2.1.1에서 tomcat이 9.0.12에서 9.0.13으로 바뀌면서 톰캣 네이티브 메소드가 다르게 요구되는것 같다고 한다. (음.. 대충 톰캣 네이티브 메소드를 바꾸면 된다는 말?) 그렇다면 방법은 두가지인데 톰캣 버전을 내리던가 아니면 요구하는 톰캣 네이티브 메소드를 설치해주면 된다.

요구하는 네이티브 메소드가 뭔데? 라고 생각이 들었을 때 실행 로그를 보다가 이러한 것을 보게 되었다.

1.2.19 이상의 버전이면 상관없는 것 같았다. 일단 http://tomcat.apache.org/download-native.cgi사이트에서 최신 버전의 tomcat-native-library를 다운 받았다.

이제 다운 받은 파일을 압축해제한 후 bin -> x64 폴더 안의 내용을 내컴퓨터의 톰캣 bin속에 넣었다. 물론 이전에 있던 파일을 뒤집어써야한다.

이렇게 하면 라이브러리 교체를 완료하였다.

다시 프로젝트를 실행해보도록 하면 아래와 같이 교체되었음을 알 수 있다.

물론 https도 정상적으로 접속이 된다.