xmpp简介-维护隐私安全

转自声网

弃用集中式的QQ和微信,改用邦联式的即时通信协议——XMPP简介

(注意:因为笔者不擅长写教程,本文可能经常更新,关注者请及时查阅最新版本。)

邦联式通信系统简介

国内的互联网服务越来越流氓,现在微信已经需要实名验证才能加入群聊。早在微信刚出来的时候,就非常流氓的会要求导入手机通讯录。同样的超级流氓,还包括QQ,因其封闭其他自由实现,而自身的Linux客户端早已废置。

这些即时通信系统之所以能够如此流氓,一个很重要的原因就是其集中式的架构。由于所有提供该即时通信服务的服务器、以及通信协议都被提供商控制着,客户端的接入权也就被提供商所垄断。

以 QQ 为例,因为 QQ 所有的服务器都掌握在麻花藤手中,用户“拒绝使用麻花藤的服务器”就等于要放弃使用 QQ 协议本身,当 QQ 上的联系人增加得越多、对其依赖性变得越来越强以后,面对随着软件和协议的更新不断增加的“负特性”(和“使用价值”相反,对用户有害的特性)对自己的侵害,用户就越难以选择一走了之;而麻花藤却能通过配置服务器随意封禁或禁言某个用户,完全阻断他和其他 QQ 用户的联系。

(我基本上没有用过 QQ 和微信,所以上面讲的主要是理论推测,不过我相信他们真正的罪恶要远远超过我的想象。还希望有受害者能出来现身说法,揭露这类国产集中式即时通信系统的累累罪行。)

提供商就这样获得了对用户为所欲为的特权。他们还常常通过不断改动通信协议来排挤负特性少的兼容客户端(这是 QQ 已确认的罪状),从而迫使用户选择同样受提供商控制、可以不断增加负特性的官方客户端。最终用户很难从提供商的动辄封禁、禁言和通过官方客户端侵犯隐私中保护自己——最近因为在微信上发言而被“请去喝茶”的事已屡见不鲜。整个系统就如同杰里米·边沁(没错,就是那个功利主义的边沁)设计的圆形监狱一般。

与此向反,在邦联式的通信系统——典型的如电子邮件——中,客户端与服务器、服务器之间的通信使用的是公开而标准化的协议——这保证了任何人都可以参考这些标准开发出可以和系统中其他组件互操作的组件——例如,常见的邮件客户端可用于访问任何使用 pop3 或 imap 收邮件、使用 smtp 发邮件的提供商,甚至可以自己搭建服务器,为自己提供服务,而换用服务提供者并不会使你失去与其他电子邮件用户的联系。

最成熟的邦联式即时通信系统——XMPP

那么,有没有邦联式,但又像 QQ 和微信那样实现即时通信的系统呢?早有了!我接下来要介绍的“可扩展消息与存在协议”(Extensible Messaging and Presence Protocol,缩写为 XMPP,曾用名 Jabber)早在 2000 年便已开始提供服务,后来在 2004 年成为国际标准RFC3920,有十分丰富的文档资料可供参考以实现其客户端和服务器,因此现在实现了这一协议的软件一点都不少,其中大部分还是自由软件。

早期的Google Talk也使用这个协议(但后来Hangout禁止了跨服务器间通讯,将其转化为集中式),Facebook Message也曾与此兼容(后来放弃了 XMPP,也转化为了集中式)。另外国产互联网服务里的新浪微博的私信功能是基于XMPP的,还有据称米聊、人人桌面和陌陌,也是XMPP/Jabber协议的实现(但往往是魔改过的,以转化为集中式)。

那么为什么如此优秀的通信协议却不怎么为人所知呢?一个很重要的原因就是:和集中式系统相比,邦联式系统对用户更加有利、更有助于用户保障自己的权利。如果一台服务器开始作恶,其下的用户可以简单地抛弃它、改用其他“善良”的服务器,甚至联合起来,共同架设服务器为自己服务。显然,资本家是不会喜欢这种不能对用户为所欲为的体系的。邦联式系统反倒更适合让无产者们通过它们联合起来——更适合成为无产者的物质力量。

客户端简介

我在这里推荐的客户端都是自由软件。主要的有:跨平台的 Pidgin (通过插件支持很多协议及扩展特性)、M$WIN 的 miranda IM(注意添加ssl/tls 插件)、Mac OS X 上的 adium (基本上就是该平台上的 pidgin,因为它就是 pidgin 的核心 libpurple 外面封了个 Mac OS X 的图形界面)、各种 UNIX(包括 GNU/Linux)上的pidgin、psi/psi+、empathy(尚不成熟,缺乏对下文要讲到的 OTR 安全协议的支持)、gajim 等等。

Android 上的客户端主要是 Conversations(因为比较长,有时会缩写为C11ns)和 Xabber。包括 Xabber 和 C11ns 在内的自由 Android 应用程序,笔者都建议通过 https://f-droid.org/ ;78 下载,它是一个由自由软件基金会的下属机构维护的,只提供自由软件的“软件商店”。您可以直接在网页上下载 apk,但我建议还是安装其首页的商店程序,通过它来管理更新等事务。

注意:Conversations 会引诱你在仅能免费试用六个月的conversations.im 上注册,建议您选择其他不收费的服务器注册账号。

IOS 上?chatsecure 的 ios 版可能算半个,不过并不好用,往往会丢消息,只有越狱并设法禁止自动挂起网络才能彻底解决这个问题——因为烂苹果这个自诩比用户自己还懂用户的需求的暴君通过一系列恶心的设计把为 ios 用户提供邦联化的即时通信服务这个本应仅仅需要一条持久TCP 连接和客户端断线时重连的工作变得难如登天——基本上想为 ios 实现即时通信服务就必须在一定程度上放弃邦联化,开发者还必须接受烂苹果的盘剥才能保证其用户能及时收到消息——这使得 ios 能用的即时通信服务基本上都是圆形监狱。所以,如果您是烂苹果的受害者,我作为马列主义者和自由软件实践者只好建议您卖掉 iThing 这个烂苹果的禁脔,换更便宜也更自由的 android 设备了。
(详情见此 12

注册账户

互联网上有很多开放的 XMPP 服务, https://list.jabber.at/ ;62 有一个列表;https://conversations.im/compliance/ ;21 也提供了一个列出支持特性的服务器列表,而且在正式尝试在服务器上注册帐号之前建议用 xmpp 观测站服务(https://xmpp.net/ ;24 和 https://check.messaging.one/ ;10 )检查一下服务器的特性(c2s 检查服务器面向客户端的表现,s2s 检查服务器互联时的表现。最好两个方面都检查)。笔者测试过的主要有 chinwag.im 、jabber.cat、xmpp.jp 、yax.im 等,不过不建议同志们在这几个服务器上扎堆,以免被针对封锁。

主观测站上的开放注册的服务器列表 39已经恢复,建议选用其中安全等级(最后两个字段)为A者注册自己的账户。

有些 XMPP 服务器在网页上提供注册功能,不过最常使用的还是通过客户端直接注册(可惜 xabber 无此功能)。注册时需要选定一台服务器、填写用户名和密码后,就可以得到形式和电子邮件地址类似——“用户名@服务器”——的身份标识——JID 了(有些客户端如 pidgin 甚至使用同一个界面来操作“创建新账号”和“添加现有账号”的功能,仅仅通过类似“在服务器上创建此账号”的选项来区分)。

在最基本的情况下,知道对方的 JID 就可以和对方用 XMPP 通信了,当然更方便的做法是将对方添加为自己的联系人。不过对方有可能不在线,因此你往往需要向对方提出申请,让他的客户端主动告知你他的在线状态(虽然大部分客户端都可以在将对方添加为联系人时自动向对方提出申请,同时自动向对方启用告知自身的在线状态,但还是有少数场景需要手动提出申请)。

XMPP 允许多个客户端同时登录一个账号,但此功能常常和下文要提到的端到端加密方案配合不好,因此个人不建议使用此特性,尽量保证同一时间只有一个客户端在线。

群聊

在一个支持群聊的服务器上建立一个聊天室(此操作一般都没有门槛),自己加入聊天室后再邀请别人加入(比较成熟的客户端支持收发“邀请群聊”的信令)就可以实现群聊了。聊天室可以加上准入口令、成员名单和权限控制以提高其安全性。
xmpp 的聊天室可以缓存一定数量(可配置)的消息并按顺序发送给新接入的用户。新来的消息会在缓存中自动替换掉最旧的,因此聊天室消息缓存最主要的用途是抵御意外断线,会议纪要还是要利用客户端的功能实现。

虽然我介绍过的客户端基本都装备了使用群聊(聊天室)的功能,但配置聊天室的功能(尤其是配置永久聊天室的功能)基本上只有在pidgin、psi/psi-plus 等桌面客户端上才比较完备。所以具体配置聊天室的方法请查阅下面讲 Pidgin 的章节。

文件传输

xmpp 分享文件的方式实际上相当丰富:可以借助 http 服务器分享,也可以端到端直传。但一般只有桌面客户端如 Pidgin、psi/psi-plus 才完整地实现了这些功能。
借助 http 服务器分享一般没有加密;端到端直传虽可选加密但大部分客户端没有实现。但这并不妨碍用户在传输前直接对欲传输的文件加密。然后在端到端加密保护的聊天通道内把解密方法告诉接收方——这也是笔者建议的做法。
xmpp 的端到端直传速度比较慢,因此对于大文件可以使用以 Firefox Send 8 为代表的一次性网盘服务中转——当然,在以传输而非分发为目的利用网盘时,同样建议上传前先加密文件(对 Firefox Send 加密可以省去,因为 ffsend 会在上传前对文件加密,就算是 ffsend 的服务器也无法解开;解密的密钥派生自下载链接最后以“#”号开头的部分,这部分是不会上传给服务器的,因此只有拿到下载链接的人才能进行解密。加密过程的详情见此 4)。

TLS 连接加密

xmpp 体系中至少可以有两种层次的加密:第一层是客户端到服务器,以及服务器之间的加密;第二层是 OTR 要实现的端到端加密。所以就算群聊无法使用端到端加密,如果所有参与的客户端到服务器,以及服务器之间的连接都是加密的话,还是能够抵御 xmpp 体系外的监听者。当然,连接加密无法抵御通过入侵服务器实现的监听——防御它是端到端加密的任务。
xmpp 的连接层加密是通过 TLS 实现的,尽管它在协议上是可选的(StartTLS 形式),但越来越多的服务器开始把它配置为必需——即会拒绝完全不支持或未启用连接加密的客户端或其他服务器接入。所以,若您使用的客户端有 TLS 相关选项,请尽可能配置成“强制加密”。(C11ns 没有 TLS 选项,但它是强制启用 TLS 加密的)
用我给出的 xmpp 观测站可以检查 xmpp 服务器对 TLS 的政策:c2s 是检查客户端到服务器的连接,s2s 是检查服务器间的互联,如果结果中有StartTLS: REQUIRED 就说明连接加密是强制启用的。

端到端加密-OTR协议

不留记录即时通讯 (Off-the-Record Messaging,缩写为OTR)是一种在任何能可靠地双向传输文本消息的低层协议(IRC、XMPP,理论上甚至 QQ、微信都满足这一要求)的基础上提供端到端加密支持的安全协议。该协议提供如下特性:
完备前向安全性:即便有人监听了全部会话并拿到了保存在端点的长寿命密钥也不能恢复会话的内容。
完整性和可抵赖性的统一:作为通信参与方,你可以确定某条消息的确是对方发出的;但中间的监听者却无法确定谁确实说过什么。
在首次使用 OTR 时需要生成(大部分客户端会自动为你生成)一对非对称的身份认证密钥,作为这一客户端的唯一标识。
OTR 的加密会话需要通过一个“握手”动作(一般在界面上体现为“启动加密会话”之类的字样,也有客户端如“C11ns”会在发送第一条消息时自动握手)来发起,在握手过程中你和对方会交换身份认证密钥的公钥部分并初始化其他一些参数,等片刻后握手完成,你就可以和对方说悄悄话了。在加密会话存续期间你还可以查看并验证对方的身份信息(身份认证密钥的“指纹”)。
OTR 严格为单端对单端设计,因此无法在群聊上工作,和多客户端登录同一账号的场景也有冲突。为了使用 OTR,建议同一时间只保留一个客户端处于登录状态。

注意:如果长时间(几个小时)未同对方交谈,则不保证通信双方的OTR 会话的状态仍然一致,因为在此期间,对方有可能下线,甚至切换账号的实例。所以,要不定期“刷新”会话状态(除 Conversations 外的大部分客户端都提供刷新 OTR 会话的功能),尤其是在最后一次交谈到现在已经“很久”的情况下。

基本上前文提到过的客户端都支持 OTR。

其他教程

https://tonghuix.io/2015/03/xmpp-chat/ ;23
https://beijinglug.club/wiki/lib … edia=xmpp-guide.pdf 14
OTR 协议原理及认证注意事项介绍:https://hardenedlinux.github.io/ … mpp_otr_debian.html 23

pidgin 使用注意事项

连续接待了几位同志,发现在 M$ Windows 上使用 pidgin 上 xmpp 的情况有一定代表性,故在此写一下如何在 M$WIN 上配置 pidgin。

获取 Pidgin

一定要从其官方网站(https://pidgin.im/ ;15 )或足够可靠的软件源(如GNU/Linux 发行版或 f-droid,可靠的 M$WIN 软件源则基本上只有“用途比较特别”的 cygwin 和 msys。)下载,否则得到的可能是被植入恶意代码的版本。这一点适用于所有单独下载自由软件的二进制可执行形式的场景。(如果是 GNU/Linux 用户通过包管理器下载软件包,则包管理器会自动为您校验其完整性;如果是单独下载源码后自行编译,也应校验源码包的完整性。)

添加账号

Pidgin 支持很多协议。如欲添加 xmpp 账号,请在“管理账号”对话框中点“添加”,“协议”选xmpp、“用户名”填@之前的部分,“域”填@之后的部分,再输入密码。
注册新账号和添加已有账号靠下方的“在服务器上创建此账号”选项区分。

TLS

强烈建议将账户配置的“高级”选项卡中的“连接安全性”选项设置为“需要加密”。

高优先级插件

如上文所述,pidgin 使用插件架构支持各种协议及其扩展,将插件文件(主体部分为动态链接库——在 M$WIN 上即为 dll)放入插件所在的目录(pidgin 的安装目录下的一个叫 plugins 的子目录),重新启动程序,即可在“工具”菜单下的“插件”对话框中启用并配置之。

OTR 插件

用于实现上文所述的 OTR 加密协议。
下载 https://otr.cypherpunks.ca/index.php#downloads ;7 中的 https://otr.cypherpunks.ca/binaries/windows/pidgin-otr-4.0.2.zip ;11 ,并将其全部内容放入 pidgin 的插件目录,插件名为 Off-the-Record Messaging,有额外选项。

一般收录了 pidgin 的 GNU/Linux 发行版都收录了该插件,因此GNU/Linux 用户可直接从包管理器中安装。

启用该插件后,对话窗口中即会出现 OTR 的菜单,且在私聊性质的会话标签的右下角会出现 OTR 的快捷按钮(该按钮同时起指示 OTR 当前状态的作用);其下的子菜单的头两项即为“启动/刷新私密对话(随 OTR 在当前会话中的状态而变)”和“结束私密对话”,用于控制 OTR 在当前会话中的状态。

插件的额外选项允许配置为“自动启动私密消息”和“要求私密消息”(类似下面介绍的 Conversations 的工作方式)。

OTR 启动后,默认的自动聊天记录归档会对该会话禁用(可通过插件的选项配置)。如仍需对该会话归档,请使用“对话”菜单中的“另存为”功能。

消息反馈插件

用于得知消息成功送达对方(以及成功解密,在使用 OTR 时),启用后成功送达的消息后面会出现对勾。
下载 https://app.assembla.com/spaces/pidgin-xmpp-receipts/documents ;15 中的 xmpp-receipts.dll 放入 pidgin 的插件目录即可,插件名为XMPP Receipts,无额外选项。

所用发行版未收录该插件的 GNU/Linux 用户可从 https://app.assembla.com/spaces/pidgin-xmpp-receipts/git/source ;5 复制源代码自行编译,将所得 xmpp-receipts.so 放入本用户的插件目录即可部署。

加入聊天室

点击“好友”菜单/“添加聊天”,在弹出的对话框中输入聊天室名(聊天室全名中@前部分)、服务器子域名(@后部分)、昵称、密码等参数即可加入已存在的聊天室。

配置聊天室

在 xmpp 体系中,聊天室等扩展服务一般绑定在服务器的子域名上,但对具体的某台服务器,扩展服务绑在什么样的子域名上却没有一定之规,而需要通过查询来确定。

Pidgin 的服务查询功能是由插件“服务目录信息(另译“服务信息目录”,英文为“XMPP Service Discovery”,插件文件名 xmppdisco)”实现的,此插件一般都和 Pidgin 主程序打包在一起,在“插件”对话框中启用它(可能已经默认启用),之后便可在“工具”菜单中找到“服务目录信息”子菜单。

一开始弹出的对话框是空空如也的,点击“浏览”按钮后输入欲查询的服务器并点击“在线服务”按钮(或按回车)即可开始查询其扩展服务。而在查询结果中,“描述”字段中有“Chatrooms”或“Multi User Chat(有时缩写为MUC)”的即是支持聊天室服务的子域名。

点击子域名左侧的三角形图标可以列出已经存在且允许搜索的聊天室。如欲新建聊天室,请选中子域名后点击“添加”按钮,即会弹出和加入已有聊天室时相同的界面,然而此时“服务器”一项的内容是您之前选中的子域名。

输入聊天室名(和昵称,默认与用户名一致)后点击“添加”即会在指定的服务器上按照输入的参数创建一个临时聊天室(或加入同名的已有聊天室)并将其加入您的 xmpp 通讯录中,同时您自动以输入的昵称加入其中,下面的两个选项“登录后自动加入”和“关闭标签后保持加入”(原文为英文)可酌情配置,并可随时在通讯录的右键菜单中调整。

临时聊天室以其名字为唯一标识,且不能设置准入条件,是一种临时的群聊手段。它会在最后一个用户退出后自动销毁(其内缓存的消息历史也会一并被销毁),并在有用户试图再次“加入”时自动以他的名义创建出来。如果希望为聊天室设置准入条件,就需要将其配置成永久聊天室。

与此相反,永久聊天室的配置(包括准入条件,成员名单及身份,缓存的消息历史等)会长期保存在服务器上,即使所有用户均已退出也是如此。如果想要销毁它,首先要将其变回临时聊天室。

新申请的聊天室总是临时的,而只有拥有“主人”身份者(一开始只有创建者具有该身份,不过可以分配给其他成员)才能配置聊天室的基本参数。如果打算建立永久聊天室,建议创建者在第一次退出前将聊天室设为永久,否则它被重新创建时所有权不一定还属于您。

Pidgin 通过命令来操作聊天室,所有命令均以“/”开头(模仿 irc 的风格),在聊天室的界面中当作消息发出即可使用(命令不是真正的消息,因此其他用户是看不见的),输入“/help” 可获得命令的帮助。

输入“/config”即可在弹出的对话框中配置聊天室的基本参数。勾选“Make Room Persistent?”即可将聊天室设为永久,勾除后又变回临时。其他重要选项包括:

“Make Room Public Searchable”:勾除后该聊天室无法通过“服务目录信息”搜索到,这样只有通过其他途径知道其存在者方能加入,如欲建立某种程度的内部聊天室,建议勾除该选项。

“Who May Discover Real JIDs?”:如设为“Anyone”则任何成员均可查询到其他成员的真实 JID,否则只有具有“司仪”角色(后文详述)者能知道其他成员的真实 JID,无此角色者仅能看到聊天室内的昵称。

Pidgin 的聊天室会话窗口中会在右侧显示其他成员的昵称,如果允许,右击查看信息时即可看到该成员的 JID,否则看到的只是他在聊天室中的身份。

密码:只有永久聊天室才能设置密码,设置后不知道密码者无法加入聊天室。

“Make Room Moderated?”:“会议模式”,改变非“成员”的默认角色,适合举办可公开旁听的在线会议。

“Make Room Menber-only”:勾选后,只有聊天室成员(包括主人和管理员)名单中的用户能加入聊天室,非成员则只有被管理员配置为成员后方可加入。

一些基本概念:

身份:分为“主人(Owner)”、“管理员(Admin)”、“成员”(Member),“无”四级的永久权限,(持续到聊天室被销毁),前者拥有后者的权限,且前三级共同构成广义的聊天室成员(所有的主人都是管理员;所有的管理员都是成员)。管理员可授予他人“司仪”的角色;。在 Pidgin 通过 “/affiliate” 命令来设置(管理员权限之一),还有一个“黑名单”(Outcast)身份用于封禁用户。

角色:分为“司仪”(Moderator)、“参会者”(Participant)、“旁听者”(Visitor)、“无”四级的临时权限(持续到用户退出聊天室),在“会议模式”中默认与后三级身份一致,否则非成员也默认有参会者角色。司仪可以调整参会者和旁听者的角色,旁听者不能发言。在 Pidgin 通过“/role” 命令来设置。

聊天室 ID 和昵称:形式为“聊天室名@子域.服务器”,其中的用户表现为“聊天室名@子域.服务器/昵称”的形式,可实现跨聊天室的私聊(一般也只有桌面客户端完整实现了可以启用 OTR 的跨聊天室私聊)。昵称和用户的真实 JID 独立,用户能否查询到他人的 JID 受角色和/或上述选项的控制。

邀请:我介绍过的客户端均实现了邀请某 JID 加入聊天室的功能。Pidgin 的实现是把用户列表中的用户拖到聊天室的窗口里。

注意:如果您是被邀请加入聊天室的,Pidgin 并不会把聊天室信息自动加到通讯录里,而要通过“对话”菜单下的“添加”功能手动保存。

XMPP 聊天室功能博大精深,笔者在这里写出的仅为冰山一角:4_93:。欲进一步了解 xmpp 群聊(聊天室),请参阅 https://xmpp.org/extensions/xep-0045.html ;19 (英文)。

来自 科创茶话
2019-2-13 11:59:53
1楼

这东西太古老了,用起来也不方便。可以了解下mtproto协议,有非常好的开源客户端实现。服务端找个兼容的开源实现就行了。

折叠评论
加载评论中,请稍候...
折叠评论
2楼

感觉KC可以搞一个?233

折叠评论
加载评论中,请稍候...
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

ID:{{user.uid}}
{{user.username}}
{{user.info.certsName}}
{{user.description}}
{{format("YYYY/MM/DD", user.toc)}}注册,{{fromNow(user.tlv)}}活动
{{submitted?"":"投诉"}}
请选择违规类型:
{{reason.description}}
支持的图片格式:jpg, jpeg, png