ec2로 서버 배포를 하고, 깃허브로 클라이언트 배포를 했으나
net::ERR_SSL_PROTOCOL_ERROR 가 뜨면서 잘 작동하지 않았다.
AWS에서 제공하는 인증서 관리 서비스인 ACM(AWS Certificate Manager)을 이용해서 웹 서버에 SSL을 적용하면 HTTPS요청을 처리할 수 있게 된다. 그런데 HTTPS 연결을 효과적으로 관리하고 분산시키려면 로드 밸런서가 필요하므로 ACM과 로드밸런서를 이용한 SSL인증서 관리를 해보려고 한다.
로드밸런서 : 클라이언트의 요청으로 인한 서버의 과부하 혹은 트래픽을 분산시켜줌으로서 속도 면에서나 서버의 가용성, 부하적인 측면에서 도움을 줄 수 있는 기술
- SSL/TLS 종료 지원 : 로드밸런서가 SSL/TLS 연결 종료를 처리하여 클라이언트와 로드 밸런서 사이의 암호화된 연결을 해제하고 복호화한 후, 내부 서버와의 일반 HTTP 연결을 유지한다.
- 보안 및 개인 정보 보호 : 로드 밸런서를 통해 SSL/TLS 암호화를 적용하면 사용자와 웹 애플리케이션 간의 통신이 외부에서 엿볼 수 없도록 보호된다.
- 부하 분산 및 확장성 : HTTPS 연결은 복잡한 계산 작업을 필요로 하는데 로드 밸런서는 서버 간 트래픽을 균등하게 분산하여 성능을 최적화하고 서버 부하를 줄인다.
- 고가용성 : 로드 밸런서는 여러 가용 영역에 걸쳐 배포하므로 하나의 가용 영역에서 장애가 발생하더라도 다른 가용 영역의 로드 밸런서가 트래픽을 처리할 수 있어서 서비스 중단을 방지한다.
- 인증서 관리 : 로드 밸런서를 통해 인증서를 관리하면 간편하게 갱신하고 관리할 수 있다.
사전작업 : 도메인 구입
1. ACM(amazon certificate manager) 에서 SSL 인증서 발급 및 호스팅 영역에 레코드 등록
2. Target group 생성
3. application load balancer 생성 및 security 정책 설정
4. route53의 domain A 레코드 변경
Rout 53에서 레코드 생성을 할 수 없어서 찾아보니 AWS DNS 서비스를 이용하여 도메인을 적용한 것이 아니라 외부 서비스로 도메인을 생성했기 때문에 EC2 서버에 nginx와 certbot 과 같은 인증서를 직접적으로 설치하고 설정하는 방법으로 해야했다.
나는 내도메인.한국에서 도메인을 구입해서 IP연결에 ec2 퍼블릭 IPv4 주소를 입력했으므로 인증서를 직접 설치해야했다.
sudo yum install nginx
sudo iptables -t nat -L --line-numbers
Chain PREROUTING (policy ACCEPT)
num target prot opt source destination
1 REDIRECT tcp -- anywhere anywhere tcp dpt:http redir ports 8080
Chain INPUT (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
num target prot opt source destination
$ sudo iptables -t nat -D PREROUTING 1
$ sudo iptables -t nat -L --line-numbers
Chain PREROUTING (policy ACCEPT)
num target prot opt source destination
Chain INPUT (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
num target prot opt source destination
$ sudo vi /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {}
http {
upstream app {
server 127.0.0.1:8080;
}
server {
# 80번으로 요청이 오면, localhost의 8080번 포트로 연결해 준다는 의미입니다.
listen 80;
location / {
proxy_pass http://app;
}
}
}
$ sudo service nginx restart
$ sudo dnf install -y python3 augeas-libs pip
...
Complete!
$ sudo python3 -m venv /opt/certbot/
$ ls /opt/certbot
bin include lib lib64 pyvenv.cfg
$ ls /opt/certbot/bin
Activate.ps1 activate activate.csh activate.fish pip pip3 pip3.9
python python3 python3.9
$ sudo /opt/certbot/bin/pip install --upgrade pip
....
Successfully installed pip-23.1.2
$ sudo /opt/certbot/bin/pip install certbot
...
Successfully installed ConfigArgParse-1.5.3 PyOpenSS-23.1.1 acme-2.6.0
certbot-2.6.0 certifi-2023.5.7 cffi-1.15.1 charset-normalizer-3.1.0 co
nfigobj-5.0.8 cryptography-40.0.2 distro-1.8.0 idna-3.4 josepy-1.13.0
parsedatetime-2.6 pycparser-2.21
$ sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot
sudo certbot certonly -d [도메인 주소] --manual --preferred-challenges dns
$ sudo vi /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {}
http {
upstream app {
server 127.0.0.1:8080;
}
# Redirect all traffic to HTTPS
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/[도메인 주소]/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/[도메인 주소]/privkey.pem;
# Disable SSL
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# 통신과정에서 사용할 암호화 알고리즘
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
# Enable HSTS
# client의 browser에게 http로 어떠한 것도 load 하지 말라고 규제합니다.
# 이를 통해 http에서 https로 redirect 되는 request를 minimize 할 수 있습니다.
add_header Strict-Transport-Security "max-age=31536000" always;
# SSL sessions
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
location / {
proxy_pass http://app;
}
}
}
sudo vi /etc/crontab
15 3 * * * certbot renew --quiet --renew-hook "/etc/init.d/nginx reload" 를 맨 아래줄에 추가
😆 완 료 😆
남자친구가 프론트엔드 배포를 깃으로 도와줘서 이제 프로그램이 언제나 작동하게 되었다.
< 참고한 자료 >
ACM 공식문서
무료 도메인 구입방법
EC2에 인증서 설치
아마존 리눅스 Let's Encrypt 설치
EC2에 도커 설치
개발남발님 블로그
나의개발족보님 블로그