nginx secure_link 지시문을 활용한 다운로드 링크 도용 방지 구현

1. nginx 설치 및 모듈 확인

먼저 nginx가 설치되어 있는지, 그리고 필요한 모듈이 포함되어 있는지 확인합니다. secure_link 모듈은 ngx_http_secure_link_module로서 nginx에 기본적으로 포함되어 있습니다.

[root@file_server ~]# nginx -V 2>&1 | grep secure_link

출력 결과에 ngx_http_secure_link_module이 포함되어 있으면 준비가 완료된 것입니다.

2. nginx 설정

다운로드용 가상호스트를 설정합니다. secure_link 지시문을 사용하여_md5와_expires 쿼리 파라미터를 검증합니다.

server {
    listen       8080;
    server_name  file_server;
    root         /var/www/html/;

    location / {
        # 쿼리 파라미터에서 MD5 해시와 만료 시간 추출
        secure_link $arg_sign,$arg_expire;
        
        # 시크릿 키와 만료 시간을 포함한 MD5 해시 생성
        secure_link_md5 "$secure_link_expire$uri mysecret123";
        
        # 해시 검증 실패 시 403 반환
        if ($secure_link = "") {
            return 403;
        }
        
        # 만료 시간 초과 시 410 반환
        if ($secure_link = "0") {
            return 410;
        }
        
        # 이미지 파일인 경우 다운로드로 처리
        if ($request_filename ~* ^.*?\.(png|jpg|gif)$) {
            add_header Content-Disposition "attachment; filename=$1";
        }
    }
}

3. 다운로드 링크 생성 스크립트

다음은 링크 생성 예시 스크립트입니다. 실제 운영 환경에서는 애플리케이션 코드에서 이 로직을 구현합니다.

#!/bin/bash

# 서버 정보 설정
HOST="file_server"
FILE_PATH="/sample.png"
EXPIRE_SEC=600  # 10분 후 만료

# 현재 시간에서 만료 시간 계산
TIMESTAMP=$(date -d "+${EXPIRE_SEC} seconds" +%s)

# 시크릿 키 (nginx 설정과 일치해야 함)
SECRET="mysecret123"

# MD5 해시 생성 및 URL安全的 인코딩
SIGN=$(echo -n "${TIMESTAMP}${FILE_PATH} ${SECRET}" | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =)

# 최종 다운로드 URL 출력
echo "http://${HOST}:8080${FILE_PATH}?sign=${SIGN}&expire=${TIMESTAMP}"

4. 테스트

설정을 적용하고 테스트를 진행합니다.

# 스크립트 실행 권한 부여
[root@file_server html]# chmod +x gen_link.sh

# nginx 서비스 시작
[root@file_server html]# systemctl restart nginx

# 테스트용 이미지 파일 준비
[root@file_server html]# cp /path/to/source.png /var/www/html/sample.png

테스트 1: 직접 접근

쿼리 파라미터 없이 파일에 직접 접근하면 403 Forbidden 오류가 반환됩니다.

테스트 2: 생성된 링크로 접근

[root@file_server html]# ./gen_link.sh
http://file_server:8080/sample.png?sign=aB3xK9mNpQ_7sLdEfGhJk2&expire=1699999999

생성된 링크로 접근하면 파일이 정상적으로 다운로드됩니다.

테스트 3: 만료 시간 경과 후

설정한 만료 시간(10분)이 지나면 410 Gone 오류가 반환됩니다.

5. 주의사항

  • 시크릿 키는 외부에 노출되지 않도록 관리하고, 정기적으로 변경하는 것이 좋습니다.
  • 링크 생성 서버와 nginx 서버 간의 시간차가 크면 파일이 만료된 것처럼 표시될 수 있으므로 NTP 동기화를 권장합니다.
  • 대역폭 비용이 발생하는 대규모 서비스에서는 이 방법을 통해 원본 서버 부하를 줄일 수 있습니다.

태그: nginx secure_link hotlinking download web-server

5월 26일 09:26에 게시됨