Nginx的防盗链和限速处理

防盗链处理

1 简单的通过referer判断

location ~ .*\.(gif|jpg|jpeg|png|bmp|wma|mp3|swf)$ {
      valid_referers none blocked server_names *.163.com 163.com baidu.com;
      if ($invalid_referer) {return 403;}
    expires      30d;
}

2 NginxHttpAccessKeyModule 插件

这个需要安装额外的模块,下载模块源码,然后按照说明文档,将下载来的源码中”$HTTP_ACCESSKEY_MODULE” 替换成 “ngx_http_accesskey_module“,再

  1. ./configure –add-module=path/to/nginx-accesskey

完了以后再重新编译一次nginx,然后就可以在配置文件中使了。

location /download {
  accesskey             on;
  accesskey_hashmethod  md5;
  accesskey_arg         "key";
  accesskey_signature   "mypass$remote_addr";
}

这样一个下载的文件就需要 http://example.com/download/file.zip?key=09093abeac094 这样的形式进行下载
其中 key的值为 mypass和下载客户端ip 进行md5运算获得。比如在 php 中可以向如下方式输出针对客户ip的下载链接地址

  1. <?
  2. $ipkeyvalue = md5("mypass".$_SERVER['REMOTE_ADDR']);
  3. $out_keyfile_link="<a href=http://example.com/download/testfile.rar?key=".$ipkeyvalue.">防盗链文件下载</a><br />";
  4. echo $out_keyfile_link;
  5. ?>

这样当一个用户将访问地址拷贝给别人时,因为访问ip不同,就造成 md5(”mypass”.ipaddr) 值不同,达到防盗链目的。

限速处理

限速使用 limit_zone, limit_conn 以及 limit_rate 进行配置
首先在 http 段配置一个 limit_zone,然后在需要的地方使用 limit_conn 和 limit_rate 进行限速设置,如下一个简单的例子

http {
  limit_zone   one  $binary_remote_addr  10m;
  server {
    location /files/ {
      limit_conn   one  1;
      limit_rate 20k;
    }
  }
}

说明:
limit_zone,是针对每个IP定义一个存储session状态的容器。这个示例中定义了一个名叫one的10m大小的容器,这个名字会在后面的limit_conn中使用。

limit_conn one 1;
限制在one中记录状态的每个IP只能发起一个并发连接。

limit_rate 20k;
对每个连接限速20k. 注意这里是对连接限速,而不是对IP限速。如果一个IP允许三个并发连接,那么这个IP就是限速为limit_rate×3,在设置的时候要根据自己的需要做设置调整,要不然会达不到自己希望的目的。

Popularity: 4% [?]

Random Posts

编译gdlib库碰到undefined reference to `png_check_sig’问题解决

采用源码方式编译php,需要gd库,同样采用源码编译,在编译过程中碰到 undefined reference to `png_check_sig’ 错误。
google了一下,发现由于使用的新的 libpng 1.4版本,去掉了png_check_sig函数,替换为了png_sig_check函数
,于是编辑gd库的 gd_png.c文件,将

  1. if (!png_check_sig (sig, 8)) { /* bad signature */
  2.   return NULL;
  3. }

修改为

  1. if (png_sig_cmp (sig, 0, 8)) { /* bad signature */
  2.   return NULL;
  3. }

再次编译通过

Popularity: 4% [?]

Related

源码安装Mysql提示No curses/termcap library found

使用源码方式安装Mysql5.0,提示No curses/termcap library found
google了一下,
下载一个ncurses-5.6.tar.gz安装,

  1. wget http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.6.tar.gz
  2. tar zxvf ncurses-5.6.tar.gz
  3. cd ncurses-5.6
  4. ./configure –prefix=/usr –with-shared –without-debug
  5. make
  6. make install clean

网上还有一篇说在./configure 时添加 –with-named-curses-libs=/usr/lib/libncurses.so.5 解决,但是添加后虽然./configure通过,但是在make时失败
在这儿记录一下

Popularity: 4% [?]

Related

在Shell中执行Mysql语句

使用shell脚本做日志分析,为了将分析后的结果直接存储到mysql数据库中需要在shell脚本中执行mysql的语句。
方法一 将每一步需要执行的语句保存到 tmp.sql 中,最后在使用

  1.   mysql -u uname -p pwd < tmp.sql

方式执行

方法二 使用参数传递执行
mysql -u$user -p$pass -D $db -e “select afield from atable;”
: 对test.dat中的每一行拼装成sql做执行

  1. cat test.dat |awk '{print "insert into table(a, b) values(\047" $1 "\047, \047" $2 "\047)" }'|while read line
  2. do
  3.   mysql -u$user -p$pass -D $db -e $line
  4. done

其中 awk print命令中的 \047 代表单引号

Popularity: 9% [?]

Related

在SQlite中遍历一张表的同时更新这个表的内容碰到的一些问题

在一个连接中遍历一个表的时候同时使用sql语句更新这个表的值,碰到错误”database table locked”
首先尝试在遍历前使用 PRAGMA read_uncommitted = True;
在遍历完成后在执行PRAGMA read_uncommitted = False;
这么处理后在遍历过程中可以对表做更新操作,不过引起另外一个问题,只能遍历一半的表记录,且当为记录行数为基数时会出现“not an error”错误,经测试估计是在遍历过程中使用执行更新sql语句时,同时向后移动了遍历的位置。
再次尝试使用两个链接来做遍历更新处理,其中一个链接做遍历,另外一个链接做更新。 在记录数少时一切正常,但是当记录数很多时候,在后面记录的更新时会出现“SQL logic error or missing database” 的错误。
最终对要遍历的表采用limit关键字分片读取出需要的数据,然后对这些数据做更新,完成后再读入下一组数据继续处理。

   load a block data
   while has block data
      foreach record in block
       do update
      load next block data

Popularity: 6% [?]

Related

以单用户模式运行MS SQL Server做数据库数据修复

数据库运行碰到问题

服务器: 消息 7105,级别 22,状态 6,行 1
text、ntext 或 image 节点的页 (1:511177),槽 0 不存在。

在查询分析器中执行

  1. DBCC CHECKTABLE (ErrTable, repair_allow_data_loss)

提示

服务器: 消息 7919,级别 16,状态 3,行 1
未处理修复语句。数据库需要处于单用户模式下。
DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。

查看了SQLServer很多设置项,没有找到以单用户方式运行的参数选项。于是通过google搜索。

在CMD命令行方式下,首先进入SQL Server的BINN路径,比如 C:\Program Files\Microsoft SQL Server\MSSQL\Binn
然后输入命令:
sqlservr.exe -c -m
只要保持这窗口开着,SQL Server就在运行,不用了关闭即可了。

运行后要确保关闭所有连接数据服务器的程序,包括SqlServerAgent处理。要不然单用户模式下在已经有一个连接的情况下不能再连接服务器。

Popularity: 6% [?]

Related

在Android NDK 中使用STLport(译)

Android NDK是Native C/C++开发,不过下载来看了一下缺少常见的STL库,使用起来诸多不便,于是网上google了一把,发现有人做了这样的事情,特别转过来
——————————–
原文: Android NDK - getting STLPort up and running
作者: Pete Cole
——————————-
如果你想在Android NDK使用STLPort, 你必须要做点处理,即便你是在windows上使用cygwin.

首先, 从http://umbel.mooo.com/ 获取一份修改版的 STLPort(by John Ripley (great job, John!)). 如果你是一个 cygwin 用户, 你首先要安装一个git包(译注:可以直接下载snapshot,这样就不要安装git了).

然后将文件拷贝到你的工作目录下. 在我的机器上, 我将文件拷贝到了c:\android-ndk-1.5_r1 目录下, 并将 两个hello-stl 文件夹移动到其他和NDK有关的目录下:

C:\android-ndk-1.5_r1\apps\hello-stl
C:\android-ndk-1.5_r1\sources\samples\hello-stl

然后在Build STLPort前必须修改一些文件…

setup.sh
将最前面的一些行修改正如下样子:

  1. #!/bin/bash
  2. if uname | grep -qi linux; then
  3. export NDK_HOST=linux-x86
  4. elif uname | grep -qi CYGWIN; then
  5. export NDK_HOST=windows
  6. else
  7. export NDK_HOST=darwin-x86
  8. fi

将倒数第三行修改成如下样子:

  1. ln -sf "$NDK_DIR/build/prebuilt/${NDK_HOST}/arm-eabi-4.2.1/bin/arm-eabi-$tool" arm-linux-$tool

stlport/build/lib/android.mak

将TOOLCHAIN_PREFIX这一行修改成

  1. TOOLCHAIN_PREFIX := $(NDK_DIR)/build/prebuilt/$(NDK_HOST)/arm-eabi-4.2.1/bin/arm-eabi-

译注: 我下载来的Wrapper包已经是这个样子了,不用修改

sources/samples/hello-stl/Android.mk
将STLPORT_BASE这一行修改成如下样子:

  1. STLPORT_BASE := /cygdrive/c/android-ndk-1.5_r1/stlport

译注:我没有修改这边,执行了一个export NDK_WRAPPERS_BASE=basepath的操作

将:

  1. LOCAL_LDLIBS += -L$(STLPORT_BASE)/build/lib/obj/gcc/so \
  2. -lstlport

修改成

  1. LOCAL_STATIC_LIBRARIES := libstlport.5.1

Building STLPort
现在文件已经被合并了,你可以立即build STLPort了!

执行如下cygwin shell脚本… 它将build STLPort的静态链接库! 对此你只需要做一次.

  1. export NDK_DIR=/cygdrive/c/android-ndk-1.5-r1
  2. cd $NDK_DIR
  3. ./env.sh
  4. ./setup.sh

现在,像下面这样讲文件拷贝到你的工程中:

  1. cp -p \
  2. /cygdrive/c/android-ndk-1.5_r1\stlport\build\lib\obj\gcc\ar\libstlport.5.1.a \
  3. /cygdrive/c/android-ndk-1.5_r1\out\apps\hello-stl\android-1.5-arm

Building your project’s shared library.
现在你可以返回cygwin的shell窗口,然后执行如下命令:

  1. cd /cygdrive/c/android-ndk-1.5_r1
  2. make APP=hello-stl

将编译你的共享库文件:
C:\android-ndk-1.5_r1\apps\hello-stl\project\libs\armeabi\libhello-stl.so

注: 这会将STLPort静态链接到你的库中.

Building the hello-stl project

在Eclipse中,使用New Project Wizard为每一个例子创建一新的Android project, 使用”Import from Existing Source” 选项从c:\android-ndk-1.5_r1\apps\hello-stl\project 导入源文件

现在你可以编译和运行你的项目了. 将显示从共享库中返回来的std::string字符串 …!

Popularity: 7% [?]

Related

ASQLite控件的Blob类型字段内存泄漏问题

使用Delphi的ASqlite控件做Sqlite数据库的数据维护,最近打开一个大的表,总是报”out of memory while expading memory stream” 的错误,提示内存不足。

经分析,是由于ASqlite控件在默认情况下总是将数据装入内存,记录数太多时造成数据不能完整装入。经查有UniDirectional数据可是设置为单方向使用表,可以不将记录完整装入到内存。但是设置了该属性值为True后,遍历表仍然是”Out of memory while expanding memory stream” 错误,感觉没有起作用。

分析ASQlite的源码,发现其将memo类型数据当作blob类型处理,而在UniDirectional为True是,读取记录时创建的BlobStream没有释放,因此和UniDirectional为False时行为一样。

修正Bug,打开ASGSqlite3.pas,将

  1. function TASQLite3BaseQuery.GetRecord(Buffer: PAnsiChar;    GetMode: TGetMode;
  2.   DoCheck: boolean): TGetResult;

函数的末尾部分

  1.     if Result = grOK then
  2.     begin
  3.       if FUniDir then begin
  4.           ptr := Connection.SQLite3_GetNextResult(Connection.DBHandle, FStatement, FParams,self);
  5.           if ptr <> nil then begin
  6.              Move(ptr^, ActiveBuffer^, MaxStrLen);
  7.           end else Result := grEOF;
  8.       end else begin
  9.           ptr := FResult.GetData(FCurRec);
  10.           if FResult.Count = 0 then
  11.              InternalInitRecord(Buffer)
  12.           else
  13.              if ptr <> nil then Move(ptr^, Buffer^, MaxStrLen); // albert 17/11/2004
  14.       end;
  15.       …

修改为

  1.     if Result = grOK then
  2.     begin
  3.       if FUniDir then begin
  4.           // 增加部分,释放前一记录的blobstream内存
  5.           if FResult.Count > 0 then begin FResult.FreeBlobs; FResult.Delete(0); end;
  6.          
  7.           ptr := Connection.SQLite3_GetNextResult(Connection.DBHandle, FStatement, FParams,self);
  8.           if ptr <> nil then begin
  9.              FResult.Add(ptr, 0);  // 增加部分,当前行添加到缓存中,等待下次释放
  10.              Move(ptr^, ActiveBuffer^, MaxStrLen);
  11.           end else Result := grEOF;
  12.       end else begin
  13.           ptr := FResult.GetData(FCurRec);
  14.           if FResult.Count = 0 then
  15.              InternalInitRecord(Buffer)
  16.           else
  17.              if ptr <> nil then Move(ptr^, Buffer^, MaxStrLen); // albert 17/11/2004
  18.       end;
  19.      …

修改后编译程序,再次打开库文件遍历表,没有再次出现问题。

Popularity: 6% [?]

Related

让crontab不再发出告警邮件

在默认情况下,如果cron程序在执行过程中出现问题,会向用户的本地信箱中发送邮件,时间长了或者碰到有问题的cron执行命令,则产生的邮件数量将会很巨大,那么如何禁用邮件报警功能呢,解决方法有如下一些:

Popularity: 18% [?]

Random Posts

在linux上php函数fgetcsv获取数据异常的解决(读取gbk数据乱码)

写了一个导入数据的小函数,因为偷懒使用了php自带的fgetcsv函数,结果在window机器上测试时一切正常,放到linux服务器上跑时,读入的数据乱码。

在google上搜索发现如下信息:

fgetcsv函数对区域设置是敏感的。比如说 LANG 设为 en_US.UTF-8 的话,单字节编码的文件就会出现读取错误。

实际应用中,当Linux系统是使用的默认设置,则在该Linux服务器上对gbk的csv格式文件进行处理的时候,就会出现乱码现象。

解决方法是

使用 setlocale 函数设置环境变量。比如要设置使用gb 的区域设置可以在fgetcsv前使用下面的语句。

  1. setlocale(LC_ALL,array('zh_CN.gbk','zh_CN.gb2312','zh_CN.gb18030'));

具体使用哪些locale 可以使用linux 命令 locale -a 查看系统支持哪些。

Popularity: 11% [?]

Related

Next Page →