현재 상황
웹 서버 (아파치, nginx) 없이 스프링부트 내장톰캣을 통해 서버를 키고 있다.
스프링부트는 Dockerfile로 이용하여 배포중이다.
https는 적용했으나 자체서명 SSL 인증서이기에 브라우저에서는 발급기관을 확인할 수 없어 주의요함을 보여주고 있다. 이게 뭐가 문제냐면 프론트와 API 통신을 하는데 안전하지 않음 을 클릭하지 않으면 API 통신을 일단 막아버린다. 개발자는 클릭하고 사용하면 되지만 일반 사용자 입장에선 무슨 오류인지 알 수 없을 것이다.
namecheap SSL 적용 그러나 실패
우선 namecheap 이라는 사이트를 통해 도메인을 구입 하였다.
SSL 인증서도 유료로 구매하였다. 구매하였더니 xxx.crt, private.key, xxx.p7b 등 SSL 적용을 위한 파일을 다운로드 할 수 있었다. namecheap 튜토리얼에 따라 하였다. 하지만 스프링 부트 내장톰캣이 아닌 외장톰캣 기준으로 튜토리얼 정리 되어있었고 튜토리얼도 많이 불친절했다.
댓글보니 외국사람들 조차 불친절하다고 욕을 써놨다.
결론적으로 적용이 잘 안되었고 래퍼런스가 부족하여 방법을 찾을 수 없었다.
해결 방법
가장 많은 래퍼런스가 존재하며 무료 SSL을 발급해주는 Let’s Encrypt SSL 을 이용하였다.
우선 SSL을 적용하기 위해서는 도메인이 무조건 필요하다.
Let’s Encrypt SSL 인증서 발급 방법은 크게 3가지 존재하는데 그 중 standalone 방식을 택했다.
적용하기 앞서 EC2가 있다고 가정하며 EC2는 도메인과 연결 되어있다고 가정한다. ex) yourdomain.co.kr
STEP 1. Certbot 설치
$ sudo apt-get update
$ sudo apt-get install certbot
STEP2. 기존 80포트가 켜져있다면 모두 Kill 한다.
# 80포트를 통해 해당 도메인이 유효한지 판단한다.
$ netstat -nap|grep 80
$ sudo kill $(sudo lsof -t -i:80)
STEP3. 인증 방식을 정한다.
$ sudo certbot certonly --standalone
- 해당 명령어를 입력하면 이메일을 입력하라고 나올테고 이메일은 도메인을 샀을 때 사이트에서 작성했던 이메일을 사용하면 될 것같다.
무조건 그런거 같지 않은데 나는 이렇게 했다. - Y / N 이 나오면 Y을 눌러준다. 그러면 도메인을 입력하라고 나오고 구매했던 도메인을 입력해준다.
- Congratulations! 뜨면 성공 만약 에러가 뜨면 복붙해서 해당 에러를 검색 해보자.
- 성공했다면 EC2에서 /etc/letsencrypt 해당 경로로 이동해보자.
- live 라는 폴더가 있을텐데 권한없이 폴더를 열 수 없다. 난 귀찮아서 권한 따로 안풀어주고 root 계정으로 들어갔다.
- live 폴더 안에 들어갔다면 내가 만든 도메인 이름으로 폴더가 또 만들어져 있을 것이다. 다시 들어가본다.
- cert.pem , chain.pem , fullchain.pem , privkey.pem 존재를 확인한다.
STEP4. PEM → PKCS12 형식으로 바꾸기
스프링부트는 pem을 인식하지 못하므로 PKCS12 형식으로 바꿔줘야지만 사용할 수 있다.
pem 있는 해당 경로에서 명령어를 실행하여 파일을 변환해주자.
sudo openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name ttp -CAfile chain.pem -caname root
- -export : 추출한다는 의미
- -in : 공개키? 같은거
- -inkey : 개인키
- -out : 결과물
- -CAfile : 인증기관 키
더 공부해야하지만 이정도로 이해하고 사용했던 것 같다. 아무튼 이렇게 명령어를 치면 비밀번호를 입력하라고 한다. 비밀번호를 입력하고 해당 비밀번호는 꼭 기억하자 스프링부트 YAML 파일 설정할 때 필요하다.
keystore.p12 파일이 만들어 졌는지 확인

STEP5. EC2 파일을 로컬로 이동
3가지 정도 방식이 있을 것이다.
- scp 명령어
- FileZilla
- VSCODE에서 제공해주는 플러그인
이 중 나는 VSCODE를 통해 EC2을 연결해주어서 가져왔다
프론트 팀에게 도움받아 이 부분은 생략
STEP6. 파일 이동 후 YAML 설정
그림과 같이 해당 경로로 이동시켜준다. (keystore.p12 대신 현재 프로젝트에 맞는 이름으로 파일명을 쓴것이므로 무시해도 된다.)

YML 설정
server:
port: 443
ssl:
enabled: true
key-store-password: 123456 # 인증서 만들 때 만들었던 비밀번호
key-store: classpath:snackr.p12
key-store-type: PKCS12
헷갈렸던 부분
Docker + Nginx + SSL + 스프링부트 관련 래퍼런스는 많았으나 스프링부트 내장톰캣 + Docker + SSL 관련 래퍼런스가 많이 없었다.
네 생각으로는 내장톰캣에 SSL 인증서를 적용해야하는데 내장톰캣은 도메인을 가질 수 없다고 생각하였다 그래서 많이 애먹었다.
해결할 수 있는 실마리를 찾은곳은 다름아닌 EC2에서 SSL 적용하기 전에도
컨테이너 9090포트가 열려있고 도메인이 api.snackr.social 이라고 가정하였을 때,
api.snackr.social:9090 으로 접근 할 수 있었다. Docker는 격리된 환경을 제공하지만 하나의 호스트를 공유한다. 라는 말이 생각이 났다.
그말은 즉, 도커로 감싸진 jar 파일이여도 keystore.p12을 읽어서 SSL 적용할 수 있다고 생각하여 해결 할 수 있었다!!
참고자료
Docker로 감싼 스프링부트 이미지 안에 인증받은 SSL을 적용해보자.
👉 Spring Boot에 Let's Encrypt SSL 적용하기
Spring Boot에 Let's Encrypt SSL 적용하기
아파치나 NginX 같은 웹서버 없이 Spring Boot으로 만든 웹 어플리케이션에 무료 SSL 중 하나인 Let's Encrypt을 적용하게 되었다. 90일동안 사용가능하며 다시 갱신을 시켜줘야하나? 싶었지만 간단한 설
jiwontip.tistory.com
'Infra' 카테고리의 다른 글
| EC2에 OpenVidu 서버 배포 (0) | 2023.04.04 |
|---|---|
| DockerFile 명령어 정리 (0) | 2023.04.04 |
| Docker로 개발서버 배포기 (0) | 2023.04.04 |