외로운 Nova의 작업실

aws - CloudFront 본문

Cloud/aws

aws - CloudFront

Nova_ 2023. 10. 13. 18:49

- CloudFront

CloudFront는 전세계에 파일을 빠른 속도로 배포하는 CDN 서비스입니다. CloudFront를 이용해서 에지 로케이션에서 빠르게 파일을 다운로드 받게 할 수 있습니다.

 

CloudFront에서 중요한 개념은 오리진입니다. CloudFront는 CDN 서비스이기때문에 항상 원본에서 파일을 복사해서 가져와야합니다. 이 파일을 가져오는 서버가 오리진입니다. CloudFront가 지원하는 오리진은 다음과 같습니다.

  • S3 버킷 : 가장 기본적인 오리진입니다.
  • EC2 인스턴스 : 웹서버를 구축하면 오리진으로 사용할 수 있습니다.
  • ELB : ELB도 오리진으로 사용 가능합니다.
  • AWS 이외의 웹서버 : 온프레미스환경에 구축해놓고 오리진으로 사용할 수 있습니다.

- CloudFront 배포

이미지 파일을 하나 만들어서 CloudFront에 배포하고 index.html에 CloudFront를 통해 빠르게 이미지를 가져와보겠습니다.

버킷을 2개 만들어줍니다. website는 웹 호스팅으로 변경해줍니다.  CloudFront 버킷에 CloudFront에 배포할 이미지를 하나 올려주겠습니다.

이제 CloudFront 배포를 해보겠습니다.

CloudFront에서 배포생성을 눌러줍니다.

도메인을 S3로 선택해줘 원본 액세스에대해 제어 설정 생성을 눌러줍니다.

생성해줍니다.

WAF는 비활성화 해줍니다.

이후에 배포하기를 누르면 위 화면이 있습니다.

배포 도메인 이름으로 https://d1d1mn76kmjza4.cloudfront.net 이 있습니다.이 도메인이름으로 CloudFront에 접근할 수 있으며, 경로는 test.png등으로 할 수 있습니다.

 

또한 버킷 정책을 업데이트해야한다면서 정책 복사 버튼이 있습니다. 이 버튼으로 정책을 복사해서 CloudFront 버킷 정책을 업데이트해줍니다.

이제 웹사이트에 올라갈 index.html을 만들어줍니다.

<html>
<head>
    <title Example CloudFront></title>
</head>
<body>
    <p>hello CloudFront</p>
    <img src="https://d1d1mn76kmjza4.cloudfront.net/test.png" width="320" height="240">
</body>
</html>

이제 이걸 올려주겠습니다.

이제 웹호스팅을 활성화해줍니다.

이제 웹에 접속해보겠습니다.

정상적으로 요청이 완료된 것을 확인할 수 있습니다. 저 이미지는 CloudFront를 통해 엣지로케이션에서 가져온 이미지입니다. S3에서 가져온 것이 아닙니다.

 

- CloudFront 커스텀 오리진

CloudFront의 기본 오리진은 S3입니다. S3이외에 EC2 인스턴스, ELB, 외부 웹 서버를 오리진으로 사용하는 것을 커스텀 오리진이라고 합니다. 커스텀 오리진은 동적 콘텐츠 전송이 필요할때 사용합니다. 서버사이드 스크립트에서 동적으로 생성되는 웹페이지를 캐시할 수 있습니다. 예를들어 사용자 그룹마다 생성되는 웹페이지를 캐시할 수 있습니다. 특히 커스텀 오리진을 사용하면 동일한 도메인에서 POST,PUT,DELETE 등의 메서드를 사용할 수 있고 로그인이나 글쓰기 기능도 구현할 수 있습니다. 커스텀 오리진의 필수 조건은 웹서버입니다. 

 

<EC2와 CloudFront 연동하기>

이번에는 EC2인스턴스에 간단하게 웹서버를 올리고 CloudFront와 연동해보겠습니다.

 

전에 생성해두었던 EC2를 가지고 만들어보겠습니다.

EC2에 접속한 후에 아래 명령어로 nodejs와 express모듈을 다운로드해줍니다.

sudo yum -y install nodejs npm
mkdir ExampleServer
cd ExampleServer
npm install express

이후 간단히 app.js를 만들어줍니다.

var express = require('express')
var app = express();

app.get(['/', '/index.html'], function ( req, res) {
	res.send('Hello CloudFront - EC2');
});

app.listen(80)

이제 아래 명령어로 서버를 실행해줍니다.

sudo node app.js

한번 접속해보겠습니다. 아래 사진속 주소로 들어가주면 됩니다.

접속하게되면

접속이 잘 되는 것을 확인할 수 있습니다.

이제 CloudFront를 설정해보겠습니다.

아까 접속했던 URL을 넣어줍니다.

캐시 정책은 위와같이 설정해줍니다.

기본값 루트 객체에 index.html을 넣어줍니다.

이제 도메인으로 접속해보겠습니다.

CloudFront 도메인으로 접속하자 CloudFront가 EC2에 캐시해서 그 index.html을 저에게 가져다주는 모습을 볼 수 있습니다.

이러한 방식으로 외부 웹서버를 통해서 CloudFront와 연동할 수 있습니다.

 

- Signed URL사용

방금 전까지 만든 CloudFront의 배포는 도메인 URL만 알면 누구나 접근이 가능합니다. 따라서 이러한 부분에 접근제어를 하기위해서는 Signed URL을 사용할 수 있습니다. Signed URL은 키 쌍을 사용해서 인증을 구현합니다.

 

한번 만들어보겠습니다. 일단 키 쌍을 하나 만들어줍니다.

보안자격증명 카테고리에서 CloudFront 키페어를 생성해줍니다.

이제 CloudFront 카테고리에서 퍼블릭 키를 생성해줍니다.

퍼블릭키 생성을 누르고 아까 다운받은 퍼블릭키를 입력해줍니다.

잘생성된 것을 알 수 있습니다. 이제 키 그룹을 생성해줍니다.

키그룹생성이 완료되었습니다. 이제 CloudFront 배포에 가줍니다.

여기서 첫번째 동작을 편집해줍니다.

위처럼 뷰어액세스 제한에 키그룹을 추가해줍니다. 그리고 완료해줍니다.

이제 도메인으로 접속해보겠습니다.

KeyPair가 없다고 합니다. 이제 Signed URL을 동적으로 만들어서 보기위해 아까 만든 EC2 인스턴스를 수정해보겠습니다.

먼저 EC2에서 패키지를 다운해줍니다. 아래명령어를 사용합니다.

npm install aws-cloudfront-sign

이제 퍼블릭 키를 환경변수로 설정해주고 개인키는 키파일을 하나 만들어줍니다.

set PUBLIC_KEY=your_public_keyID_value
vi privateKey //개인키 생성

app.js를 아래와 같이 수정해줍니다. 

var express = require('express')
var app = express();

var cfsign = require('aws-cloudfront-sign');

var signingParams = {
  keypairId: 'K3SK2XOHWDZVM',
  privateKeyString: process.env.PRIVATE_KEY,
  // Optional - this can be used as an alternative to privateKeyString
  privateKeyPath: './privatekey',
}

// Generating a signed URL
var signedUrl = cfsign.getSignedUrl(
  'http://d1d1mn76kmjza4.cloudfront.net/test.png',
  signingParams
);

app.get(['/', '/index.html'], function ( req, res) {
          res.send(`
    <html>
      <body>
        <h1>Hello CloudFront - EC2</h1>
        <img src="${signedUrl}" alt="Signed Image">
      </body>
    </html>
  `);
});

app.listen(80)

expireTime은 기본적으로 15분입니다. 이제 실행시켜줍니다.

sudo node app.js

이제 접속해보겠습니다.

이미지가 정상적인 것을 볼 수 있습니다. 아까는 접근이 거부됬었는데 말입니다.

cntl+u로 소스코드를보면 URL이 signed된 것을 확인할 수 있습니다.

   <img src="http://d1d1mn76kmjza4.cloudfront.net/test.png?Expires=1697191504&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2QxZDFtbjc2a21qemE0LmNsb3VkZnJvbnQubmV0L3Rlc3QucG5nIiwiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxNjk3MTkxNTA0fX19XX0_&Signature=X%7E0qDYqFEWlYfapIaMWO9yku5P8ar6GY0FSSnn9ma4c2Tml3mcCFpmPYEL4xW232CiNyKmCMOI8ArT9SvE4jqhm9hB-53qsc1fL%7EQ7fl-LEyOL02UxMT8KhZEn9HFf7NeKmajdazCKVHoCXK2cWxnJZ9KW6ybmaGTj17Rt7KEWfzfNCj1tv7aR%7Em06Ys7sXaT2SIayXq0p9ZylGVAZlFdTaiBfNuwNK0Pu80nIn67rifxWtJa7P6NmbrSQSgYBusF8dLSHPymt7Y1gHNxT42GFZMeQ72ZjHTxofsUgrKjpukhimbIyU0AayVH-5jTlnMmqfnt4qPibao4mcS1u5fOw__&Key-Pair-Id=K3SK2XOHWDZVM" alt="Signed Image">

 

Expires : 만료되는 날짜와 시간입니다. 

Policy : 파일 사용 제한을 정의하는 정책 파일의 내용을 개인키로 서명한 해시값입니다. BASE64로 인코딩되어있습니다.

signatrue : 서버가 cloudFront와 통신해서 만들어내는 값으로 인증된 서버에서 만들어진 것을 증명합니다.

Key-Pair-id : 키 전용 쌍입니다.

'Cloud > aws' 카테고리의 다른 글

aws - DynamoDB  (0) 2023.10.14
aws - RDS  (0) 2023.10.14
aws - S3  (0) 2023.10.13
aws - CloudWatch  (0) 2023.10.12
aws - access Key  (0) 2023.10.12
Comments