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

2009年5月18日星期一

Ubuntu升级到9.04 Jaunty的变化和遇到的问题

  • 长按键盘自动连续击键的间隔缩短了。
  • 显卡驱动没有问题,终于能够摆脱8.10里像涂了墨水一样的中文字乱码了。
  • Firefox的速度好像也快了不少,或许也是显卡驱动的原因?
  • Fluxbox apps文件中Position设置LOWERLEFT/BOTTOMLEFT原来时从屏幕最下方算间距,现在时从工具栏上方开始算,所以原来的值要减去工具栏的高度(25)。
  • 消失很久的启动时的Splash屏又回来了,不过是Xubuntu的小老鼠(我用的WM是Fluxbox),想取消的话,删掉usplash及其相关的包即可。

如果在没有正式发布的时候就升级了,每天的更新比正式发布后要多得多,每天都要下载一大堆包升级,得考虑好,当然你也可以忍着不频繁升级。

Fluxbox任务栏上当前聚焦的窗口和其他窗口的风格是一样的,区分不开了,更换任何styles都无效。

Firefox窗口的标题栏里中文字显示为方块

先这个是Gnome的问题,所有窗口标题栏中包含中文时都是方块,而Fluxbox工具栏上是能够正确显示中文的。尝试更换不同的fluxbox styles发现menu.title.font设置为dejavu字体时窗口标题栏就能正常显示中文了,其他的窗口内容、网页中文全部显示正常。

终于让我找到原因了,又是一个哭笑不得的问题,在我自定义风格里,使用了dejavusans这个字体,而这个字体现在好像在系统中找不到了,因此它就像出错后就不再往下执行了一样,导致后面overlay里定义的新字体也不生效,窗口栏上的中文就成方块了。换其他style之所以能正常显示窗口标题栏上的中文,是因为他们没用dejavusans这个字体。最后的解决方案,把这个自定义style里的dejavusans替换成dejavu -_-!

字体大小dpi优化

字体DPI设置会根据显示器进行优化,而不再局限于默认的96DPI,还可以在System → Preferences → Appearance → Fonts → Details里自行定义。原来是在.Xresources里设置的Xft.dpi:96,不知道还有用没。目前发现的问题是窗口标题栏中的文字比以前大了一些。

我的Fluxbox还遇到了一个问题,屏幕尺寸、位置计算出现了错误,原先我是/etc/gdm/Init/Default中用xrandr -s 1024x768强制重设分辨率,现在把这行禁用后发现桌面的"尺寸"比1024大,鼠标移动到屏幕边缘后会自动移动,但显示不全。

	$ xdpyinfo |grep resolution 	  resolution:    78x78 dots per inch

78是显示器真正的dpi数,但按这个设置又显得字太小了。最后,把xorg.conf里大于1024的分辨率都删掉,这样就可以去掉上面xrandr那句了,显示也正常了,dpi仍然用的是96。

上某些网站中文字模糊(像粗体字那样的模糊)

打开/etc/fonts/conf.d/44-wqy-zenhei.conf,找到下面这行:

	<edit name="antialias" mode="assign"><bool>true</bool></edit>

把true改成false后重启X即可。

Ctrl+Alt+Backspace关闭X的组合键被禁用了

编辑/etc/X11/xorg.conf,在最后加上:

	Section "ServerFlags" 		Option "DontZap" "no" 	EndSection
Tags: , , , , ,

Related posts

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

Mysql升级到5.1后库升级失败的问题

一台 mysql 5.0 服务器,升级到 5.1 后,发现原来有个 database 名字变成了 #mysql50#t-2008-zbb ,刚开始没在意想直接 RENAME DATABASE ,结果这个语法由于过渡危险已经取消了,改用ALTER DATABASE db_name UPGRADE DATA DIRECTORY NAME,结果执行错误:

mysql> ALTER DATABASE `#mysql50#db_name` UPGRADE DATA DIRECTORY NAME; ERROR 1450 (HY000): Changing schema from '#mysql50#db_name' to 'db_name' is not allowed. 

原来这里面还有个 BUG ,刚刚修正过来,发行版中肯定还没有呢。幸好,从中得到了提示,因为 View 的存在导致库无法升级的,删掉所有视图后 UPGRADE 成功:

mysql> ALTER DATABASE `#mysql50#db_name` UPGRADE DATA DIRECTORY NAME; Query OK, 0 rows affected (0.08 sec) 

这台服务器还作了双向同步,我还得手工重置同步状态,又是麻烦一连串儿的事情,幸亏这次操作的是测试服务器,下次升级正式服务器之前,记得先把所有 View 删掉,升级完成后再重新创建。

另外 RENAME DATABASE 实在是危险,我执行过程中出错终止了,结果一部分表在新库里、一部分表在旧库中,不小心把未转完的目标库删掉了(不然后面的正常 ALTER DATABASE 无法继续),结果就丢失了这些表的数据。

Tags: , , , ,

Related posts

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


2009年4月23日星期四

小巧的编辑器Geany

我对PHP编辑器的要求不高,不过很多软件却不合我意:

首先,最好是免费的,所以挺好用的Zend Studio落选了。并且我发现似乎Zend Studio与ibus或者ubuntu jaunty有点冲突,有时候中文就出不来了。

其次,小巧,java的最好不要,所以Eclipse也落选了。

最后,最小功能集:语法高亮(废话)以及类函数列表(可以帮助我快速定位)。就这两项功能,淘汰了gedit(支持得不好)、vim(无法列出类函数)等工具。

当然,隐含要求,支持中文输入法,所以gphpedit也不能用,正好也不喜欢它的颜色高亮模式(色彩搭配)。

所以,选来选去,今天才算碰到一个比较满意的────Geany,ubuntu源中有,目前版本0.14,看来开发历史并不长。使用gtk2,操作流畅。除了类函数列表以外,还有一些贴心的小功能,比如自动补齐文件末尾的空行、保存时自动删除行尾空格等。

geany screenshot

默认的,Geany的快捷键Complete Word与中文输入法冲突,还好,可以通过设置删掉:双击-->Del-->回车。

geany-solve-conflict-with-input-method

可怜的gphpedit也是这种快捷键冲突,不过我没找到设置方法。

其实Geany不仅能够处理PHP文件,还能够编辑多种脚本文件,新建文件时有内置模板可选,能够自动生成文件头的copyright及GPL声明。

总之,到目前的感觉,挺好用的。

Tags: , , ,

Related posts

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

2009年4月12日星期日

控制ThinkPad的风扇

 Link    

我的旧本子X31风扇很久都不转了,今天查了点资料,搞了搞,感觉状态上好,记录如下:

首先要能了解当前温度和风扇转速,安装lm-sensors包就能用了:

$ sensors acpitz-virtual-0 Adapter: Virtual device temp1:       +42.0°C  (crit = +91.0°C)                    thinkpad-isa-0000 Adapter: ISA adapter fan1:       3614 RPM temp1:       +42.0°C                                     temp2:       +48.0°C                                     temp3:       +48.0°C                                     temp4:       +42.0°C                                     temp5:       +32.0°C                                     ERROR: Can't get value of subfeature temp6_input: Can't read temp6:        +0.0°C                                     temp7:       +29.0°C                                     ERROR: Can't get value of subfeature temp8_input: Can't read temp8:        +0.0°C       

按说lm-sensors也能控制风扇的,但对我的本子不适用。

然后就是在内核中挂载ThinkPad的高级电源控制模块,在/etc/modprobe.d/options里添加这么一句,后面的参数fan_control很重要:

options thinkpad_acpi fan_control=1 

重启,或者手工重新挂载模块:

rmmod thinkpad_acpi modprobe thinkpad_acpi 

好了,控制风扇转速,最基本的方法是(如无意外,本文中的大部分命令都要用root用户操作):

echo level [level] > /proc/acpi/ibm/fan 

[level]的取值可以是0-7之间的数字,或者auto,或者disengaged/full-speed,在不同的本子上会有不同的效果,总体来说数字越大转速越高,auto是系统自动判断,但在我的本子上却是不转,disengaged/full-speed是全速。我自己用的本子,设为4左右就能达到温度和噪音的平衡点。

还有人在这个基础上写了一些小工具,比如tp-fancontrol或者ThinkPad Fan Control,主要功能都是定时探测温度,然后安装预先的设定来控制风扇的转速。但由于不同硬件的差异,他们并不适用于所有情况,比如我的X31装上哪一个风扇都是auto不转,只好手工echo然后让风扇常转了。智能一点的,还可以借助cron来个定时开关、定时检测什么的。

参考

Tags: , , , , ,

Related posts

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

2009年3月29日星期日

/bin/sh: root: not found

root用户经常收到这样的错误邮件:

  From: Cron Daemon <root>   To: root   Subject: Cron <root@fwolf> root /home/fwolf/bin/cmd_run_in_crontab   X-Cron-Env: <SHELL=/bin/sh>   X-Cron-Env: <PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin>   X-Cron-Env: <HOME=/root>   X-Cron-Env: <LOGNAME=root>     /bin/sh: root: not found    

这个问题很简单,但也容易让人糊涂,先说原因吧, /etc/crontab 中格式是这样的:

  17 * * * * root cd / && run-parts --report /etc/cron.hourly    

而 root# crontab -e 出来的应该是这样:

  17 * * * * cd / && run-parts --report /etc/cron.hourly    

注意, /etc/crontab 是针对整个系统的,所以第6列是用户名, root# crontab -e 是root用户的,所以第6列就直接是命令了。

这有什么好糊涂的呢,因为这两个文件很可能会一模一样,我就是这样,后来才发现他们的不同,不信用 root# crontab -e 修改些内容再和 /etc/crontab 对比就知道了。

现在, /bin/sh: root: not found 这个错误不用我再解释了吧?直接拷贝crontab到root的后遗症。

Tags: , , ,

Related posts

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