【问题标题】:nginx secure link to rewrite url (PHP)nginx 安全链接重写 url (PHP)
【发布时间】:2021-03-11 21:44:58
【问题描述】:

最后,经过两天的调试工作,我让它完全工作了。 这就是我在场景中使用它的方式。

nginx 配置:

location ~ /stream/ {
         proxy_no_cache 1;
         proxy_cache_bypass 1;
         secure_link $arg_md5,$arg_expires;
         secure_link_md5 "$arg_expires$uri$remote_addr salty";
         if ($secure_link = "") {
                      rewrite ^(.*)$ /error.php?m=$uri&e=$arg_md5&t=$arg_expires;
         }
         if ($secure_link = "0") { return 410; }
         rewrite ^(.*)$ /mp4.php?f=$uri&t=sec; #proxy_pass http://127.0.0.1/mp4.php?f=$uri&t=sec;
}

videotest.php

<?php
#This file is used with mp4.php  and secure link module for nginx

$f = (isset($_GET['f'])) ? htmlspecialchars($_GET['f'], ENT_QUOTES) : NULL; #Get file or ID and do basic injection cleaning.

#Various configurations. Expire time, secure key, and paths.
$expires = time()+3100;  # e.g. 2 hours url expiry would be time()+7200;
$prefix = '/stream'; #Secured URI base. Where nginx secure link module is configured. (ex: /stream )
$ip = $_SERVER['REMOTE_ADDR']; #fetch client ip
$server_ip = '172.22.151.68'; #replace with server IP for URLS. (ex: 127.0.0.1)
$url = 'http://' . $server_ip; #Just a clean base URI.
$salt = ' salty'; #change according to nginx directive. Note space before.
$file = $prefix . '/' . $f . '.mp4'; #uri that nginx expects. (ex: /stream +  <file/id> + ext) (/stream/q3-1lI4KWfE.mp4)

function getSecureHash($ip, $uri, $secure_text, $expires){
 $str = $expires . $uri . $ip . $secure_text;
 echo 'nginx expects md5(expires+file+ip secret)<br>';
 echo 'string md5(' . $str .')<br>'; # secure_link_md5 should be "$arg_expires$uri$remote_addr<value of $salt>";
 $tmp = md5( $str, true );
$tmp1 = base64_encode( $tmp ); #base64encode the md5
return str_replace( array('+', '/', '='), array('-', '_', ''), $tmp1 ); #remove extra bits
}

$sec_h = getSecureHash($ip, $file, $salt, $expires); #normal hash
$sec_hi = getSecureHash($server_ip, $file, $salt, $expires); #server hash for curl
echo 'Debug: ' . $sec_h . '<br>';
echo 'Debug 2: ' . $sec_hi . '<br>';
echo 'Expires: ' . $expires . '<br>';
echo 'CURL commands:<br>';
echo 'curl -I ' . $url . $file . '?md5=' . $sec_hi . ' (without exp)<br>';
echo 'curl -I ' . $url . $file . '?md5=' . $sec_hi . '&expires=' . $expires . '<br>';
echo '<br>---<br>';
echo 'New Test:<br>';
echo "MD5 test: echo -n '" . $expires . $file . $_SERVER['REMOTE_ADDR'] . $salt . "' | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =<br>";
exec("echo -n '" . $expires . $file . $_SERVER['REMOTE_ADDR'] . $salt . "' | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =", $output, $retval);
print_r($output);
echo '<br>';
$link =  $url . $file . '?md5=' . $output[0] . '&expires=' . $expires;
echo $link;
echo '<br>Bad link example:';
$blink = $url . $file . '?md5=sumbadcode&expires=012345674';
echo $blink;
?>
<br>
<video width="1280" height="720" controls>
  <source src="<?php echo $link; ?>" type="video/mp4">
Your browser does not support the video tag.
</video>
<br>
<video width="1280" height="720" controls>
  <source src="<?php echo $blink; ?>" type="video/mp4">
Your browser does not support the video tag.
</video>

所以这总结了我无法工作的部分,即生成一个友好的 URL 以放入重写的链接中,该链接可以放入视频播放器中以便安全播放。老实说,一旦我将 403 重定向到 error.php 我可以看到发生了什么,什么不起作用。最大的部分是 secure_link_md5 是不对的。那它会默默地重定向到 404 确实有效。所以,access.log 成了我最好的朋友。

我的 error.php 只是对 $_GET 和 php 的 getallheaders() 进行了一次 foreach。

mp4.php 接受 f 的输入,然后在文件内部执行 file_exists 通过 PHP 中的 headers 将其作为附件显示出来。

这是一个演示:

<?php
$f = (isset($_GET['f'])) ? htmlspecialchars($_GET['f'], ENT_QUOTES) : NULL;
$t =  (isset($_GET['t'])) ? htmlspecialchars($_GET['t'], ENT_QUOTES) : NULL;
if ($t != NULL) {
$rfile = explode("/stream/", $f);
$file = $rfile[1];
}
else $file = $f;

if (file_exists('/var/www/myfiles/private/' . $file)) {
$mm_type="video/mp4";
$path = 'http://172.22.151.68/private/' . $file;
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($path)) );
header('Content-Disposition: attachment; filename="'.basename($path).'"');
header("Content-Transfer-Encoding: binary
");

readfile($path); // outputs the content of the file

exit();
}
else exit();
?>

我可以在此处添加更多安全性以确保安全性始终如一,但我得到了它的工作,我很高兴。

【问题讨论】:

    标签: security nginx hyperlink url-rewriting


    【解决方案1】:

    所以,我自己解决了这个问题。花了相当长的时间,因为我不太明白为什么它不起作用。所有指南都相同,但缺少一些变量,或者仅涵盖了脚本的用法。因此,如果将来有人遇到此帖子,我已经编写了完整的说明指南。第一个问题:URI 必须是安全 URL,而不是你想要的文件。预计这两件事会独立工作。第二期:我正在查看的指南将 $secure_link_expires 放入 md5 指令中。使它永远不会成功。编辑帖子以反映。

    【讨论】:

      猜你喜欢
      • 2013-07-14
      • 2012-02-26
      • 2021-01-06
      • 2013-01-12
      • 2011-11-18
      • 1970-01-01
      • 2015-03-19
      • 2014-02-18
      • 2022-08-19
      相关资源
      最近更新 更多