동적 파일에 대해서는 미리 주소를 생성할 수가 없다. Html, Css, Js를 만들 수 없기 때문에 어쩔 수 없이 동적 파일은 컴퓨터 한 대가 필요했다
- HTTP 못 쓰겠다! -> HTTPS / SSL / TLS
- EC2에 동적파일을 배포해보자 -> EC2 / LB
- 부하 분산하기! -> LB
HTTPS 사용해보기
와이어샤크
- 실제 데이터가 어떻게 주고 받고 하는지, 화면을 보여주는 프로그램으로 네트워크 데이터를 가져오며 실시간 네트워크 분석을 위해 패킷 교환 과정을 포착하는 도구 중 하나이다.
💡 패킷이란?
네트워크상에서 주고받는 메시지 데이터 블록의 기본 단위를 패킷 이라부른다.
- 네트워크에서 source는 출발지를 의미하고 src라 표시한다. Destination은 목적지로 dst라 표시한다. 프로토콜은 TCP프로토콜을 사용하고 있고 길이는 54, 길이가 크면 데이터를 많이 보낸다는 의미이다. 많이 보내게 되면 느려지는 것은 당연하다. 이어서 포트번호도 나오는데 80번이 http, 443번이 https이다.
💡 80번 포트와 443번 포트
표시되어 있는 80은 http를 의미하며, 443포트는 https를 의미한다.
이 포트 번호들은 생략이 가능하다.
- 단방향 암호화로 백엔드와 DB에서 비밀번호 해시에서
bcrpyt
가 사용된다.
- 단방향이므로 해시하게 되면 복구는 못시킨다.
- 양방향 암호화는 프론트와 백엔드에서 암호화하여 주고 받을때
crypto-js
사용된다.
- 프론트에서 암호화해서 백엔드로 전송하고 백엔드에서 원상복귀 시켜서 사용한다.
- https로 사이트에 접속해서 로그인하게 되면 와이어샤크에서 확인했을 때 위와 같이 암호화된 것을 볼 수 있다.
- https 사이트를 만들기 위해서는 SSL 인증서를 설치해야 한다.
SSL(Secure Sockets Layer)인증서
- https를 하기 위해서 SSL을 설치해줘야 한다.
- SSL이 업그레이드 되어 TLS를 사용하고 있으나 호칭은 입에 붙은 SSL이라고 한다.
3-Way-Handshake, 4-Way-Handshake
- http 통신을 할떄 Response, Request가 이뤄진다 했는데 이전에 연결하고 하는 둘 사이에 연결하는 과정인
3-Way-Handshake
를 한다.
- 3번의 악수라는 뜻으로 총 3번 요청과 응답을 통해 연결을 한다.
-
왼쪽이 프론트엔드, 오른쪽이 백엔드 컴퓨터라 가정해 봅시다.
-
프론트 엔드 컴퓨터에서 백엔드 컴퓨터로 요청을 보내는 것을 ‘SYN’
-
백엔드 컴퓨터에서 프론트엔드 컴퓨터로 요청에대한 응답을 ‘SYN + ACK’
-
다시 프론트엔드 컴퓨터에서 백엔드 컴퓨터로 ‘ACK’를 돌려주게 됩니다.
-
연결 시 3번의 요청과 응답이 이뤄지는 것을 3-Way-Handshake
라고 한다.
-
이 다음부터 request, response가 가능해지고 매번 이렇게 해야하는 것은 아니다. 한 번의 연결을 해놓고 계속 주고 받다가 특정 timeout 시간까지 더 이상 request를 보내지 않으면 둘 사이의 연결 끊기를 시도한다.
-
연결 종료 시 ACK-FIN
패킷이 추가되어 요청을 보낸다. 이렇게 연결 종료까지는 4번의 요청과 응답이 이뤄지는데 이것을 4-Way-Handshake
라고 한다.
-
4-Way-Handshake로 연결 종료 이후에 다시 연결하고 싶으면 3-Way-Handshake 과정을 거쳐야 한다.
-
두 컴퓨터 사이에 접속자가 많아져서 접속이 혼잡한 상황의 경우 그럴 때 네트워크 패킷을 보게 되면 ECN(Explict Congestion Notification)
으로 혼잡을 알리게 되면 CWR(Congestion Window Reduce)
로 보내는 데이터의 양을 조금씩 나눠서 보낸다.
-
TCP 3-Way-Handshake라고 한다. TCP 연결이 먼저 되어 있어 http 통신이 가능하다. 80번 포트 http 서버이고 랜덤값을 배정받고 SYN 요청을 보내고 있다. 응답으로 SYN + ACK 오고 다시 ACK 요청을 보낸 뒤 연결이 되어 OPTIONS / graphql 요청을 보내고 있다.
- 4-Way-Handshake로 연결이 끊어진다.
HTTPS 적용
1)SSL 인증서 설치 방법
- HTTPS는 SSL/TLS 인증서가 있어야 사용할 수 있다.
- AWS에서는 웹서비스 제작을 위해 필요한 기본적인 퍼블릭 인증서를 무료로 제공하고 있다.
1. LB에 설치하기
- 브라우저와 프론트엔드 서버가 있는데 다이렉트로 프론트 서버에 SSL을 설치할 수 있다. SSL을 설치하기 위해서는 certbot을 설치해야 한다. 이 작업이 매우 번거롭다.
- 그래서 클라우드(AWS, GCP)에서는 여러 개의 프론트 서버를 instance나 target으로 묶은 거 앞에 LB를 붙이고 LB를 통해 부하를 분산 시켰는데, LB에 설치를 하게끔 Cloud에서 제공을 해준다. 이 설치가 매우 간편하다.
2. CDN(AWS에서는 Route53)에 설치하기
- DNS(AWS-Route53)에서 CDN(AWS-CloudFront)으로 간 다음 정적페이지의 경우 CloudStorage(AWS-S3)로 동적페이지의 경우 LB로 분기를 처리한다.
- CDN이 처음으로 요청을 받는 분기점이 되기 때문에 LB 대신 CDN에 설치를 한다.
CDN(Content Delivery Network)
- 미국에 있는 컴퓨터는 물리적으로 매우 멀어 느리다.
- 그렇기에 전세계에 임시 저장소가 있어서 가장 가까이 있는 곳에서 다운받아온다.
- SSL 인증서를 기본 지역 기준으로 설치해야 한다. -> 버지니아 북부
CloudFront
2) SSL 인증서 발급
- CNAME이 저번시간에 배운 TXT 인증방식을 사용하고 있다.
- 사이트의 본인 인증을 위해서 Route53에서 CNAME에 주소 값을 입력하면 CNAME value 값이 나오는지 TXT record 해보는 것이다.(여기서는 예외적으로 CNAME 사용)
- 이 번거로움을
Create records in Route53
버튼을 클릭하여 해결할 수 있다.
- route53에 자동으로 만들어진 것을 확인할 수 있다. 이후에 DNS query하도록 기다려준다.
- route53에서 A레코드가 다이렉트로 storage로 갔었는데 CDN으로 향하게끔 수정해야 한다.
- CDN에서 도메인을 S3 주소로 입력해야 한다.
- 네이버에서 진행되는 것처럼 http를 입력하더라도 https로 입력되도록 하는
redirect
과정이 필요하다
SSL 인증서 검증
- AWS에서는 SSL 인증서가 무분별하게 사용되는 것을 방지하기 위하여 도메인에 맞는 인증서를 발급한 다음, 실제로 해당 도메인을 소유하고 있는 지 검증하여야 활성 상태로 변경한다.
- Route53에 검증용 CNAME 레코드를 추가하여 도메인 소유 여부를 검증할 수 있다.
검증 프로세스
1) DNS 검증을 위해 인증서 ID를 클릭
2) Route53에서 레코드 생성
3) 생성한 호스팅 영역의 레코드 목록에 CNAME 생성 확인
4) 연결 확인을 위해 ACM에서 인증서 정보 조회 후 CNAME 이름 복사
5) 인증서 상태 발급됨 확인
HTTPS 적용 - 3) 인증서 적용
- Route 53과 CloudFront를 연결하여, 유저가 도메인을 입력하면 https를 이용하여 S3에 접속할 수 있도록 설정해 보도록 해보자
- CDN 주소인 배포 도메인의 이름을 Route53에서 A 레코드 편집을 통해 트래픽 라우팅 대상을 S3에서 CloudFront로 변경해주어야 자물쇠가 걸리게 된다.
- HTTP로 주소창에 입력해도 자물쇠가 걸리는 HTTPS 연결이 되는 것을 확인할 수 있다.
동적 페이지 배포
오늘의 목표 : LB 만들어서 TargetGroup(InstanceGroup) 안에 EC2를 활용하여 VM 만들고 연결하기!
동적페이지 배포 프로세스
- EC2 메뉴를 통해서 VM을 만들 수 있다 AWS에서 제공하는 컴퓨터를 빌리는 것인데 4GB 4-5만원 정도 한다. 이렇게 구입한 컴퓨터에 접속하면 터미널에 접속하게 되는데 터미널에서 git clone하여 폴더를 만들고 yarn dev하여 24시간 켜놔야 한다. 이것을 LB와 연결을 하여 한다.
- yarn dev하면 모든 페이지를 다운받아 올 수 있으나 storage로 정적페이지 분리한 이유는 정적페이지에 대한 트래픽을 분리하기 위함이다.
4) EC2 인스턴스 생성
- Global 주소의 경우 버즈니아 북부로 주소를 해놨다면 EC2는 물리적인 컴퓨터 위치를 어디에 둘지이므로 서울로 위치를 바꿔주어야 한다.
- 컴퓨터 한대를 인스턴스라고 한다.
- 인스턴스가 생성되었고 앞으로는
localhost:3000
이 아닌 위 사진의 주소:3000
을 통해 접속한다.
5) git/node 설치
- amazon 인스턴스에 연결한 후 초기 세팅을 해주어야 한다.
-
node 설치
-
git 설치
-
git clone
-
yarn dev
동적페이지 생성
- yarn dev는 저장할 때마다 소스코드 바뀌면 refresh 되기 때문에 배포에서 하면 안되고 개발단계에서만 해야 한다.
- yarn build 한 후 최적화 과정을 거치고 yarn start를 24시간 동안해야 한다.
6) git clone
- 동적 페이지가 있는 파일의
git remote -v
를 통해 깃 주소를 복사하여 인스턴스에서 git clone 주소
를 실행한다.
- git clone시 깃허브 로그인을 요구하는데 아이디는 git 아이디를 입력하지만 비밀번호는
github 토큰
을 입력해야 한다.
- yarn install 대신
yarn install --production
을 통해 package.jsondml devDependencies는 제외하고 다운로드를 받는다.
- 그 이후에
yarn build
를 통해 최적화를 하고 yarn start
하기 때문에 소스코드가 바뀐다고 해도 refresh 되거나 그러지 않는다.
- localhost:3000 대신 인스턴스
퍼블릭 ip 주소:3000
하였는데 접속이 되지 않는다.
- 접속이 되지 않는 이유는 EC2를 감싸는 방화벽이 존재하는데 이것을 허용해줘야 접속이 가능해진다.
7) 인스턴스 연결 허용
-
인스턴스에서 프론트엔드 서버 가동을 완료하였지만, 아직 외부 접근이 가능하도록 설정하지 않았다.
보안 그룹 설정을 통해 방화벽을 허용하여 외부 연결을 허용해 보도록 하자
-
Inbound가 들어오는 것 : 3000번 포트를 허용해주어야 한다. outbound가 나가는 것
-
위에서 source 0.0.0.0/0: 누구든지, Port range 22: 포트번호 22번 포트로 접속 가능하다. 22번 포트가 SSH 지금 열고 있는 터미널을 의미한다.
-
여기에 누구든지 3000번 포트에 접속할 수 있도록 추가해주어야 한다.
-
적용이 된 것을 확인할 수 있다. 퍼블릭IPv4 DNS로 접속이 가능해졌으나 아직 CDN과 연결하지 않았으므로 HTTP이다.
Storage가 아닌 터미널에 이렇게 하는 이유:
프로그램이 켜져 있기 때문에 해당 페이지를 동적페이지의 경우 즉시 만들어서 보내줄 수 있는 역할이 가능하다. 또한 서버사이드 렌더링도 가능하다.
- 가장 쉽게 배포하는 방법은 storage를 두지 않고 EC2 만들고 정적, 동적, 서버사이드 렌더링 다 되는 yarn start 하면 된다
- 정적 페이지만 가능한 storage에 빼 놓은 이유는 EC2에서는 컴퓨터 비용이 나가게 되므로 모든 트래픽을 받으므로 이것을 분산시키기 위해 정적페이지에 대한 트래픽을 storage를 관리해주는 아마존으로 보낸다. 비용뿐만 아니라 페이지 접속이 안되거나 서버가 죽거나 그러지 않는다.
- EC2의 메모리가 넘치는지 CPU가 넘치는지 모니터링한다.
8) 로드밸런서(LB) 생성
- 지금까지 인스턴스에 다이렉트로 접속할 수 있도록 방화벽을 허용시켜 주었다.
- 이 다음 스텝은 targetGroup, 그 안으로 부하를 넘겨줄 LB를 만들어 연결시켜주어야 한다.
- 그렇게 하면 DNS로 접속하지 않고 LB에 ip가 있으므로 그쪽으로 접속할 수 있다.
- LB를 생성해면 Schema를 선택해야 하는데
- Internet-facing
: 브라우저 인터넷에서 실제 VM으로 접속할 때
- Internal
: 브라우저(인터넷)에서 백엔드는 Internet-facing, 백엔드와 DB가 있을 때 서버 간에 부하를 분산시키도록 하는 것이 Internal
Network Mapping
에서 EC2에서 확인 가능한 Instance에서 Availability Zone 하나를 포함한 총 2개를 선택해야 한다.
- 80번은 LB에서 들어오는 포트이고 LB에서 TargetGroup으로 넘겨주는 포트는 3000번이다.
Health check
는 LB옆에서 여러 대의 컴퓨터가 있을때 LB가 프로그램이 실행중인 곳으로만 트래픽을 보내야 하므로 서버가 살아있는지 죽어있는지 주기적인 요청을 통해 확인하는 것으로 확인 후 LB에게 알려줌으로써 죽은 서버로는 트래픽을 보내지 않도록 한다.
- 이제 targetGroup을 만들었으니 이 안으로 컴퓨터를 넣어주어야 한다. 들어간 것 확인할 수 있다.
- LB에 만든 targetGroup이 들어온 것을 확인할 수 있다.
9) 인바운드 규칙 추가
- LB의 방화벽도 열어주어야 한다.
- 보안 그룹 설정을 통해 방화벽을 허용하여 외부 연결을 허용한 것을 동일하게 누구든지 80번 포트로 들어오도록 추가해준다.
정리
로드밸런서 연결을 해줌으로서 SSR 배포시 안정적인 클라이언트 배포를 위한 부하분산처리를 해주었다.
여기까지 S3에 파일을 올려 정적 파일 SSG 배포와, EC2를 활용하여 서버에 접근해 동적 파일 SSR 배포까지 각각 완료했다 . 이제는 요청이 들어올때마다 SSR과 SSG방식을 분기처리 해주어 각각 다른쪽으로 요청을 보내주어야 한다. (SSR + SSG Hybrid) 이를 위해 분기처리를 위한 CloudFront 라우팅을 연결해주도록 해야 한다.
소소한 꿀팁
- 패킷을 클릭하면 아래 데이터를 확인할 수 있다.
- 카페에서 무료 와이파이 사용시 http로 된 사이트로 로그인할 때 해커가 공유기를 해킹해서 와이어샤크로 패킷을 보게 되면 공유기를 통해서 접속하는 페이지 이동, 사이트 접속의 response, request가 찍히고 누군지는 모르지만 사이트의 주소, 아이디 비밀번호를 해킹할 수 있다.
- 따라서 무료 와이파이 사용시 http 사이트 접속은 주의해야 한다.