들어가면서
인터넷을 통해 다른 서비스를 사용해 봤거나, 개인 프로젝트로 웹 서비스를 개발해본 분들은 HTTPS에 대해 들어본 적 있을 것이다. 이번 글에서는 HTTPS를 적용해야하는 이유, 적용 방법 그리고 동작 원리를 정리하겠다.
HTTPS 필요한 이유
HTTPS를 사용해야하는 이유는 크게 3가지 존재한다. (물론 더 있을 수도 있다.)
1. 보안
HTTPS를 사용하면 사용자와 서버간 통신이 암호화돼 제 3자(해커)가 통신 내용을 알 수 없다. 덕분에 사용자에게 신뢰성을 줄 수 있다.
2. 마케팅
마케팅 관점에서 내 서비스가 검색 엔진에 자주 노출되는게 유리하다. 실제로 구글 검색 엔진은 HTTPS가 적용된 사이트에 적용 안된 사이트 보다 더 높은 우선선위를 부여한다. (구글 문서)
3. 기술 선택
HTTPS를 도입하면 사용할 수 있는 기술 폭이 넓어진다.
예를 들어 HTTPS를 적용하지 않으면 브라우저에서 제공하는 HTTP/2 기능을 사용할 수 없다. (출처)
Does HTTP/2 require encryption?
No. After extensive discussion, the Working Group did not have consensus to require the use of encryption (e.g., TLS) for the new protocol.
However, some implementations have stated that they will only support HTTP/2 when it is used over an encrypted connection, and currently no browser supports HTTP/2 unencrypted.
추가로 IOS 9+ API는 TLS가 적용돼 있지 않으면 API를 사용할 수 없다. (출처)
If you’re developing a new app, you should use HTTPS exclusively. If you have an existing app, you should use HTTPS as much as you can right now, and create a plan for migrating the rest of your app as soon as possible. In addition, your communication through higher-level APIs needs to be encrypted using TLS version 1.2 with forward secrecy. If you try to make a connection that doesn't follow this requirement, an error is thrown. If your app needs to make a request to an insecure domain, you have to specify this domain in your app's Info.plist file.
3 가지 이유 모두 비지니스에 큰 영향을 준다. 즉, HTTPS 적용은 성공적인 비지니스를 위해 선택이 아니라 필수이다.
HTTPS 적용하기 (feat. AWS EC2(Amazon Linux 2023) + NginX + Certbot(Let)
SSL/TLS 암호화 작업은 CPU 연산이 필요하다. 해당 작업을 어플리케이션 서버에서 수행하면, 트래픽이 몰릴 때 부하가 증가하는 원인이 될 수 있다. 이 문제는 앞단 웹서버에서 암호화 작업을 수행하면 해결할 수 있다.
NginX에 HTTPS를 적용하는 일은 너무나 간단하다. 단, 도메인은 갖고 있어야 한다.
1. certbot을 이용해 TLS 인증서 발급
Amazon Linux 2023은 Pip를 사용해 certbot을 다운 받고, 인증서를 발급 받을 수 있다.
# 가상 환경 세팅 및 Pip 업데이트
sudo python3 -m venv /opt/certbot/
sudo /opt/certbot/bin/pip install --upgrade pip
# Certbot 설치
sudo /opt/certbot/bin/pip install certbot cerbot-nginx
# Certbot 명령어를 사용할 수 있게 세팅
sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot
# 인증서 발급 받기
sudo certbot certonly --nginx
(출처 - cerbot nginx pip guid)
다른 OS를 사용한다면 Certbot 공식 홈페이지에서 설치하고 인증서를 발급 받는 방법을 찾아 진행하면 된다.
2. NginX HTTPS 설정
NginX 공식 문서에 따르면 아래와 같이 설정하라고 나와있다.
http {
# http 요청 관련 설정 (80번 포트로 오는 요청은 https(443)으로 리다이렉트)
server {
listen 80;
listen [::]:80;
server_name www.freetalk.shop;
root /usr/share/nginx/html;
location / {
return 301 https://www.freetalk.shop$request_uri;
}
}
# https 요청 관련 설정
server {
# 443 포트에 SSL 모드 적용
listen 443 ssl;
server_name www.freetalk.shop;
# 인증서 위치(Public Key) (Client에 전송되는 인증서)
ssl_certificate /etc/letsencrypt/live/www.freetalk.shop/fullchain.pem;
# 개인키 위치(Private Key)
ssl_certificate_key /etc/letsencrypt/live/www.freetalk.shop/privkey.pem;
# 보안 강화를 위한 세팅 (NginX 1.9.1 부터는 기본값)
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNuLL:!MD5;
# 뒷 단 어플리케이션 서버로 요청 프록시
location / {
proxy_pass http://backend;
}
}
}
(자세한 내용은 주석과 NginX 공식 문서를 참조하기 바란다.)
3. 테스트
http://www.freetalk.shop 으로 접속해보자.
Let's Encrypt의 인증서를 사용해 HTTPS 연결에 성공한 것을 확인할 수 있다.
HTTPS 동작 원리 이해하기
HTTPS는 HTTP 위에 SSL/TLS가 추가돼 메시지를 암호화해 통신한다. 메시지 암복호화는 Symmetric-Key Cryptography를 사용하고, Symmetric-Key 교환을 위해 Asymmetric-Key Cryptography를 사용한다.
HTTPS 통신을 위해 서버의 준비 과정
1. 서버에서 Public Key와 Private Key를 생성한다.
2. 서버는 Public Key를 CA(Certificate Authority)에게 보내 인증서 발급을 요청한다.
3. CA는 자신의 Private Key로 서버의 Public Key에 서명해준다.(인증서)
HTTPS 통신이 이뤄지는 과정
1. 클라이언트가 서버에게 HTTPS 연결 요청을 한다.
2. 서버는 CA게 받은 인증서를 클라이언트에게 넘겨준다.
3. 클라이언트는 CA의 Public Key를 이용해 인증서를 검증한다.
4. 클라이언트는 Symmetric-Key Cryptography에 사용할 Key를 생성한다.
5. 클라이언트는 생성한 Key를 서버의 Public Key(인증서에서 얻은 정보)를 이용해 암호화 한 후, 서버에게 전달한다.
6. 서버는 Private Key를 이용해 클라이언트가 보낸 Key를 복호화한다.
7. 클라이언트와 서버는 Symmetric-Key를 공유했고, 이를 이용해 HTTPS 통신을 한다.
지금까지 HTTPS 동작원리에 대해 알아봤다. 이를 통해 우리가 CertBot을 이용해 받은 인증서가 어떤 역할을 하는지도 이해했다.
정리
이번 글을 통해 HTTPS를 사용해야 하는 이유, 적용 방법 그리고 동작 원리까지 정리했다. HTTPS를 사용하면 비지니스 적으로 많은 이점이 있다. 그리고 적용하는 방식은 생각보다 어렵지 않다. 그렇다고 동작원리를 대충 넘기지 말고 제대로 이해하고 사용하면 좋겠다.
출처
https://snyk.io/blog/10-reasons-to-use-https/
'네트워크' 카테고리의 다른 글
HTTP Connection 역사 알아보기 (0) | 2024.02.24 |
---|---|
SSE(Server Sent Event) 개념 정리 (0) | 2024.02.15 |
WebSocket과 친해지기 (0) | 2023.05.30 |
REST API (0) | 2022.06.14 |