戴耀廷的言论并不可取

最近,香港“占中”发起人之一的戴耀廷,在台北的“台湾青年反共救国团”主办的活动上的发言,遭到香港建制派和北京的强力打压。戴的发言,论述的是他对中国大陆民主化之后的一种想象,属于言论自由的范畴。但看在北京眼里,这无疑是鼓吹不但要香港独立,而且要分裂中国,遭到强力打压在所难免。好在戴在台北时,也说他已做好坐牢的准备,那就无需太过为他担心了。

戴耀廷爱说什么是他的自由,相信他也明白在现今的氛围下,他的发言会有什么样的后果,也能够为自己的言论负责。只是从香港争取民主的角度,戴的发言实在并不可取,对香港的民主运动,一点帮助也没有。

戴耀廷发言时说,

反专制成功以后我们要建立一个民主的国家,...,所以在中国大陆现在不同的族群,可能包括上海的族群,也可以决定是不是应该成为一个,用什么样的关系大家连系在一起,我们可以考虑成为独立的国家,可以考虑成为联邦的一个部分,我们也可以考虑成为欧盟那种邦联的一个部分,这就是‘民主自决’

看起来,戴耀廷也明白,香港要争取“民主自决”,只能是在中国大陆实现民主化之后的事。在现阶段,或者只要共产党继续执政,“港独”也好,“台独”也罢,别说“五独”,即便“十独”,也皆是镜花水月而已。没办法,这就是这个世界的现实。民主如西班牙,加泰罗尼亚经过全民公投,尚且不能独立;库尔德人为了争取美国承诺支持,流血牺牲,结果轻易就被美国背叛。“港独”“台独”比起加泰和库尔德人来差得远了,如何能在共产党政权下独立?

中国大陆民主化,不会自发的产生。最高领导人已经表明,共产党就是要坚持一党专政,而且要党管一切。那么大陆的民主化,长期而言只能依靠大陆的人民,需要大陆民意对民主自由的支持。这将是一个漫长而艰难的过程,而戴的发言对此一点帮助也没有。戴所描绘的民主化之后的中国,是一个四分五裂的中国,不但香港台湾新疆西藏会独立,甚至他鼓吹上海也独立。中国大陆的民意,是绝对不会接受这样的国家分裂的。在现在的民族主义氛围下,他的发言正给了共产党加强一党专政的借口。

我始终认为,要推进大陆的民主化,包括香港和台湾的在内的民主化的华人社会,就需要更多展现民主制度的优越之处。有一种观点认为,号称华人世界民主之光的台湾,它的存在不但不能帮助中国大陆实现民主转型,反而可能会阻碍这一进程。某种程度上,我是赞成这种观点的。看看如今“转型正义”之下,国民党的下场,以及两蒋在台湾被如何对待。这看在共产党眼中,他们绝对会认为,如果走民主宪政这条路,他们的下场会比国民党和两蒋更惨。这只会让他们下定决心坚持一党专政,并且会防止党内出现“李登辉”。

与此同时,台湾政坛的蓝绿恶斗,政治人物不讲诚信,香港民主派为了反对而反对,“拉布”拖延议会的议事效率等等,经过大陆媒体的放大宣传,就给大陆人留下了自由民主也没那么好的印象。中国大陆经济崛起,中产阶层不断壮大,但公知和党内改革派的声音却越来越小,除了共产党对言论的钳制,改革派得不到基层民意的支持,恐怕是更重要的原因。

所以,香港民主派如果真的为香港长远未来着想,应该少采取戴耀廷式的言论,那只是空想,给中央借机打压徒增口实而已。真正应该思考的,是如何化解陆港两地矛盾,争取大陆民意对香港的同情。

Create authorization header for Cosmos DB with Go

I started a side project to create a client package for Cosmos DB SQL API with Go so I can try Go in a real project. My plan is to implement something similar to .NET Core SDK with Go. As this is a project for learning and practice, I will do it little by little, and there is no timeline regarding when it can be done.

I build the project based on SQL API via REST. To access resources in Cosmos DB with SQL API via REST, an authorization header is required for the requests. The value of the authorization header has the following format, as it is mentioned in this document.

type={typeoftoken}&ver={tokenversion}&sig={hashsignature}

In the above string, the values of type and version are simple: type is either master or resource, while the current version is 1.0. The value of signature is a bit complex. It is a hash of several other values by using the access key of Cosmos DB as the hash key. The document has all details in it and even better it has a sample written in C#.

So following the document and the sample, I implemented a Go equivalence as follows. It is a good example to try the base64 encoding and HMAC hash in Go.

The date format in the signature is required to be in HTTP-date format defined by RFC7231. However, the time package in the Go standard library doesn’t seem to support this format out of the box, but it provides a very easy way to create custom format. The utcNow() function in the above code is what I implemented to format the time to RFC7231 format.

手机短信

人在国外的一大困扰,是如何使用中国国内的手机号码,来收取国内的短信。随着移动互联网和智能手机的普及,国内的几乎所有服务都可以通过网络来完成,尤其是金融服务和移动支付。但是使用这些服务的前提是,用户需要一个中国国内的手机号码,并且能够随时收到各种服务发出的短信验证码。手机号码还好说,许多人即使出了国,也还是会每个月交月租费,保留自己原来的手机号码。但是如何用这个号码在国外收短信,却是一个问题。

如果在网络上搜索这个问题,会看到各种各样的解决方法。有每个月多花点钱,开通短信漫游服务的;有使用联通的沃信,或移动的Jego服务的;还有用Raspberry Pi来硬件hack,将短信转发到邮箱的。可以说海外的华人在这个问题上充分发挥了聪明才智。

我之前一直使用移动的Jego服务,因为我在国内的时候,一直用的是移动的号码。而且联通的沃信很早就不开放新用户注册了,即使我想让国内的朋友帮忙开个联通的号码,也没机会注册沃信。后来随着手机号码的实名制,更不好意麻烦国内的朋友开新号码了。之前Jego的服务一直不错,虽然手机应用界面比较丑,也没什么更新,但短信服务一直还比较稳定。每个月0.99美元月租,也不算贵。所以我一直用着。

可是这个月初,Jego服务突然中断了。账号无法登录,给他们的客服发邮件,也如石沉大海,没有回应。上网查了查,有人说Jego服务没人管了,人员都被调去做无忧行了。也不知真假。直到前两天,Jego的客服忽然回复了我邮件,确认说Jego服务已经停了,他们推出了Jego升级版,Jego trip,也就是无忧行。新版比原来的Jego功能更多,支持“免费接收来电和短信”,他们建议我换无忧行。

注册了无忧行用了两天,这个应用确实可以免费接收来电和短信,但需要开通国际漫游功能。不过还好,移动的号码只是开通国际漫游的话,并不产生任何费用。这岂不是比以前的Jego还好,连每个月0.99美元也省了?应用是针对Android和iOS新写的,也比以前的好用。现在我只希望,这个无忧行的服务能稳定运营下去,不会说关就关了。

一个加密的世界

我之前配置了一台基于Linux的邮件服务器,我曾经写过配置的步骤。那篇文章还是我的blog上访问量颇高的一篇。

这个邮件服务器我一直在用。大部分时间是用来收邮件,偶尔也发邮件。我原来配置的时候,邮件收发都是启用了TLS的,只是一直用的是自签名的证书,除了在配置客户端的时候,要专门信任一下证书之外,也没什么大的影响。可是最近随着各大邮件服务商,比如outlook和gmail,纷纷升级了TLS策略之后,似乎都不再信任用自签名证书发送的邮件了,必须使用由受信任CA签发的证书。各大浏览器也早已对http的页面提出安全警告了。今后要想玩自建网站和邮箱,一张由CA签发的证书是标配。还好有Let’s Encrypt出来提供免费的证书服务,否则网站和邮箱就没法随便玩了。

如今互联网成了漏洞攻击和数据泄露的高危之地,各大服务商层层防范,端到端加密,HTTPS/SSL更是成为了网站标配,整个世界都快要被加密了。尽管如此,数据泄露的事故还是经常发生。这两天闹得最厉害的,莫过于Facebook的数据泄露事件了,直接导致Facebook股价暴跌,市值一度被阿里巴巴超越。最终扎克伯格不得不亲上火线灭火。毕竟,用户的信任是所有社交网络业务的立足之本,一旦失去用户的信任,想要赢回将是很难的。扎克伯格的回应还算漂亮,这也再次说明,互联网时代最好的危机公关,就是公开透明,让用户知道来龙去脉,以及接下来的因应之道。如果试图掩盖,结果只会是欲盖弥彰,进而被唾弃了。

其实由CA签的证书,只是保证了一层信任关系。有了SSL/TLS,你和服务器之间的通讯,比较难被窃听,比较不会受到所谓的中间人攻击。但是中间人攻击,只是千变万化的网络攻击方式中的一种。即便没有被攻击,但要说有SSL的网站就值得信任,那也不尽然。更有甚者,根证书的签发单位本身也许就有问题,就像之前CNNIC闹出来过的一样。作为普通用户,我们所能做的有限,只能是尽量提高自己的水平,尽量避免让自己成为受害者了。

马航

最近这半年多,我经常要在新加坡和吉隆坡之间往返。新吉两地之间,每天的往返航班很多,我比较经常坐的是新航,胜安航空,还有马航。尤其是最近这两个月,几乎坐的都是马航。

比较起来,新航执飞的是A320这样的大飞机,票价贵,座位多,但人也多,常常满座。人多上下飞机就麻烦。胜安航空和马航用的则是737这样的单通道小飞机,相对而言即使满座,也没新航的人多。由于新加坡到吉隆坡的航程不到一个小时,机上服务基本谈不上,新航和胜安会发杯饮料,马航则是一杯果汁加一小包花生。这样,马航就显得性价比很高了。因为他家的票价最便宜,常常只有新航票价的三分之一,胜安的六成。即使这样还常常坐不满,三人的座位只坐两人,不像其它两家那么挤。但相比其它两家,马航的一大问题是,他的航班有时会晚点,尤其是从吉隆坡飞往新加坡的航班,晚点的几率挺高的。

马航的票价这么便宜,还坐不满,而另外两家贵很多,却还常常满座,表面看来,是航空公司的声誉对于经营真的很重要。马航自从经历MH370这宗现代航空史上的最大谜案,以及之后MH17被击落的悲剧之后,声誉跌入谷底,似乎一蹶不振了。人们买机票时,出于心理因素,会避免选择马航。虽然之后被国有资金控股,退市重组,又请了老外来当CEO,大规模裁员,但感觉一直没有缓过来,经营没什么起色。

空难事故的影响是一方面,但我想,企业文化和国企的效率不彰,恐怕是经营不善的更大根源。在MH370事件之后上任CEO的Mueller,上任一年就辞职了。他曾形容马航是一艘又许多漏洞的船,离职前也暗示马航的企业文化有问题。比如飞机的经常晚点,也许就反应的马航的管理和纪律问题。如果不能从根本上解决这些企业的本质问题,马航要想从谷底翻身,恐怕还需要不少时间呢。

Go语言笔记

最近接了个业余任务,给对Go语言感兴趣的同事讲讲Go语言是怎么回事。

说起来我对Go语言也不是很懂。记得我第一次听说Go,是在大概2011年的时候。那时听说Google开发了一种新语言,看了一眼,留下的第一印象是丑。那时候我正好在研究比特币是怎么回事,没时间玩这个新语言。2013年的时候,Go忽然在国内火了起来,很多网站开始用Go来写后台。我于是好奇这个语言有什么特别,花了点时间了解了一下。只是在工作中一直没有机会用,所以也谈不上精通了。这次趁着准备这个技术分享,我又深入学习了一下Go语言。

准备材料的时候,我在想怎么跟有其他语言经验的人介绍Go。我觉得作为一个简介,如果能回答好下面三个问题,应该就算不错了吧。

什么是Go?

不同于C#或Java这样依赖虚机的语言,或者Python这样的解释型动态语言,Go是一种编译型的静态类型语言,更接近C。实际上,C是直接影响go的语言之一。看看Go的三个创始人的背景,就大概知道Go会有怎样的基因了。编程语言领域转了一圈又回来了,十几年前我刚工作时,C/C++几乎一统天下。后来为了解决内存管理问题,Java和C#流行起来。然后随着机器性能的提升和解释器的改进,Javascript和Python在不同的领域崛起。现在随着云计算的普及,静态编译语言如Go和rust又开始流行了,所不同的是,它们提供了比C/C++更好的内存管理。

Go的最突出的几个特性是,可编译;静态类型,但也有部分类型推导;垃圾收集,这是其它大部分编译型静态类型语言所没有的;基于CSP(Communicating sequential processes)的并发编程;等等。

这两年,Go语言社区成长很快。据说Go是2017年,GitHub上用户增长最多的语言。而stack overflow的2017年开发者调查中,Go是most loved第五名,most wanted第三名,足见其火爆。

Most Wanted vs. Most Loved

为什么需要Go?

可是我们已经有无数种编程语言了,为什么还需要go呢?这就要从go试图解决什么问题说起了。根据go的创始人之一,Rob Pike,的说法,go的设计初衷是为了解决两个问题:

  1. Google的问题:big hardware, big software. 编译慢;依赖关系复杂;每个程序员都有自己的风格,不易合作;缺少文档;升级困难;经常重复造轮子;等等。
  2. 让Go的设计者的日常工作能够更轻松,生活更美好。

为此,Go的设计哲学遵循了下面两条核心规则。

  1. 极简:使用类Pascal语法,语法简单,关键字少;不支持类,继承,泛型等语言特性。
  2. 正交:数据结构和方法分开,通过聚合而非继承来联系二者;类型抽象通过接口实现;数据结构和接口都可以通过内嵌的方式来扩展。

虽然关于Go的设计哲学,不同的人可以列举出不同的项目,但极简和正交是最重要的两条。这两条使得Go简单易学,容易上手。这是Go受欢迎的重要原因之一。

但也由于这两条哲学,我觉得导致Go,至少是Go 1,并没有很好的解决所有它的设计者打算解决的问题。比如,Go的依赖通过package实现,但是它并没能解决大型项目的依赖问题。这个问题Go通过不同的package试了好几次,不过看来又要推倒重来,Go 1.11会有新的依赖管理工具。再比如不支持泛型,导致重复造轮子变成了免不了的问题。这些都是Go在大受欢迎的同时,为人诟病的问题。

目前Go有哪些应用场景?

目前看了,Go使用比较多的场景,还是在服务端的后台程序。容器领域里,Go俨然成为了标准语言。Docker, Kubernetes等等都是Go编写的。根据Go 2017 Survey的结果,其它go比较流行的领域包括中间件,微服务等等。Go比较不适合用来写桌面GUI应用。

坡岛十年

时间如白驹过隙,一转眼,今年已经是我在新加坡生活的第十个年头了。这是我自离家读书开始,到目前为止的人生中,生活最久的一座城市,超过了西安,也超过了上海。十年前踏足狮城时,我从没想过,我们会在新加坡生活这么久。这十年之中,我们经历了生活中的种种高低起伏,新加坡也慢慢变成了我们的家。

记得2008年我们刚来新加坡时,因为生活习惯和语言的关系,闹过不少笑话。有一次我去星巴克,点了一杯咖啡之后,帮我点单的小哥,好心问了一句,要不要加点奶油(cream)在上面。当时因为还不适应新加坡口音,我愣是没听懂cream这个词,于是问了一句“那是什么”(What is it?)。那小哥当时就凌乱了,看着我不知如何解释什么是cream。现在想起来还很好笑。

刚来的时候,每次坐公交车也很紧张,因为新加坡的公交车不报站名。路不熟的话,需要提前查好路线,数好有多少站,然后在车上留意有没有到站。这样紧张兮兮的有时也并不管用,因为如果有车站没人上下车的话,车是不停的。我有一次去客户那里开会就坐错了站,忘记是提前还是推后一站下车,反正赶到会议室时,已经是汗流浃背,狼狈不堪了。

这些生活中的小挑战,在初来乍到的时候有很多,不过一段时间之后,我们就都适应了。大的挑战就要看历史潮流的发展了。我们第一次申请PR,恰好赶上2011年的新加坡大选。在08,09年时,据说PR申请是相对比较容易的。但是到2011年那次大选,移民和人口问题是相当热的议题,人民行动党的得票在那次大选很低。我们的PR申请在这样的情况下被拒了,作为中国人,我们第一次感受到了选票的力量。PR申请被拒打乱了我们的很多计划,着实让我们彷徨了一番,幸好半年后的第二次申请被批准了,没有耽误太久。我有同事和朋友,PR申请几次三番得不到批准,最终不得不离开新加坡。

这十年之中,女儿在新加坡出生成长,我们也适应了新加坡人的生活,喜欢上了本地咖啡和榴莲。最近国会在讨论2018年的预算案。希望新加坡政府能继续保持廉洁高效,经济和社会能够继续稳定发展,我们能够继续在此安居乐业。

是为记。

Install Minikube on Ubuntu Server 17.10

I have some experiences with Docker and containers, but never played with Kubernetes before. I started to explore Kubernetes recently as I may need a container orchestration solution in the coming projects. Kubernetes is supported by Azure AKS. Even Docker has announced their support of it. Looks like it is going to be the major container orchestration solution in the market for the coming years.

I started with deploying a local Kubernetes cluster with Minikube on a Ubuntu 17.10 server on Azure. Kubernetes has a document on its site which is about installing the Minikube. But it is very brief. So in this post, I will try to document the step by step procedure both for the future reference of myself and for others who are new to Kubernetes.

Install a Hypervisor

To install Minikube, the first step is to install a hypervisor on the server. On Linux, both VirtualBox and KVM are supported hypervisors. I chose to install KVM and followed the guidance here. The following are steps.

  • Make sure VT-x or AMD-v virtualization is enabled. In Azure, if the VM is based on vCPUs, the virtualization is enabled. To double check, run command egrep -c '(vmx|svm)' /proc/cpuinfo, if the output is 1, the virtualization is enabled.
  • Install the KVM packages with the following command:
sudo apt-get install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils
  • Use the following command to add the current user to the libvert group, and then logout and login to make it work. Note, in the guidance the group name is libvirtd, but on Ubuntu 17.10, the name has changed to libvert.
sudo adduser `id -un` libvirt
  • Test if your install has been successful with the following command:
virsh list --all
  • Install virt-manager so that we have a UI to manage VMs
sudo apt-get install virt-manager

Install kubectl

Follow the instruction here to install kubectl. The following are the commands:

curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl

Install Minikube

Follow the instruction on the release notes of Minikube to install it. I used the following command:

curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.25.0/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/

When you finish this step, according to the official document, the installation of Minikube has been completed. But before you can use it, there are several other components which needs to be installed as well.

Install Docker, Docker-Machine, and KVM driver

Minikube can run on natively on the Ubuntu server without a virtual machine. To do so, Docker needs to be installed on the server. Docker-CE has a different way to be installed and Docker has a document for it.

Docker Machine can be installed with the following commands:

curl -L https://github.com/docker/machine/releases/download/v0.13.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine && \
sudo install /tmp/docker-machine /usr/local/bin/docker-machine

Finally, we need to install a VM driver for the docker machine. Kubernetes team ships a KVM2 driver which is supposed to replace the KVM driver created by others. However, I failed to make the Minikube work with the KVM2 driver. There is a bug report for this issue and hope the Kubernetes team will fix it soon.

So I installed the KVM driver with the following command:

curl -LO https://github.com/dhiltgen/docker-machine-kvm/releases/download/v0.10.0/docker-machine-driver-kvm-ubuntu16.04
sudo cp docker-machine-driver-kvm-ubuntu16.04 /usr/local/bin/docker-machine-driver-kvm
sudo chmod +x /usr/local/bin/docker-machine-driver-kvm

Test if Minikube Works

With the completion of all the above steps, we can test the Minikube now.

minikube start --vm-driver kvm

It will create a vm named as minikube in KVM and configure a local Kubernetes cluster based on it. With kubectl, you should be able to see the cluster info and node info.

kubectl cluster-info
kubectl get nodes

With that, you can start to explore Kubernetes.

Running Linux Containers on Windows Server 2016

I never thought running Linux containers on Windows Server is a big deal. A reason that I run Docker for Windows on my Windows 10 laptop is to run some Linux based containers. I thought I just need to install Docker for Windows on a Windows Server 2016 server with Container feature enabled, then I should be able to run both Linux and Windows containers. I didn’t know it is not the case until when I tried it yesterday.

It turns out the Linux Containers on Windows (lcow) Server is a preview feature of both Windows Server, version 1709 and Docker EE. It won’t work on Windows Server 2016 of which the version is older than 1709. As a side learning of this topic, I also got some ideas about the Windows Server semi-annual channel. An interesting change.

So here is a summary of how to enable lcow on Windows Server, version 1709.

  1. First of all, you need to get a Windows Server, version 1709 up and running. You can get the installation media of Windows Server, version 1709 from here. As I use Azure, I provision a server based on the Windows Server, version 1709 with Container image. Version 1709 was only offered as a Server Core installation. It doesn’t have the desktop environment.

  2. Once you have the server up and running, you will have to enable the Hyper-V and Containers feature on it, and install the Docker EE preview. It can be installed with the following PowerShell script.

    As I use the Azure image, the Container feature and Docker EE has been enabled on it, and docker daemon has been configured as a Windows service. I don’t have to run the above script.

  3. Now you can follow the instruction here to configure the lcow. Specifically, I use the following script to configure it. I also update the configuration file in C:\ProgramData\Docker\config\daemon.json to enable the experimental feature of LinuxKit when docker service is started.

  4. Once you finish all the above configuration, you have enabled the lcow on Windows Server 1709. To test it, simply run

docker run --platform linux --rm -ti busybox sh

That is it. If you want, you can also try to run Ubuntu containers by following the instructions here.

电影 Mark Felt

不知道是不是由于特朗普上台后,美国政治气候的关系,最近接连看了两部去年拍摄的,以尼克松总统任期内的故事为背景的政治电影。一部是电影The Post,另一部是Mark Felt,在从西雅图回来的飞机上看的。

看电影之前,我并不知Mark Felt是谁。在飞机的娱乐系统中点开这部电影,纯粹是因为它的副标题,The Man Who Brought Down the White House。我还以为是一部虚构的枪战片呢。随着电影情节的发展,我渐渐觉得,这个Mark Felt难道就是大名鼎鼎的“深喉”?可是我对水门事件的了解有限,多年前在《美国宪政历程》这本书里,读到过尼克松的案子,水门事件是作为案子的背景介绍的。那本书出版时,真正的“深喉”,身份也还没有曝光。所以直到电影接近尾声,我才确定这个Mark Felt真的就是“深喉”本人。看完电影之后,我又好奇心起,去翻了翻水门事件和Mark Felt的资料。

The Post讲述的是新闻报道自由的重要性,这部电影则是在讲述独立调查权的重要性。电影开场Mark Felt已经是FBI的二号人物了,局长胡佛已经不过问FBI的日常运作,一切日常事务都是Felt在管理。白宫想要收买他,许以FBI局长的位子,但Felt并没有被收买。在胡佛去世之后,尼克松任命了FBI的局外人Patrick Grey来担任局长,并试图通过Grey来控制FBI。恰于此时,水门事件爆发了,白宫通知Grey,要终止水门事件的调查。在FBI的独立调查权受到威胁之际,Felt不得已,选择通过泄露消息给华盛顿邮报,来曝光尼克松和白宫的隐秘行动,最终导致了尼克松的下台。

这部电影是以Felt的自传为蓝本改编的。电影将Felt塑造为一个忠诚的FBI探员,一位爱国者。当Grey通知Felt,要终止水门事件的调查时,Felt愤怒地对Grey说,FBI不受干扰的调查权,是FBI最宝贵的资产,一旦失去了,就再也拿不回来了。但Felt选择做“深喉”,通过违反FBI原则的方式对新闻媒体爆料,到底是真的担心FBI的权力受损,还是因为没能当上FBI局长而做出的报复,一直存在争议。电影中有一幕,是Felt的妻子Audrey,在得知Felt没能当上FBI局长后,对Felt抱怨,三十多年,十三次搬家,Audrey自己放弃了事业追求,唯一的安慰是Felt有一天能坐上FBI局长的位子,结果现在却落空了。在这通抱怨之后,Felt开始动用特工寻找自己的女儿,也开始通过“深喉”来爆料,这或许暗示了Felt心理转变的过程。或许Felt的行动,并非完全出于对FBI调查权受损的担心,或是完全为了报复尼克松。更大的可能是,这二者兼而有之。

水门事件过去40多年后的今天,美国总统和FBI的关系又变得空前紧张。特朗普一上台就解雇了FBI局长科米,又不断通过Twitter批评副局长麦凯布,这些都没能阻止FBI的“通俄”门调查。最近,特朗普又公布了共和党的备忘录,指责司法部和FBI滥用调查权。这一切似乎又显示着总统对FBI独立调查权的不满和干预。

到底是FBI滥用调查权,还是总统干预独立调查权?会出现另一个“深喉”吗?接下来的发展,还真是让人期待呢。