色破飞机 发表于 2018-8-31 09:02:21

【Anychat音视频开发】apache防盗链之mod_perl

  客户需求如下:
  在web请求视频时,按算法生成密文和明文串,然后依规则组成最终的url请求;
  算法规则——用如下三个关键词生成MD5密文:
  1、自定义密钥:abcde.;
  2、视频文件真实路径,即/path/to/file.rmvb;
  3、请求时间,以当前UNIX时间换算为十六进制字符串,并作为明文;
  最终url格式是http://www.test.com/path/to/file.rmvb?key=1234567890abcdefghijklmnopqrstuy&t=1234abcd这样。
  要求失效时间为8小时。
  这个需求和之前一次相当类似,不过上回是squid,这次是apache。同样采用perl脚本进行防盗链设置,apache需要使用mod_perl模块。
  首先安装perl模块:
  wget http://perl.apache.org/dist/mod_perl-2.0-current.tar.gz
  tar zxvf mod_perl-2.0-current.tar.gz
  cd mod_perl-2.0-current.tar.gz
  perl Makefile.PL MP_APXS=/home/apache2/bin/apxs
  make && make install
  echo "LoadModule perl_module modules/mod_perl.so" >> /home/apache2/conf/httpd.conf
  perl -MCPAN -e shell
  >install Apache2::Request
  >look Apache2::Request
  rm -f configure
  rm -f apreq2-config
  ./buildconf
  perl Makefile.PL
  make && make install
  exit
  (因为64位系统的libexpat.so有问题,编译libapreq2会出问题,只好如此强制安装)
  echo "LoadModule apreq_module modules/mod_apreq2.so" >> /home/apache2/conf/httpd.conf
  因为libapreq2.so安装在/home/apache2/lib/下了,所以需要echo "/home/apache2/lib">/etc/lo.so.conf.d/apache.conf,然后ldconfig。
  修改httpd.conf,加入如下设置:
  PerlPostConfigRequire /home/apache2/perl/start.pl
  
  SetHandler modperl
  PerlAccessHandler DLAuth
  PerlSetVar ShareKey abcde.
  
  然后mkdir /home/apache2/perl/,在其中创建start.pl和DLAuth.pm两个文件。start.pl文件内容如下:
  use strict;
  use lib qw(/home/apache2/perl);
  use Apache2::RequestIO ();
  use Apache2::RequestRec ();
  use Apache2::Connection ();
  use Apache2::RequestUtil ();
  use Apache2::ServerUtil ();
  use Apache2::Log ();
  use Apache2::Request ();
  1;
  DLAuth.pm文件内容如下:
  package DLAuth;
  use strict;
  use warnings;
  use Socket qw(inet_aton);
  use POSIX qw(difftime strftime);
  use Digest::MD5 qw(md5_hex);
  use Apache2::RequestIO ();
  use Apache2::RequestRec ();
  use Apache2::Connection ();
  use Apache2::RequestUtil ();
  use Apache2::ServerUtil ();
  use Apache2::Log ();
  use Apache2::Request ();
  use Apache2::Const -compile => qw(OK FORBIDDEN);
  sub handler {
     my $r = shift;
     my $s = Apache2::ServerUtil->server;
     my $shareKey = $r->dir_config('ShareKey') || '';
     my $uri = $r->uri() || '';
     my $args = $r->args() || '';
     my $expire = 8 * 3600;
     if ($args =~ m#^key=(\w{32})\&t=(\w{8})$#i){
     my ($key, $date) = ($1, $2);
     my $str = md5_hex($shareKey . $uri . $date)
     my $reqtime = hex($date);
     my $now = time;
     if ( $now - $reqtime < $expire){
         if ($str eq $key) {
           return Apache2::Const::OK;
         } else {
                 $s->log_error(&quot;[$uri FORBIDDEN] Auth failed&quot;);
           return Apache2::Const::FORBIDDEN;
         }
     }
     }
     $s->log_error(&quot;[$uri FORBIDDEN] Auth failed&quot;);
     return Apache2::Const::FORBIDDEN;
  }
  1;
  就可以了。
  apachectl restart。测试一下,先用perl自己生成一个测试链接:
  #!/usr/bin/perl -w
  use Digest::MD5 qw(md5_hex);
  my $key = &quot;bestv.&quot;;
  $path = shift(@ARGV);
  my $date = sprintf(&quot;%x&quot;,time);
  $result = md5_hex($key . $path . $date);
  my $uri = &quot;http://127.0.0.1$path\?key=$result\&t=$date&quot;;
  print $uri;
  运行./url.pl /smg/abc.rmvb生成http://127.0.0.1/smg/abc.rmvb?key=4fb6b4e6a0ec484aea98fa727fc7149d&t=4bc7dd5a,然后wget -S -O /dev/null &quot;http://127.0.0.1/smg/abc.rmvb?key=4fb6b4e6a0ec484aea98fa727fc7149d&t=4bc7dd5a&quot;,返回200 OK;任意修改t为12345678,再wget,返回403 Forbidden。error_log显示如下:
   Auth failed
  Anychat专业即时通讯方案,专注六年的研发。能够给你提供最高清实时的音视频即时通讯。
  如有需要下载体验可以访问http://www.bairuitech.com/
  详细了解可以致电020-38109065/ 020-38103410或者加Q1816573263。

页: [1]
查看完整版本: 【Anychat音视频开发】apache防盗链之mod_perl