双葉幼稚園 A Layman's Repository

Python 判断一个变量是否是字符串

忏悔啊,就写了一个类还出了 bug⋯⋯

写了单元测试还出了 bug⋯⋯

type(data) == type("") 这种办法是不行的,因为 "" 是 str 类型,如果 data 是 unicode 的话这种判断就不成立了,而应该采用这种办法:isinstance(data, basestring),其中 basestring 是 str 和 unicode 两个类的父类。

期待 python 3k⋯⋯

Get Nagios to Work with Nginx (Gentoo)

今天装 Nagios,开源监控软件。

照例第一步:

emerge net-analyzer/nagios

这个包是个 meta 包,里面似乎有一个内核和一些插件,以后再研究,先搭起来再说。

跑起 Nagios:

/etc/init.d/nagios start
rc-update add nagios default

安装完成之后它会告诉你,要是 Apache 或者 Lighttpd 的话我会给你配好,不是的话自己看着办吧,于是我就自己来了。:-(

首先安装 spawn-fcgi 和 fcgiwrap,第一个是管理 fcgi 进程的,第二个是把 CGI 包装成 fcgi 的。fcgiwrap 这兄弟目前被 ~x86 mask 了,先 unmask。

echo www-misc/fcgiwrap ~x86 >> /etc/portage/package.keywords

然后安装:

emerge www-servers/spawn-fcgi www-misc/fcgiwrap

跑起 spawn-fcgi:

sudo spawn-fcgi -a 127.0.0.1 -p 22222 -P /var/run/fcgiwrap.pid -u nagios -g nagios -- /usr/sbin/fcgiwrap

-a 是主机,-p 是端口(用 unix domain 也行),-P 是 pid 文件,-u 是用户,-g 是组,-- 后面是要运行的命令,用户名和组一定要对,主机和端口要跟 nginx 对上。这条命令是起 CGI 部分的,Nagios 也用了 PHP,PHP 请通过 fcgi 自行跑起来 :-),php-fpm 或者 spawn-fcgi 均可,参考 WordPress 之类就行。

下面是 nginx 的配置,主要是抄的别人的,主体参考这里,另外也参考这里。尤其是fastcgi_param AUTH_USER $remote_user; fastcgi_param REMOTE_USER $remote_user; 两句,前一篇没有,害惨我了,nagios 一直说认证不通过……

自己发挥改改就好撒。

location / {
        auth_basic "Restricted";
        auth_basic_user_file /PATH/TO/HTPASSWD;

root /usr/share/nagios/htdocs;

location ~ \.php$ {
fastcgi_pass YOUR_PHP_UPSTREAM;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/share/nagios/htdocs$fastcgi_script_name;
include fastcgi_params;
}

location /nagios/ {
location /nagios/images/ {
gzip off;
}
expires 30d;
alias /usr/share/nagios/htdocs/;
}

location /docs/ {
root /usr/share/nagios/htdocs/;
index index.html;
}

location ~ \.cgi {
fastcgi_pass 127.0.0.1:22222;
fastcgi_index index.cgi;
fastcgi_param SCRIPT_FILENAME /usr/lib$fastcgi_script_name;
include fastcgi_params;
fastcgi_param AUTH_USER $remote_user;
fastcgi_param REMOTE_USER $remote_user;
}
}

关于里面提到的 htpasswd,是 basic auth 用的,咋生成看文档吧。

Restart Nginx & enjoy!

参考:

  1. http://yemaosheng.com/?p=899
  2. http://www.matejunkie.com/howto-let-nginx-serve-the-nagios-web-interface/
  3. http://wiki.nginx.org/HttpAuthBasicModule

A Password Generator

一个简易的密码生成器,python 写的,遵循 2 句 BSD 许可证,应该很好懂,参数什么的可以自己调调。

PS:其实我写完了才发现有个叫 pwgen 的东西,pwgen -cns 16 似乎也不错。

参考:

  1. https://blog.delphij.net/2010/12/post-598.html
  2. phpmyadmin 生成密码的代码:https://github.com/Reen/phpmyadmin/blob/master/js/server_privileges.js#L80

#!/usr/bin/env python2.6

# Copyright 2011 Kou Zuyang. All rights reserved.
# # Redistribution and use in source and binary forms, with or without modification, are
# permitted provided that the following conditions are met:
# # 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
# # 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
# # THIS SOFTWARE IS PROVIDED BY Kou Zuyang ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# # The views and conclusions contained in the software and documentation are those of the
# authors and should not be interpreted as representing official policies, either expressed
# or implied, of Kou Zuyang.

import random;

def generate_password():
alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNPOPQRSTUVWXYZ'
number = '1234567890'
special = '[email protected]#$%^&*()-=_+[]{};:,./\~`?'
charset = alphabet * 3 + number * 7 + special * 2
print ''.join([random.choice(charset) for x in xrange(16)])

if __name__ == "__main__":
generate_password()

解决 WordPress 自动升级中遇到的一个验证问题

WordPress 要升级 3.0.5,我懒,所以自动升级,点开自动升级的页面,输入验证方式,发现木有 sftp 的选项,印象中原来是有的,去查了一下,发现不是 WordPress 的问题,而是 PHP 没有装载 ssh 的模块,于是装上。

emerge dev-php5/pecl-ssh2

然后升级页面就神奇地出现了 SSH2 的选项,于是开心地填上用户名密码,一个回车,告诉你用户名或密码错误……我说不可能啊,于是去查系统日志,日志里竟然一个字都没写……明显就不是密码错了嘛。

啥问题呢,不清楚,咋办呢,查 WordPress 的源码吧。发现 wp-admin/includes/file.php 里有个函数叫 get_filesystem_method(),它的注释告诉我 WordPress 升级写文件有这么几种方式:Direct, SSH2, FTP PHP Extension, FTP Sockets,优先级依次递减,于是发现还有 Direct 这么一种神奇的方式,快速解决问题: chown -R nobody:nobody /path/to/WordPress。(我用 php-fpm 运行的,php 的 user 是 nobody)

不能把问题放着不管是不?去看看是啥问题,在 WordPress 源码里搜 "Username/Password incorrect for",发现几个文件里都有,分别对应几种连接方式:direct、ssh2、ftpext、ftpsockets。当然我们要看 SSH2 是不?于是这个文件是 wp-admin/includes/class-wp-filesystem-ssh2.php,里面那个 connect() 函数是我感兴趣的,里面有这么一句:

if ( !$this->keys ) {
  if ( ! @ssh2_auth_password($this->link, $this->options['username'], $this->options['password']) ) {
    $this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username']));
    return false;
}

也就是说没有使用 key 的时候,用密码验证,ssh2_auth_password() 失败的话就说是用户名或密码错。(PHP 达人告诉我前面的 @ 是啥?)

查这个函数的原型,人家只说失败的时候返回 false,谁说一定是密码错误了,你妹的……

不过在这个文件里还有新发现,在这个类的注释里,发现了一篇 pecl-ssh2 的安装指南,在里面发现了问题:On the serverside, 'PasswordAuthentication yes' must be enabled in the sshd_config. 一查我的配置,果然给弄成 no 了……

欣喜若狂地改成 yes,然后重启 sshd,/etc/init.d/sshd restart,竟然没法重启……尝试 reload,/etc/init.d/sshd reload,说 sshd 没运行(No /usr/sbin/sshd found running; none killed.),又开始扯淡了!!!

遵循不知道谁的教导,重新 emerge 一遍 openssh。

emerge net-misc/openssh

然后

/etc/init.d/sshd restart

就能重启了……

之后回到 WordPress 输上密码,发现能登录上了,变成 PHP 错误了……仔细一看,我的账户也没有改 WordPress 代码的权限啊……

折腾一圈白干了,专门弄个账户还不如改权限(chown -R nobody:nobody)呢。

不过过程中还发现了新的问题,sshd_config 里面 PasswordAuthentication no 之后还是能从别的主机用密码登陆(不过 php 这个 ssh2 的库登陆不了了),很神奇吧……以后再看是什么问题吧。

大概找到是啥问题了,下篇发出来吧。

禁止 ssh 密码登陆

/etc/ssh/sshd_config 里面

PasswordAuthentication no
UsePAM no

为啥这样不要问我……去看看 /etc/ssh/sshd_config 里面的注释或者 man sshd 之类的吧,因为我也说不非常清楚,哈哈哈哈。

cURL 下载迅雷离线

今天下载 Xcode 4 GM,很大,3G+(苹果东西一向大),于是想走这样的线路,BT->迅雷离线->某服务器->笔记本,这样就避免迅雷离线有的时候下载不稳定之类的问题,所以需要用 cURL 之类的东西下载迅雷离线,稍微尝试之后,办法出来啦。

  1. 首先用浏览器获得真实的下载链接,开头类似 http://vod19.c7.lixian.vip.xunlei.com/download 这样的,要真正开始下载之后的链接。

  • 找到 vip.xunlei.com 这个域名下面的 cookie,名字是 gdriveid,把名字和值记下来。
  • curl "http://DOWNLOAD.LINK/" --cookie "gdriveid=VALUE" -o FILE_NAME
  • OK 了。
  • 本来是用 http://gdl.lixian.vip.xunlei.com/download? 开头的链接来尝试的,后来发现重定向到 http://vod19.c7.lixian.vip.xunlei.com/download 之后 cURL 没有把 cookie 带上,而服务器对这两个 URI 的访问都需要验证这个 cookie,我对 cURL 又不是很熟,就转而用 http://vod19.c7.lixian.vip.xunlei.com/download 这样的链接了……

    可能从文件里读取 cookie 可行,我没试成功。

    Gentoo/Nginx with IPv6 (Tunnel) Support

    弄了一个 he.netIPv6 隧道,给服务器用。(你说你 Linode 为啥不提供原生 IPv6,为啥?)

    一会就申请完了,你就获得 4 个 IP,服务器的 IPv4、IPv6,客户端的 IPv4、IPv6,你需要这些 IP 来做一些配置。

    首先是配好 Gentoo,LInode 的 wiki 写的很清楚,注意 interface 的名字似乎不能太短,一开始我起的叫 he,出了奇怪的错误……改成 hetun 就好了……

    注意 Linode 的 eth0 是用的 DHCP,别乱改。

    接下来是 Nginx,因为编译的时候已经带上 USE="ipv6" 了,所以就不需要重新编译了,改一下 Listen 语句就行。我原先都是用的 Listen 0.0.0.0:80,要使 IPv6 有效的话要改成 [::]:80,于是尝试性地改了一个域名的配置。

    重启 Nginx,报错,说 80 端口已经被 bind 了,我说不可能啊,lsof -i tcp:80 也是空的。想了想隐约知道是怎么回事了,于是把所有的配置文件都从 Listen 0.0.0.0:80 改成 Listen [::]:80,重启,OK 了。

    想来是因为 Nginx 把 0.0.0.0:80 和 [::]:80 认成了两个端口,于是 bind 了两遍,这不就冲突了嘛……都改成 Listen [::]:80 就好了。

    参考文献:

    1. http://kovyrin.net/2010/01/16/enabling-ipv6-support-in-nginx/
    2. tunnelbroker.net 给的配置命令
    3. http://www.linode.com/wiki/index.php/IPv6#Gentoo

    2010 -> 2011

    不知道这时候写这种标题的文章算不算有点太晚了呢?

    先总结总结吧,从年初开始。

    依我自己的记忆力,估计是什么都想不起来了,于是还是询问了一位重要参考人,嗯嗯。

    1 月,复习考试……咋上来就是考试呢,考试复习,高数杯具了……

    2 月放假,放假了,看书,玩,反正也没做什么正事吧。买了机械键盘,不过一直也没机会用,也就在家用用,以后或许就好了。

    开学了,半路跟着做了个项目,为 MSTC PK 赛做的游戏,进去的时候就已经很乱了,其实我也没做啥……就是提供了一台笔记本测试用……帮忙调试,写了一些网络相关的代码。第一次通宵,终于做完了,天亮了起来去 M 记一起吃早饭,然后回去睡觉……中午再出去做 PK 赛的宣传。两轮比赛完了活动也就结束了,开发挺累,不过比赛就当是玩了。

    结束了之后也就快考试了,再次复习考试。这次还好。

    放假前找好了一个实验室,放假之后就去了,开始做项目,内容就不说了。

    去看了移动开发者大会,Google 创新论坛,出去逛逛挺好。

    下学期也跟上学期差不多,开学 -> 项目 -> 休息 -> 复习考试。考试也还好,嗯。

    老婆说这一年我逐渐适应大学生活了,嗯,应该是这样吧。每学期换个地方,每学期做个项目,每学期一次考试,呵呵。

    这一年做的项目在变,呆的地方在变,不过还是有些东西没变。比如说一直还是在玩 Linux,虽然不拿来当桌面用已经有一年半了,不过各种机会还是一直在折腾,手里有几台服务器,也装过一段时间 Gentoo Prefix。也折腾过两天 FreeBSD,觉得不好玩……主要是跟 Linux 的区别没有体会出来。

    暑假还做了一会 Mac 开发,一个小项目,仿照单词随意背做的一个 Mac 版本。算是了解了一下 Objective-C 和 Cocoa,算是为接下来的 Cocoa Touch 和 iOS 做了点铺垫。

    接下来的比较长的一段时间,我会专注于一个项目,我的职责主要是 Linux、Web 和 iOS 开发,基本上都是我稍微有点熟的领域,另外还能远离 Windows,真好。

    下学期的课应该不是很重了,有更多的时间做自己的事情,哈哈哈哈。

    给自己订几个本年目标吧,截止明年寒假?

    • 翻译一篇维基百科条目。既锻炼了英语水平又做了贡献,当然,一篇只是开头而已,一旦第一篇搞定了,接下来也就简单了。
    • 平均每两周一篇博客。2010 年没写多少东西,惭愧。
    • 锻炼。据说 7+1>8,加油。
    • 读一本自己觉得有深度的书。偏底层、偏理论或者偏思想的。
    • 学五笔。唉……不知道拖了多久了……

    还有些推荐执行的?

    • 博客要有题图。(就像这篇一样这么烂的?)
    • 读一本非技术类英语书。
    • 日语。现在这个日语水平啊……惭愧啊……

    明年这个时候来 check 吧!

    最后给大家拜年!

    Flush DNS Cache on Mac & Chrome

    Mac Leopard & Snow Leopard:

    dscacheutil -flushcache

    Chrome:

    chrome://net-internals/#dns

    click on "Clear host cache"

    西单大悦城一日游

    该说这是悲催呢,悲催呢,还是悲催呢?
    一切从周日早上说起,说早上女友叫我起床。迷迷糊糊接电话呢,然后(据事后报道)就没声音了……挂了再打无人接听(其实我这边没响),过段时间再打就暂时无法接通了……
    于是十一点我才起来,起来按手机,怎么按怎么不亮 >_< 接在笔记本上,iTunes 表示完全无压力……完全无视……
    于是乎马上准备去修,毕竟不能一直没手机用不是? 调查好维修流程,发现要修去苹果,要换要在苹果开条去联通换,而且必须在领 iPhone
    分别营业厅才行…… 打各种电话时发现,苹果服务就是比联通好(联通也不差……),虽然苹果那个 adviser
    是个南方人(香港人?),语言有些障碍,但服务还是很好。 苹果在海淀这边有俩授权维修点,不过还是不放心,预约了晚上八点四十的西单天才吧。
    提前好久到了那,人很多,没法提前,逛了逛大悦城,回去又等,八点的时候中午轮到我了。 坐在天才吧里坐了半天,我们的女天才出现了……我说我
    iPhone 完全沉默了,她拿过来说试试她能不能帮我,只见她同时按住电源键和 Home
    键,白苹果出现了……我……我当时就……我自己按为啥就不行呢?她看到密码框,把手机给我,输完密码我没给她,而是自己试了试,怕她看到我的
    Cydia…… 我说我自己按为啥不行……她说很多人都这样说……难道这就是人品…… 接着说蛋疼地排队的时候发现的小事吧。(这才是正题?)
    说我在试用 iMac,旁边一个大概初中生年纪的人也在用 iMac,他在人人上玩 flash
    游戏,旁边一个穿西服工作人员(穿西服的是保安?天才穿红
    T-shirt)的看他不爽,走过去,拿起桌子上的塑料配置单(价目表?)猛敲了一下桌子,那小孩吓跑了,我也吓了一跳。>_<
    你说这算啥,人家玩个小游戏咋了?算测试 flash 性能行不?你家跟 Adobe
    这么紧张人家关心下咋了?有事好好说,吓唬人家干什么,何况旁边的人做错了什么?为啥要被你吓一跳?总之很不爽。
    说专卖店里大部分地方都有移动信号,但是最里面的天才吧没有,只有联通信号,故意的吗? 用 MacBook Pro 的时候突然想用
    terminal,手电筒搜索未果,后来发现需要搜索“终端”才行……点开终端,出来一个赤裸裸的密码框……要输密码!不知道还有没有其他程序要输密码……(另外,怎么实现的?)
    专卖店里的 iTunes 只能激活 iPhone 不能同步,也算意料之中。 iPod nano
    的体验还不错,触摸导航什么都不错,就用了一会,算是第一印象。 天才们的胸卡后面空间挺大,没看错的话是放 iPhone 4
    的,看有几个人放着。 店里时常响起警报,似乎是防盗用的,每次响起警报,穿黑衣(西服)的都要去看看,有点吵。
    从店里出来之后又在大悦城转了转,买了一对杯具,总不能白来吧……