2009年10月26日星期一

可恶,被 PHP-Mcrypt 的官方 Example 误导了

在看 php 的 mcrypt 加密,想使用对称算法,解决小块内容(比如 url、post)网上传输的安全性。即加密、解密用同一个密码。官方文档有个非常完整的演示功能的例子,大概顺序是:

  • 打开 module
  • 生成 IV
  • 得到 key/密钥/密码
  • 初始化(引擎?)
  • 进行加密操作
  • 关闭(引擎?)
  • 重新初始化(引擎?)
  • 进行解密操作
  • 关闭(引擎?)
  • 关闭 module

加密、解密放在了一个代码片段中,大概是想说,加、解密就那一句代码不同而已。

按照这个理解,为了使用方便,我把加、解密分解成了2个函数,内容都和例子差不多,不会有错。但一运行,不管用哪种加密算法,都会出现奇怪的解密后与原文不一致的错误。还不是完全不一致,后面大半段内容都是正确的,比如原文是包含 a-z 26个字母的字符串,运行结果如下:

$ ./mcrypt.php  Encrypt: M~<5¶¤Jw^TÝ×. ÃV¯ Decrypt: Âò¹ÁIijklmnopqrstuvwxyz 

好一通找原因,最后在支持算法列表页面中找到这么一句:The IV must be unique and must be the same when decrypting/encrypting.加、解密时所使用的 IV 必须相同。

昏,例子代码中 IV 是使用随机数生成的,分成2个函数之后,加、解密操作生成的 IV 肯定不一样,这就是解密失败的原因。mcrypt_create_iv() 函数文档页面的 user notes 中有位 Chris 还对 IV 纠正了一些错误观点。

综上,正确解密需要将 IV 与密文一同存储、传递。而我的需求比较简单,就没有必要这么作,反正 IV 也不需要保密,所以直接用 key 的 sha1 值的片断,比如前8位(与 git 版本号简写类似)作为 IV,对安全性影响不大,应该是可以接受的。

问题解决,收工,有和我一样吃过亏的同学么?

Tags: , , , , ,

Related posts

Source: http://www.fwolf.com/blog/post/450


2009年9月28日星期一

Flash 无法修改设置的问题

Adobe flash player settings

这个怪怪的问题也不是一天两天了,就是 flash 设置窗口,或者当 flash 游戏需要使用本地存储空间时,自动弹出的设置窗口,这个窗口无法用鼠标点击,用键盘 TAB 键能在各部分之间游荡但还是无法调整设置,基本上就卡死在这里了。

遇到这种情况,可以访问这个链接:http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager07.html,注意链接中并不是图片,而是实际的设置调整组件。比如刚才说的访问本地资源需要确认的问题,在这里设置成Never Ask Again,同网站的资源就再也不会弹出窗口导致 flash 卡死了。

Ubuntu 9.04, Firefox 3.0.13, Flash Player 10.0 r32.

参考:

Tags: , ,

Related posts

Source: http://www.fwolf.com/blog/post/449


2009年8月18日星期二

压缩网页图片

不压不知道,一压下一条,大部分图片几乎都能在近似无损的情况下压缩到 65% 原始大小左右,如果指明有损压缩,比如 jpeg 的 85 %,还能更小。

Smush.it

smushit 现在已经属于 Yslow 的一部分了,可以通过 firefox 插件使用,也能在线用,缺点就是你的图片必须能够从公网访问。

可以压缩各种图片,按照官方的解释,它会尝试各种工具和算法,找到最优的方式。因此,smushit 是一种很安全的压缩工具,几乎看不到差别,就是用起来麻烦些。

imagemagick

不同的图片格式有各自的特点,比如 gif 善于存储颜色较少的图片,也是动画图片的首选;png 善于存储能够矢量化的图片,jpg 则善于存储颜色、图片变化都比较多的图片。根据不同的图片特点,进行类型转换,有时能收到不错的效果。

图片 convert 之后,还可以利用其它工具进一步压缩,不过效果不大了。

另附一个转换图片类型之后,批量替换模板中调用文件名的脚本:

grep logo.gif * -R | awk '{print $1}' | sed 's/://' | xargs -I '{}' sed -i 's/logo.gif/logo.jpg/' '{}'

jpegoptim

这是今天刚发现的好东西,ubuntu 源中有,主要可以用它去除 jpg 图片文件当中的 comment exif IPTC 等无用标记,我测试的情况压缩率比 smushit 略低一点点。由于能够通过命令行使用,所以易用性更强。

一般我喜欢用 --strip-all 参数去除所有无用内容,实际压缩之前可以用 -n 参数预测一下压缩率(默认直接压缩覆盖源文件了),24bit Adobe 类型的图片基本上都能够压缩到 65% 原始大小,碰到 24bit JFIF 这种类型的图片一般压不动,但带上有损压缩参数比如 -m85之后,依然能够达到较理想的压缩率,并且图片损失效果不明显。

遇到无法压缩的图片、压缩后体积反而增大的图片会自动跳过,很贴心。

基本上,有了上面三种方式,就能够处理大部分网页图片了。

Tags: , , , , , , ,

Related posts

Source: http://www.fwolf.com/blog/post/447


2009年8月4日星期二

[Git]初学者注意事项

实在是受不了有些人的 Git 提交,费大力气"回滚",遂整理了这些刚开始用 git 或者还没有建立 scm 概念时容易犯的错误。

和源码无关的东西,尽量不要进仓库

不得不说一些图形化软件,在提交内容的时候大多提供一个"全选"或者"Select All"功能,这是最不好的了,一些懒惰的同志看都不看就连瓢带碗都提交了。

  • 测试时上传的文件,测试时的临时文件,统统不要
  • 对应上一条,强烈建议把所有文件的上传保存目录另行设置,放到源代码目录以外
  • 编辑器产生的备份文件、临时文件,编译时的中间文件,统统不要
  • 对应上一条,有个例外就是为了实现通过 Git 更新系统,.NET 的 bin 文件要进仓库,导致那个仓库现在都 100+m 了
  • 图片等资源文件,进仓库也可以,但应当使用有意义的文件名,便于后期管理
  • 对应上一条,现在设计网站界面喜欢先作图然后切割,产生一大堆 001_r5_c1.jpg 这样的文件,讨厌之极
  • 使用的外部类库,比如 php 类、js 类等,统统扔到源码目录以外,如果实在没办法要放在目录树中,也可以留出空目录,打包发行的时候再包含进来,依然不进代码仓库
  • 不要中文文件名,主要是跨平台使用有问题,文件名完全能够只用字母数字减号下划线

尽量采用相对小、相对独立的提交

Git 是作什么用的?Git 不是代码上传工具,也不是网站更新工具,而是软件开发过程的记录工具,为了更加准确的定位每个问题、每个功能修改,就需要在每完成一部分可以称得上是"一项"的工作时,就 commit 一次。哪怕只是修改了一两行,只要产生了必要的功能改变,就有价值记录。

当采用代码审核机制或者需要用邮件提交补丁时,较小的提交能够更有效、更容易、更准确的被检查和审核,这个在 linux kernel 开发文档中也有提到。

当然不能矫枉过正,必须有可记录的改变才有提交的价值。对应的,Git 日志大多数情况下主要显示第一行,控制每次提交都能用一句话简单概括,也是有必要的。

注释格式

格式属于个人习惯和团队规范范围,有必要采用相对统一的风格。

Git 本身不允许空注释,同时建议注释的第一行写简要说明,下面留一行空行,再写详细说明。

我的个人习惯,喜欢在每条注释前面用大约三个字母来表示本次修改的性质:

  • Add something
  • Bug [fix|found]: describe the bug or fix.
  • Chg something
  • Del something
  • Enh some treatment
  • New something
  • Tmp for some cause

为了保持语法通顺,也可以采用前三个字母后面加冒号,后面有啥写啥的方法。

最后,我觉得,能够遵守行业规范和团队约定,主动养成良好习惯,应当是鉴别人才的一项重要因素。

Tags: , , , ,

Related posts

Source: http://www.fwolf.com/blog/post/446


2009年8月2日星期日

Windows安全更新KB951748可能导致dns无法解析

很久没有鼓捣 windows 了,今天帮一个朋友修复他"不能上网"的问题,遇到了,记录于此。

首先遇到的是局域网 ip 设置问题,居然自己无法 ping 出去,别人却能 ping 通自己,怀疑是网络管理员作了什么设定,更改ip设置绕过。

然后就是 windows 里 dns 的怪问题了,具体表现为:用 nslookup 能够正常解析域名,直接 ping 域名却得到域名无法解析的错误。用 ip 地址可以直接打开网站,可输入域名却由于无法解析而打不开。

怀疑是 winsock 或者 lsp 的问题,尝试修复却未发现任何问题。

最终原因就是这个 windows 安全更新 KB951748,网上的说法是:

这个问题是microsoft把dns解析的本地端口改成了49152-65535,和visita一样(所以visita系统不受影响)。对于lns等 rules based firewall,只需要把dns rule的本地端口范围改成49152-65535就ok了(xp系统缺省是1024-5000)。

卸载之,一切恢复正常。

Tags: , ,

Related posts

Source: http://www.fwolf.com/blog/post/445

2009年7月4日星期六

Curl奇怪的403错误

自己用的小PHP应用,使用curl抓网页下来处理,为了穿墙方便,使用Privoxy作为代理,便于选择哪些网站使用proxy、哪些不用。但今天却遇到了奇怪的问题,访问google baidu这些网站居然都返回403错误,而访问其他的一些网站没事,如果设置为不使用proxy则都能正常访问。

难道google baidu就不让用proxy连接么?显然不可能,所以打开curl的信息输出(curl_setopt($this->mSh, CURLOPT_VERBOSE, 1);)看看,得到以下结果:

*   Trying 127.0.0.1... * connected * Connected to 127.0.0.1 (127.0.0.1) port 8118 (#0) * Establish HTTP proxy tunnel to www.baidu.com:80 > CONNECT www.baidu.com:80 HTTP/1.0 Host: www.baidu.com:80 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) Proxy-Connection: Keep-Alive  < HTTP/1.0 403 Connection not allowable < X-Hint: If you read this message interactively, then you know why this happens ,-) <  * The requested URL returned error: 403 * Received HTTP code 403 from proxy after CONNECT * Closing connection #0 ... Failed. 

可以看到proxy服务器工作正常,的确是baidu返回了403错误,但原因肯定还在我这边。终于,从网上(1of2, 2of2)得到了点启发──我使用的是proxytunnel而非proxy。

在代码中,有这么一句:

	curl_setopt($this->mSh, CURLOPT_HTTPPROXYTUNNEL, true); 	curl_setopt($this->mSh, CURLOPT_PROXY, $phost);

php文档中没有详细说明,不过man curl中有详细解释,两者都是代理,proxytunnel(-p参数)允许其他协议通过http代理传输,而proxy(-x参数)则只能走http协议。所以我猜测,google baidu的服务器和curl的proxytunnel不和,所以返回403。

禁用掉上面2行代码的第一句后,curl访问恢复正常。

比较奇怪的是,几种操作系统下还不一样,一台MAC OSX就要显式的禁用proxytunnel才可以,curl版本:

$ curl --version curl 7.16.3 (powerpc-apple-darwin9.0) libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3 Protocols: tftp ftp telnet dict ldap http file https ftps  Features: GSS-Negotiate IPv6 Largefile NTLM SSL libz  

而另外一台ubuntu则完全不受影响,怎么都能用,curl版本:

$ curl --version curl 7.18.2 (i486-pc-linux-gnu) libcurl/7.18.2 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.10 Protocols: tftp ftp telnet dict ldap ldaps http file https ftps  Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz  

MT主机上的centos也没事,curl版本:

$ curl --version curl 7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5 Protocols: tftp ftp telnet dict ldap http file https ftps  Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz  

看来不完全是curl版本问题,MAC OSX的确与众不同啊。

还有一个原因也会导致curl返回403错误,如果设置了:

	curl_setopt($ch, CURLOPT_NOBODY, true);

则需要紧跟着设置:

	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

不然会因为http服务器不允许 HEAD 命令而返回403错误。参考:Trouble with a cURL request in PHP。MAC OSX上curl之所以特殊,也不排除是这种原因吧。

Tags: , , , , , ,

Related posts

Source: http://www.fwolf.com/blog/post/444

配置安全的共享web服务器(抛砖引玉)

本文所讲的共享web服务器,并非共享文件的服务器,而是多人一起使用的web服务器,各有各自的网站、管理自己的文件,互不干涉,且对系统无影响。鉴于功力较浅,只敢对较信得过的朋友开放这种账号,本文涉及的范围也有限,所以安全漏洞可能还有,请诸位切勿直接用于生产环境。

服务器环境:Ubuntu 8.10, OpenSSH_5.1p1 Debian-3ubuntu1, Apache 2.2.9, PHP 5.2.6-2ubuntu4

登录 - SFTP

传统的 FTP 肯定是不如这个安全,telnet 更不用说了。使用 SFTP 还有一个起始想法是想配置证书自动登录,后来发现 SFTP 客户端(FileZilla)没这功能,就没再作下去,命令行下 scp 的自动登录倒是 和 ssh 的一样很好配置。

网上很多文章介绍把 sftp 用户限制在 $HOME 目录下的方法,使用的是 sshd 的 ChrootGroups 选项,这个选项在我的版本里没有找到,找到另外一篇参考文章使用的是 ChrootDirectory,也很好用。

创建一个用户组,作为所有 sftp 用户的用户组:

$ sudo groupadd sftp 

创建用户,设置密码,并归入 sftp 组:

$ sudo useradd -m friend $ sudo passwd friend $ sudo usermod -g sftp friend 

为了进一步增强安全性,还可以将用户的登录 shell 设置为 /bin/false,是个好习惯,但在本例中并非必须,下面的 sshd 设置也会让用户无法登录 shell (我观察的结果)。

$ sudo usermod -s /bin/false friend 

下来就要配置 sshd 了,编辑配置文件 /etc/ssh/sshd_config

# 修改下面这句 #Subsystem sftp /usr/lib/openssh/sftp-server Subsystem sftp internal-sftp 

然后在此配置文件末尾添加:

Match group sftp     X11Forwarding no     ChrootDirectory %h     AllowTcpForwarding no     ForceCommand internal-sftp 

配置含义大概为:凡是 sftp 组的用户,关闭 X 转发,chroot 到 $HOME 目录,关闭 TCP 转发(无法使用隧道了?),强制使用 internal-sftp(这个不明白)。

现在,重启 ssh 服务,用户就只能通过 sftp 访问 /home/friend 下的文件了。

PS: 我发现 sshd 如果配置错误,在 restart 服务的时候会先检查,而不是直接 stop 服务然后在 start 的时候出现错误,搞得服务启不来。大概是考虑到很多人都是远程 ssh 上来进行维护,服务 down 了以后就麻烦了,很贴心的设置。

Apache & PHP

Apache 配置简单,创建 /home/friend/www 目录,约定网站文件都放在这个目录下,然后弄个 Alias 指向就可以了。

但有一个极大的安全隐患需要堵上,用户可以通过编写 PHP 程序,读取系统中任何 www-data 用户有权限访问的文件,包括系统的 shadow 文件,包括 其它用户的网站文件等等。解决这个问题,一种是开启 PHP 的 safe_mode ,安全模式下 PHP 将只能访问 owner 为自己(也就是 www-data)的文件;另外一种是使用 open_basedir,这将限制 PHP 只能打开某一目录树下的文件,并且不可能通过符号链接避开此限制。显然 safe_mode 的副作用太多,后一种方法更适合我的这种情况,配置写到 Apache 的 conf 里就行了:

<Directory /home/friend>     php_admin_value open_basedir "/home/friend/" </Directory> 

注意open_basedir 后面的参数只代表文件路径的前缀,所以要带上末尾的斜杠,明确指出是目录。

不使用 safe_mode 的另外一个原因是在未来的 PHP6 里就要删掉它了。

缺点

最大的缺点就是 sftp 用户无法自己更改密码,除非自己写个守护程序啥的。这个程序在写的时候要非常小心,因为操作的是系统用户文件,如果遗留有安全漏洞可能会使别人获得其它用户权限。一个折中的方法是写个程序,定期更改密码并通过邮件告知用户,虽不方便但安全性要好一些。

Tags: , , , , ,

Related posts

Source: http://www.fwolf.com/blog/post/443