/dev/null 的另类用法

/dev/null 是个黑洞,进去的东西永远出不来,在脚本编程的时候经常会用它(空设备文件)来屏蔽标准或错误输出(stdout 或 stderr),比如 command > /dev/null 2>&1 把 command 执行的结果(标准输出和错误输出)全部重定向到 /dev/null,也就是在控制台上不回显任何输出。

今天发现我们的 Graphite 监控服务器硬盘空间不够了(因为监控日志体积日益增加),一些不必要的日志占据了不少硬盘,比如 graphite 里面的 console.log,一般来说日志配置都在相关的配置文件里,在 graphite 的配置文件里找了一圈居然没找到如何关闭 console.log 日志配置(有其他日志的配置选项,但是没有 console.log 这个日志的关闭选项),难道要写个 cron 定期清理 console.log?一个更好的办法是把 console.log 这个连接到 /dev/null(如果确定以后不需要查看 console.log 的话),这样 graphite 写到 console.log 就永远的消失了,对现在的系统和配置不会有任何影响,甚至连 graphite 服务都不用重启,下面的脆香米兄的评论是对的,graphite 正在操作 console.log,简单改变文件名称并没有更改已打开的文件句柄,所以需要重启 carbon-cache.py.

# cd /opt/graphite/storage/log/carbon-cache/carbon-cache-a/

# ls -l
total 1811016
-rw-r--r-- 1 root     root     1360161601 Aug  6 15:18 console.log

# /opt/graphite/bin/carbon-cache.py stop

# mv console.log console.log.bak
# ln -s /dev/null console.log

# /opt/graphite/bin/carbon-cache.py start

# ls -l
total 1811032
lrwxrwxrwx 1 root     root              9 Aug  6 15:18 console.log -> /dev/null
-rw-r--r-- 1 root     root     1360178736 Aug  6 15:18 console.log.bak

升级到 Mac OS X 10.8 Mountain Lion

mac os x mountain lion

苹果上周发售了新版的 Mac OS X Mountain Lion,周末升了一下级。购买和升级过程越来越容易了,上次从 Tiger 升级到 Leopard 的时候从订购安装盘到完成升级花了几天。这次升级到 Mountain Lion 要简单方便得多,登陆 Mac App Store 点击 install,输入帐号后就开始下载了,下载完后自动启动安装界面,只需要点击一次就开始升级安装,整个升级过程无需任何干预(期间两次重启也是自动的)。

晚上给另一台 Macbook Pro 升级的时候发现一个比较坑爹的地方,下午下载的 4GB 多的 Mountain Lion 安装镜像升级完后就消失了,这样不得不在另一台 Macbook Pro 上重新下载一遍(购买 Mountain Lion 一次后可以不限次下载,20美元的 Mountain Lion 授权可以用在自己的多台 Mac 上)。所以家里有多台 Mac 的话最好先下载、拷贝镜像或者做成 DVD/USB 后再升级。

完成升级后登陆最先看到的是变化是壁纸,桌面壁纸改成了更简洁的淡蓝银河,不知道是心理作用还是审美疲劳?每次升级 Mac OS X 后都觉得壁纸比前一个版本要好看。

外观方面没有大的变化,但很多细节都有改进。比如以前的滚动条很小不容易鼠标点击到,现在的滚动条会在鼠标碰到的时候自动放大,不过在 Mac 上都是用双指触摸来上下拖动页面的,滚动条其实不是那么常用,所以这个改进对用户来说不是那么重要(如果不是追求完美的话~)。拷贝和下载大文件的时候进度条出现在文件的图标(icon)上。3个指头点击触摸板就可以预览,这个挺方便。Dock, Dashboard, 桌面屏保和壁纸等等都有变化。

点击苹果主菜单的软件升级 Software update… 后自动连上 App Store,以后的 update 和 App store 紧密连在一起,而不是分开的程序了。

到处都是 Share 按钮,share 无处不在。

Notification Center 整合了所有烦人的通知消息,不用单独去查看和处理哪里来的 notification 了,生产力大大提高。

mountain lion notification

应用程序增加了 Reminder, iMessage,Reminder 对于我来说比较有用,可以当作简单的 todo list 用,之前一直在用第三方的 Wunderlist.

Safari 升级到了 6.0,改进很大,地址栏搜索历史纪录、书签等响应很快,终于有了 Chrome 里面早就有的直接在地址栏输入查询关键字的功能,而且比 Chrome 做的更好。Safari 增加了一个 Reader 按钮更加专注于阅读,还可以把未看完的文章加入 Reading list. 增加了 tab 预览,对于我这种一次开 n 个 tab 的人来说这个功能实在来得太及时了,很容易在不同 tab 里(依靠预览)切换,不用一个一个点击 tab 看内容。

mountain lion notification

Mail, QuickTime, Dictionary, Time Machine, Photo Booth 等都有升级和改进。

自带的中文输入法有一些改进,加入了手写识别,词库更大了,还加入了中文字典释义功能,有汉字不懂意思的话选中后用3个指头轻击触摸板就会出现意思,类似中文-中文字典。

字体有改进,更加精致饱满了。下面这张截图是刚从 Mountain Lion + Safari 6.0 上拔下来的,对比一下以前 Mac OS X 上的字体:Mac 和 Windows 的中文字体显示效果看看。

font on mountain lion

网上很多人讨论这次升级19.99美元值不值,这个价格比苹果应用商店上的小应用程序还便宜,一个 Things.app 要 $49.99,连一个 Todo.app 都要 $14.99,这样比较起来有 4GB 体积的 Mountain Lion 可以简直就是免费。苹果说这次有200多项改进,没有一一去核实,不过从这两天使用来看,系统和浏览器性能明显有提升,系统响应快、稳定,细节改进很多。按照 OS X Mountain Lion 10.8 License Agreement,Mountain Lion 可以授权安装在任何属于自己的 Mac 上,如果家里有多台 Mac(家人都在用 Mac 的话),20美元就更超值了~

强制删除 OpenStack Nova (Essex) 实例

上周在新版的 OpenStack (Essex) 上测了瞬间启动1000个 m1.tiny (512mb RAM) 实例的情况,主要看看 OpenStack 能否在短时间内正确处理大量创建实例请求以及各个节点、资源分配等情况。结果留下了大量状态为 ERROR 或 BUILD 的僵尸实例,这个结果和上个版本 Diablo 测试的情况差不多,没有明显改进,进一步调查发现主要原因在 RabbitMQ 服务,中途有很多连接都 timeout 了。这些僵尸实例没有运行或者创建不成功,只是在 nova 数据库里有纪录而已,直接用 nova delete 命令无法删除,那么如何强制删除呢?

# nova list
+--------------------------------------+--------+--------+-------------------+
|                  ID                  |  Name  | Status |      Networks     |
+--------------------------------------+--------+--------+-------------------+
| 6fc5696c-ed65-4e99-8fce-87dfc3cf36d9 |  c23   | BUILD  | private=10.0.0.23 |
| 98f5f421-581f-43d2-b1c7-f27cf5b61f02 |  c30   | BUILD  | private=10.0.0.30 |
| b768ebeb-4d73-4c31-8ec5-6bb2e90d4303 |  c63   | ERROR  | private=10.0.0.63 |
| b79e213b-055c-414f-a9f1-f230ed9aaae1 |  c95   | ERROR  | private=10.0.0.95 |
| efc6e9c7-4ef8-4350-9451-83bcfcafe101 |  c12   | ACTIVE | private=10.0.0.12 |
+--------------------------------------+--------+--------+-------------------+

先清理 instances 目录,看看对应的哪些 instance 是僵尸实例,有的话 rm -rf 删除即可:

# ls /var/lib/nova/instances/
_base  instance-00000023  instance-00000030

# rm -rf /var/lib/nova/instances/instance-00000023

然后清理 nova 数据库,可以登陆数据库后手动删除纪录,不过这是常见操作,最好还是保存成一个脚本方便以后使用:

# vi deletevm.sh
#!/bin/bash
mysql -uroot << EOF
use nova;
DELETE a FROM nova.security_group_instance_association 
 AS a INNER JOIN nova.instances AS b
 ON a.instance_id=b.id where b.uuid='$1';
DELETE FROM nova.instance_info_caches WHERE instance_id='$1';
DELETE FROM nova.instances WHERE uuid='$1';
EOF

# chmod +x deletevm.sh

8月15日更新,才过了不到一个月,OpenStack 又更改了数据库表结构和字段,上面的脚本改为:

#!/bin/bash
mysql -uroot << EOF
use nova;
DELETE FROM nova.security_group_instance_association where instance_uuid='$1';
DELETE FROM nova.instance_info_caches WHERE instance_uuid='$1';
DELETE FROM nova.instances WHERE uuid='$1';
EOF

运行脚本,比如删除 ID 为 6fc5696c-ed65-4e99-8fce-87dfc3cf36d9 的实例:

# ./deletevm.sh 6fc5696c-ed65-4e99-8fce-87dfc3cf36d9

# nova list
+--------------------------------------+--------+--------+-------------------+
|                  ID                  |  Name  | Status |      Networks     |
+--------------------------------------+--------+--------+-------------------+
| 98f5f421-581f-43d2-b1c7-f27cf5b61f02 |  c30   | BUILD  | private=10.0.0.30 |
| b768ebeb-4d73-4c31-8ec5-6bb2e90d4303 |  c63   | ERROR  | private=10.0.0.63 |
| b79e213b-055c-414f-a9f1-f230ed9aaae1 |  c95   | ERROR  | private=10.0.0.95 |
| efc6e9c7-4ef8-4350-9451-83bcfcafe101 |  c12   | ACTIVE | private=10.0.0.12 |
+--------------------------------------+--------+--------+-------------------+

旧版本的 OpenStack (Diablo) 可以参考:如何删除 OpenStack Nova 僵尸实例

在 Ubuntu 12.04 上配置 Radius 和 LDAP 服务

上次提到了我们实验室的 Wi-Fi 更改了认证方式,不再使用 WPA2/PSK 通用密码,而是通过 LDAP 把 Wi-Fi 上网密码和个人帐号联系起来,大家只需要用自己平时的 Unix/Linux/Mail/GroupWise 帐号就可以登陆 Wi-Fi,那么如何配置这样一个系统呢?涉及到的东西有点多,首先需要一个支持 Radius 的无线路由器,然后需要一台装有 Radius 的服务器,这台服务器还需要作为 LDAP 客户端和 LDAP 服务器连起来。

准备工作

  • Linksys WRT 54GS 无线路由器,可以替换开源固件的 hacker-friendly 路由器;
  • DD-WRT 固件,刷固件的过程可以参考:把 Linksys WRT54GL 路由器当作交换机用
  • FreeRadius 服务,安装在一台 Ubuntu 服务器上;
  • LDAP 客户端,安装在同一台 Ubuntu 服务器上;
  • LDAP 服务器,一般安装在另一台服务器上,也可以和上面的 FreeRadius/LDAP client 装在一起,LDAP 服务器的配置和安装过程超出本文范围,这里不介绍。

配置 Wi-Fi

刷固件以后按照下图配置 Linksys WRT 54GS,指定 Radius 服务器的 IP 和端口、安全模式、WPA 算法、WPA Shared Key 等,这个 WPA Shared Key 由下面的 FreeRadius 配置指定:

dd-wrt and radius

安装和配置 LDAP

这里只是安装 LDAP 客户端,不包括 LDAP 服务器的安装,所以需要事先知道 LDAP 服务器的 IP 或域名等相关信息。

$ sudo apt-get install ldap-auth-client ldap-auth-config libpam-ldap

填入 LDAP 服务器地址 host, base 等:

$ sudo vi /etc/ldap.conf
host ldap.vpsee.com
base dc=vpsee,dc=com
pam_password exop
pam_lookup_policy yes

nss_initgroups_ignoreusers Debian-exim,backup,bin,daemon,dhcp,games,gnats,irc,klog,libuuid
,list,lp,mail,man,news,ntpd,proxy,root,snmp,sshd,statd,sync,sys,syslog,uucp,www-data

确认 nsswitch.conf 先搜索本地文件,用户登陆的时候先检索本地 /etc/passwd 找不到相关用户名再检索 ldap 服务器上的用户数据库:

$ sudo vi /etc/nsswitch.conf
passwd:         files ldap
group:          files ldap
shadow:         files ldap
automount:      files

hosts:          files dns
networks:       files

protocols:      db files
services:       db files
ethers:         db files
rpc:            db files

安装和配置 FreeRadius

安装 FreeRadius:

$ sudo apt-get install freeradius freeradius-utils freeradius-ldap openssl 

编辑 clients.conf,确定哪个 IP 范围可以访问 Radius 服务,这里 secret 一行的 testing123 就是上面 DD-WRT 要用到的 WPA Shared Key:

$ sudo vi /etc/freeradius/clients.conf
...
client 192.168.2.0/24 {
        require_message_authenticator = no
        secret          = testing123
        shortname       = vpsee-network
}
...

配置 default,确定 pam 一行没有被注释掉:

$ sudo vi /etc/freeradius/sites-available/default
...
authorize {
        preprocess
        chap
        mschap
        suffix
        eap {
                ok = return
        }
        unix
        files
        expiration
        logintime
        pap
}
...
authenticate {
        Auth-Type PAP {
                pap
        }
        Auth-Type CHAP {
                chap
        }
        Auth-Type MS-CHAP {
                mschap
        }
        pam
        unix
        eap
}
...

同样的确定 inner-tunnel 配置文件里面的 pam 一行没有被注释掉:

$ sudo vi /etc/freeradius/sites-available/inner-tunnel
...
authenticate {
        Auth-Type PAP {
                pap
        }
        Auth-Type CHAP {
                chap
        }
        Auth-Type MS-CHAP {
                mschap
        }
        pam
        unix
        eap
}
...

在 users 加入下面认证类型:

$ sudo vi /etc/freeradius/users
...
DEFAULT Auth-Type = PAM
      Fall-Through = 1
...

测试

配置完毕后重启 freeradius:

$ sudo /etc/init.d/freeradius restart

如果要 debug 的话这样启动 freeradius:

$ sudo /etc/init.d/freeradius stop
$ sudo freeradius -X

先测试使用 LDAP 方式登陆系统是否正确,使用 LDAP 用户名和密码从另一台电脑 ssh 登陆到这台 Radius 服务器,如果不用本地帐号而用 LDAP 帐号顺利登陆的话就说明这台服务器已经能顺利使用 LDAP 登陆了:

$ ssh [email protected]

测试 Radius 服务是否能正确从 LDAP 那里得到验证信息,使用 ldap 用户名和密码测试 Radius 服务是否反馈正确消息 Access-Accept:

$ radtest vpsee "password" 192.168.2.65 1 testing123
Sending Access-Request of id 233 to 192.168.2.65 port 1812
	User-Name = "vpsee"
	User-Password = "password"
	NAS-IP-Address = 192.168.2.65
	NAS-Port = 1
rad_recv: Access-Accept packet from host 192.168.2.65 port 1812, id=233, length=20

另一种办法

另外有个办法是不用 pam 的方式,直接用 freeradius-ldap 模块和 LDAP 服务器连接,这种办法不适合我们实验室的应用场景,不过配置要简单一些。简单说一下就是利用 freeadius 的 ldap 模块直接连接 LDAP 服务器验证用户。先安装 freeradius-ldap 模块:

$ sudo apt-get install freeradius-ldap

然后配置 clients.conf

$ sudo vi /etc/freeradius/module/ldap
...
ldap {
        server = "ldap.vpsee.com"
        identity = "cn=admin,o=My Org,c=UA"
        password = mypass
        basedn = "o=My Org,c=UA"
        filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})"
...

然后取消下面2个文件里面关于 ldap 的相关注释:

$ sudo vi /etc/freeradius/sites-available/default
$ sudo vi /etc/freeradius/sites-available/inner-tunnel

重启 freeradius 让配置生效:

$ sudo /etc/init.d/freeradius restart

迁移 VMware ESXi 上的 Windows 虚拟机到 KVM

我们发现 VMware vShpere 私有云成本太高,比如我们实验室随便一台服务器就有 512GB 内存,按照 VMware vSphere Standard(标准版)的授权我们需要 512/32=16 个授权,每个授权1293.5美元(又涨价了),1台服务器就需要约2万美元(16个授权),这个授权只是版权价格(LICENSE PRICE),还不包括每年的 1 YEAR SUPPORT & SUBSCRIPTION(419.9美元),这是在抢钱不~,今年初我们买了3个授权来评估和测试,但是按照这个授权方案只能用在2台服务器上(1台 24GB 内存,1台 64GB 内存),VMware 的产品实在不适合我们,我们打算把 VMware ESXi 上现有的一些虚拟机迁移到 OpenNebula/KVM 上。

最先迁移的是一台 Windows Server 2008 R2 虚拟机,这台虚拟机跑在 VMware ESXi 上专门用来运行 VMware vCenter Server(vCenter Server 只能安装在64位的 Windows 系统上),有些现成迁移工具比如 virt-v2v 等,不过个人还是喜欢自己动手,那些工具有时候不太好用。下面的步骤应该对其他的 Windows 版本也有效。

首先用 vShpere Client 登陆到 VMware ESXi 5.0 上打开防火墙设置,允许 ESXi 上的 ssh server 和 ssh client 可用,否则不能 ssh 登陆到 ESXi 也不能从 ESXi 上 scp 镜像到 KVM 服务器,设置具体在 Configuration > Software > Security Profile > Firewall > Properties … > SSH Client 里:

vmware esxi 5.0 enable ssh client

然后 ssh 登陆 VMware ESXi 5.0 服务器(172.16.39.100)后,scp 所需要的镜像文件(后缀名为 .vmdk)到 KVM 服务器(172.16.39.101)上

$ ssh [email protected]
Password: 
The time and date of this login have been sent to the system logs.

VMware offers supported, powerful system administration tools.  Please
see www.vmware.com/go/sysadmintools for details.

The ESXi Shell can be disabled by an administrative user. See the
vSphere Security documentation for more information.

~ # scp /vmfs/volumes/localstore/vcenter/vcenter-flat.vmdk [email protected]:/root

把 VMware 的 vmdk 格式转化成 KVM 的格式,因为从 v0.12 开始 qemu-kvm 已经支持 VMware 的硬盘格式 v6 和 v7,所以这一步其实是可以省略的,换句话说 kvm 可以直接启动 vmdk 格式的虚拟机。

$ ssh [email protected]
# qemu-img convert vcenter-flat.vmdk vcenter.img

最后用 virsh create vcenter.xml 的时候记得 vcenter.xml 文件里面关于硬盘的部分是如下设置,还有记得打开 vnc 设置(别忘了 Windows 是图形界面的):

# vi vcenter.xml
...
 <disk type='file' device='disk'/>
      <driver name='qemu' type='raw'/>
      <source file='/root/vcenter.img'/>
      <target dev='hda' bus='ide'/>
      <address type='drive' controller='0' bus='0' unit='0'/>
    </disk>
    <controller type='ide' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
...
    <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'>
      <listen type='address' address='0.0.0.0'/>
    </graphics>
...

# virsh create vcenter.xml

Troubleshooting

如果启动 Windows 后用 vnc 客户端连接 KVM 服务器,Windows 启动过程中可能出现蓝屏 Stop 0x0000007B 错误,这是因为硬盘控制器驱动变了:

windows blue screen

解决办法是在迁移前下载 MergeIDE.zip 后解压,双击运行 MergeIDE.bat 文件,然后关闭 Windows 重新按照上面的步骤走一遍。

Mac OS X Lion 上使用 TTLS/PAP 访问 Wi-Fi

我们实验室的 Wi-Fi 更改了认证方式,不再采用简单的 WPA2/PSK (Pre-Shared Key),这种方式的弊端显而易见,所有人都知道 Wi-Fi 密码,大家容易把这个 “共用” 密码传给外人,如果是 “个人” 密码的话会好一些,所以我们打算通过 LDAP 把这个密码和个人的邮件密码连在一起,这样会有效的阻止密码扩散(不会有人轻易告诉别人自己的邮件密码),还减轻了管理员经常换密码的痛苦。除了密码管理方面的好处外,还可以通过 Radius 对用户进行统计、对通讯加密等等。我们采用了 DD-WRT + Radius + LDAP 这种方式和现有的基础设施连在一起,用户通过 Linksys WRT 54GS 无线 AP 输入自己内部的 LDAP 帐号就可以登陆 Wi-Fi,和我们其他服务一样 “一次登陆到处使用”。

Mac OS X Lion (10.7) 上默认使用的是 TTLS/MSCHAPv2 方式,如果使用 TTLS/PAP 的话就需要更改配置,问题是 Mac OS X Lion 的配置文件页面没有提供任何方式更改或新建配置来支持 PAP. 打开 Apple > System Preferences … > Network > Wi-Fi > Advanced … > 802.1X 后会发现是空的列表,没有新建按钮也没有导人,怎么增加一个 Profile 呢?我记得 Mac OS X Snow Leopard (10.6) 是有个新建按钮的,不知道为啥 Apple 把这个按钮去掉了,官方给的解释是通常这个 .mobileconfig 配置文件都是由网络管理员提供的,用户拿到这个文件双击就可以完成配置,不需要自己动手配置。

解决这个问题有两个办法:第一个是下载一个别人配置好的.mobileconfig 文件,其实就是一个 xml,然后调整一下后双击使用;第二个是下载 iPhone Configuration Utility 工具自己创建一个 .mobileconfig 文件。办法一可以直接到这里下载 .mobileconfig 后修改,这里不详细介绍了。这里采用办法二:

1、下载和安装 iPhone Configuration Utility 3.5 for Mac OS X 工具
2、打开 Applications > Utilities > iPhone Configuration Utility.app 选择左边列表的 Configurations Profiles;
3、按照下图在 General 页面填写信息;

ttls/pap on mac os x

4、按照下图在 Wi-Fi 页面填写必要的信息,比如 SSID 等,注意选择 WPA/WPA2 Enterprise, TTLS 和 PAP;

ttls/pap on mac os x

5、点击菜单的 Export 配置到某个文件,然后双击这个后缀名为 .mobileconfig 的文件就会自动导入到上面的 802.1X 页面,会提示输入 Radius 服务器的登陆信息等;
6、最后切换无线网络测试一下。

OneStack:Ubuntu 12.04 上一键自动部署 OpenStack

前几天 OneStack 项目 的作者 Kayven 在 vpsee.com 上留言谈到了 OneStack,一个国人的 OpenStack 一键安装工具,在 vpsee 的忽悠下 Kayven 终于同意写一篇 OneStack 的介绍性文章,如果大家对手动安装配置 OpenStack 有恐惧的话可以试试这个 OneStack 一键安装工具,类似的项目还有 DevStack.

大家如有问题欢迎参与讨论或联系原作者 Kayven ([email protected]). 以下内容来自 Kayven:

在发表了 OneStack: Ubuntu 12.04 (“Precise”) 一键安装部署云计算平台 OpenStack Essex 这篇文章、公布了 OneStack 这个项目后,受到一些人的关注和邀请,诚惶诚恐,非常感谢大家的支持,下面将对这个项目进行更详细的介绍。

OneStack 的引入

为什么需要 OpenStack?作为众多云计算项目的一个,OpenStack 很火。

一是因为 OpenStack自身的优势、Apache2.0 授权的开源性以及兼容性、灵活性和可扩展性等优点;
二是众多企业和组织的参与开发,尤其是世界领军企业的加入,推动了 OpenStack 的高速成长。

为什么需要 OneStack?类似项目有 DevStack,但是使用 DevStack 有如下问题:

部署过错的可定制性和灵活性不是太好,自己只能选择安装哪些服务,如果中间遇到问题或者自己想调整就比较麻烦;
使用 screen 管理运行 OpenStack,重启服务器需要用 screen 进入,很多人以为有些服务会停止或者希望不使用 screen,于是自己 kill 服务并自己手动开启,容易出各种问题(OpenStack 由很多独立组件和服务组成,注意不要遗漏);
没有提供重启、重置、清空数据库等有用功能,还稍显复杂;
而且,使用 DevStack 后还是不清楚整个部署过程是怎样的,自己不能安装官方安装文档来实验和尝试;
由于组件独立分散,安装过程过于繁琐,可以抽象成通用的项目供大家方便使用;
官方提供了一个比较完善的入门文档,但是,按照这几十页的步骤下来需要做很多无用功,容易漏错而引起很多莫名和头疼的问题;
本项目希望不只是提供实验环境,更可以实际部署使用,可以自己修改配置,按需增加组件和功能,实现一键部署,可扩展、可添加任意计算节点。

为什么需要一键自动部署工具?

很多人首先希望尝试一下 OpenStack,做做实验,弄清楚具体怎么实践。官方文档的一大堆步骤会让人忘而生畏;同时又不想部署好后都不知道到底怎么做的,像 DevStack 这样封装比较难看懂,也就难自己修改。OneStack 能够很好的自动部署,同时又能灵活的实验,对于大部分尝试者是个很好的途径。

为什么使用 Ubuntu 12.04?

OpenStack 官方指定的操作系统是 Ubuntu,当然也可以使用其他的,比如 CentOS,不过安装过程有可能会不同。OpenStack 目前主要是以 Ubuntu 版本 Linux 系统为基础写成的,而且很多测试和文档都是在 Ubuntu 下完成的,所以在 Ubuntu 下部署将会有很多便利。另外,Ubuntu 12.04不仅是LTS(长期支持版本),还可以得到五年的支持,对于开发者是个不错的平台。

OneStack 的项目结构

  • oneStack.sh(一键部署 all-in-one 的 OneStack,最主要文件);
  • addComputeNode.sh(增加计算节点);
  • delStack.sh(只卸载nova、glance、keystone等);
  • delAll.sh(卸载所有安装的组件和工具);
  • resetStack.sh(清空数据库,镜像、网络和实例等);
  • addClient.sh(添加客户端,nova管理等);
  • setup_base.sh(安装基本系统);
  • setup_test.sh(添加镜像和实例);
  • HAStack 目录(OneStack 的高可用性,希望更多人可以提出自己的解决方案)。

OneStack 的安装部署

可以一键自动部署 all-in-one 的 OneStack 实验环境,也可以分步骤部署(下次再讨论分步骤部署)。
一键自动部署最简单,只需要文件 oneStack.sh 把所有服务安装到一个机器。

# wget http://onestack.googlecode.com/files/oneStack.sh && \
chmod +x oneStack.sh && ./oneStack.sh

如果需要更多功能,需要 chechout 整个 svn;当然,安装同样只需要 oneStack.sh
1、安装 Ubuntu Precise (12.04);
2、下载 OneStack 脚本:

# svn checkout http://onestack.googlecode.com/svn/trunk/ onestack-read-only

3、运行 OneStack:

# cd onestack-read-only/ && ./oneStack.sh

注意:其实上面的安装还是需要更改网络配置的(其余可以不改,这个是需要改成你自己的)因为,为了简单,在上面的工具里,所有前期工作都加到了文件 oneStack.sh,比如:

  • root 用户密码设置(刚安装的 Ubuntu 默认不启用这个 root 用户);
  • apt 源的配置,可以设置为国内的 163、ustc 的源等;
  • 网络配置,控制节点是需要外网 ip 的,你需要更改oneStack.sh里面的一些配置:/etc/network/interfaces 里面双网卡的 ip、网关等,在脚本靠前的位置,请查找 interfaces. 参数设置:外网 ip 地址等,这些也都在脚本开头一个块里面。自行检查下面 network/interfaces 的两个网卡设置:
    ## 2、自行检查下面 network/interfaces的两个网卡设置
    + OUT_IP=192.168.139.50 
    + OUT_IP_PRE=192.168.139
    ...
    
  • 选择虚拟机技术,裸机使用 kvm,虚拟机使用 qemu 即可
    ## 选择虚拟技术,裸机使用 kvm,虚拟机里面使用 qemu
    VIRT_TYPE=”qemu”
  • 数据库的安装和配置,为了自动化部署,参数设置里面设置好帐号和密码,后面就不需要交互;## 配置 /etc/nova/nova.conf,这里与控制节点的配置相同!比如ip是控制节点的ip
    MYSQL_PASSWD=${MYSQL_PASSWD:-“cloud1234”}
    NOVA_DB_USERNAME=${NOVA_DB_USERNAME:-“novadbadmin”}
    NOVA_DB_PASSWD=${NOVA_DB_PASSWD:-“cloud1234”}
  • 系统会安装 Ubuntu 12.04 的镜像,并启动一个实例。这个过程中镜像自动从 Ubuntu 官网下载,可以查找 cloud-images 更换地址或者镜像 precise-server-cloudimg-amd64-disk1.img,也可以注释掉这个步骤,直接使用 dashboard 在 web 添加镜像启动实例。这个镜像有700多 MB,对于网速不好的用户,可能需要较长时间,因此可以先下载好镜像,然后把这里的地址改成本地即可。

总结一下需要设置的参数:

  • 设置 root 密码这一步可以删掉,使用 root 执行即可;
  • 可选,如果不需要跳过本步骤
    系统语言设置,可以参考oneStack.sh locale部分,不在此介绍
    设置apt源 /etc/apt/sources.list
  • 设置网络
    /etc/network/interfaces
    可以参考oneStack.sh locale部分
  • 配置参数,除了网络ip,其它可以不变
    ## 数据库
    MYSQL_PASSWD=${MYSQL_PASSWD:-“cloud1234″}
    ## 自行检查下面network/interfaces的两个网卡设置与此处一致
    OUT_IP=”192.168.139.50″
    ## 选择虚拟技术,裸机使用kvm,虚拟机里面使用qemu
    VIRT_TYPE=”qemu”
    ## token, 登录dashboard密码
    ADMIN_TOKEN=”admin”
  • 然后执行./oneStack.sh安装即可。

OneStack 的展望

1、加入高可用性 OpenStack 的部署
详见构建 OpenStack 的高可用性(HA,High Availability)对高可用性OpenStack的讨论。对照 CAP 理论,OpenStack 的分布式对象存储系统 Swift 满足了可用性和分区容忍性,没有保证一致性(可选的),只是实现了最终一致性。对于 Swift 的研究和学习网上很多,我不做介绍。但是,在整个 OpenStack 架构中,要满足高可用性需要进行很多工作来保证。主要是通过分离、冗余技术实现,也就是 nova-api、nova-network、glance 等可以分别在多节点上工作,RabbitMQ 可以工作在主备模式,MySQL 可以使用冗余的高可用集群。这些组合可能有很多问题,有些也需要加入到 OpenStack 项目。

2、加入对 Ubuntu 以外的操作系统(如 CentOS)的支持
个人精力有限,所以没有对 CentOS 等其它版本进行支持,也没有对 Ubuntu11 等版本进行测试。但是大家应该只需要把 OneStack 稍加改动就可以用到这些版本的操作系统。因此,如果有人有改好的,可以拿出来分享,别人也也可以顺便帮你改善和讨论。

3、希望更多的有时间的同行参与
正如上面所说,个人精力有限,业余所做,肯定有诸多不足,而且对其它版本没有添加支持,更主要的,希望对高可用性(HA)这个很关键的要求实现自动化部署,因此希望多提出意见建议、多分享自己的经验和成果,造福别人也提高自己。

在 Ubuntu 12.04 上安装和配置邮件服务

postfix

前段时间把一台 FreeBSD 邮件服务器移到了 Ubuntu 虚拟机,又痛苦的配置了一次邮件服务器,配置完后再写一遍 Puppet 代码,把整个配置过程代码化,然后再重建一次虚拟机测试和应用 Puppet 代码,每次看到满屏的自动配置过程都会惊讶 Puppet 的魔力

邮件服务器配置之所以麻烦是因为需要了解很多东西,牵涉到域名服务 DNS/Bind,Web 收发邮件 Apache/PHP/MySQL/SquirrelMail,认证服务 LDAP, Kerberos, PAM,邮件通常存放在额外存储上还要 NFS/SAN,邮件服务 Postfix/Dovecot,反垃圾反病毒 Postgrey/Clam AV/SpamAssassion,安全认证 SSL,监控和备份等等,这一套下来基本包括了 Linux 系统管理的方方面面,所以说配置一个安全可靠的企业级邮件系统不容易,足够写一本书。个人配置邮件服务器通常不需要 LDAP/Kerbersos/NFS/SAN/SSL 这些,剔除这些后就不是那么复杂了,不过再想一下,个人有必要配置邮件服务器么?直接用免费的 Google App 不是很方便么。

准备工作

简单介绍一下我们将要安装的软件包:

  • Postfix: 用来接受和发送邮件的邮件服务器,正确说法应该叫邮件传送代理(Mail Transfer Agent,MTA),是邮件服务最重要的部分;
  • Dovecot: POP 和 IMAP 服务器,用来管理本地邮件目录以便用户能通过 Mail.app, Thunderbird, Mutt 等邮件客户端(又叫邮件用户代理 Mail User Agent, MUA)登陆和下载邮件;
  • Postgrey: 邮件灰名单工具,可简单的抵挡垃圾邮件;
  • amavisd-new: 一个代理,用于连接邮件传输代理和内容检查器,可以理解为 Postfix 把邮件交给它,它负责联系病毒扫描和垃圾邮件过滤;
  • Clam AntiVirus: 病毒扫描工具;
  • SpamAssassin: 垃圾邮件内容过滤工具;
  • Postfix Admin: Postfix 的 Web 前端,用来管理邮件用户和域名。

设置主机名(不要跳过这一步):

# hostname mail.vpsee.com

# vi /etc/hosts
127.0.0.1 mail.vpsee.com localhost

更新系统:

$ sudo apt-get update
$ sudo apt-get upgrade

安装必要软件包

安装 LAMP,Postfix 本身不需要 Apache/PHP/MySQL,但是因为要安装 Postfix Admin,并且管理用户需要用到数据库,所以要安装 Apache/PHP 和 MySQL.

$ sudo apt-get install lamp-server^
$ sudo apt-get install php-apc php5-curl php5-gd php-xml-parser php5-imap

安装邮件服务器及一些工具:

$sudo apt-get install mail-server^

$sudo apt-get install postfix-mysql dovecot-mysql postgrey
$sudo apt-get install amavis clamav clamav-daemon spamassassin

$sudo apt-get install libnet-dns-perl pyzor razor
$sudo apt-get install arj bzip2 cabextract cpio file gzip nomarch pax unzip zip

配置 Apache

编辑 apache 配置文件后重启:

$ sudo vi /etc/apache2/sites-available/default
...
    DocumentRoot /var/www
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
...

$ sudo /etc/init.d/apache2 restart

配置 MySQL 数据库

创建一个名为 mail 的数据库并设置权限和密码:

$ mysql -uroot -p

mysql> create database mail;
mysql> grant all on mail.* to 'mail'@'localhost' identified by 'password';

配置 Postfix Admin

下载 psotfixadmin,解压后放到 /var/www:

$ wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin-2.3.5/postfixadmin-2.3.5.tar.gz
$ gunzip postfixadmin-2.3.5.tar.gz
$ tar -xf postfixadmin-2.3.5.tar
$ sudo mv postfixadmin-2.3.5 /var/www/postfixadmin
$ sudo chown -R www-data:www-data /var/www/postfixadmin

配置 postfixamdin,标准的 php 程序配置方法,填入访问数据库需要的信息,其中 setup_password 部分稍后再填入:

$ sudo vi /var/www/postfixadmin/config.inc.php
...
$CONF['configured'] = true;
$CONF['setup_password'] = '稍后替代';
$CONF['postfix_admin_url'] = 'http://mail.vpsee.com/postfixadmin';
$CONF['database_type'] = 'mysql';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'mail';
$CONF['database_password'] = 'password';
$CONF['database_name'] = 'mail';
$CONF['admin_email'] = '[email protected]';
$CONF['encrypt'] = 'md5crypt';
...

用浏览器访问 http://mail.vpsee.com/postfixadmin/setup.php,用哈希后的密码字符串替代上面 $CONF[‘setup_password’] = ‘稍后替代’ 中的相关部分。

为了安全考虑,最好禁止 web 访问 setup.php:

$ sudo vi /var/www/postfixadmin/.htaccess

deny from all

配置 Dovecot

给系统添加 vmail 帐号:

$ sudo useradd -r -u 150 -g mail -d /var/vmail -s /sbin/nologin -c "Virtual Mail" vmail
$ sudo mkdir /var/vmail
$ sudo chmod 770 /var/vmail
$ sudo chown vmail:mail /var/vmail

开始配置 Dovecot,dovecot 支持多种认证方式,这里采用数据库认证,注意下面的配置文件一个包含一个,初看比较乱,10-auth.conf 有 !include auth-sql.conf.ext 一行,会包含 /etc/dovecot/conf.d/auth-sql.conf.ext,而 auth-sql.conf.ext 会包含下面要提到的 /etc/dovecot/dovecot-sql.conf.ext,这样只要用不同的 include 就可以切换不同的认证方式,虽然初看复杂一点但是熟悉以后用起来还是挺方便的。

$ sudo vi /etc/dovecot/conf.d/10-auth.conf

disable_plaintext_auth = yes
auth_mechanisms = plain login

!include auth-sql.conf.ext

配置 Dovecot,设置数据库参数,以便 dovecot 能正确访问刚才创建的 mail 数据库:

$ sudo vi /etc/dovecot/dovecot-sql.conf.ext
...
driver = mysql
connect = host=localhost dbname=mail user=mail password=password
default_pass_scheme = MD5-CRYPT
...
password_query = \
  SELECT username as user, password, '/var/vmail/%d/%n' as userdb_home, \
  'maildir:/var/vmail/%d/%n' as userdb_mail, 150 as userdb_uid, 8 as userdb_gid \
  FROM mailbox WHERE username = '%u' AND active = '1'

user_query = \
  SELECT '/var/vmail/%d/%n' as home, 'maildir:/var/vmail/%d/%n' as mail, \
  150 AS uid, 8 AS gid, concat('dirsize:storage=', quota) AS quota \
  FROM mailbox WHERE username = '%u' AND active = '1'
...

用户在服务器上用来存放邮件的地方在哪呢?所以需要指定邮件存放地址 /var/vmail,这个目录上面在创建 vmail 帐号时已经创建了:

$ sudo vi /etc/dovecot/conf.d/10-mail.conf
...
mail_location = maildir:/var/vmail/%d/%n
mail_uid = vmail
mail_gid = mail
...

修改 /etc/dovecot/conf.d/10-master.conf

$ sudo vi /etc/dovecot/conf.d/10-master.conf
...
service auth {
  unix_listener auth-userdb {
   mode = 0600
    user = vmail
    group = mail
  }
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix        
  }
...

确认 dovecot 有权限读取配置文件:

$ sudo chown -R vmail:dovecot /etc/dovecot
$ sudo chmod -R o-rwx /etc/dovecot

配置 Amavis, ClamAV, SpamAssassin

互加 clamav, amavis 用户到对方组里以便能互相访问,配置过滤模式:

$ sudo adduser clamav amavis
$ sudo adduser amavis clamav

$ sudo vi /etc/amavis/conf.d/15-content_filter_mode
use strict;
@bypass_virus_checks_maps = (
   \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);
@bypass_spam_checks_maps = (
   \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);
1; # ensure a defined return

启用 spamassassin:

$ sudo vi /etc/default/spamassassin
...
ENABLED=1
CRON=1
...

配置 Postfix

main.cf 是 postfix 的主要配置文件:

$ sudo /etc/postfix/main.cf
...
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes

myhostname = mail.vpsee.com
myorigin = /etc/hostname
mydestination = mail.vpsee.com, localhost
mynetworks = 127.0.0.0/8
inet_interfaces = all
mynetworks_style = host

virtual_mailbox_base = /var/vmail/
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf, mysql:/etc/postfix/m
ysql_virtual_alias_domainaliases_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf

mail_spool_directory = /var/mail
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1

content_filter = amavis:[127.0.0.1]:10024

header_checks = regexp:/etc/postfix/header_checks
...

注意上面配置有行 header_checks = regexp:/etc/postfix/header_checks,我们现在还没有 header_checks 文件,创建一个并包含一下内容,给自己邮件增加一点隐私,过滤一些信息:

$ sudo vi /etc/postfix/header_checks
/^Received:/                 IGNORE
/^User-Agent:/               IGNORE
/^X-Mailer:/                 IGNORE
/^X-Originating-IP:/         IGNORE
/^x-cr-[a-z]*:/              IGNORE
/^Thread-Index:/             IGNORE

还需要配置 master.cf 文件:

$ sudo vi /etc/postfix/master.cf
...
smtps     inet  n       -       -       -       -       smtpd
  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_tls_auth_only=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject_unauth_destination,reject
  -o smtpd_sasl_security_options=noanonymous,noplaintext
  -o smtpd_sasl_tls_security_options=noanonymous

amavis      unix    -       -       -       -       2       smtp
  -o smtp_data_done_timeout=1200
  -o smtp_send_xforward_command=yes
  -o disable_dns_lookups=yes
  -o max_use=20
127.0.0.1:10025 inet    n       -       -       -       -       smtpd
  -o content_filter=
  -o local_recipient_maps=
  -o relay_recipient_maps=
  -o smtpd_restriction_classes=
  -o smtpd_delay_reject=no
  -o smtpd_client_restrictions=permit_mynetworks,reject
  -o smtpd_helo_restrictions=
  -o smtpd_sender_restrictions=
  -o smtpd_recipient_restrictions=permit_mynetworks,reject
  -o smtpd_data_restrictions=reject_unauth_pipelining
  -o smtpd_end_of_data_restrictions=
  -o mynetworks=127.0.0.0/8
  -o smtpd_error_sleep_time=0
  -o smtpd_soft_error_limit=1001
  -o smtpd_hard_error_limit=1000
  -o smtpd_client_connection_count_limit=0
  -o smtpd_client_connection_rate_limit=0
  -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks

dovecot      unix   -        n      n       -       -   pipe
  flags=DRhu user=vmail:mail argv=/usr/lib/dovecot/dovecot-lda -d $(recipient)

还需要配置几个文件:

$ sudo vi /etc/postfix/mysql_virtual_alias_domainaliases_maps.cf
user = mail
password = password
hosts = 127.0.0.1
dbname = mail
query = SELECT goto FROM alias,alias_domain
  WHERE alias_domain.alias_domain = '%d'
  AND alias.address=concat('%u', '@', alias_domain.target_domain)
  AND alias.active = 1

$ sudo vi /etc/postfix/mysql_virtual_alias_maps.cf
user = mail
password = password
hosts = 127.0.0.1
dbname = mail
table = alias
select_field = goto
where_field = address
additional_conditions = and active = '1'

$ sudo vi /etc/postfix/mysql_virtual_domains_maps.cf
user = mail
password = password
hosts = 127.0.0.1
dbname = mail
table = domain
select_field = domain
where_field = domain
additional_conditions = and backupmx = '0' and active = '1'

$ sudo vi /etc/postfix/mysql_virtual_mailbox_domainaliases_maps.cf
user = mail
password = password
hosts = 127.0.0.1
dbname = mail
query = SELECT maildir FROM mailbox, alias_domain
  WHERE alias_domain.alias_domain = '%d'
  AND mailbox.username=concat('%u', '@', alias_domain.target_domain )
  AND mailbox.active = 1

$ sudo vi /etc/postfix/mysql_virtual_mailbox_maps.cf
user = mail
password = password
hosts = 127.0.0.1
dbname = mail
table = mailbox
select_field = CONCAT(domain, '/', local_part)
where_field = username
additional_conditions = and active = '1'

大功告成,重启相关服务:

$ sudo service spamassassin restart
$ sudo service clamav-daemon restart
$ sudo service amavis restart
$ sudo service dovecot restart
$ sudo service postfix restart

测试 Postfix

用 telnet 连上邮件服务器的 25 端口(SMTP),然后发送 HELO mail.vpsee.com 指令就会得到 250 mail.vpsee.com 确认信息:

$ telnet mail.vpsee.com 25 
Trying 192.168.2.66...
Connected to mail.vpsee.com.
Escape character is '^]'.
220 mail.vpsee.com ESMTP Postfix (Ubuntu)
HELO mail.vpsee.com
250 mail.vpsee.com

用 telnet 发送一封邮件试一下,下面的 MAIL FROM, RCPT TO, DATA, ., QUIT 都是指令:

$ telnet mail.vpsee.com 25 
Trying 192.168.2.66...
Connected to mail.vpsee.com.
Escape character is '^]'.
220 mail.vpsee.com ESMTP Postfix (Ubuntu)
MAIL FROM:<[email protected]>
250 2.1.0 Ok
RCPT TO:<[email protected]>
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
Subject: a test message
This is a test message!
.
250 2.0.0 Ok: queued as 6832FF0036
QUIT
221 2.0.0 Bye
Connection closed by foreign host.

ssh 登陆邮件服务器后去 /var/vmail 邮件目录看一下就可以证实 test2 用户是否收到来自 test1 用户的邮件,当然这个邮件也可以通过 Mail.app, Thunderbird, Mutt 这类工具收到本地电脑上看

使用 mutt, fetchmail, maildrop, msmtp 收发邮件

现在已经有了 Mail.app, Thunderbird, Outlook 这些图形化工具能很方便的处理邮件,为啥还需要 mutt 这种命令行文本方式的邮件工具呢?mutt 的一个优势是占用资源小,可以很好的运行在低配置的虚拟机或古老的电脑上(应该不会有人想在 256MB 内存的虚拟机或 VPS 上用 X Window/Gnome/Thunderbird 这种组合吧)。那为什么要在虚拟机上收发邮件呢,不能在自己电脑上处理邮件吗?可能有多个电脑而且电脑经常换,电脑可能被盗,硬盘可能坏、数据可能丢,邮件放在本地电脑不太方便,有些电脑可能是共用的,在共用电脑上保留自己的邮件帐号不爽。那为啥不直接用 Gmail 收发 POP/IMAP 工作邮件呢?有时候可能需要在别人的电脑上打开工作邮件,比如核对一些事情、计划、会议记录之类的,在公共电脑或者别人电脑上开自己的私人邮箱是件很危险的事情,谁知道电脑上有没有病毒、木马或者键盘纪录程序?

建议经常使用 Gmail 的用户激活 2-step verification 增加安全性。

总之吧,现在的需求是:ssh 到一台服务器或虚拟机上,用 mutt 处理邮件。

在 Ubuntu 上

在 Ubuntu 上安装 mutt + fetchmail + maildrop + msmtp:

# apt-get install mutt fetchmail maildrop msmtp

在 FreeBSD 上

在 FreeBSD 上安装 mutt + fetchmail + maildrop + msmtp:

# pkg_add -r mutt
# pkg_add -r fetchmail
# pkg_add -r maildrop
# pkg_add -r msmtp

配置 mutt

touch 一个文件用来存放邮件:

# mkdir /var/spool/mail
# touch /var/spool/mail/vpsee

配置 fetchmail 通过 POP 收邮件:

$ vi .fetchmailrc
poll "mail.vpsee.com"
protocol pop3
username "vpsee"
password "password"
mimedecode                      # 自动处理 mime 
mda "/usr/bin/maildrop"         # 告诉 fetchmail 使用哪个 MDA (for Ubuntu)
#mda "/usr/local/bin/maildrop"  # 告诉 fetchmail 使用哪个 MDA (for FreeBSD)

$ chmod 0700 .fetchmailrc

配置 maildrop,告诉 maildrop 把邮件分发到哪里(其实是一个 /var/spool/mail/ 下的一个文件),注意这个时候要处理一下权限问题,否则用户登陆执行 fetchmail 后由 maildrop 分发到邮箱( /var/spool/mail/vpsee)的时候会出现权限错误(因为 maildrop 没有权限写那个文件):

# touch /var/spool/mail/vpsee
# chown vpsee:vpsee /var/spool/mail/vpsee

$ vi .mailfilter
HOME=/home/vpsee              # 指定 home 目录
DEFAULT=/var/spool/mail/vpsee # 想在哪里保持邮件
logfile "$HOME/.maillog"      # 日志

配置 msmtp 用 SMTP 发邮件:

$ vi .msmtprc
account default
host mail.vpsee.com
from [email protected]
auth off

配置 mutt,在 mutt 配置文件里面指明 msmtp 路径,注意 Ubuntu 和 FreeBSD 的默认安装路径不同(/usr/bin vs /usr/local/bin)

$ vi .muttrc
set realname            = "vpsee"
set from                = "[email protected]"
set use_from            = yes
set envelope_from       = yes
set spoolfile           = /var/spool/mail/vpsee
set sendmail="/usr/bin/msmtp" # for Ubuntu
#set sendmail="/usr/local/bin/msmtp" # for FreeBSD

使用 mutt

执行 fetchmail 收邮件,然后就可以用 mutt 读、写、回复邮件了:

$ fetchmail -v

$ mutt

mutt

分享一些程序员的办公桌

优秀的程序员和普通的程序员之间的生产力差距在10倍到100倍之间。窥视高手的办公桌看看能不能找到高手生产力的秘密,没有高手的智慧和经验但至少不要让自己输在工具上,好的工具真的可以提高生产力,飞机真的比汽车快。看看什么样的环境和电脑帮助这些高手提高生产力的,VPSee 发现有两点值得注意:

  • 最简风格,工具都很简单,大多办公桌上没有乱七八糟的东西;
  • 都用 Mac(有一人同时用 Mac 和 ThinkPad),这个不稀奇,三年前就讨论过:为什么国外程序员爱用 Mac?

Coderwall 是 Y Combinator 最近孵化的其中一家创业公司中,致力于聚合 Geek 们在 Github、Twitter、LinkedIn 等的项目和信息,为 Geek 打造一张“技术名片”。最近 Coderwall 社区分享了几位技术高手的工作平台,以下图片来自 Codewall.

Ilya Grigorik: Google 工程师。

igrigorik

Alex MacCaw: JavaScript 程序员,O’Reilly 作者,目前在 Stripe 公司工作。

alex

Sam Soffes: iOS 和 Rails 软件工程师,Synthetic 前雇员,目前在创业。

samsoffes

Max Howell: Homebrew 的作者。

mxml

Scott Hanselman: 微软工程师。

shanselman

Jeff Lindsay: 开源黑客,Hacker Dojo 创始人,目前在 Twilio 工作。

progrium

Dr Nic Williams: 每个 Ruby 社区的人都应该听过或看过他的作品,贡献了超过100个开源项目,目前在 Engine Yard 工作。

drnic

Phil Haack: 前微软 ASP.NET 程序经理,目前在 GitHub 工作。

haacked

Michael Bleigh: 开发了几个被广泛使用的 Ruby 开源软件库。

mbleigh

Chris Eppstein: Compass 框架作者和 Sass 贡献者。

chriseppstein