[AWS] nginx as a proxy for S3

스윗포테이토·2023년 1월 10일
0

지난 글에서 엔드포인트를 생성해서 EC2 컨테이너에서 S3버킷에 접근하는데 성공했었다. 이제 EC2 인스턴스에서 nginx를 프록시 서버로 사용해 S3를 서빙해보려고 한다. 말이 많이 복잡한데... 구현하려는 구조는 아래와 같다.

VPC와 endpoint에 대한 이해는 아직 약간은 부족해서 자세히 그리지 않았다.

물론 S3 자체도 파일 서버의 역할을 수행할 수 있지만, 굳이 EC2에서 접근하려는 이유는
1. S3를 퍼블릭으로 여는 것은 보안적으로 좋은 선택이 아니다.
2. nginx의 캐싱 기능을 사용해서 요청 수를 줄일 수 있다.
3. 이미 nginx를 사용하고 있다...

사실 3번이 아니라면 cloudfront 등의 다른 서비스의 도입을 고려해봤을 것 같다. 그러나 이미 웹서버로 nginx를 쓰고 있고, 당분간은 요청이 많지 않기 때문에 우선 nginx를 프록시 서버로 쓰기로 했다.

도커 파일 작성

  • nginx/Dockerfile

    # 사용할 이미지
    FROM nginx:1.21.6-alpine
    
    # 기본 설정 삭제
    RUN rm -rf /etc/nginx/conf.d
  • docker-compose.yml

    version: "3"
    
    services:
      nginx:
        container_name: nginx
        restart: unless-stopped
        stdin_open: true
        build: ./nginx
        volumes:
          - ./nginx:/etc/nginx/conf.d
          - ./client/build:/usr/share/nginx/html # 프론트엔드 빌드 파일
        ports:
          - 80:80
        command: '/bin/sh -c ''while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g "daemon off;"'''

nginx.conf

server {
    listen 80;
    server_name "www.example.com";
    server_tokens off;
    set $bucket "<bucket-name>.s3.ap-northeast-2.amazonaws.com";

    # 파일 서빙 - S3
    location /file/ {
        rewrite /file/(.*) /$1 break;
        proxy_pass https://$bucket;
    }

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;
    }    
    ...
}

이제 nginx가 www.example.com/file/~~~~~로 들어오는 요청에 대해 <bucket-name>.s3.ap-northeast-2.amazonaws.com/~~~~~의 응답을 대신 받아준다.

http 헤더에서 불필요한 내용 지우기

S3에서 오는 응답을 그대로 전달하게 되면, 헤더에 여러가지 정보가 같이 들어온다. 클라이언트에 그대로 전달할 필요는 없기 때문에 몇가지 설정을 통해 지워주려고 한다.

    # 파일 서빙 - S3
    location /file/ {
    	...

        resolver 8.8.8.8;
        proxy_http_version     1.1;
        proxy_redirect off;
        proxy_set_header       Connection "";
        proxy_set_header       Authorization '';
        proxy_set_header       Host $bucket;
        proxy_set_header       X-Real-IP $remote_addr;
        proxy_set_header       X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_hide_header      x-amz-id-2;
        proxy_hide_header      x-amz-request-id;
        proxy_hide_header      x-amz-meta-server-side-encryption;
        proxy_hide_header      x-amz-server-side-encryption;
        proxy_hide_header      Set-Cookie;
        proxy_ignore_headers   Set-Cookie;
        proxy_intercept_errors on;
        add_header             Cache-Control max-age=31536000;

        proxy_pass https://$bucket;
    }
  • http 응답 (EC2에서 S3에 직접 요청)
  • http 응답 (nginx로 요청한 경우)

reference

How to use Nginx to proxy your S3 files

profile
나의 삽질이 미래의 누군가를 구할 수 있다면...

1개의 댓글

comment-user-thumbnail
2023년 9월 22일

command: '/bin/sh -c ''while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g "daemon off;"'''
창의적인 방법이네요

답글 달기