Post

ELB 를 활용한 HTTPS 적용하기와 SSL 인증서가 그래서 어떻게 동작하는데?

안녕하세요! 이번에 [2024 SKT-하나금융그룹 TECH4GOOD] 에 (강제) 참여하게 되면서 1박 2일로 짧게 개발을 진행하게 됐는데요! 비록 결과는 아쉬웠지만, 내가 짧은 시간 안에 이 정도의 아웃풋을 낼 수 있는 사람이구나를 알 게 되었고 또 기획적으로 이런 부분이 아쉬웠구나 등을 느낄 수 있어서 그럼에도 뜻 깊은 시간이었습니다

image

개발을 진행하던 중에 프론트가 버셀로 배포하게 되면서 백엔드도 HTTPS 를 필수적으로 설정해야 했는데요 ELB를 활용해서 HTTPS 를 적용한 경험과 또 SSL 인증서와 HTTPS 가 어떻게 보안적으로 더 안전할 수 있는지에 대한 궁금증이 생겨 이에 대해 블로그를 써보려고 합니다!

아쉬운 점이 하나 있다면, 빠른 시간 내에 아웃풋을 내야 하다 보니 ELB 적용 과정에 대해 캡쳐를 거의 못했습니다만.. 모두가 쓸 수 있는 블로그는 지양하고, 내 경험을 녹일 수 있는 블로그를 쓰자 가 블로그 원칙 중 하나라.. 이렇게 된 거 없는 사진과 적용 과정 만큼, 그 분량으로 더 알차게 내용을 녹이려 노력하려고요 😓 나중에 다시 적용하는 기회가 조만간 생기면, 그때 사진을 더 추가하도록 하겠습니다

HTTPS 왜 필요할까?

일단.. 솔직하게 저는 이틀 간의 해커톤이고 아이디어가 중요했기에 HTTPS 설정까지는 크게 고려하지 않았으나 프론트가 버셀로 배포되면서 서버도 HTTPS 설정이 불가피해졌습니다.

혹시 HTTP 사이트를 이용하시면서 사이트가 보안 연결(HTTPS)가 사용되지 않아 사이트 정보가 공격자에 의해 도용될 수 있다는 위험 문구를 마주해보신 적 있으실까요? 저는 예전에 저런 문구를 보면서 HTTPS가 뭐길래, 사용하지 않으면 공격자가 도용할 수 있게 될까 궁금했었는데요!

따라서 HTTPS 설정이 왜 필요한가에 대해 함께 설명해보고자 합니다

이유 1. 데이터 암호화

데이터를 평문으로 전송하기 때문에, 네트워크에서 데이터를 가로채는 중간자 공격에 매우 취약합니다. 특히, 로그인 정보나 개인 데이터가 전송될 때 이 정보들이 쉽게 노출될 수 있습니다. HTTPS는 SSL/TLS 프로토콜을 통해 데이터를 암호화하므로, 중간에 누군가가 데이터를 가로채더라도 그 내용이 암호화되어 해독할 수 없어 데이터의 기밀성을 보장합니다.

이러한 데이터 암호화는 TLS 프로토콜을 통해 이루어지며,
여기서 중요한 두 가지 개념은 비대칭키 암호화와 대칭키 암호화입니다.

비대칭키 암호화

통신 초기에 클라이언트와 서버는 서로의 신원을 확인하기 위해 비대칭키 암호화를 사용합니다. 비대칭키 암호화는 공개키개인키로 이루어지며, 이 두 키는 한 쪽에서 암호화한 데이터는 다른 쪽에서만 복호화할 수 있는 특성을 가집니다. 서버는 SSL 인증서를 통해 공개키(공개적으로 알려져도 되는 키)를 브라우저에 제공합니다. 브라우저는 서버의 공개키를 사용해 데이터를 암호화해서 서버로 전송하고, 서버는 자신만이 보유한 비밀키(비공개된 개인키)를 사용해 이 데이터를 복호화합니다. 이 비대칭키 암호화는 안전하지만 성능이 느리기 때문에, 주로 초기에만 사용됩니다.

  • 비대칭키 암호화 과정
    1. 서버는 서버 난수와 SSL 인증서를 클라이언트(브라우저)에게 제공합니다. 이 인증서에는 서버의 공개키와 서버의 신원을 확인할 수 있는 정보( 공인 인증 기관(CA)이 서명한 서버 인증서 등)가 포함되어 있습니다.

    2. 클라이언트는 서버로부터 받은 공개키를 사용해 프리 마스터 시크릿(Pre-Master Secret)이라는 데이터를 암호화합니다. 이 프리 마스터 시크릿은 클라이언트와 서버가 세션 키를 만들기 위한 중요한 정보입니다.

    3. 서버는 클라이언트가 공개키로 암호화한 프리 마스터 시크릿을 자신의 개인키를 사용해 복호화합니다. 서버는 이를 통해 세션 키 생성에 필요한 정보를 얻습니다.

대칭키 암호화

비대칭키 암호화를 통해 클라이언트와 서버는 안전하게 세션 키(Session Key)를 공유하게 됩니다. 이 세션 키는 대칭키 암호화를 위해 사용됩니다. 대칭키 암호화에서는 동일한 키를 사용해 데이터를 암호화하고 복호화하기 때문에 매우 빠르고 효율적입니다. 세션 키는 TLS 핸드셰이크 과정에서 협상된 키로, 세션이 유지되는 동안 사용됩니다.

  • 대칭키 암호화의 과정
    1. 세션 키 생성: 대칭키 암호화에서 사용되는 세션 키는 클라이언트 난수서버 난수, 그리고 클라이언트가 생성한 프리 마스터 시크릿(Pre-Master Secret)을 조합하여 생성됩니다. 이 세션 키는 대칭키 암호화에 사용됩니다.
      • 클라이언트 난수: 클라이언트가 핸드셰이크 과정에서 서버에게 전송한 난수(random number).
      • 서버 난수: 서버가 클라이언트에게 SSL 인증서를 전송할 때 함께 전송한 난수.
      • 프리 마스터 시크릿: 클라이언트가 서버의 공개키로 암호화하여 전송한 중요한 값. 이 세 가지 값을 조합하여 양측(클라이언트와 서버)은 동일한 세션 키를 독립적으로 생성합니다. 이를 통해 두 측은 동일한 키로 데이터를 암호화하고 복호화할 수 있게 됩니다.
    2. 대칭키 암호화 시작: 클라이언트와 서버가 생성한 세션 키는 이후 대칭키 암호화에서 사용되는 키로, 통신을 위해 사용됩니다. 대칭키 암호화는 동일한 키로 데이터를 암호화하고, 동일한 키로 데이터를 복호화하게 됩니다.
      • 클라이언트가 세션 키로 암호화한 데이터를 서버로 전송하면, 서버는 해당 세션 키로 데이터를 복호화합니다.
      • 서버가 세션 키로 암호화한 데이터를 클라이언트로 전송하면, 클라이언트는 세션 키로 이를 복호화합니다.

    이렇게 사용된 세션 키는 세션이 끝나면 더 이상 사용되지 않으며, 양측은 새로운 세션을 시작할 때마다 동일한 과정을 거치며 새로운 세션 키를 협상해야 합니다.

이유 2. 데이터 무결성

HTTPS는 단순히 데이터를 암호화하는 것뿐만 아니라 무결성도 보장합니다. 방금 전 중간자 공격에 대해 언급했었는데요! 중간에 악의적인 해커가 데이터를 탈취해 변조하지 않았는지를 체크합니다.

메시지 인증 코드(MAC)

HTTPS는 데이터가 전송되는 도중 변조되지 않도록 메시지 인증 코드, MAC(Message Authentication Code)을 사용합니다. MAC은 암호화된 해시 값을 사용하여 전송된 데이터가 변조되었는지 확인하는 역할을 합니다. MAC은 데이터를 보낸 쪽에서 생성하여 함께 전송하고, 받는 쪽에서 이 MAC 값을 재계산해 원래 데이터와 비교합니다. 만약 데이터가 전송 중에 변조되었다면, 재계산된 MAC 값이 달라져 변조된 사실을 알 수 있습니다.

  • MAC의 동작 방식
    1. 데이터 전송 전 준비: 데이터를 보내는 측(아마 웹 서버)은 전송할 데이터를 먼저 준비하고, 이를 기반으로 MAC 값을 생성합니다. 이때, 대칭키 암호화 방식을 사용하여 데이터와 함께 공유된 비밀 키(대칭키)를 입력으로 사용해 MAC 값을 계산합니다.
    2. MAC 값 생성: 서버는 전송하려는 원본 데이터와 공유된 대칭키(세션키)를 사용해 MAC 값을 계산합니다. 이 과정은 보통 암호화 해시 함수(예: HMAC-SHA256) 같은 알고리즘을 통해 수행됩니다. 예를 들어,
      1
      
        MAC = HMAC(대칭키, 데이터)
      

      여기서 HMAC은 해시 기반 메시지 인증 코드(HMAC) 알고리즘입니다.

    3. 데이터와 MAC 값 전송: 데이터를 보내는 측은 원본 데이터를 전송할 때, 해당 데이터의 MAC 값도 함께 전송합니다. 이렇게 하면 받는 쪽에서 데이터와 MAC 값을 비교하여 데이터가 안전하게 도착했는지 확인할 수 있습니다.
    4. 받는 쪽에서 MAC 재계산: 데이터를 받는 측(예: 클라이언트)은 서버로부터 받은 데이터를 가져와, 같은 방식으로 MAC 값을 재계산합니다. 이때도 데이터와 함께 공유된 비밀키를 사용하여 MAC을 계산합니다. 예를 들어,
      1
      
        MAC' = HMAC(대칭키, 받은 데이터)
      
    5. MAC 값 비교: 데이터를 받은 클라이언트는 서버에서 보낸 MAC 값과 자신이 재계산한 MAC 값(MAC’)을 비교합니다.
      • 동일하다면: 데이터는 전송 중 변조되지 않았으며 무결성이 보장됩니다.
      • 다르다면: 전송 중에 데이터가 변조되었을 가능성이 있습니다. 이는 데이터가 중간에서 수정되었음을 의미하며, 클라이언트는 해당 데이터를 신뢰하지 않습니다.

이유 3. 서버 인증

HTTPS는 또한 서버의 신원을 확인할 수 있도록 돕습니다. SSL/TLS 인증서를 통해 웹사이트가 신뢰할 수 있는 서버임을 증명하므로, 피싱 사이트나 악의적인 서버로부터 사용자를 보호할 수 있습니다. 인증서는 공인 인증 기관(CA)이 발급하며, 클라이언트는 서버가 진짜 사이트임을 확인할 수 있습니다. 이를 통해 사용자와 서버 간의 신뢰를 구축합니다.

공인인증기관 (CA)

CA(Certificate Authority)는 공인 인증 기관으로, 인터넷 상에서 특정 서버가 진짜 서버임을 보장해주는 역할을 합니다. 이를 통해 사용자(클라이언트)는 자신이 방문한 웹사이트가 실제로 신뢰할 수 있는 웹사이트인지 확인할 수 있습니다.

  • SSL/TLS 인증서란?:
    비대칭키 암호화에서 잠시 SSL 인증서가 나왔었는데요! SSL/TLS 인증서는 서버가 웹사이트에서 안전한 HTTPS 연결을 제공할 수 있도록 보장하는 디지털 문서입니다. 이 인증서에는 서버의 신원을 증명하는 정보가 들어 있습니다. 인증서를 통해 클라이언트는 해당 서버가 가짜 서버(피싱 사이트 등)가 아닌 진짜 서버라는 것을 알 수 있습니다.

  • CA의 인증서 발급 및 체인
    CA는 서버가 안전하고 신뢰할 수 있다는 사실을 검증하고, 이를 바탕으로 SSL/TLS 인증서를 발급합니다. 클라이언트는 CA가 발급한 인증서를 통해 서버의 신원을 확인할 수 있습니다.
    이러한 CA는 루트 인증서를 가지고 있으며, 루트 CA는 자체적으로 인증서를 발급할 수 있습니다. 하지만 일반적으로는 중간 CA가 루트 CA의 신뢰를 받아 인증서를 발급합니다. 이렇게 하면 루트 CA의 인증서가 노출되지 않고 안전하게 관리될 수 있습니다.

    • 루트 CA: 공인된 CA의 인증서로, 각 브라우저와 운영체제는 이 루트 인증서를 신뢰합니다.
    • 중간 CA: 루트 CA에 의해 인증된 CA로, 루트 CA를 대신해 SSL 인증서를 발급합니다.
    • 서버 인증서: 중간 CA가 서버에 발급하는 인증서입니다.

이 인증서들이 인증서 체인을 형성하여 클라이언트는 루트 인증서까지 추적하면서 신뢰성을 확인합니다.

  • CA의 역할
    그렇다면 CA는 인증서 발급을 위해 어떻게 서버가 신뢰할 수 있다는 걸 알 수 있을까요? 다음으로는 CA가 어떠한 과정으로 서버의 신원을 보증하는지를 살펴보려 합니다
    1. 서버의 공개키를 인증서에 포함: 서버는 CA에 SSL/TLS 인증서를 요청할 때, 자신의 공개키를 CA에 전달합니다. CA는 서버의 공개키를 포함한 인증서를 발급합니다. 클라이언트는 서버와의 HTTPS 통신을 시작할 때 이 인증서를 다운로드하고, 이를 통해 서버의 공개키를 얻습니다.
    2. 서버 검증: CA는 서버가 주장하는 도메인에 대한 소유권을 확인하고, 서버의 신원을 검증한 후에 인증서를 발급합니다. 도메인 소유권 검증 과정에는 서버가 해당 도메인의 소유권을 실제로 가지고 있는지 확인하는 절차가 포함됩니다. 예를 들어, CA는 서버가 소유한 이메일 주소로 확인 메일을 보내거나, 해당 도메인에 특정 파일을 업로드하도록 요청할 수 있습니다.
    3. CA의 디지털 서명: CA는 서버의 인증서에 디지털 서명을 추가합니다. 이 서명은 CA의 비밀키를 사용하여 생성되며, 클라이언트는 이 서명을 통해 인증서가 진짜 CA에서 발급된 것인지 확인할 수 있습니다.

지금까지는 CA가 무엇이고, 어떤 과정을 통해 서버의 신원을 보증하는지에 대해 살펴보았는데, 그럼 이제 서버는 이 인증서를 어떻게 발급 요청 하고, 클라이언트는 서버가 발급받은 인증서를 통해 어떻게 해당 서버가 신뢰할 만 한 서버인지를 확인하는지에 대해 살펴보려 합니다

  • 인증서 발급 과정
    먼저 서버가 SSL/TLS 인증서를 요청하고 발급받는 과정은 다음과 같습니다

    1. 서버 인증서 요청: 서버 관리자는 CA에 서버의 공개키와 도메인 정보가 포함 되어 있는 CSR (Certificate Signing Request) 파일을 제출합니다.
    2. CA의 검증: CA는 서버가 실제로 해당 도메인을 소유하고 있는지 도메인 소유권을 검증하고, 서버 정보가 정확한지 등 서버에 대한 신원 확인 절차를 거칩니다.
    3. 인증서 발급: 검증이 완료되면 CA는 서버의 공개키와 서버 정보, 그리고 CA의 디지털 서명이 포함된 SSL/TLS 인증서를 발급합니다.
    4. 인증서 설치: 서버는 발급받은 인증서를 자신의 서버에 설치하고, 클라이언트와의 HTTPS 연결에서 이 인증서를 사용합니다.
  • 인증서 검증 과정
    클라이언트(브라우저)는 HTTPS 사이트에 접속할 때 서버로부터 SSL/TLS 인증서를 받는데요,
    이때, 클라이언트는 다음 단계를 통해 인증서를 검증합니다.

    1. 신뢰된 루트 인증서 확인: 클라이언트는 운영체제나 브라우저에 내장된 루트 인증서 목록을 가지고 있습니다. 이 루트 인증서는 공인된 여러 CA의 인증서로, 브라우저는 여기에 포함된 CA를 신뢰합니다. 서버가 제공한 인증서가 신뢰된 CA에서 발급된 것인지, 인증서 체인을 확인합니다.
    2. 디지털 서명 검증: 클라이언트는 CA의 공개키를 사용해 서버 인증서의 디지털 서명을 검증합니다. CA가 인증서에 서명할 때 사용한 비밀키의 쌍인 공개키로 서명을 확인하며, 이를 통해 인증서가 신뢰된 CA에서 발급된 것인지 확인할 수 있습니다.
    3. 인증서의 유효성 검사:
      • 유효 기간: 클라이언트는 인증서가 만료되었는지, 또는 아직 유효한지 확인합니다.
      • 도메인 일치: 인증서에 포함된 도메인이 클라이언트가 접속한 웹사이트의 도메인과 일치하는지 확인합니다.
      • 취소 여부: 클라이언트는 인증서가 인증서 폐기 목록(CRL, Certificate Revocation List) 또는 OCSP(Online Certificate Status Protocol)을 통해 취소되지 않았는지 확인합니다.

이렇게 인증서가 유효하고 서명이 확인되면, 클라이언트는 서버가 신뢰할 수 있는 웹사이트임을 확인하고 안전하게 통신을 시작합니다!

HTTPS 동작 구조 : TLS 핸드셰이크

위에서 설명한 일련의 과정들을 요약해서 6컷 만화로 그려봤습니다! 귀엽죠? 😝

제목_없는_아트워크

세션이 종료될 때는 클라이언트가 서버에게 TLS 프로토콜의 종료 알림인 “Close_notify” 메시지를 TLS 경고 레코드에 포함된 경고 코드로 설정해 보냄으로써 종료를 요청하고 서버는 메세지를 받아 세션 종료 요청을 인식하면 서버도 클라이언트에게 자신의 “Close_notify” 메시지를 보내, 서버도 세션 종료를 시작한다는 것을 알립니다. 이렇게 클라이언트와 서버가 “Close_notify” 메시지를 주고받은 후에는 양측 모두 세션에서 사용했던 세션 키를 즉시 폐기합니다.

HTTPS, 어떻게 설정할까?

일단 가장 먼저, HTTPS 를 설정하는 방법에는 크게 3가지가 있습니다.

  1. 직접 CA에서 구매한 인증서를 기반으로 HTTPS 서비스를 구축하는 방법
  2. 서버 앞단에 HTTPS를 제공하는 CDN 을 둬서 구축하는 방법
  3. 서버 앞단의 HTTPS를 제공하는 로드밸런서를 두는 방법

저는 이 중에서 3번, 서버 앞단의 HTTPS를 제공하는 로드밸런서를 두는 방법을 선택했는데요!
그 이유에 대해 설명 해보려 합니다

방법 1. 직접 CA에서 구매한 인증서를 기반으로 HTTPS 서비스 구축

제가 파악한 다음 방법의 장단점은 다음과 같았습니다

장점단점
✅ 서버에 직접 인증서를 설치하므로
서버 설정을 세밀하게 제어할 수 있다.
❎ 인증서 갱신, 만료일 관리, CA와의 상호작용
등을 직접 해야 하므로 관리 부담이 크다.
✅ 서버가 모든 HTTPS 트래픽을 처리하므로
보안 정책을 서버 수준에서 세밀하게 적용할 수 있다.
❎ 서버에서 HTTPS 암호화를 직접 처리해야
하므로 CPU 사용량이 증가할 수 있어,
트래픽이 많아지면 서버 성능에 영향을 줄 수 있다.

저는 서버가 비교적 가볍고 트래픽이 많지 않은 소규모 서비스이긴 했지만, 인증서 관리의 번거로움을 피하고 싶었기에 해당 방법은 패스했습니다.

방법 2. 서버 앞단에 HTTPS를 제공하는 CDN을 둬서 구축

제가 파악한 다음 방법의 장단점은 다음과 같았습니다

장점단점
✅CDN은 콘텐츠를 사용자 가까운 엣지 서버에서 제공하므로,
전 세계 사용자에게 빠르게 서비스를 제공할 수 있다.
CDN 서비스를 이미 이용하고자
한다면 일석이조가 될 수 있다.
❎ CDN 서비스는 트래픽 양에 따라
비용이 발생하기 때문에,
대용량 트래픽을 처리할 때
비용이 빠르게 증가할 수 있다.
✅CDN은 DDoS 방어, WAF(웹 애플리케이션 방화벽) 등의
보안 기능을 기본으로 제공하므로,
서버 보안을 강화할 수 있다.
❎ CDN을 처음 설정하는 과정에서
캐시 설정, 도메인 설정 등이 추가적으로 필요하다.
✅SSL/TLS 인증서를 자동으로 관리해주므로,
서버 측에서 별도로 인증서를 관리할 필요가 없다.
 

일단 음.. 이 방식은 프론트에 HTTPS 를 적용하고 싶을 때 Cloudflare, AWS CloudFront 등을 이용해 HTTPS 를 설정하는 방법이지, 서버를 위한 방법이라기엔 무리가 있지 않을까? 라는 개인적인 생각 있었고, 트래픽도 적은데 필요 이상의 기능이기도 하고, CDN은 CDN은 주로 정적 콘텐츠(이미지, CSS, JavaScript 파일 등)를 전 세계 엣지 서버에 캐시해서 사용자가 가까운 서버에서 콘텐츠를 빠르게 제공받도록 도와주는 시스템인데 외부 사용자와의 직접적인 접점이 많지 않은 서버의 경우 CDN 을 붙일 필요가 없어 패스하게 됐습니다.

CDN은 주로 정적 콘텐츠 캐시에 특화되어 있어, 실시간으로 변화하는 동적 데이터(사용자 세션, DB 조회 결과 등)를 처리하는 데는 적합하지 않은데다가, 정적 콘텐츠 트래픽이 많아지면 사용량에 따라 비용이 급증할 가능성도 있습니다.

만약 프론트를 HTTPS 설정을 해야 하는 상황이었다면 해당 방법을 선택했을 겁니다.

방법 3. 서버 앞단에 HTTPS를 제공하는 로드 밸런서를 둬서 구축

결국 제가 채택하게 된 방법인데요, 제가 파악한 다음 방법의 장단점은 다음과 같았습니다

장점단점
✅로드 밸런서가 서버에 가해지는
HTTPS 처리 부하를 대신 처리하기 때문에,
서버는 HTTP만 처리하므로
리소스 소모가 줄어든다.
❎ 로드 밸런서를 사용하면 추가 비용이 발생할 수 있다.
✅로드 밸런서가 트래픽을
여러 서버로 분산시키기 때문에
트래픽 증가에 대응하기가 쉬워져, 확장성이 좋다
❎ 로드 밸런서 설정이 추가되기 때문에
처음 설정할 때 약간의 복잡함이 있을 수 있다.
✅로드 밸런서에서 인증서 관리가 가능하여
서버마다 별도로 인증서를 설치할 필요가 없다.
❎ 로드밸런서와 백엔드 서버 간의 트래픽이 암호화되지 않기 때문에,
내부 네트워크가 충분히 안전하지 않다면 데이터가 유출될 가능성이 있다.

일단 저는 인증서 관리를 로드 밸런서에서 처리할 수 있으므로 서버마다 SSL 설정을 할 필요가 없어 관리가 편리하다는 장점으로 인해 해당 방법을 선택하게 되었습니다. 물론 저는 동적 데이터 처리와 트래픽 분산, 고가용성 유지 등의 기능이 필요한 상황은 아니었지만 인증서 관리를 대신 해주는 2가지 방법 중 더 서버를 위한 방법이기 때문이기도 했습니다. 또 HTTPS 트래픽 처리를 로드밸런서에서 대신해줌으로써 백엔드 서버의 부하를 줄일 수 있기도 했고요.

이 방식을 채택하게 되면 로드밸런서가 클라이언트의 SSL 인증서를 검증한 뒤, HTTPS 요청을 해제한 후 HTTP로 백엔드 서버에 요청을 전달하기 때문에 나중에 실제 서비스를 좀 더 기간을 두고 배포해야할 일이 생긴하면
클라이언트와 서버 간 모든 구간에서 암호화를 유지하여 데이터 유출 가능성을 최소화할 수 있으므로 End-to-End Encryption 방식으로 방식 1도 함께 적용할 수 있으면 좋을 것 같습니다.

Nginx vs ELB 어떤 걸로 HTTPS 를 설정할까?

그래서 서버 앞단에 HTTPS를 제공하는 로드 밸런서를 두려고 했는데요!

먼저 제가 왜 nginx 가 아닌 ELB 로 HTTPS 를 적용하였는가, 그 판단 이유에 대해 먼저 이야기 해보려고 합니다
먼저 제가 생각한 각각의 방식의 장단점은 다음과 같았습니다

비고ELBNginx
장점✅ SSL 인증서 관리, 자동 갱신, 인증서 설치 등의
작업을 AWS가 대신 처리하므로 관리 부담이 적다
✅ 트래픽 부하를 자동으로 분산하고 수평적으로
확장할 수 있어, 높은 트래픽을 처리에 유리하다
✅ AWS에서 제공하는 인증서를 사용하면 보안
설정이 강화되고 최신 보안 규정을 준수할 수 있다
✅ 고도로 커스터마이징 가능하여 특정 트래픽 처리 방식
이나 고급 보안 설정에 용이하다
✅ 자체적으로 SSL 인증서를 관리하면 ELB를 사용할
때보다 비용을 절감할 수 있다
단점❎ ELB 사용에 비용이 들며 특히 대규모 트래픽
의 경우 비용이 증가할 수 있다
❎ SSL 설정에 대한 세부적인 조정이 필요한 경우
제한이 있을 수 있다.
❎ 인증서 관리, 갱신, 보안 설정 등 모든 과정을
직접 관리해야 한다.
❎ 자체 인프라에서 수평적 확장을 구축해야 하므로,
클라우드 네이티브 방식의 확장성에서 떨어질 수 있다.

따라서 AWS와 같은 클라우드 환경을 사용하고 있으며, 확장성, 관리 편의성, 자동화된 SSL 인증서를 원한다면 ELB가, 특정 요구 사항에 맞게 세부적인 설정이 필요하거나 비용을 최소화해야 하는 경우, 그리고 온프레미스나 자체 서버 인프라를 사용하는 경우에는 Nginx가 더 부합하다 판단했습니다.

제 경우에는 AWS 에서 모든 환경이 구성되어 있었으며 (RDS, EC2 배포 등) 지원받는 비용이 있었고 이틀 간 서버를 띄우면 됐기에 비용 부담이 크게 없었으며 세부적인 설정보다는 빠르고 편리한 SSL 인증서가 필요했기에 ELB 사용을 선택했습니다.

ELB로 HTTPS 설정하기

설정 방법에 대해서는 나중에 다시 적용하게 되면 그때 사진과 함께 추가하도록 하겠습니다.. 지금은 어떻게 설정이 됐는지만 유일하게 캡쳐한 사진 두 장으로 간략하게 설명해보려고 하는데요!

대상그룹 설정

사진 상에 표기된 설정에 대해 간단하게 설명하고 넘어가겠습니다.

먼저 대상 그룹을 준비합니다. 저는 대상 그룹의 이름을 yesable-target-group 라고 명명해주었습니다. 이 그룹은 로드 밸런서가 트래픽을 라우팅할 때 어떤 대상(서버 또는 인스턴스)으로 보낼지 정의합니다.

먼저 제 대상 그룹에서는 인스턴스로 설정해 로드 밸런서가 트래픽을 AWS EC2 인스턴스로 전달하도록 했습니다. 또 대상 그룹이 트래픽을 EC2 인스턴스로 전달할 때 EC2 인스턴스 내부에 SSL 인증서를 설치하진 않았기에 HTTP 프로토콜을 사용하고 , 포트 9475 로 전달하도록 설정하며 프로토콜 버전으로는 HTTP/1.1 버전을 사용해 IPv4 주소 체계의 인스턴스로 연결하도록 합니다. HTTP 프로토콜 버전 별 차이가 궁금하시면 HTTP 와 HTTPS 의 비교 에 정리해두었습니다 😃 HTTP와 HTTPS의 차이도 정리해두었으니 관심 있으신 분들은 참고하시면 좋을 것 같습니다

Video Label

HTTPS와 동작 방식에 대해 알기 쉽게 설명한 유튜브가 있어 관심 있으신 분들은 추천드립니다! 개인적으로 해당 유튜버분이 전체적으로 알게 쉽게 설명해주셔서 좋아합니다

이때, 사진 상으로 비정상이라고 뜨는 이유는 헬스 체크에 실패했기 때문입니다.

헬스체크란?

헬스체크란, 서버나 컴퓨터가 잘 작동하고 있는지 확인하는 일종의 건강검진 입니다. ELB에서 헬스체크가 필요한 이유는 ELB는 여러 대의 서버에 걸쳐 트래픽을 분산시키는 역할을 하는데 이때 각 서버의 건강 상태를 지속적으로 점검하여 문제가 있는 서버에는 트래픽을 보내지 않도록 관리하기 때문입니다.

설정된 간격에 따라 ELB는 각 서버로 핑 요청을 보내고 서버가 제시간에 올바르게 응답하면 그 서버는 건강하다고 판단합니다. 서버가 응답하지 않거나 오류 응답을 반환하면 설정된 실패 임계값에 도달할 때까지 계속 검사를 수행합니다. 임계값에 도달하면 해당 서버는 건강하지 않다고 판단되어 트래픽에서 제외됩니다. 비정상으로 판단된 서버가 다시 연속적으로 건강 판정 임계값만큼 정상 응답을 하면 다시 트래픽을 받을 수 있게 합니다.

이때 핑 (Ping) 요청이란 컴퓨터 네트워크에서 특정 서버나 장치가 온라인 상태인지 확인하기 위해 사용하는 테스트 방법으로 네트워크 통신 문제를 진단하는 데 사용하는 네트워크 계층 프로토콜인 ICMP(Internet Control Message Protocol)라는 프로토콜을 사용해 네트워크 상의 다른 장치에 “나 여깄는데 너 응답할 수 있어?”라고 묻는 방식입니다. 이를 통해 네트워크 연결 상태를 확인하고 네트워크 연결에 문제가 있을 때, 어느 지점에서 문제가 발생했는지 진단할 수 있으며 요청을 보내고 응답이 돌아오기까지 걸린 시간을 통해 네트워크의 속도(응답 시간)를 파악할 수 있습니다.

이렇게 ELB는 서버 그룹의 건강을 지속적으로 모니터링하면서 트래픽을 안정적으로 관리할 수 있도록 하며 전체 시스템의 가용성과 안정성을 높이는 데 중요한 역할을 합니다.

헬스체크 설정하는 법

이렇게 중요한 헬스체크, 어떻게 설정할까요?

IMG_0061

일단 ELB 설정 하단에 다음 사진과 같이 헬스체크를 설정할 수 있습니다. 일단 저는 대상 그룹의 각각의 EC2 인스턴스에 HTTP 프로토콜을 활용해 GET /health URI로 요청을 보내게끔 설정합니다. 정상적인 헬스 체크 기능을 위해 EC2 인스턴스에서 작동하고 있는 백엔드 서버에 Health Check용 API를 만들어야 합니다!

1
2
3
4
5
6
7
8
9
@Slf4j
@RestController
@RequiredArgsConstructor
public class HealthController {
    @GetMapping("/health")
    public ResponseEntity<String> healthcheck() {
        return new ResponseEntity<>("ok", HttpStatus.OK);
    }
}

따라서 다음과 같은 Health Check용 API를 추가해주면, ELB가 서버로 핑 요청을 보내고 서버가 제시간에 올바르게 응답하는지를 테스트합니다. 더 자세한 내용을 알고 싶으면 AWS의 Network Load Balancer 대상 그룹의 상태 점검 글을 읽어보시면 좋을 것 같습니다!

로드 밸런서 설정

이제 로드 밸런서의 설정에 대해 살펴 보겠습니다.

로드 밸런서엔 HTTPS:443 리스너가 설정 되어 있습니다. 리스너는 로드 밸런서가 클라이언트 요청을 수신하는 방법을 정의합니다. 여기서 HTTPS:443은 로드 밸런서가 포트 443(HTTPS 기본 포트)에서 HTTPS 프로토콜을 사용해 클라이언트 요청을 수신합니다. 클라이언트의 HTTPS 요청이 로드 밸런서에 도달 하면 로드 밸런서는 이 요청을 위에 설정한 보안 그룹인 yesable-target-group-https로 전달합니다.

즉, 로드 밸런서가 HTTPS:443으로 클라이언트의 요청을 수신하고 이후 대상 서버로 HTTP 프로토콜을 사용해 트래픽을 전달하도록 설정했습니다. 로드 밸런서가 프록시 서버와 같은 역할을 하도록 한 겁니다.

프록시 서버와 로드 밸런서의 상관관계

프록시 서버와 로드 밸런서의 공통점은 둘 다 클라이언트와 서버 사이에서 요청을 중계하는 역할을 합니다. 클라이언트가 직접 서버에 요청을 보내는 대신, 먼저 로드 밸런서나 프록시 서버에 요청을 보내고, 이 서버가 요청을 최종 목적지인 서버로 전달하는 구조를 갖습니다.

다만 차이점도 존재하는데요, 로드 밸런서는 서버 간의 부하를 분산하고 가용성을 보장하는 것에 주된 목적을 갖고 있습니다. 반면, 프록시 서버는 클라이언트와 서버 사이의 중개 역할과 더불어 보안, 캐싱, IP 마스킹 등의 역할을 수행 합니다. 이 둘의 차이가 정확하게 뭘까요?

프록시 서버와 로드 밸런서의 역할 비교

이번 시간에는 HTTPS 에 대해 알아보는 글이므로, HTTPS에 중점을 맞춰 이야기 해보겠습니다.

프록시 서버

프록시 서버는 주로 클라이언트의 요청을 중계하는 역할로, 클라이언트의 IP 주소를 숨기고 캐싱을 통해 요청 속도를 높이거나 특정 콘텐츠 필터링 등 보안을 강화 하는 데 사용 됩니다. 프록시 서버는 두 가지 주요 유형으로 나뉩니다.

  • Forward Proxy: 클라이언트가 외부 서버에 접근할 때 중간에 위치하여 요청을 대리하는 역할로, 클라이언트의 요청을 서버로 대신 보내고, 서버의 응답을 다시 클라이언트로 전달합니다. 따라서 클라이언트가 서버에 접근할 때 프록시 서버를 통해 접근합니다. HTTPS 환경에서는 클라이언트와 프록시 서버 간의 연결이 SSL로 보호됩니다.

  • Reverse Proxy: 서버의 앞단에 위치하여 클라이언트의 요청을 받아 내부 서버로 전달하며 보안이나 로드 밸런싱을 위한 역할로, 서버 쪽에 위치 하며, 클라이언트가 서버로 보내는 요청을 받아서 해당 요청을 실제 서버로 전달합니다. 일반적으로 리버스 프록시는 부하 분산, SSL 처리, 캐싱 등의 기능을 제공합니다. 여기서 로드 밸런서는 리버스 프록시의 한 형태로 이해될 수 있습니다. 리버스 프록시는 로드 밸런서의 기능도 할 수 있으며, SSL Termination 역할을 맡아 서버 대신 클라이언트와 SSL 연결을 해제할 수 있습니다. 즉, 로드 밸런서와 마찬가지로 SSL 인증서를 대신 관리할 수 있습니다.

그렇다고 모든 로드 밸런서가 리버스 프록시의 형태인 건 아닙니다!

로드 밸런서

로드 밸런서는 다수의 서버에 트래픽을 분산하는 역할을 합니다. 여러 백엔드 서버로부터 요청을 받아들여 트래픽을 균등하게 나누어 시스템 성능을 최적화합니다. 로드 밸런서는 두 가지 방식으로 동작할 수 있습니다.

  • L4 로드 밸런싱 (전송 계층): 전송 계층 프로토콜인 TCP/UDP 패킷을 기반으로 트래픽을 분산합니다. 애플리케이션의 내부 구조나 세부적인 내용은 신경 쓰지 않고 트래픽을 처리합니다. 또한 연결 상태를 추적하지 않으며, 클라이언트의 트래픽을 단순히 설정된 규칙에 따라 백엔드 서버로 라우팅합니다. TLS/SSL 처리에 있어서는 트래픽의 암호화된 상태를 그대로 유지하면서 분산시키며, SSL passthrough 로 처리하는 경우도 많습니다. 따라서 단순히 연결 정보로 라우팅하며 SSL 복호화 작업을 로드 밸런서가 하지 않기 때문에 L7 로드 밸런서와 비교해 트래픽을 더 빠르고 가볍게 처리합니다. 이 경우에는 로드 밸런서가 패킷을 그대로 전달하기 때문에 프록시 역할을 하지 않을 수 있습니다. HTTPS 관점에서 본다면 L4 로드 밸런싱은 TCP 레벨에서 패킷을 분산하고 SSL 세션을 직접 처리하지 않으므로, 로드 밸런서는 프록시 서버와 별개의 역할을 수행합니다.

  • L7 로드 밸런싱 (애플리케이션 계층): HTTP/HTTPS와 같은 애플리케이션 레벨에서 요청을 분산합니다. 이 경우 로드 밸런서는 리버스 프록시 서버처럼 작동합니다. 클라이언트의 요청을 받고 적절한 백엔드 서버로 전달하는 역할을 하므로, 프록시 서버와 유사하게 행동합니다. HTTPS 관점에서 본다면 L7 로드 밸런싱은 HTTPS 요청을 처리할 때 프록시 서버처럼 작동합니다. SSL Termination을 통해 클라이언트와 백엔드 서버 간의 SSL 통신을 관리하고 트래픽을 분산합니다. 이 과정에서 프록시 서버와 유사한 동작을 하게 됩니다.

SSL Termination 이라는 말이 나왔는데 이건 뭘까요?
로드 밸런서가 HTTPS와 상호작용하는 방식에는 두 가지 시나리오가 있습니다

  1. SSL Termination: 제가 채택한 방법이기도 한데요, 로드 밸런서에서 클라이언트와의 SSL 연결을 해제하고, 그 이후의 통신은 암호화되지 않은 HTTP로 백엔드 서버와 통신합니다. 로드 밸런서가 SSL 인증서를 관리하며, 클라이언트와 로드 밸런서 간에는 HTTPS로 통신하지만, 로드 밸런서와 서버 간에는 HTTP로 통신됩니다. 이 방식은 서버의 부하를 줄이고 SSL/TLS 처리를 중앙에서 관리할 수 있게 해 줍니다.
  2. SSL Passthrough: 로드 밸런서는 클라이언트의 SSL 요청을 단순히 백엔드 서버로 전달하고 SSL 해제 작업은 백엔드 서버에서 처리됩니다. 이 방식에서는 로드 밸런서가 클라이언트와 백엔드 간의 SSL 연결을 해제하지 않고, 서버가 직접 SSL을 처리합니다. 이 경우 백엔드 서버는 각자의 SSL 인증서를 관리해야 합니다. 위의 HTTPS 를 설정하는 방법에서 첫 번째 방법인 직접 CA에서 구매한 인증서를 기반으로 HTTPS 서비스를 구축하는 방법 이 될 수 있겠죠!

L7 로드밸런싱과 Reverse Proxy의 차이

방금 전, Reverse Proxy는 로드 밸런서와 마찬가지로 로드 밸런서의 기능도 할 수 있고 SSL 인증서를 대신 관리할 수 있으며, L7 로드 밸런서는 리버스 프록시의 한 형태로 이해될 수 있다 했는데요.

둘 다 애플리케이션 계층인 L7 계층에서 작동하며, 클라이언트의 HTTP/HTTPS 요청을 받아들여 특정 URL 경로나 쿠키 값에 따라 트래픽을 분배하는 등 클라이언트의 요청 패턴에 따라 트래픽을 분석하고, 해당하는 백엔드 서버로 전달하고 응답을 클라이언트로 반환하는 역할을 합니다. 이 과정에서 클라이언트는 백엔드 서버의 실제 IP를 알지 못하게 됩니다. 즉, 클라이언트와 서버 간의 중개자 역할을 한다는 점에서 유사합니다.

그렇다면 둘의 차이는 뭘까요?

Reverse ProxyL7 로드 밸런서는 기능적 유사성이 있지만, 그 목적에 따라 다르게 사용됩니다.

Reverse Proxy는 주로 보안, SSL 처리, 캐싱 및 요청 라우팅을 위해 사용됩니다. 즉, Reverse Proxy는 클라이언트 요청을 받아 특정 서버로 라우팅하는 역할을 하고, 서버의 부하 분산이 주목적이 아닙니다. 클라이언트와 서버 간의 중개자로서 서버를 보호하고, 서버의 IP를 숨기며, 부하가 아닌 특정 서버에 대한 요청을 전달합니다. 특히, 보안적인 이유로 클라이언트가 직접 서버에 접근하지 못하게 할 때 유용합니다. 예를 들어, 프록시 서버가 SSL 인증서를 관리하거나, 캐시를 활용해 응답 속도를 높이는 역할도 합니다. Reverse Proxy는 주로 정적인 서버와 연결하는 방식입니다. 클라이언트가 서버에 보내는 모든 요청은 Reverse Proxy를 통해 특정 서버로 전달되며, 트래픽을 나누기보다는 라우팅에 중점을 두며 클라이언트와 특정 서버 간의 중간자 역할에 집중합니다. 클라이언트 요청을 어느 서버로 보낼지 정하고, 백엔드 서버로부터 받은 응답을 클라이언트에게 돌려주는 중개자 역할이므로 보통 고정된 하나 또는 소수의 서버로만 요청을 보내는 경우가 많습니다.

반면, L7 로드 밸런서의 주목적은 트래픽 분산입니다. 다수의 서버 풀에 트래픽을 분산하는 것에 주목적을 둡니다. 즉, 클라이언트가 로드 밸런서에 요청을 보내면, 로드 밸런서는 그 요청을 백엔드 서버들 간에 분배하여 부하 분산을 수행합니다. 이때 로드 밸런서는 서버 상태(헬스체크 등)를 모니터링하고, 장애가 있는 서버를 자동으로 제외할 수 있습니다. 이렇게 여러 백엔드 서버 간에 HTTP/HTTPS 요청을 효율적으로 분배해 서버의 부하를 줄이고, 트래픽이 특정 서버에 몰리지 않게 합니다. 물론 SSL 처리, 요청 라우팅 등도 할 수 있지만, 그 핵심 기능은 서버 풀 간의 부하를 균등하게 분산하는 것입니다. 즉, 다수의 서버 간에 동적인 트래픽 관리가 필요할 때 사용됩니다.

그렇다면, 스위치와 로드밸런서는?

방금 로드밸런서를 설명할 때 애플리케이션 계층인 L7 계층과 L4 계층에서의 로드밸런서를 비교했었는데요! L7, L4 계층은 네트워크의 근간이 되는 OSI 7계층에서 애플리케이션 계층과 전송 계층을 의미합니다. 이러한 애플리케이션 계층에는 L7 스위치가, 전송 계층에는 L4 스위치가 있는데요, 이때 스위치란 네트워크 장비 중 하나로, 데이터 패킷을 전송할 목적지로 효율적으로 전달하는 역할을 합니다.

L7 스위치와 L7 로드밸런서

L7 스위치와 로드 밸런서는 유사한 개념으로, 주로 OSI 7계층인 애플리케이션 계층에서 작동하면서 트래픽을 관리하는 역할을 수행합니다. 하지만 둘 사이에는 약간의 차이가 있습니다.

L7 스위치은 애플리케이션 계층에서 작동하는 스위치로, HTTP(S), FTP, DNS 같은 프로토콜에 따라 트래픽을 처리하고 라우팅합니다. 따라서 URL, 쿠키, 세션 정보 등을 기반으로 트래픽을 라우팅할 수 있고, 특정 요청(예: 로그인 페이지, 이미지 요청 등)에 따라 적합한 서버에 트래픽을 보내는 등, 다양한 요청을 세밀하게 처리할 수 있으며 SSL/TLS 암호화 처리, 인증 및 기타 보안 검사를 적용할 수 있습니다.

L7 스위치는 일종의 고급 트래픽 관리 장치로, L7 로드 밸런싱 기능을 포함할 수 있습니다. 그러나, 스위칭이라는 용어는 더 광범위한 네트워크 관리 기능을 의미할 수 있습니다. L7 스위치도 서버 간 트래픽을 분배하는데 사용할 수 있지만, 기본적인 목적은 트래픽을 다양한 기준으로 처리하고 제어하는 것입니다.

반면, L7 로드 밸런서는 주로 트래픽을 부하 분산하기 위한 목적으로 사용됩니다. 하지만 둘 다 애플리케이션 계층에서 작동하며, 트래픽을 HTTP/HTTPS 기반으로 분석하고, 서버 간에 지능적으로 라우팅하는 공통점이 있습니다.

즉, L7 스위치는 더 광범위한 네트워크 관리 기능을 수행하는 제어 장치, L7 로드밸런서는 부하 분산에 특화된 장치입니다.

L4 스위치와 L4 로드밸런서

L4 스위치는 OSI 모델의 4계층, 즉 전송 계층에서 작동하는 스위치로, TCP, UDP 같은 전송 계층 프로토콜을 기반으로 트래픽을 관리합니다. L4 스위치는 주로 IP 주소와 포트 번호를 기반으로 트래픽을 처리하며, 이는 TCP/UDP 헤더의 정보만을 참조해 트래픽을 서버로 라우팅하는 방식입니다. 또한 트래픽의 상태를 추적하지 않으며, 단순히 들어오는 요청을 적합한 서버로 분배합니다. 그렇다보니 방금 살펴본 L7 스위치보다 더 빠른 처리 속도를 가지며, 트래픽을 더 간단하고 빠르게 분배할 수 있습니다.

L4 스위치와 L4 로드 밸런서는 기능적으로 거의 동일한 방식하지만, L7에서의 차이점과 동일하게 L4 스위치는 더 광범위한 네트워크 관리 기능을 수행하는 제어 장치, L4 로드밸런서는 부하 분산에 특화된 장치입니다.

허브: 네트워크에 연결된 모든 장치에 데이터를 브로드캐스트하며, 목적지에 상관없이 데이터를 보냅니다.
스위치: 패킷의 목적지를 확인하고, 해당 장치에만 데이터를 전송합니다.
라우터: 서로 다른 네트워크 간의 통신을 관리하며, 데이터를 네트워크 경로를 통해 라우팅합니다.

ALB vs NLB

AWS 등의 클라우드 서비스에서 L7 스위치를 이용한 로드밸런싱은 ALB 컴포넌트로 사용하며,
L4 스위치를 이용한 로드밸런싱은 NLB 컴포넌트로 합니다.

AWS 클라우드 서비스에서 제공하는 ALB(Application Load Balancer)NLB(Network Load Balancer)는 각각 L7 로드 밸런싱과 L4 로드 밸런싱을 지원하는 로드 밸런서입니다. 둘 다 AWS의 ELB 서비스의 일환으로 제공되며, 각각의 계층에서 트래픽을 처리하는 방식이 다릅니다.

ALB

ALB는 애플리케이션 계층에서 작동하는 애플리케이션 계층 로드 밸런서입니다. ALB는 HTTP 및 HTTPS와 같은 애플리케이션 계층 프로토콜을 처리하며, URL 경로, 호스트 이름, HTTP 헤더 및 메소드, 쿠키 값 등을 기반으로 클라이언트의 요청 내용을 분석해 특정 서버로 트래픽을 분배헐 수 있어 다양한 조건에 따라 요청을 처리하는 세밀한 트래픽 관리가 가능합니다. 또한 클라이언트와 ALB 사이에서 SSL/TLS 암호화를 처리하여 백엔드 서버로는 복호화된 요청을 전달해 백엔드 서버의 부담을 줄여주는 역할을 하며, 웹 애플리케이션 방화벽(WAF) 등 보안 기능과 통합되어 웹 애플리케이션의 보안을 강화할 수 있습니다.

NLB

NLB는 TCP와 UDP 패킷을 기반으로 트래픽을 처리하며, 애플리케이션 계층에서 일어나는 작업에는 관여하지 않는 대신 더 빠르고 경량화된 방식으로 트래픽을 분산합니다. 따라서 매우 높은 처리량과 낮은 지연 시간을 제공하는 고성능 로드 밸런싱을 제공합니다. 수백만 개의 연결을 지원할 수 있으며, 주로 실시간 애플리케이션, 게임 서버, IoT 기기 등에서 사용됩니다. 또한 NLB는 DNS 기반 라우팅이 아닌 정적 IP 기반의 라우팅을 지원하기에 고정 IP 주소를 제공할 수 있으며, 특정 포트를 통해 트래픽을 분배합니다. 물론 NLB도 TLS 종료를 지원하지만, 일반적으로 클라이언트의 SSL 암호화된 트래픽을 그대로 서버로 전달하며, 복호화는 서버에서 처리한다고 합니다.

성능 최적화와 HTTPS 비용 절감을 위한 ELB의 전략

마지막으로 성능 최적화와 HTTPS 비용 절감을 위해 ELB가 활용하는 몇 가지 주요 전략들에 대해 알아보면 좋을 것 같습니다! HTTPS는 암호화와 복호화로 인해 추가적인 CPU 부하를 발생시키고, 인증서 관리 비용이 들기 때문에, 성능과 비용을 효율적으로 관리하는 것이 중요한데, ELB는 이러한 문제를 해결하기 위한 몇 가지 기능을 제공합니다.

SSL Offloading

위에서 설명 드렸던 제가 채택한 방식인 SSL Termination 입니다!

SSL Termination라고도 불리는 이 방식은 ELB가 클라이언트로부터 HTTPS 요청을 받고, 해당 요청을 암호화된 채로 백엔드 서버로 전달하지 않고, ELB에서 암호화를 해제(복호화)한 후 HTTP 요청으로 백엔드 서버에 전달하는 방식입니다. 즉, 클라이언트와 ELB 간의 통신은 암호화되지만, ELB와 백엔드 서버 간의 통신은 암호화되지 않은 HTTP로 이루어집니다.

SSL Passthrough

SSL Passthrough는 클라이언트와 백엔드 서버 간의 완전한 암호화 통신을 유지하는 방식입니다. 클라이언트의 HTTPS 요청이 ELB를 거칠 때, ELB는 SSL 종료를 하지 않고 해당 요청을 그대로 백엔드 서버로 전달합니다. 백엔드 서버는 자신의 SSL 인증서를 사용하여 HTTPS 요청을 처리하고 클라이언트와 서버 간의 통신은 처음부터 끝까지 암호화된 상태로 유지됩니다.

SSL Session Reuse

SSL 세션은 클라이언트와 ELB가 처음 통신할 때 TLS 핸드셰이크 과정에서 세션 키를 협상하고 암호화된 통신을 시작하는 과정으로, 상대적으로 시간이 오래 걸리며 리소스 소모가 큽니다. 따라서 SSL 세션 재사용을 통해 한 번 TLS 핸드셰이크를 완료한 후, 동일한 클라이언트가 다시 연결할 때 새로운 세션을 생성하지 않고 기존 세션을 재사용하여 핸드셰이크 시간을 절약합니다.

HTTP/2

HTTP/2는 기존의 HTTP/1.1보다 더 효율적인 방식으로 데이터를 전송합니다. 여러 요청을 하나의 TCP 연결에서 동시에 처리할 수 있고 헤더 압축을 통해 데이터 전송 크기를 줄여줍니다.

  • 멀티플렉싱: 한 번의 TCP 연결로 여러 요청을 동시에 처리할 수 있어 성능이 향상됩니다.
  • 헤더 압축: 요청 및 응답 시 사용하는 헤더를 압축해 네트워크 트래픽을 줄입니다.
  • 보안과 성능: HTTPS를 통해서만 사용할 수 있으며, 암호화된 상태에서 빠른 데이터 전송이 가능합니다.

자동 스케일링 및 연결 재사용

트래픽이 증가하거나 감소할 때 백엔드 서버의 수를 자동으로 조절함으로써 리소스를 효율적으로 관리하고 성능을 최적화할 수 있으며, TLS 연결은 비싼 비용이 발생하기 때문에 클라이언트와 ELB 간의 연결뿐만 아니라 ELB와 백엔드 서버 간의 연결도 재사용하여 성능을 향상시킵니다.

결론

  • 작은 트래픽에서 성능 최적화와 비용 절감을 동시에 추구할 때는 SSL Termination를 적용하여 ELB에서 암호화/복호화를 처리하고, 백엔드 서버는 HTTP로 통신함으로써 CPU 부하를 줄이고 비용을 절감할 수 있습니다.
  • 고급 보안과 성능을 동시에 고려할 때는 SSL Passthrough를 선택하여, 모든 구간에서 암호화를 유지하고 보안을 강화할 수 있습니다. 이 경우 백엔드 서버의 성능 최적화는 HTTP/2를 통해 이루어질 수 있습니다.
  • 빈번한 연결을 처리할 때는 SSL Session Reuse를 적용하여 핸드셰이크 과정을 최적화하고 성능을 향상시킬 수 있습니다.

번외

처음 github 블로그 설정을 하면서, 공부와 웬만한 내용은 구글링만 하면 모든 블로그에 존재하니까 남들이 다 쓸 수 있고 내가 드러나지 않는 블로그가 아니라 내 경험이 녹아 있고 내가 어떤 사람인지 어떤 사고를 갖고 학습을 하는지를 보는 사람들로 하여금 간접적으로 알 수 있게끔 하는, 나만이 쓸 수 있는 글을 쓰자 생각했었습니다.
내가 했던 트러블 슈팅, 그리고 그걸 어떻게 타파하는지, 기술을 도입하고자 할 때 어떤 판단으로 선택하는지, 공부하고자 하는게 생기거나 처음 경험해보는 기술을 적용할 때 어떤 테스트를 거치고 어떤 궁금증을 갖고 공부를 하는지를 녹이고자 했는데 생각보다 어려운 것 같아 고민이네요 😶‍🌫️

담고 싶은 내용들을 채워넣다보니 한 포스트에 호흡이 너무 길다느 느낌도 드네요 개인적으로 NLB와 ALB 등 실질적인 로드밸런싱과 관련된 내용은 추후에 실제로 트래픽 분산을 위해 로드밸런서 기능을 사용하게 됐을 때 작성하면 더 좋았을 것 같긴 하지만 아직 기약이 없기 때문에 짤막하게나마 내용에 담아보고 싶어 욕심을 부린 것도 있는 것 같습니다

뭐든 하다보면 안 느는게 없듯, 블로그도 쓰다보면 늘겠죠?

This post is licensed under CC BY 4.0 by the author.