吐槽一下 Go 语言

由于公司一直都在大力推广 Go 语言,我也有幸接触了一下。虽然 Google 内部已有三大语言(C++、Java、Python),Go 在公司内部的政治意义大于它的实际使用,但它的设计却有着很多亮点。比如 Go 自带了代码格式化工具(gofmt)和自动化测试工具(go test),这些标准化的工作在其它语言中一直都存在着多方争议,一直都不能统一,而 Go 从一开始就搞定了这些琐碎问题,让广大程序员可以把重心都放在开发新程序上,而不是争一些有的没的。

当然,这篇文章并不想表扬 Go 语言,而是要吐槽一下它的缺点。

Go 的设计者有着强烈的 Unix 背景,有一些平台依赖的东西都默认甚至是强制成 Unix 的。比如 Go 语言中有一个名为“path”的包,用来操作路径,而它强制路径分隔符为“/”,而无视 Windows 中的“\”。后来估计是开发中遇到一些问题,又做了一个叫“filepath”的包,来兼容 Windows 的使用。又比如 Go 语言中对环境变量的解析,强制环境变量的标识符为“$”,而不视 Windows 中的“%”,甚至整个标准库中都找不到对“%”的处理方法。这些基本的区别都不做处理,很难想象 Go 语言在跨平台设计中有哪些更为隐藏的坑。

这还不是主要的问题。更严重的问题是,Go 语言中有过多的“私有”特性,对使用者不公平。

先来举一个 C++ 的例子,C++ 中有一些运算符,比如加减乘除,这些运算符可以使用于 C++ 的基础类型(如 int)上。基础类型是 C++ 语言本身提供的,如果运算符只能作用于基础类型,那么 C++ 也可被视为“自私”的。然而 C++ 的设计者并没有这么做,这些运算符,不仅可以用于基础类型,也可以在自定义类型中,通过重载的方式来使用,使得 C++ 中不仅两个 int 可以相加,两个 class 的实例也可以相加。这样一来,运算符对于使用者就是公平的。

而 Go 语言中,则有着很多反例。比如它的泛型:Go 的官方说法是“我们不支持泛型”,具体原因就不深入讨论了。但是,Go 语言的自有类型 map 和 channel 却是支持泛型的。这就成了一个典型的“自私”的例子。类似的例子还有 Go 语言中的 internal 包有着特殊的作用域;Go 的官方库有着极短的包名,而第三方库通常是以“github”开头的很长一串文本。

这些“私有”特性,说明 Go 语言的设计者并没有为开发人员考虑过,自己设计得爽了,却徒增了学习曲线,不利于 Go 语言的推广。如果能把这些问题解决好,Go 还是可以成为一门不错的语言的。

在 Markdown 中设置链接由新窗口打开

尽管我对 Markdown 不是那么感冒,但工作和生活中总是难免会使用到一些,比如在向某些开源项目发 PR 的时候。于是对 Markdown 的一些小技巧也有所了解。

Markdown 中的链接语法是这样的:[文本](链接)。它相当于 HTML 中的

但众所周知,HTML 的 a 标签有一个实用的属性 target,当它的值为“_blank”的时候,浏览器会默认为这个链接打开一个新窗口,而不是在当前页面转向新页面。而 Markdown 中没有这个“_blank”选项,于是所有链接都只能在当前页面打开,有些情况会非常不方便。

在多数 Markdown 解释器中(如 GitHub Flavored Markdown),这个情况无解。如果一个 Markdown 解释器同时支持 HTML 语法,则这种情况可以通过直接写 HTML 解决。

于是我又多了一个不喜欢 Markdown 的理由。

iPhone 6s 省电设置

我把 4s 时代的省电方法用在了 6s 上面,结果是我的 iPhone 6s Plus 不充电的情况下可以正常使用至少三天。一到家就插充电线的情况就此离我远去了。

接下来介绍一下省电的经验:

关闭通知

几乎每个应用都会有通知(Notification),从应用的角度来说,它肯定希望多发一些通知来引起你的注意,以便经常打开那个应用;而从我们用户的角度来说,大多数通知是没有意义的,通知多了不仅令人烦躁,还大量地消耗电力。

关闭的方法如下:

  1. 打开“设置 -> 通知”,会看到一排应用列表;
  2. 对于不必要应用,点进去把“允许通知”关闭即可。

我只保留了一些必要功能的通知,比如短信和 Facetime,而 90% 的应用通知都被我关闭了。

仅在应用中使用位置服务

iOS 的位置服务(Location Service)有三种权限设定:永不(Never)、使用应用程序期间(While Using)、始终(Always)。由于 iOS 的伪多线程机制,一个应用在不显示的时候,实际上处于挂起状态。于是把权限设为“当使用时”可以避免位置服务一直处于开启状态,以节省电量。

设置方法:

  1. 打开“设置 -> 隐私 -> 位置服务”,会看到一排应用列表;
  2. 对于每一个应用,点进去选择“使用应用程序期间”;
  3. 如果这个应用不支持“使用应用程序期间”,我一般会设成“永不”。

关闭后台程序刷新

iOS 允许应用程序在后台挂起的同时,做一些必要的工作,比如音乐应用在后台下载歌曲等。然而并不是所有的应用都有必要在后台运行。对于那些我们并不关心的应用,大可把“后台程序刷新”给关了。

设置方法:

  1. 打开“设置 -> 通用 -> 后台程序刷新”,会看到一排应用列表;
  2. 对于大多数应用,都可以把这项功能关闭;

我只保留了一些必要的应用,比如 Google Photos(后台上传照片)、Google Calendar(刷新日程)等,90% 的应用都关闭了后台刷新。需要注意的是,这项功能对新应用是默认开启的,所以过一段时间之后,还要回来看看,把那些新安装的应用也关掉。

关闭 Siri

个人经验,Siri 除了偶尔调戏一下之外,并不会经常使用,但它启用的状态下,却一直在消耗电力。

设置方法:

  1. 打开“设置 -> 通用 -> Siri”;
  2. 把 Siri 整体关闭;

关闭 iCloud 备份

在最新 iOS 中,照片已经有了单独的一项,称为“iCloud 照片库”,而之前的“iCloud 备份”只是用来备份一些应用程序设置和数据。而我从来都没有用到过这些备份,每次换新的 iPhone 都是设置为全新的 iPhone 而不是从备份中恢复。于是这些备份所占用的空间和备份时使用的电量,对我来说是完完全全的浪费。

设置方法:

  1. 打开“设置 -> iCloud”;
  2. 找到“备份(Backup)”;
  3. 点进去把它关闭;

总结

以上这些设置可以让 iPhone 4s 在用了三年之后,还可以待机一天左右。而 iPhone 6s 的电量是 4s 的大约两倍,并且性能上有很大的提升,于是待机三天不成问题。

在德语键盘中输入 @ 符号

标准的英语键盘大家都很熟悉了,其中的“@”符号在数字“2”的上方,使用 Shift-2 按键组合即可打出。

不幸的是,某一次我把输入法改成了德语,然后我的 Macbook Pro 休眠了,唤醒之后,密码怎么输也不对。碰到这种情况,按公司的传统,我的反应是:

后来仔细想了想,大概是输入法改了的原因。只不过 Mac OS X 在输密码的阶段会锁定输入法,不能切换回英文。好吧,还好我有一个正宗的德语键盘,找一下 @ 字符在哪就可以了。德语键盘长这样:

可以看到数字“2”上面是引号而不是“@”,这就是为什么密码一直不对的原因。而德语键盘中的“@”在“Q”下方,可以通过组合键 AltGr-Q 或者 Ctrl-Alt-Q 打出,其中 AltGr 特指右手边的 Alt 键。

然后我就按了 AltGr-Q,但系统还是说密码不对。

于是,不死心的我又去查了一下德语版的 Macbook 键盘长什么样。

我去,原来苹果把“@”符号设计到了字母“L”那里……

好了,问题解决了,大家洗洗睡吧。

网易所谓的“EAL 3+”证书是个什么东西?

今天一早,乌云上曝出了网易邮箱的安全问题,过亿的用户信息被泄漏。而网易方面也是反应神速,一份宣传稿发到各大媒体,说是自己家的邮箱不仅没问题,而且安全性方面还是全国最牛X的。公告原文如下(摘自新浪):

文中提到了一个 EAL 3+ 的认证,而且号称是国内最高等级。这个到底是什么呢?我们来研究一下。

网易的企业邮箱网站在今年 8 月底发布了一则新闻,说是企业邮箱系统获得了 EAL 3+ 认证,还有一个像模像样的证书。图片就不贴了,大家点链接进去看吧。证书大意是“网易企业级邮箱系统”获得 中国信息安全评测中心信息安全实验室 颁发的 EAL 3+ 证书。

首先,这个系统的名字有歧义,企业级的邮箱系统,不一定只是给企业用的。网易可以说自家的免费邮箱也做到了企业级的安全性。当然网易算是心虚,没有在自己的首页发表这么个新闻,只是在企业邮箱的网站上发了。那我们只能认为只有网易的企业邮箱获得了这个证书,而大众所使用的免费邮箱却没有。而乌云提到的过亿的用户信息,显然不是从企业邮箱来的。网易在公告中宣称的“国内最安全”,只不过是偷换概念罢了。

当然,不能排除网易内部实际上使用的是同一套系统,即企业邮箱和免费邮箱的后台是一样的,只是页面看上去不一样。那么企业邮箱获得了安全认证,免费邮箱也就同样安全。好吧,然后我又去看了一下 EAL 3+ 的实际内容。

EAL(Evaluation Assurance Level)是某个国际组织设立的标准,按它的实际操作来看,每个国家都可以设立自己的评测实验室,对本国的软件进行评测。中国、美国、英国、法国、西班牙等国都有自己的评测实验室。中国的评测由上面提到的 中国信息安全评测中心信息安全实验室 来进行。在中国信息安全评测中心的网站上,可以找到中文版的 EAL 1 - 5 的评测细节,其中这个链接指向的是 EAL 3 的指南(PDF)。文档我稍微看了一下,实际它只有 20 页不到,大约就是一个对文档细节的约束。其中对于测试文档的要求,只有半页,还没我的一篇博文长。摘录如下:

基本上它就是要求了测试文档的完整性,对于要测哪些方面、具体测试的实施以及测试的结果,通通没有要求。也就是说,只要文档写得好,通过 EAL 评测并不难。而做过产品的同学们都知道,文档和最终产品的差距还是相当大的。举个例子:

另外,网易的证书上还提到了评测方法:GB/T 30270-2013 信息技术 安全技术 信息技术安全性评估方法。我搜索了一下,这个《方法》没有电子版,只有纸制书籍出售,当当网的卖价是 103 元。我自然不会为了写博客还去买本破书,因为当当的介绍中提到,这本书只有 200 多页,目录显示它的内容就是 EAL1 到 EAL5 的实际内容,外加一些前言备注什么的。大致可以看到,书中没有额外的内容,具体的评测和上面给出的 PDF 链接没有两样。

所以实际上,网易获得了证书 和 系统的安全性 这两件事并没有直接联系。而即使是网易获得证书的企业邮箱,它的安全性也令人堪忧:

上图中,即使我选择了“全程使用 SSL”,登录页面也没有使用 SSL。在登录页面不使用 SSL 的情况下,即使登录接口使用了 SSL 也是形同虚设的,因为未加密的登录页面可能被劫持,只需要添加一段脚本,就可以神不知鬼不觉得拿到帐号信息。详细的分析我曾经在乌云看过一篇文章,一下子找不到了,等找到了再补上。

对于那些担心自己密码失窃的同学们,我只能建议一句:保护个人信息,远离网易。当然,如果你在其它网站使用了和网易一样的密码,请立即修改。

感谢国家

好久没写文章了,最近这段时间公司事务繁忙,好不容易有点闲暇时间了,就跑过来照顾一下博客。

前几天 StrongVPN 的客服联系了我,问我要 Paypal 的帐号以便付款。他家前段时间升级了代理系统,可能是把我的 Paypal 记录弄丢了,于是我写信回了过去,也顺便去看了一下,我将收到多少钱。

不看没关系,一看吓了一跳,佣金居然有四位数?然后看了一下详细数据,确定了是新系统才有的记录,不是历史数据。敢情在这两个月里网络环境如此地恶劣,大家一起上 VPN 的节奏。

感谢国家,下个月收到佣金可以换个 iPhone 6s 了。

顺便做个广告,StrongVPN 更新了他们的服务,现在更注重隐私,并且提到了无限流量的 VPN,要体验一下的同学点这里

写于博客密码泄露之后

很不幸我的博客密码被盗了,一个不名黑客在半夜入侵了我的主机,植入了菜刀,远程控制了机器。然后他窃取了一些重要资料(比如一些羞羞照),并且把主机变成了一台肉机。我发现的时候,肉机已经偷跑了超过 5000 美元的流量......

在电脑手机前偷笑的各位可以稍微停一下了。以上只是我被害妄想症的一种表现,它实际上并没有发生。

由于对安全的偏执,我假想了各种安全漏洞的情形,然后加以防御。之前讨论过 WordPress 的密码安全性插件安全性,这次来探讨一下密码失窃之后,有哪些亡羊补牢的方法。

假设一名黑客偷取了本博客的管理员密码,(先假设只是博客的密码,而不是主机的管理员权限),那么他能做哪些事情?

一,很明显,他可以操作博客的数据库,新建用户、新建文章、删除文章等。

二,黑客可以在后台直接挂马,然后进行更强大的远程操作。

对于第一条,似乎没有特别好的方法,一旦密码被盗,数据库就只能放弃了。当然,如果你的博客没有任何加密的内容,数据库被盗也没什么好怕的,本来就都是公开的东西。

接下来重点说一下第二条。

PHP 有一个很好用也很危险的特性,就是源代码可以直接执行;而 WordPress 也有一个很好的特性,即可以在后台直接修改插件代码。于是一旦黑客控制了后台,他可以在源代码里嵌入一行如下的语句,然后就可以远程控制了。对,PHP 就是那么强大。

要防止这种情况,最有效的方法是在把所有源代码设置为只读,即 Linux 文件属性 400(或 444),这样可以避免任何人对文件进行修改。但这样做之后,自己真想要修改文件的时候,却是非常麻烦,先要 SSH 登录,把文件属性设为可写(如 755),然后再回到后台改文件。另外,这样做也阻止了 WordPress 的自动更新,一定程度上降低了安全性。

对此, WordPress 提供了一个简单的防御方式,可以 wp-config.php 中添加一行:

这样可以禁用掉 WordPress 中修改源代码的界面,包括插件和主题,同时也禁止了安装新的插件和主题。当然这样同样会有上述的问题,即每次修改文件之前,需要先修改 wp-config.php。为了避免对 wp-config.php 的频繁修改,我们可以加一点小小的逻辑,如下:

它的含义是在不是运行 WP Cron 并且 Session 中没有定义 enable_edit 的时候,才禁用对主题和插件的修改。开启 WP Cron 的原因是它会定期检查并更新 WordPress,而 Session 的定义则可以按需开启修改的界面。

手动启用修改界面,还需要一段代码,写在 functions.php 中:

然后访问 http://你的博客地址/wp-admin/admin-ajax.php?action=temp_enable_edit 即可临时开启对插件和主题的修改,有效期到 Session 过期为止。需要注意的是,并不所有的主机都启用了 Session。如果你的主机把 Session 关了,你可以改成使用 Cookie,效果类似。

这种方法是安全和易用的一个折中,它假设了 WordPress 不会有 Bug,比如 DISALLOW_FILE_MODS 工作正常,并且没有安装可以直接运行 PHP 代码的插件

另外还有一些其它的方法仅供参考:

  • 给 wp-admin/ 文件夹加一个密码,比如 Apache 的 Basic Authentication。我觉得每次登录都需要多输一个密码,实在太麻烦了。
  • 重命名 wp-admin/ 文件夹让别人找不到。根据前几年的讨论贴,这种方法并不能完美工作,也就说是 WordPress 的代码某种程度上依赖于 wp-admin 而不能改名。
  • 创建一个新的域名,只用来访问 wp-admin,而原先的域名供访客浏览。这种方法的前提是你愿意支付双倍的 SSL 证书费用。

这个世界上没有绝对的安全,只不持之以恒的防御。