메뉴 닫기

nginx에서 hmac-sha1을 통한 uri 암호화 보안

본내용은 일반적으로 특정 디렉토리의 보안을 설정할때 아이디/암호등의 단조로운 방식을 벗어나서

특정 client에게만 특정 디렉토리의 내용을 열람할수 있게 하고 싶을때 유용하다 

 

# 일반적인 nginx에서는 지원하지 않으므로 openresty 패키지가 필요하다 openresty는 nginx + 유용한 번들 모듈의

모음

소스 다운로드  : https://openresty.org/ 

 

# devel kit를 add해야 아래 misc 모듈설치가 가능하다 

모듈 다운로드1: https://github.com/simpl/ngx_devel_kit 

 

#nginx 설정의 지시자를 사용하려면 반드시 필요

모듈 다운로드2: https://github.com/openresty/set-misc-nginx-module/pulls 

 

 

# 설치 

./configure –with-http_ssl_module \ –add-module=/path/to/ngx_devel_kit \ –add-module=/path/to/set-misc-nginx-module

make -j2

make install

 

# nginx 설정 예제 

# GET /?e=1893452400&n=MC4wLjAuMC8w&s=QVvNrcn-j4smvOFhuPTUU7EgoI8
# returns 403 when signature on the arguments is not correct OR
# when expire time is passed or network does not match.
# It is an alternative to the HttpSecureLinkModule in Nginx.
# This example has expiry "2030-01-01" and network "0.0.0.0/0".
 
location /secret-directory {             # /secret-directory에 설정
# $signature(client 요청값 php참조) 에 인증키값과 e n 의 아규먼트를 hmac_sha1로 암호화
  set_hmac_sha1 $signature 'secret-key' "e=$arg_e&n=$arg_n"; 
# $signature값을 base64url 로 인코딩 
  set_encode_base64url $signature;
  if ($signature != $arg_s) {
    return 403; # 값이 맞지 않을겨우 에러
  }
  set_expired $expired $arg_e;
  if ($expired) { # 만료일을 넘어섰을시 에러
    return 403;
  }
  set_decode_base64url $network $arg_n;
  set_ip_matches $ip_matches $network $remote_addr;
  if ($ip_matches = 0) {
    return 403; # 암호화된 signature의 ip와 실제 clientip의 값이 맞지 않을경우 에러
  }
  root /var/www;
# 모든것을 충족할때 접근허용
}
 
 
# php소스 예제 
<?php
function base64url_encode($s) # s아규먼트 
{ return rtrim(strtr(base64_encode($s),"+/", "-_"),"="); 
}
$secret = "secret-key";
$expiry = strtotime("2030-01-01 00:00:00");
$network = base64url_encode("0.0.0.0/0");
$query = "e=$expiry&n=$network";
$signature = base64url_encode(hash_hmac('sha1',$query,$secret,true));
$url = "http://도메인/secret-directory/?$query&s=$signature";
echo "$url\n";
#  $url의 값이 인코딩된 형태로 나타나게 되며, 아규먼트 e n s가 없거나 맞지 않을경우 403에러를 뿌린다 
 
정상적인 요청($url) e=만료일  n=네트워크+만료일의 암호화값  s=$signature를 암호화한값
http://도메인/package.zip?e=1893452400&n=MC4wLjAuMC8w&s=QVvNrcn-j4smvOFhuPTUU7EgoI8
 
그외요청: 모두 403 차단
 
# openresty 와 각 변수값들을 custom 하여 여러가지로 활용할수 있습니다 
# network 값을 $remote_addr 변수처리해 client마다 각각 다른 sha1암호화 signature를 생성할수 있습니다
 
more information: 
https://www.leaseweblabs.com/2014/03/custom-http-secure-link-using-openresty-nginx-module/
 
감사합니다
 

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다