【发布时间】: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