又一个 ksh 的 bug

见鬼的事怎么总是我碰上。

$ cat kshbug
{ return 0; } &
evil=$(/bin/true) # XXX: works fine without this line
wait $!
echo $?

$ ksh kshbug
127

$ ksh --version
version sh (AT&T Labs Research) 1993-12-28 r

The correct return code should be 0. Without the line of "eval=$(bin/true)"
everything works fine. The problem happens only when

  1. Execute a function or a clause in background, and
  2. A subshell is invoked between the background execution and the "wait", and
  3. An external command is executed in the subshell

I googled for a while, there's no ksh bug report so far, workaround could be use output text for return code check instead. Note there's a similar report for ksh on solaris but it's not the identical issue.

Pdksh (public domain ksh) doesn't have the problem. (See another bug.)

Update: this issue doesn't happen on Ubuntu ksh version "sh (AT&T Research) 93s+ 2008-01-31".

Review

原来我已经 5 个月没碰这里了。最忙的时候过了后生活实在是太简单了,除了上班下班做饭吃饭遛狗爬山就没有别的了,不抽烟不喝酒不社交不下棋,我已经提前进入老年化生活阶段了。翻看旧帖,年初时许了个愿,看看完成得怎么样了。

> 1. 管理自己和老婆的健康,少宅多运动

无非是带着破狗爬了几次香山,差强人意。

> 2. 工作上争取“出人头地”,令同事信服,老板放心

薪水没加,责任没少,表现平平,不过尔尔。倒是悟到一条心得略感欣慰:只要设计得当,shell 脚本也可以“面向对象”。

> 3. 提高涵养,不斗气,对事对人能包容,做事要与年龄相称

这其实很难,成为老婆的司机后我努力在这方面提高,还远不够...,

> 4. 拿到驾照

算是超额完成。

> 5. 攒房子

以北京现在的房价,换大点的房子是遥遥无期了。每月又多出油费支出,这个目标更远了 :-(

我升职了

今天老板召我去他的办公室,笑眯眯滴向我宣布升我职已经批准了,就等大老板正式宣布了。丫说,但是现在大形势不好,上个月通知的公司全员降薪也是没有办法,这次虽然升职但暂时还不能加薪,丫然后给我画了张饼,“等过上几个月形势好了再把这个缺口给你补上”,“希望可以激发你的斗志”。

丫比我更 high,因为不多花一分钱,却可以名正言顺要老子做更多事情,faint。

ping 不通怎么度量延迟

公司 VPN 网关都过滤了 ICMP,ping 是不通的,恼火完了之后想到可以从 connect() 入手,看一下连接主机某个端口要多长时间,精度足够了。别去写 code,有现成的工具 netcat,在 Linux 系统上基本上是标配,用端口扫描选项 "-z" 去连 www 端口 80 可也。

$ host example.org
example.org has address 208.77.188.166

$ time nc -z 208.77.188.166 80
real 0m0.075s
user 0m0.000s
sys 0m0.000s

先解析出 IP 是为了更精确的,不计算域名解析的时间。

换到 Habari 了

换过来的原因很简单,这个 VPS 只有 64M 内存,我要多留些内存给 sshd 做穿墙隧道,同时还要起个 vpn client,于是拿 mysql 开刀。找了一圈支持 sqlite 的感觉也就 habari 值得尝试了。一个小小的 blog 么,完全用不着 mysql。

除了跟 lighttpd 的 rewrite 规则斗争之外,感觉还是相当不错。自带插件可以从 wordpress 数据库导入所有东西,装了 RN Custom Permlink 可以定制 permlink 保持跟以前的一致,就是两个 feed 地址实在恼人,最后在 Wayne 同学的指导下自己弄了个插件直接把 Wordperss 形式的 feed 地址转向。lighttpd 为什么不行,因为它 rewrite 之后并不会修改 REQUEST_URI,而 habari 把 index.php 也处理成 slug...,这时候就看出来 nginx 的好了,它可以只转向不对应实际存在文件的 URL,真不明白怎么 lighttpd 一直不加这个(民间有 patch),影响性能?

URL rewrite 的解决方法应该可以从 DB 直接入手,等有空再研究研究,habari 还是很强大的。希望 UI 方面不要再加华丽的东西了,就现在这样就非常好了。

回北京了,自觉隔离中

着陆后飞机停在离建筑物至少 1 公里的广场中间,所有人被要求等待体温检查,四名身着生化防护服的检疫人员登上飞机,神情紧张地对每一位机上人员检查体温,机组人员也不放过。前后折腾了近一个小时才下飞机,从北美回来的人还真是不受首都人民欢迎呢。

H1n1 defender

为了不引起恐慌,鄙人自觉在家中隔离一个星期,目前感觉很热,但不是发烧,北京已经 34℃ 了撒。

猪堡包

不知怎么提起猪流感就会想起麦当劳那个猪堡包的广告。老板已经回北京了,刚才上 MSN 碰见,告诉我那趟飞机着陆后有人上来查体温,三人被带走,所有人都留了联系方式,现已经到办公室上班了,无碍。

现在米国这里根本就没人在乎 H1N1,按说已经是世界病例第一多的地方了,至少该紧张点才对,可人家就不,平时根本不谈论这个,地铁照坐,口罩不带,社交活动一样都没少,是米国人太大条还是俺们中国人自己吓唬自己?在和菜头那里看到一个成都人被关的帖子,还真是草木皆兵啊,过两天我也该回去了,祷告中...

vpnc 笔记

vpnc 是一个开源的 VPN 客户端,可以用来连接 Cisco VPN 网关,在 VPS 上使用 vpnc 连接办公网络,可以实现在一个严格限制端口的办公网络里管理 VPS。我的 VPS 是 vpsvillage 的 32-bit Debian 系统,最近折腾了一通,笔记记录如下。

1. 首先要保证系统装有 tun 模块,不巧的是,我的 VPS 上的 kernel 模块全是 64-bit 的版本,这个应该是操作系统安装脚本的问题,联系客服后得知他们提供有 32-bit 的 kernel module 包,并且有个脚本帮助完成安装。

wget ftp://ftp.grokthis.net/pub/linux/modules/install_modules.sh
mv /lib/modules/`uname -r` /lib/modules/`uname -r`.orig
sh install_modules.sh
depmod -a
modprobe tun

2. 安装 vpnc

apt-get install vpnc

3. 导出 VPN 网关的配置文件

公司机器都是 windows 已经装有 Cisco VPN Client,通常在 C:\Program Files\公司\VPN Client\profiles 里面就能找到配置文件。vpnc 带有一个工具可以将 pcf 配置文件直接转换为 vpnc 的配置文件,工具默认安装在 /usr/share/vpnc/pcf2vpnc,是个 perl 脚本,依赖 LWP::Simple 模块,我的 VPS 上没有这个,perl -MCPAN -e 'install LWP::Simple' 等了很久也没完成,放弃。其实可直接根据 pcf 文件里面的内容,参考 /etc/vpnc/example.conf 写一个配置文件,只要 ——

4. 解码配置文件中的 enc_GroupPwd

vpnc 主页提供了个工具 cisco-decode,直接到那解码即可。

5. 默认情况 vpnc 建立了 vpn 隧道之后会把默认网关和 /etc/resolv.conf 修改掉,如果这时候你在外网 ssh 在鼓捣这个,那 ssh 连接就会断了并且再也连不上,要用到两个配置:Target networks 和 DNSUpdate。完整的 vpnc 配置文件示例:

IPSec gateway 12.34.56.78
IPSec ID CorpVPN
IPSec secret grouppassword
Xauth username myusername
Xauth password mypassword
Target networks 10.0.0.0/8 192.168.0.0/16
DNSUpdate no

6. vpnc 需要 root 权限,即使把它 chmod u+s 也没有用,因为它使用的一个库 libgcrypt 会在 init 的时候放弃 euid root 权限,导致不能对 tun0 设备进行 ioctl。

7. 在严格限制端口的办公网络内部,在 VPS 上放一个 cgi 程序来建立 VPN 隧道即可穿透端口限制,但是通常 web 服务都是普通用户(如 www-data, nobody)运行,要调用 vpnc,需要写个 wrapper:

/* VPNC.c */
#include <unistd.h>
#include <stdio.h>

int main(int argc, char **argv)
{
/* gcry_control from libgcrypt drops root euid privilege in vpnc.c */
setuid(0);
return execve("/usr/sbin/vpnc", argv, NULL);
}

然后

gcc -o VPNC VPNC.c
cp VPNC /usr/sbin/
chown root:www-data /usr/sbin/VPNC
chmod 4710 /usr/sbin/VPNC

在 cgi 程序中调用 VPNC 才能拥有 root 权限。vpnc-disconnect 也是一样。

8. cgi 程序的写法就各显神通了,我的 cgi 程序是 bash 脚本,可以 URL/vpnc/q 查询 IP,URL/vpnc/<key> 建立连接,URL/vpnc/d 断开连接,相关的 lighttpd 配置(适应任何脚本):

$HTTP["url"] =~ "^/cgi-bin/.*" {
cgi.assign = ( "" => "" )
}

参考资料:http://www.gentoo.org/doc/en/vpnc-howto.xml

vpn tunnel

这是一个突破公司端口封锁的完美解决方案,比 webtunnel 要好得多。

背景是:公司网络只允许 http 和 https 外出访问,以及 msn 端口(1863)到指定的几个服务器,我在外网有一个具有独立域名和 IP 的 服务器(就是这个 VPS),我有该服务器的 root 权限,从外网我可以用公司安装的 Cisco VPN Client 连接到公司网络。这种情况下,我想当自己在公司内网时能无限制的访问外网的任何资源,比如登陆管理自己的 VPS 或者 Home Server。

思路如下:

  1. 在 VPS 上 Web 服务器内起个 CGI 程序,在公司内部访问这个 CGI,将 VPN token 密码传入
  2. CGI 程序拿到 token,启动 vpnc 开启一个 VPN 隧道从外网接入公司内网,并且传回自己获取的内网地址
  3. 从公司内网 ssh 用 -D 选项登陆 VPS 建立 SSH 隧道用做 socks 代理
  4. 公司内网客户机程序使用该 socks 代理外网资源

这是这趟出差跟美国这边同事聊起来才有的点子,超简单是不是,但是个中曲折,真是一言难尽。今天只说下思路,细节后表,太晚了该洗洗睡了...

webtunnel

公司的防火墙升级,原先开放的端口(漏网之鱼)cvspserver 现在被关,只留了个 msn 端口、www 和 htttps,msn 端口只针对 msn 服务器,其他的就更没指望了(没错,我就是敢在公司内部用 nmap 慢速扫描),为了能在公司的网络登录我的 VPS,把 ssh 端口改成 443 也没有用,哇塞,超级厉害的防火墙!居然是基于协议的,难怪我们上网这么慢呐。

于是,webtunnel 成为(似乎?)唯一的穿墙法门。真是天外有天啊。此物只需要放在 web server 上作为 cgi 程序即可提供穿墙隧道,用来登录 ssh 全无问题,甚至可以 ssh -D 进而作为 socks 代理,遗憾就是响应速度不够理想。不过人家才是 0.0.5,走着瞧吧。

用法看它的 README,或者先看这里

← Previous  1 2 3 4 … 26 Next →