概述
假设要以用户 rainux 的身份登录运行 OpenSSH Server 的远程主机 www.rainux.org(现在几乎所有的 Linux 服务器都使用 OpenSSH Server 作为 SSH Server),那么需要做的操作如下:
生成用于 SSH 身份认证的密钥。密钥由公钥和私钥组成,一个公钥只对应一个私钥,一个私钥也只对应一个公钥。
将 OpenSSH 格式的公钥文本追加到远程主机上的
~rainux/.ssh/authorized_keys文件里(~rainux意为用户 rainux 的 HOME 目录)。注意公钥文本中应该没有换行符,一行就是一个公钥。确保
~rainux/.ssh/authorized_keys权限为 600,~/rainux/.ssh目录权限为 700,并且它们的所有者都是 rainux。指定 SSH 客户端使用对应的私钥并以用户 rainux 的身份登录 www.rainux.org,此时无需输入 rainux 在 www.rainux.org 上的密码。
注意,如果私钥是以加密形式存储的(强烈建议使用一个强壮的密码加密私钥,这样即使私钥文件被窃取,也无法被直接使用),第四步仍然需要输入加密私钥所用的密码。但是 PuTTY 和 OpenSSH 都有提供一个代理程序用于避免多次重复输入密码。运行代理程序后将私钥添加到其中,并且输入一次加密私钥所用的密码,然后保持代理程序的运行,以后 SSH 客户端即可在需要使用私钥进行身份认证的场合请求代理程序去完成身份认证(这是为了确保私钥不会被泄漏到任何使用代理程序的客户端上),无须再次输入任何密码。
Linux / Cygwin / MSYS 上使用 OpenSSH Client
生成密钥
执行 ssh-keygen 接受默认文件名,并且输入加密私钥用的密码(passphrase)即可生成私钥 ~/.ssh/id_rsa 和对应的公钥 ~/.ssh/id_rsa.pub。其中 id_rsa.pub 的内容可以直接追加到远程主机的 authorized_keys 文件里。
使用私钥
把公钥部署到远程主机上后,即可直接执行 ssh rainux@www.rainux.org 来登录远程主机。但如果私钥是加密形式保存,如上所述应该使用代理程序 ssh-agent 来避免每次输入密码。
直接执行 ssh-add 命令可以添加刚才生成的私钥到 ssh-agent 里,也可以用 ssh-add -l 查看已经添加的私钥。如果执行 ssh-add 时提示无法连接身份认证代理,则需要使用以下命令来启动 ssh-agent。
eval `ssh-agent`
使用 eval 是为了执行 ssh-agent 输出的设置环境变量的 bash 命令,以确保 ssh-add 可以通过 SSH_AUTH_SOCK 环境变量找到 ssh-agent。
GNOME 的桌面系统如果有安装 gnome-keyring,它会自动管理 ssh-agent,通常甚至无须手工添加私钥到 ssh-agent 里,第一次使用公钥时 gnome-keyring 就会提示输入一次密码,以后则不再需要。
Windows 上使用 PuTTY
生成密钥
到 PuTTY 的下载页面下载 putty-0.60-installer.exe 或者 putty.zip,两者都包含 PuTTY 所有的组件。
安装好 PuTTY 之后(对于 zip 版本来说,解压到任意目录即可)运行 PuTTYGen 生成自己的密钥。选择密钥类型为 SSH-2 RSA,点击 Generate,按照提示在 PuTTYGen 窗口内随机移动鼠标直到进度条达到 100%,然后 PuTYYGen 会生成密钥并且显示其公钥部分信息。这里可以填写一个有意义的注释,然后输入一个用来加密私钥的强壮的密码(Key passphrase)。最后点击 Save private key 将私钥保存为一个 .ppk 文件。不需要单独 Save public key,因为 .ppk 文件里已经包含了公钥。并且通过 Save public key 保存出来的公钥文件格式与 OpenSSH 的格式并不相同,若要将公钥部署到使用 OpenSSH Server 的服务器上,只能使用 PuTTYGen 窗口上显示的那一段 Public key for pasting into OpenSSH authorized_keys file。
使用私钥
将公钥部署到远程主机上之后,使用 PuTTY 登录该远程主机时可以在 Connection > SSH > Auth 里选择用于身份认证的私钥文件。同样,如果私钥是加密形式保存,应该使用代理程序 Pageant 以避免每次输入密码。
最简单的办法是创建一个 Pageant 的快捷方式,并且将 .ppk 私钥文件作为参数加到快捷方式的“目标”栏里,添加之后看上去应该像这样:
C:\PuTTY\pageant.exe D:\main.ppk "D:\My Secrets\secondary.ppk"
就像上面的例子一样,如果私钥文件路径中带有空格,应该使用引号将其括起来。通过这个快捷方式启动 Pageant 则会自动装载指定的私钥文件,并且立即询问用于加密私钥的密码。以后只要保持 Pageant 的运行,并且在 PuTTY 的某个 Saved session 里设置 Connnection > Data 里设置 Auto-login username,即可实现双击该 session 则完全自动登录。
Tags: GNU/Linux, Software 软件, Windows解决 ssh 创建连接极慢的问题
六月 18th, 2008
做 Web 开发的工作经常需要 ssh 或者 scp 连接一堆远程主机,同样是 Linux 主机,其中一些创建 ssh 连接速度特别慢,连接建立之后执行操作速度却很正常,看来应该不是网络原因。
Google 了一下,这位老兄也遇到类似的问题,看完他描述的问题才知道可以用 ssh -v 来查看详细的连接建立过程,马上用一台建立连接很慢的主机试了一下,在一大堆输出信息中发现在这里停留最久:
debug1: Authentications that can continue: publickey,gssapi-with-mic,password
debug1: Next authentication method: gssapi-with-mic
debug1: Unspecified GSS failure. Minor code may provide more information
No credentials cache found
debug1: Unspecified GSS failure. Minor code may provide more information
No credentials cache found
debug1: Unspecified GSS failure. Minor code may provide more information
debug1: Next authentication method: publickey
原来是因为尝试了个没有意义而且会失败的 gssapi-with-mic 认证方式浪费了时间,打开 /etc/ssh/ssh_config 把里面的 GSSAPIAuthentication yes 改成 no 关掉它,即可让 ssh 直接尝试美妙的 publickey 认证方式。
禁用 GSSAPIAuthentication 前后建立 ssh 连接时间的对比:
rainux@mutalisk:~$ time ssh root@i-will-not-tell-you.com exit
real 0m18.488s
user 0m0.004s
sys 0m0.008s
rainux@mutalisk:~$ time ssh root@i-will-not-tell-you.com exit
real 0m3.531s
user 0m0.016s
sys 0m0.000s
Tags: GNU/Linux, Software 软件, ssh最近需要测试 Flash 内容,搜到了这个很简单的办法,原文是针对 etch 的,对于 lenny 来说更简单,官方仓库里已经有 nspluginwrapper 了,直接 apt 安装即可。
aptitude install nspluginwrapper
然后在自己的账户(非 root 账户)里下载 Adobe 的 flash player 并使用 nspluginwrapper 安装为 Iceweasel/Firefox 的插件即可。
wget http://fpdownload.macromedia.com/get/flashplayer/current/install_flash_player_9_linux.tar.gz
tar -zxf install_flash_player_9_linux.tar.gz
mkdir ~/.mozilla/plugins/
mv install_flash_player_9_linux/libflashplayer.so ~/.mozilla/plugins/
nspluginwrapper -i ~/.mozilla/plugins/libflashplayer.so
# Start/restart iceweasel/firefox/whatever
Tags: GNU/Linux, Software 软件使用 SVN 来管理 Vim 配置文件 .vimrc 及插件集
十一月 5th, 2007
注: 本文第一次写作时没有进行全面的测试,由于 svn update 操作更新文件时会破坏 NTFS 上的硬链接而导致第一次的方法无法正常使用。现在你看到的已经是新的方法。在此为我的疏忽向大家道歉。
现在我的生活早已离不开 Vim 了,无论是在公司还是在家里,无论是在本地计算机还是远程服务器上,Vim 必定是我使用得最多的程序之一。当然了,Vim 虽好,也一定要有符合自己习惯的 .vimrc 和插件集才能发挥出更大的潜能,让我们用得更爽。也就是说,.vimrc 肯定是会被经常修改的,插件集也应该会时常添加新成员或进行版本更新。显然,要在家里和公司以及一些远程服务器之间频繁地同步这些修改是件很烦人的事。幸好,我们有 Subversion 可以让这一切变得简单。
让我们从公司的 Linux 桌面机上开始。
# 将 $HOME 里的 .vimrc 和 .vim 目录放到 vimfiles 目录里以便进行 SVN 导入操作 cd ~ mkdir vimfiles mv .vimrc vimfiles mv .vim vimfiles svn import vimfiles http://svn.rainux.org/vimfiles/trunk # 从 SVN 里 checkout 出一份 working copy 到 $HOME 里, # 并且设置忽略掉 $HOME 里其他所有文件 svn co http://svn.rainux.org/vimfiles/trunk . svn ps svn:ignore '*' . svn ci -m "Let's ignore all files those not managed by Subversion in $HOME." # 用来进行导入操作的 vimfiles 目录已经不再有任何存在的意义了 rm -rf vimfiles
好了,我们的 .vimrc 和插件集已经版本化了,下班回家。
# 先备份一下家里 Windows 上的文件,这假设我们没有使用 Cygwin CD %HOME% MOVE .vimrc .vimrc.backup MOVE vimfiles vimfiles.backup svn co http://svn.rainux.org/vimfiles/trunk .
现在我们遇到问题了,Vim 在 Windows 上会尝试从 %HOME%\vimfiles 目录加载用户脚本,而不会理会 %HOME%\.vim 目录。我的解决办法是为 .vim 目录建立符号链接 vimfiles,这需要 %HOME% 所在分区必须是 NTFS 文件系统。新的问题是 Windows 本身并没有附带创建符号链接的工具,需要用 Sysinternals 提供的命令行工具 junction.exe 或者 Windows 2000 Resource Kit 里的 linkd.exe 来创建。
CD %HOME% junction vimfiles .vim
OK,开始享受 Subversion 为我们带来的便利吧!不仅仅可以方便的同步在公司和在家里对 .vimrc 及插件集的修改,在远程服务器上要取得这些最新的修改也变得非常容易。什么,某个服务器上还在使用古老的 Vim 6.3 ?没有关系,为 http://svn.rainux.org/vimfiles 创建一个名为 6.x 的 branch,删掉无法用于 6.x 的插件即可。
最后,如果你对我的 Vim 配置感兴趣,可以从上面提到的 URL 里 checkout 一份出来看看,是的,它是真实的 URL。:)
Tags: GNU/Linux, Software 软件, Subversion, Vim, Windows修改已处于 SVN 版本控制下的项目的版本库布局
十一月 1st, 2007
按照《使用 Subversion 进行版本控制》 书中的建议,项目在被 import 到版本库前,最好能在项目根目录下建立 trunk、branches、tags 等目录,并将项目源代码存放在 trunk 子目录下,这将有利于工作中对相对稳定的项目做较大修改时创建分支。
但是一些历史项目,或者我们自己在对 Subversion 不够熟悉的情况下创建的项目,可能是直接把项目源代码存放在项目根目录里的,这种情况下要修改版本库布局,将所有文件移动到 trunk 子目录下就比较麻烦了。设想过使用 svn mv 命令应该可以做到,但是它会产生一个整个项目所有文件被移动的 revision,不但很不优雅,也不便于以后查看历史记录以及回溯到旧版本。
这种情况下我们可以这样做:
- 将整个项目的版本库导出为一个 dump 文件(它是一个可编辑的文本/二进制混合文件,其中包含了所有的 revision 记录)。
- 在 dump 文件中所有的路径前加上 trunk/ 前缀,使它们处于 trunk 子目录下。
- 在 dump 文件中 revision 1 里直接加入 trunk 等目录的创建。
- 删掉项目的版本库并重建新版本库,然后导入我们修改后的 dump 文件。
进行这样的操作后,项目的版本库状态就是从 revision 1 开始所有的文件就存在于 trunk 目录下了。
具体操作步骤,以在 Linux 命令行下为例:
svnadmin dump /path_to_svn_repos/your_project > your_project.svn_dump vim -b your_project.svn_dump # 以下为 Vim 命令 :%s/^Node-path:\s\+/\0trunk\//ge :%s/^Node-copyfrom-path:\s\+/\0trunk\//ge # Vim 命令结束 # 添加 trunk 等目录的创建,见后文详述 rm -rf /path_to_svn_repos/your_project svnadmin create /path_to_svn_repos/your_project svnadmin load /path_to_svn_repos/your_project < your_project.svn_dump
注意一定要用 -b 参数启动 Vim,这样可以避免 Vim 在没有配置好多字节文件支持的选项时对 dump 文件可能的破坏。添加 trunk 等目录的方法是在 Revsion-number: 1 那一行后的第一个 PROPS-END 行后插入以下蓝色的代码。注意那些空行,有些是空一行有些是空两行,我是严格按照已有的目录的格式来写的,在没有看到这个 dump 文件的规格文档前最好连空行也照原样复制。
... Revision-number: 0 Prop-content-length: 56 Content-length: 56 K 8 svn:date V 27 2007-10-11T14:15:09.781135Z PROPS-END Revision-number: 1 Prop-content-length: 100 Content-length: 100 K 7 svn:log V 0 K 10 svn:author V 6 rainux K 8 svn:date V 27 2007-10-11T14:15:48.344335Z PROPS-END
Node-path: trunk Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: branches Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: tags Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END
Tags: GNU/Linux, Software 软件, SubversionNode-path: trunk/README Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 8001 Text-content-md5: 2ffe7715fd6ba5509508a29022c22a17 Content-length: 8011 PROPS-END == Welcome to Rails ...
见到 Debian GNU/Linux 创始人 Ian Murdock 了
十月 22nd, 2007
四个小时前,在上海紫金山大酒店四楼的会场见到了自由软件社区的大哥级人物 Ian Murdock。一身白色 T shirt 的他看上去比活动宣传照上更年轻。
虽然了解、使用和喜爱 Debian 已经有四年了,但对于创始人 Ian Murdock 却没有太多的了解,只知道他现在为 Sun 工作,Debian 这个词源自他当时的女友(现在的妻子)Debra 和他自己名字的组合。很浪漫的命名方式,如果有机会,我也希望能做这样的事。 :) 看到活动的介绍后,才知道 Ian 还是 Linux Foundation 的 CTO,Linux Standard Base 的 Chief。
今天活动的主要内容是 Ian 的个人演讲和跟现场的 Linux 用户交流。给我的印象是 Ian 比较健谈,对大家提出的大多数问题都聊了很多。可惜,可惜,最大的遗憾是,他说的话有 95% 我都没听懂……-_-b 平时自诩流畅阅读英文技术文档的我,听力实在是太差了。(以后一定要经常对照字幕看原版电影来练习听力!)
晚上九点左右,活动结束后,Ian 还坐在舞台的一角为大家签名,跟大家合影。我也有幸跟他合影了一张(感谢好友 AKAI 帮助拍摄!),本来想说 "I've loved and enjoyed Debian for several years and will continue, many thanks to your hard work!",不过没好意思说出口。-_-b
这次活动到会的粗略估计大概有四五百人,应该是超出了报名人数不少,以致于主办方准备的简单晚餐在还有很多人排队时就已经被“洗劫一空”了。
PS: 发现到会的 Geek 中 MM 还挺多的。

使用 Linux shell I/O 重定向简化小程序的日志记录
三月 12th, 2007
一些自动执行特定任务的小脚本程序,如果希望能使程序的 stdout/stderr 输出到屏幕的同时也把他们记录到一个日志文件,可以使用 tee 命令结合 shell I/O 重定向来轻松完成:
./a_tiny_script 2>&1 | tee the_log_contain_both_stdout_and_stderr.log
这个命令的精华在于 2>&1,意为让 stderr 使用 stdout 的文件描述符,效果也就是将 stdout 和 stderr 内容合并,并且输出到 stdout 被定向的位置。在这里也就是管道中的 tee 命令的 stdin 上,然后 tee 将得到的输入同时显示在屏幕上和记录到日志文件里。爽吧?
以前为了在 PHP 脚本里实现这样的功能竟然使用了 ob 系列函数 + 自定义的 output callback 函数,并且这样也只能做到同时显示和记录 stdout,真是晕到死。
Tags: bash, GNU/Linux, PHP, Programming 编程正确设置 Vim 的字符编码选项 (gVim/Vim on Win32 中文环境)
十月 20th, 2005
和所有的流行文本编辑器一样,Vim 可以很好的编辑各种字符编码的文件,这当然包括 UCS-2、UTF-8 等流行的 Unicode 编码方式。然而不幸的是,和很多来自 Linux 世界的软件一样,这需要你自己动手设置。
Vim 有四个跟字符编码方式有关的选项,encoding、fileencoding、fileencodings、termencoding (这些选项可能的取值请参考 Vim 在线帮助 :help encoding-names),它们的意义如下: Read the rest of this entry »
Tags: GNU/Linux, Software 软件, Vim, Windows回到 Vim,回到 GNU/Linux
三月 9th, 2005
还记得几年前初次接触 GNU/Linux 时,听说 GNU/Linux 下最常用的文本编辑器叫做 vi。在 DOS/Windows 下已经生活了一两年的我,自然知道文本编辑器的重要性。于是尝试输入 vi 启动这个被众多 GNU/Linux 用户“吹捧”的著名文本编辑器。
"Oh, shit!" 这是什么怪物?作为文本编辑器它居然就给我一个没有菜单的,只显示了一些莫名其妙的 ~ 符号和它自己名字的黑屏幕。最要命的是在我按了几个字母键之后,它居然除了让机箱里的 speaker 吱吱叫几声之外没有任何反应! Read the rest of this entry »
Tags: GNU/Linux, Software 软件