В конфигурационный файл добавлена директива secure_link_timeout, которая определяет время жизни ссылки в секундах (по умолчанию 3600 секунд - 1 час).
URL защищённой ссылки теперь выглядит так:
/prefix/hash/timestamp/file
Поле timestamp представляет собой hex-предстваление unixtime.
MD5-хэш счиается от имени файла, поля timestamp и секретного слова (указывается директивой secure_link_secret).
Таким образом, сначала сравнивается поле timestamp с разницей текущего времени и таймаута. Затем проверяется md5-хэш.
Ссылку можно сформировать таким образом: (пример на php):
< ?php $secret = 'topsecretword'; $fname = 'file.ext'; $ts = sprintf("%08x",strtotime("now")); echo '/' . md5($fname . $ts . $secret) . "/{$ts}/{$fname}n"; ?>
Патч применяется к файлу ngx_http_secure_link_module.с web-сервера nginx версии 0.7.41.
Для того, чтобы это сделать в командной строке нужно набрать всего несколько команд:
# tar -zxf nginx-0.7.41.tar.gz # cd nginx-0.7.41/src/http/modules # patch < ngx_http_secure_link_module.patch
По умолчанию модуль не собирается, поэтому не забываем указать при конфигурировании параметр
--with-http_secure_link_module.
Ссылки:
http://sysoev.ru/nginx/docs/http/ngx_http_secure_link_module.html
http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ModSecDownload
А вот и содержимое файла
--- ./ngx_http_secure_link_module.c.orig 2009-03-12 14:55:33.000000000 +0200 +++ ./ngx_http_secure_link_module.c 2009-03-13 17:52:12.000000000 +0200 @@ -1,6 +1,9 @@ /* * Copyright (C) Igor Sysoev + * + * Timeout: + * Copyright (C) Nikolai Olexienko, digital-ventures */ @@ -12,6 +15,7 @@ typedef struct { ngx_str_t secret; + time_t timeout; } ngx_http_secure_link_conf_t; @@ -29,7 +33,13 @@ NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_secure_link_conf_t, secret), NULL }, - + + { ngx_string("secure_link_timeout"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_sec_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_secure_link_conf_t, timeout), + NULL }, ngx_null_command }; @@ -68,21 +78,38 @@ static ngx_str_t ngx_http_secure_link = ngx_string("secure_link"); +static u_char +ngx_hex2int(u_char hex) +{ + + hex = hex - '0'; + if (hex > 9) { + hex = (hex + '0' - 1) | 0x20; + hex = hex - 'a' + 11; + } + if (hex > 15) + hex = 0xFF; + + return hex; +} + + static ngx_int_t ngx_http_secure_link_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - u_char *p, *start, *end, *last; - size_t len; + u_char *p, *start, *end, *last, *tss, *tse; + size_t len, tslen; ngx_int_t n; ngx_uint_t i; ngx_md5_t md5; + time_t ts; ngx_http_secure_link_conf_t *conf; u_char hash[16]; conf = ngx_http_get_module_loc_conf(r, ngx_http_secure_link_module); - if (conf->secret.len == 0) { + if (conf->secret.len == 0 || conf->timeout == 0) { goto not_found; } @@ -103,22 +130,47 @@ while (p < last) { if (*p++ == '/') { end = p - 1; - goto url_start; + goto tstamp_start; } } goto not_found; +tstamp_start: + + tss = p; + + while (p < last) { + if (*p++ == '/') { + tse = p - 1; + goto url_start; + } + } + + goto not_found; + url_start: + tslen = tse - tss; + len = last - p; - if (end - start != 32 || len == 0) { + if (end - start != 32 || len == 0 || tslen != 8) { goto not_found; } + + ts = 0; + for (i = 0; i < 8; i++) { + ts = (ts << 4) + ngx_hex2int(tss[i]); + } + if (ts < r->start_sec - conf->timeout) { + goto not_found; + } + ngx_md5_init(&md5); ngx_md5_update(&md5, p, len); + ngx_md5_update(&md5, tss, tslen); ngx_md5_update(&md5, conf->secret.data, conf->secret.len); ngx_md5_final(hash, &md5); @@ -161,6 +213,8 @@ * conf->secret = { 0, NULL } */ + conf->timeout = NGX_CONF_UNSET; + return conf; } @@ -172,7 +226,8 @@ ngx_http_secure_link_conf_t *conf = child; ngx_conf_merge_str_value(conf->secret, prev->secret, ""); - + ngx_conf_merge_sec_value(conf->timeout, prev->timeout, 3600); + return NGX_CONF_OK; } @@ -191,3 +246,4 @@ return NGX_OK; } +
Постоянные ссылки
При копировании ссылка на TeaM RSN обязательна!