首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于重写url的nginx安全链接(PHP)

用于重写url的nginx安全链接(PHP)
EN

Stack Overflow用户
提问于 2021-03-06 01:30:33
回答 1查看 335关注 0票数 0

最后,经过两天的调试工作,我使它完全正常工作。这就是我在我的场景中如何使用它。

nginx conf:

代码语言:javascript
复制
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

代码语言:javascript
复制
<?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中的头文件将其作为附件输出。

这是一个演示:

代码语言:javascript
复制
<?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();
?>

我可以在这里添加更多的安全性,以确保安全性始终遵循,但我让它工作了,我很高兴。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-11 17:13:31

所以,我自己解决了这个问题。我花了相当长的时间,因为我不太明白为什么它不能工作。所有的指南都是相同的,只是缺少了一些变量,或者只介绍了他们的脚本的用法。因此,我已经写了一个完整的澄清指南,如果有人在未来遇到这篇文章。第一个问题: URI必须指向安全的URL,而不是您想要的文件。预计这两件事是独立工作的。第2期:我看过的指南将$secure_link_expires放在了md5指令中。让它永远不会成功。编辑帖子以反映。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66497020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档