2010年10月30日星期六

Let's SSH

28号的时候SSHChina又断了整整一天,无法,只好在网上找个临时的。翻了一下,发现Paying.org.ru还不错,只是会半个小时就修改密码并且断线一次。Bitvise Tunnelier蛮好用,但是每半个小时就打开浏览器再复制粘贴,也太折磨人了。

网上现成的脚本大多不是Windows里可以用的,而且也处理不了密码会变的问题,所以就自己写了个。这个脚本比较适用于频繁修改密码的SSH帐户,登陆信息固定那种还是用Bitvise Tunnelier吧。

话说,每次为了方便给别人用而逼不得已写VBScript或者JavaScript的时候我都在想,Windows要是内置一套Ruby该多好……

将以下内容保存为letsSSH.js,再去下一个Plink放到同一个目录,双击letsSSH.js即可。

function lets_ssh(ask_for_account) {
    var fso = new ActiveXObject('Scripting.FileSystemObject');
    var plink = fso.GetParentFolderName(WScript.ScriptFullName) + '\\plink.exe';

    var sh = new ActiveXObject('WScript.Shell');
    var ios;
    var s, cmd, buf;
    while (true) {
        s = ask_for_account();
        cmd = plink + ' -N -D 127.0.0.1:7070 -l ' + s[2] + ' -pw ' + s[3] + ' -P ' + s[1] + ' ' + s[0];
        if (_debug) WScript.Echo(cmd);

        ios = sh.exec(cmd);
        buf = '';
        while (true) {
            try {
                buf += ios.StdErr.read(1); // 写大了不成,会等读满N个字符才返回
                if (/Store key in cache\? \(y\/n\)/.test(buf)) {
                    ios.StdIn.write("n\n");
                }
            } catch(e) {
                break;
            }
        }
    }
}

function bytes_to_str(data, charset) {
    var stm = new ActiveXObject('ADODB.Stream');
    stm.Type = 1;
    stm.Open();
    stm.Write(data);
    
    stm.Position = 0;
    stm.Type = 2;
    stm.Charset = charset;
    var s = stm.ReadText();
    stm.close();
    return s;
}

function get_account(url, args) {
    var xhr = new ActiveXObject('Msxml2.XMLHTTP');
    var s, html, r, re = / charset=([^"']+)[^"']?/i;
    var n = 0;
    while (n < 3) {
        try {
            xhr.open('GET', url, false);
            xhr.send();
            if (xhr.getResponseHeader('Content-Type').match(re)) {
                html = xhr.responseText;
            } else {
                r = xhr.responseText.match(re);
                if (r) {
                    html = bytes_to_str(xhr.responseBody, r[1]);
                } else {
                    throw 'Unknow Content Charset!!';
                }
            }
            
            s = [];
            for (var i=0;i<args.length;i++) {
                if (typeof(args[i]) == 'string') {
                    s.push(args[i]);
                } else {
                    r = html.match(args[i]);
                    s.push(r[1])
                }
            }
            
            break;
        } catch(e) {
            WScript.Echo(e.description);
        }

        n++;
    }

    if (s.length != 4) {
        WScript.Echo("Cannot Get SSH Account Info!\n" + url);
        WScript.Quit(-1);
    }
    return s;
}

function paying_org_ru() {
    return get_account(
        'http://blog.paying.org.ru',
        [
            /服务器地址:.*?value="(\d+\.\d+\.\d+\.\d+)"/,
            '22',
            /服务器用户:.*?value="([^"]+)"/,
            /服务器密码:.*?value="([^"]+)"/
        ]
    );
}

function sshdlw_com() {
    return get_account(
        'http://www.sshdlw.com/ssh/gd/46.html',
        [
            /ssh服务器 :<font color="#000000">([^<]+)<\/font>/,
            /ssh端口:<\/strong><\/span>(\d+)/,
            /帐号:<\/strong><a href="[^"]+"><strong>([^<]+)<\/strong><\/a>/,
            /<strong>密码:([^<]+)<\/strong>/
        ]
    );
}

var _debug = false;
if (/cscript.exe$/i.test(WScript.FullName)) {
    _debug = true;
    lets_ssh(paying_org_ru);
} else {
    // Shell.Exec无法隐藏plink窗口,所以只能这么干
    var sh = new ActiveXObject('WScript.Shell');
    var r = sh.Run('cscript.exe "' + WScript.ScriptFullName + '"', 0, true);
    if (r != 0) {
        WScript.Echo('Something Wrong...');
    }
}


2010年10月18日星期一

SSL证书制作

证书签名方案

使用OpenSSL制作证书其实还蛮简单的,只是证书签名的部分有一点复杂,方法有三:

  1. 交由受浏览器信任的第三方证书颁发机构签名;
  2. 自签名;
  3. 自制CA证书并用其签名。

对于上线运营的网站来说,第一个方案是首选,因为只有这样浏览器才不会报警。过去买证书很贵,现在倒是有免费的了,比如IE和Firefox都内置的StartSSL

不同的证书颁发机构对于证书生成多少都会有自己的要求,所以本文主要讨论后两种方案。

自签名证书

注:下面提到的很多命令都需要一个openssl配置文件,该文件一般名为openssl.cnf。Linux里一般不用管,Windows可使用参数config指定路径,使用环境变量OPENSSL_CONF也可以。

使用如下命令即可生成自签名证书:

openssl req -x509 -newkey rsa:1024 -nodes -days 365 -out self.pem -keyout self.key

req命令表示创建证书,newkey参数表示创建私钥而不是从已存在的文件中读取,nodes参数表示不加密私钥。如果不添加nodes参数,以后每次使用私钥时都必须输入密码(如Apache每次重启)。

输入证书信息时,Common Name需要写域名,支持通配符,如*.domain.tld。

程序运行完成后,self.pem即为完成签名的证书,self.key则为私钥。

使用上述命令创建的证书只能写一个域名匹配字符串,如写了*.domain.tld之后,访问https://domain.tld仍然会报错。如果想在一个证书中指定多个域名匹配字符串,则需要打开openssl.cnf文件,在末尾处添加如下内容:

[ ca_x509v3_more_cn_ext ]
nsComment="OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints=CA:true
subjectAltName = DNS:domain.tld,DNS:*.domain.tld

将subjectAltName行修改为需要的内容后保存退出,使用如下命令重新生成自签名证书:

openssl req -x509 -newkey rsa:1024 -nodes -days 365 -out self.pem -keyout self.key -extensions ca_x509v3_more_cn_ext

自制CA证书并用其签名

如需要使用多个证书,每一个都自签名则意味着每一个都需要导入浏览器,这样就很麻烦。自制CA证书并用其签名后,无论制作了多少个证书,都只需要将自制的CA证书导入浏览器即可,相对来说方便些。

上例中用一条命令直接生成了私钥和证书,这次换个方法,分解为两步。

首先,生成自己的个人私钥:

openssl genrsa -des3 -out my.key 2048

des3参数表示使用该算法加密生成的私钥,以后每次使用私钥时都必须输入密码,去掉这个参数则不进行加密。

根据个人私钥生成自签名CA证书:

openssl req -x509 -key my.key -days 911 -new -out my.pem

输入证书信息时,Common Name可以写自己的名字。将该CA证书导入浏览器后,该名字会显示在证书管理器中。

接下来生成服务器的私钥和证书:

openssl req -newkey rsa:1024 -nodes -days 365 -out server_unsigned.pem -keyout server.key

再之后,就可以用个人证书签名服务器证书了:

openssl ca -days 365 -md sha1 -in server_unsigned.pem -out server.pem -cert my.pem -keyfile my.key

如该命令报错找不到index.txt之类的,视openssl.cnf中的配置,则需要做点准备工作:

mkdir demoCA
mkdir demoCA\newcerts
touch demoCA\index.txt
echo 11 > demoCA\serial

index.txt为空,serial随便写一个两位的数字进去。

多个域名的支持问题,跟上面说的一样,添加extensions参数:

openssl ca -days 365 -md sha1 -in server_unsigned.pem -out server.pem -cert my.pem -keyfile my.key -extensions ca_x509v3_more_cn_ext

完成后,server.key和server.pem即为已签名的证书及私钥。如果用在Lighttpd中,将两个文件合并即可。

最后,将my.pem导入至浏览器中“受信任的根证书颁发机构”即可。

其他

如果要去掉私钥的密码保护,可以这样做:

openssl rsa -in my.key -out my_plain.key

如果需要根据私钥生成公钥,可以这样做:

openssl rsa -in my.key -pubout -out my_public.key

证书生成后,可以使用如下命令查看详细信息:

openssl x509 -fingerprint -text -in my.pem

使用证书加密信息:

openssl smime -encrypt -in ptest.txt -out etest.txt my.pem

使用私钥解密:

openssl smime -decrypt -in etest.txt -out dtest.txt -inkey my.key

若需要DER格式的证书,可使用如下命令进行转换:

openssl x509 -in my.pem -outform DER -out my.der

2010年10月16日星期六

《植物大战僵尸》之我圆满了…

首先是有钱就能办到的,两个方向各11种颜色的金盏花。

若说是彩虹金字塔吧,其实也挺像张开双臂躺下的人……

水生植物就3种。呃,十字固定?

夜生植物8种。

队形怎么排纠结了一下,最后就这个了。

朵朵红花向太阳……

最后,也是最花时间的,日常植物27种。

向左看齐向右看齐的貌似都有人收集过,我就弄了一个向左看向右看……