NGINX 이미지 외부링크 막기 설정 방법

NGINX

웹서버를 NGINX로 세팅해서 홈페이지나 블로그를 운영하다 보면 커뮤니티 같은 경우 이용자가 이미지를 업로드해 다른곳에 링크를 걸어 사용하는 경우가 있고 블로그 같은 경우 작성한 포스트를 통째로 긁어다 불펌을 하는 경우에 이미지도 포함되어 있기 때문에 <img>태그로 인해 다른 곳에서 링크가 걸리게 됩니다.

이렇게 이미지나 파일등의 링크를 외부에서 거는 것을 Hotlink 라고 하는데 운영하는 서버의 트래픽을 낭비하게 되기 때문에 NGINX에서 외부링크 방지 설정을 통해 불필요한 트래픽을 절감하고 서버에 업로드된 컨텐츠를 보호할 수 있습니다.

NGINX Hotlink 설정

server {
server_name mysite.com;

location ~* \.(jpeg|jpg|gif|png|bmp|svg|swf|ico|zip|7z|ttf|woff|eot)$ {
valid_referers none blocked
server_names ~($host)  ~.domain.;
if ($invalid_referer) {
rewrite (.*)$ /custom/403_forbidden.png redirect;
access_log /var/log/nginx/$host-hotlink-access.log;
}
log_not_found off; access_log off;
expires 1w;
try_files $uri =404;
}

location = /custom/403_forbidden.png { }

location / {
...
}
}

필자가 사용하고 있는 Hotlink 설정입니다. 코드를 설명하자면 server 블럭 안에 위치하는 location에서 확장자를 지정해 해당 확장자에 해당하는 파일들은 valid_referers로 서버 이름으로 등록되어 있는 도메인 이외의 리퍼러 요청을 HTTP 코드 403으로 응답함으로써 권한이 없음을 리턴하게 됩니다.

보시면 서버 이름의 제일 처음 ~($host) 로 선언이 되어 있는데 이는 server_name에 등록되어 있는 도메인을 변수 그대로 가져오기 때문에 여러 사이트에 적용시 도메인을 바꿀 필요가 없습니다. 예로 가상호스트 설정에서 server_name mysite.com 으로 되어 있다면 이 도메인에서만 이미지 링크를 사용할 수 있겠죠?

뒤의 ~.domain. 부분은 전역으로 적용하고 싶은 도메인을 따로 입력하게끔 설정했는데 위에서 지정된 mysite.com 이외에 허용할 도메인을 설정하는 것입니다.

만일 ~.naver. 로 설정하게 되면 naver 가 들어간 모든 도메인을 허용하게 되는 와일드카드 설정이 되시겠습니다.

server_names ~($host);

만일 지정된 가상호스트만 허용하고 싶다면 지우면 되겠습니다. 만일 지운다면 위 코드와 같이 설정하면 되겠죠?

그리고 if ($invalid_referer) 구문에서 설정된 도메인 이외의 도메인에서 외부링크로 접속하는 경우에는 경고 이미지를 출력하게 됩니다. 설정된 rewrite rules로 작동하며 절대경로이던 상대경로이던 상관 없는데 위 코드는 상대경로로 되어 있습니다.

그리고 외부링크로 접속시 별도의 로그를 기록해 나중에 외부링크를 추적하고 싶을때 로그를 기반으로 추척할 수 있게 설정했습니다. 로그 파일명에도 중간에 $host로 변수 설정되어 있어있습니다.

if ($invalid_referer) {
return 403;
access_log /var/log/nginx/$host-hotlink-access.log;
}

만일 이미지 출력이 필요없고 단순히 막기만 하고 싶다면 위 코드로 권한 없음을 리턴하면 되겠습니다. 로그도 필요 없다면 access_log 라인도 삭제하면 되겠죠?

location 블럭에 rewrite될 이미지 파일을 별도로 설정한 이유는 위에서 해당 도메인이 아니면 출력이 안되게 설정했기 때문에 이 설정이 걸려 있으면 이미지 출력이 되지 않습니다. 그래서 rewrite가 적용될 이미지만 아무런 설정을 넣지 않음으로써 다른 도메인에 출력될 수 있게 설정합니다.

브라우저에서 캐시를 사용하게 설정할 경우에는 별도의 location에 expires를 지정하게 되면 해당 파일들에 대한 처리 선언이 중복이 되기 때문에 코드가 깔끔하지 않고 순서에 따라 작동이 이상해지는 경우도 있으니 expires 코드를 합치고 위에 이미지 파일들의 로그를 남기지 않게 설정하려면 위와 같이 Hotlink 설정에 포함하는 것이 좀더 깔끔한 코드를 유지합니다.

위의 코드는 도메인에 관련된 부분을 전부 변수 처리했기 때문에 location { } 구문을 별도로 저장해서 가상 호스트 설정에 include 로 불러와 다른 여러 가상호스트에서도 재활용할수 있게 구성되었습니다.

Hotlink 테스트

1

리퍼러를 기반으로 이미지 불펌을 막는 핫링크 설정을 했다면 제대로 동작하는지 테스트를 해서 직접 확인하는게 가장 좋겠죠.

구글에서 자신의 사이트/블로그의 이미지를 검색해서 이미지 보기를 통해 구글을 경유해 리퍼러를 찍어 가면 핫링크가 작동하는지 간단하게 확인할수 있습니다. 물론 구글 도메인을 막아놨다면요. 하지만 좀더 확실하게 확인하는 방법은 CURL을 활용하는 것입니다.

3

curl -I --referer [리퍼러 도메인(or 봇)] [대상 도메인]

리눅스에는 대부분 CURL이 내장되어 있어 별도의 설치가 필요 없으며 Syntax는 위와 같습니다.

CURL 옵션의 –referer 로 리퍼러를 조작해 해당 도메인으로 링크되는 이미지가 어떠한 리퀘스트로 반환하는지 간단하게 확인이 가능합니다.

1 댓글. Leave new

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

Fill out this field
Fill out this field
유효한 이메일 주소를 입력해주세요.

nginx title 03
NGINX WebDAV 설정 방법
WebDAV(Web Distributed Authoring and Versioning)는 http를 이용해 웹서버에 저장되어 있는 파일을 여러 사용자가 편집하기 위해 고안된 프로토콜입니다. 실제로는 FTP 대용으로…
windows nginx php setting title
윈도우 NGINX PHP 연동 및 서비스 등록 방법
이전 포스트에서 윈도우에 NGINX를 설치하고 서비스에 등록하는 방법까지 알아봤는데요. NGINX를 개발 환경 또는 웹서버 환경으로 만들기 위해서 PHP를 설치해야 하는…