最后,经过两天的调试工作,我使它完全正常工作。这就是我在我的场景中如何使用它。
nginx conf:
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()进行了一次访问。
PHP接受f的输入并在内部对文件执行file_exists,然后通过PHP中的头文件将其作为附件输出。
这是一个演示:
<?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();
?>我可以在这里添加更多的安全性,以确保安全性始终遵循,但我让它工作了,我很高兴。
发布于 2021-03-11 17:13:31
所以,我自己解决了这个问题。我花了相当长的时间,因为我不太明白为什么它不能工作。所有的指南都是相同的,只是缺少了一些变量,或者只介绍了他们的脚本的用法。因此,我已经写了一个完整的澄清指南,如果有人在未来遇到这篇文章。第一个问题: URI必须指向安全的URL,而不是您想要的文件。预计这两件事是独立工作的。第2期:我看过的指南将$secure_link_expires放在了md5指令中。让它永远不会成功。编辑帖子以反映。
https://stackoverflow.com/questions/66497020
复制相似问题