S3 정적 사이트 호스팅 기능을 프라이빗으로 공개하기

2022.03.21

S3에는 정적 웹 사이트 호스팅이라는 기능이 있습니다. 해당 기능을 이용하면 S3 버킷을 이용하여 정적인 페이지를 호스팅 할 수 있게 됩니다.
이번 글에서는 이 기능을 이용하여 인터넷을 경유하지 않고 내부에서만 사이트가 접속할 수 있도록 해보겠습니다.

VPC에 대하여 공개할 경우

사용 서비스

  • AWS S3
    • 호스팅 기능을 이용하기 위해 사용합니다
  • AWS VPC Endpoint
    • 인터넷을 경유하지 않고 AWS 내부망을 이용하여 버킷에 접근하기 위해 사용합니다

구성도

단순히 엔드포인트를 생성하고 버킷폴리시에 해당 엔드포인트로의 접근만 허용합니다.
그리고 EC2의 라우팅 테이블에 엔드포인트의 루트를 등록합니다.

만들어보기

EC2와 S3는 생성되어있다는 전제로 설명합니다.

  1. VPC 콘솔에서 [엔드포인트]에서 이미지와 같이 옵션을 설정합니다. 서비스는 꼭 게이트웨이 타입으로 선택합니다.
    접속할 인스턴스가 있는 VPC와 서브넷을 선택하여 생성합니다.

  2. 해당 서브넷의 라우팅 테이블에 엔드포인트의 루트가 추가되어 있는지 확인합니다.

  3. S3의 퍼블릭 액세스를 차단합니다. 그리고 버킷 폴리시에 다음과 같이 엔드포인트 경유의 접근만을 허용합니다.

    {
    	"Version": "2012-10-17",
    	"Statement": [
    		{
    			"Sid": "PublicReadGetObject",
    			"Effect": "Allow",
    			"Principal": "*",
    			"Action": "s3:GetObject",
    			"Resource": [
    				"arn:aws:s3:::sujae-test-routing.com/*",
    				"arn:aws:s3:::sujae-test-routing.com"
    			],
    			"Condition": {
    				"StringEquals": {
    					"aws:SourceVpce": [
    						"vpce-{vpce id}"
    					]
    				}
    			}
    		}
    	]
    }

  4. 이후 인스턴스에서 호스팅하고 있는 url로 액세스 해봅니다.

만약 대상으로 하는 VPC가 여러개라면 여러개의 엔드포인트를 생성하고 버킷 폴리시의 조건(Condition)에 해당 엔드포인트들을 추가하면 됩니다.

온프레미스에서 접근하는 경우

리버스 프록시 서버를 설정합니다.

사용 서비스

  • AWS S3
    • 호스팅 기능을 이용하기 위해 사용합니다
  • AWS VPC Endpoint
    • 인터넷을 경유하지 않고 AWS 내부망을 이용하여 버킷에 접근하기 위해 사용합니다
  • AWS Transit Gateway or Dirct Connect or VPC Peering 등
    • 온프레미스 환경과 AWS를 연결하기 위해 사용합니다

구성도

단순히 첫번째 구성에서 서버를 프록시 서버로 바꾸는 작업이 끝입니다.
온프레미스와 네트워크를 연결하는 서비스는 상황에 맞춰 선택할 수 있습니다. 구성도에서는 Transit Gateway를 이용한 방법을 기재하였습니다.

만들어보기

네트워크 연결을 위한 리소스 작성은 설명하지 않습니다.
1. 이 글의 [VPC에 대하여 공개할 경우]와 같이 구성을 작성합니다.
2. 이후 내부 인스턴스에 리버스 프록시를 설정합니다. 이 글에선 nginx를 이용합니다.

nginx 의 경우
(기본 값에서 server 내용만 바꾸었습니다)

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;
    default_type text/html;
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server ;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.

        include /etc/nginx/default.d/*.conf;
        location / {
            resolver               169.0.0.2 valid=300s;
            proxy_pass             http://public-hosting-test.s3.amazonaws.com/index.html;
        }

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
   }
}

3. 온프레미스 환경에서 원하는 도메인이 리버스 프록시 서버로 향하도록 설정합니다.

  1. 인스턴스의 라우팅 테이블에 온프레미스 환경의 루트를 등록합니다.

  2. 이후 해당 도메인으로 온프레미스에서 접속하면 바로 s3로 향하게 됩니다.

마무리

이외에도 다양한 서비스를 활용하여 정적 웹사이트 호스팅 기능을 내부 한정으로 공개할 수 있습니다.
필요에 따라 더 많은 서비스를 활용하여 더 안전한 환경을 구성하도록 합시다.

긴 글 읽어주셔서 감사합니다.
오탈자 및 내용 피드백은 언제나 환영합니다. must01940 지메일로 연락 주시면 감사합니다!


본 블로그 게시글을 보시고 문의 사항이 있으신 분들은
클래스메소드코리아 (info@classmethod.kr)로 연락 주시면 빠른 시일 내 담당자가 회신 드릴 수 있도록 하겠습니다 !