본문 바로가기

🧑🏻‍💻 Dev/SpringBoot

[Spring | LetsEncrypt] Http 서버를 Https로 바꿔보자

1. 문제


프론트엔드 팀과 협업을 위해서 API 서버를 개발하고, AWS LightSail을 사용해서 서버를 배포했습니다.

클라이언트 서버가 띄워지기 전까지는 로컬에서 작업을 해서 몰랐지만, 띄우고 나서 확인해 보니 통신에 문제를 겪었습니다.

클라이언트 서버는 https로 배포가 되어있고, 개발 서버는 http로 배포가 되어 있어 두 서버 사이의 통신에 문제가 발생했습니다.

 

 

 

2. 해결


(1) SSL 인증서가 필요하다!

첫 번째로 HTTPS로 배포를 하기 위해서는 CA의 인증을 받은 SSL 인증서가 필요합니다. 

이 인증서는 보통 비용을 지불하고, 받아서 사용합니다. 하지만 저희는 돈이 없기 때문에!

무료로 SSL 인증서를 발급 받을 수 있는 Let's Encrypt를 사용했습니다.

무료라는 특징도 있지만 3개월(90일)마다 인증서를 갱신해줘야 한다는 특징도 존재합니다.

 

 

 

(2) 도메인 구매하기

letsencrypt에서 SSL 인증서를 받기 위해서는 "이메일"과 "도메인"이 필요합니다.

그래서 이 도메인이라는 것을 구매해야하는데, 가비아라는 사이트에서 도메인을 구매했습니다.

이렇게 사이트에서 원하는  도메인을 검색해보면 사용할 수 있는 도메인 목록이 나오게 됩니다.

이렇게 뜨면 원하는걸 골라서 선택한 후 신청하기를 진행하고, 결제를 하면 이제 제 도메인이 생깁니다.

위에는 20,000원짜리로 예시가 되어있는데 잘 찾아보면 500원짜리도 존재하고, 가격은 다양합니다.

자신이 적당하다고 생각되는 가격으로 도메인을 하나 구매해 주시면 됩니다.

이제 이렇게 도메인을 구매했으면 링크를 참고해서 미리 준비되어 있는 서버(AWS)의 Public IP를 DNS로 등록해줘야 합니다.

 

 

 

(3) My 가비아 > 도메인으로 접속

도메인을 구매하고, 조금 있으면 가비아 홈페이지의 오른쪽 상단에 My가비아에 들어가 보면 도메인을 관리할 수 있는 홈페이지로 갈 수 있습니다.

여기서 빨간색 박스에 있는 "도메인"을 클릭합니다.

들어가면 내가 구매한 도메인을 확인할 수 있고, "관리" 버튼을 클릭합니다.

쭉 내리다 보면 오른쪽 아래 DNS 레코드 설정으로 갈 수 있는 버튼이 있습니다. "설정"을 눌러줍니다.

내가 구매한 도메인을 확인하고, 체크하고 "DNS 설정"을 클릭합니다.

 

이제 "레코드 추가"를 누르고 호스트에 @와 www를 추가해줘야 합니다. 값/위치에는 AWS EC2 또는 다른 클라우드 서비스를 통해 띄운 서버의 IP를 입력해 줍니다.

 

오른쪽 수정 또는 확인 버튼을 눌러주고, "저장"을 눌러주면 DNS 서버에 내가 구매한 도메인과 내 서버의 IP가 연결이 완료되었습니다.

 

이렇게 등록하고 나서 http://poppleserver.store:8080 에 접속해 보면 http://{ubuntu ip}:8080에 접근했을 때와 같은 결과 페이지가 나오면 됩니다. 

DNS 서버의 쿼리가 퍼지기까지는 약간의 시간이 소요되고, 도메인 등록 업체에서는 12시간 정도를 얘기하고 있습니다. 하지만 실제로는 30분 정도 기다리면 사용하는데 문제가 없다고 합니다. 연결될 때까지 기다려 봅시다.

 

이렇게 연결이 되었으면 어떻게 확인해 볼까? 터미널을 켜고 nslookup 명령어로 확인해볼 수 있습니다.

nslookup 명령어 사용

NXDOMAIN 에러가 뜨면 DNS 서버에 제대로 등록될 때까지 조금만 여유를 가지고 기다려보시길 바랍니다!

그래도 해결이 안 된다면 방법을 찾아야 하겠지만, 제대로 된 IP에 등록하셨다면 될 겁니다!

 

 

 

(4) Certbot 설치

Ubuntu 서버로 접속한 후에 Certbot을 설치해줘야 합니다.

$ sudo apt-get update
$ sudo apt-get install certbot

저는 Ubuntu로 서버를 만들어서 apt-get을 사용했지만, 만약 Amazon Linux를 사용해서 서버를 띄우셨다면 yum을 사용해서 조금 복잡하게 설치를 했던 거 같습니다. (구글링 해보시면 좋을 거 같습니다!)

 

 

 

(5) 인증서 발급받기

$ sudo certbot certonly --standalone

standalone 옵션 말고 다른 옵션들도 있는데, 아래 링크에 첨부를 해뒀습니다.

저는 설정을 모두 끝마치고 서버를 다시 재시작할 것이기 때문에 standalone 옵션을 사용해서 발급했습니다.

 

위 명령어를 치면 이메일을 치라고 하고, 몇 가지 동의 사항을 받습니다. 본인의 이메일을 입력하고, yes를 입력해 주면 됩니다.

그러고 나서 마지막에 도메인을 입력하라고 합니다. 이때 저희가 구매한 도메인을 입력해 줍니다. (DNS 서버에 등록된 상태여야 합니다.)

 

입력하라고 하는 것을 모두 입력해 주면 LetsEncrypt에서 우리 도메인에 어떤 요청을 보내고, 제대로 연결된 도메인이 맞는지 확인하는 작업을 한 후 아래와 같은 문구가 뜹니다.

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/subbak2.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/subbak2.com/privkey.pem

 

💡 만약 계속해서 certification failed이 뜬다면 몇 가지를 확인해 보자!

(1) 우리 서버가 이미 80번 포트를 사용하고 있지는 않은가?
: LetsEncrypt는 80번 포트(http)로 GET 요청을 보내서 어떤 처리를 하고 나서 응답되는 결과가 기대한 결과여야 성공적으로 인증서를 발급해 준다. 하지만 80번 포트를 이미 누군가 쓰고 있으면 안 된다.

(2) 도메인이 DNS 서버에 잘 등록이 되었는가?
: LetsEncrypt가 이 도메인이 우리 서버와 잘 연결되었는지 확인하기 때문에 필수 조건이다. 이건 터미널에서도 확인이 가능하다. nslookup {도메인} 명령어를 사용해 보자.

 

 

 

(6) 인증을 통해 받은 파일로 Springboot 프로젝트로 가져갈 keystore 파일 생성하기

$ cd /etc/letsencrypt/live/subbak2.com

위 경로로 이동을 해봅시다. 위 경로는 인증 성공했을 때 나왔던 메시지의 경로입니다. 인증을 통해 만들어진 pem 파일이 있는 곳입니다.

 

저는 위 경로로 이동하려고 했을 때, live 파일에 대한 접근 권한이 없었습니다. 그래서 접근 권한을 풀어준 후 접근했습니다.

$ sudo chmod 777 live

이제 위 경로로 이동했다면 발급받은 pem 파일을 통해서 keystore 파일을 만들어 내야 합니다.

$ openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name tomcat -CAfile chain.pem -caname root

코드는 길지만 그냥 Certbot을 통해서 발급받은 fullchain.pem과 privkey.pem을 이용해서 지지고 볶고 해서 Springboot에서 사용할 암호화된 keystore.p12 파일을 만든다는 명령어이다.

 

위 명령어를 입력하면 비밀번호를 치라고 하는 게 나오는데, 이때 치는 비밀번호는 나중에 application.yml에 넣어줘야 하는 비밀번호입니다. 아무거나 입력해도 되는데 기억하고 있어야 합니다.

 

생성된 keystore.p12를 Spring 프로젝트의 /src/main/resources로 가져가야 합니다. 이때는 리눅스의 mv 명령어로 가져가봅니다.

keystore.p12의 파일 권한이 없다면 권한을 허용하고, 이동을 해준다.

$ sudo chmod 777 keystore.p12
$ mv keystore.p12 {/src/main/resoureces 경로}

 

 

 

(7) application.yml 설정

#SSL
server:
  ssl:
    enabled: true
    key-store: classpath:keystore.p12
    key-store-type: PKCS12
    key-store-password: {keystore.p12 파일 만들 때 입력한 비밀번호}
    key-alias: tomcat

security:
  require-ssl: true

classpath:는 모두 알겠지만 /src/main/resources 경로를 나타냅니다.

 

아래 있는 security 설정은 Spring Security 때문에 해둔 설정인데, 추가하지 않아도... 되는 거 같은데 더 알아봐야 할 거 같습니다.

 

 

 

(8) 포트 포워딩 설정

이제 https://poppleserver.store로 요청을 하면 Spring 내장 톰캣의 8080으로 연결되도록 하고 싶습니다.

이때는 443 포트(HTTPS)로 들어온 요청을 8080 포트(톰캣)로 포트 포워딩을 해줍니다.

그럼 이제 https://poppleserver.store로 요청을 보내면 8080 포트로 포트 포워딩이 되어 실행됩니다.

$ sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8080

 

 

 

(9) https://{구매한 도메인}에 들어가서 API 요청 보내서 확인

위에 주소창 왼쪽에 자물쇠 모양이 생기고, 정상적으로 요청이 간다면 성공입니다!

주소창 자물쇠 확인

LetsEncrypt는 무료이지만, 단점이라고 하면 90일마다 인증서를 재발급해줘야 하는 귀찮음이 있습니다. 이 부분도 찾아보니 자동화를 하는 방법이 있었는데, 필요해질 때 적용해 보면 될 거 같습니다.

 

 

 

 

🔗 참고 링크


https://velog.io/@kirilocha/Spring-boot-SSL-%EC%9D%B8%EC%A6%9D%EC%84%9C-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0

 

Spring boot SSL 인증서 적용하기

요즘 웹사이트는 기본적으로 HTTPS를 바탕으로 동작한다. HTTPS의 S는 secure을 나타내는 약자로 HTTP통신을 통해 주고받는 데이터를 암호화 하는 것을 말한다. 즉, 안전한 사이트라는 걸 인증하기 위

velog.io

https://catalina.tistory.com/17

 

리눅스 80 to 8080 포트포워딩

포트포워딩(Port Forwarding) 현재 웹 서비스 실행한 것을 웹 브라우저에서 보려고 하면 :8080 을 뒤에 붙여줘야 한다. 이 포트 번호를 없애려면 어떻게 해야할까? HTTP 요청에서 80포트가 기본 포트이기

catalina.tistory.com

https://ecogis.net/268

 

우분투 포트 포워딩 조회 및 설정 삭제

1. 포트 포워딩 80포트를 5000포트로 포트 포워딩하기 위해 다음 구문을 실행한다. web1mhz@deepgis:~$sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 5000 2. 포트 포워딩 조회 80포트를 5000

ecogis.net

https://velog.io/@chrkb1569/Spring-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%B0%B0%ED%8F%AC-%EB%8F%84%EB%A9%94%EC%9D%B8-%EC%84%A4%EC%A0%95

 

[Spring] 프로젝트 배포 & 도메인 설정

AWS EC2를 통한 프로젝트 배포 & 가비아를 활용한 도메인 설정

velog.io

https://m.blog.naver.com/hsmang/221836126462

 

Amazon Linux2 Certbot 인증하기 (Nginx 사용 )

참고 링크 https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/SSL-on-amazon-linux-2....

blog.naver.com