使用Prosody作为服务端。轻量级、易于配置、资源占用少,非常适合初学者和小型社区。
系统准备
操作系统是安装在virtualbox虚拟机里面的debian11系统。因为我要使用虚拟机作为测试的服务器系统。我安装的是standard版,只有900MB,无图形界面。
配置debian11的设置,网络模式为桥接网卡,便于直接获取ip地址。
进入debian系统后,输入命令获取ip地址信息
ip addr
我的地址是192.168.10.11
安装Prosody
首先需要编辑apt源,在国内使用了清华大学的源比较快。把下面的语句加入到/etc/apt/sources.list文件里
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main non-free contrib
更新apt工具
sudo apt-get update
直接安装Prosody
sudo apt-get install prosody
安装好就可以了。
生成自签名证书
因为使用TLS安全连接,需要生成一个证书。这个本地测试生成自签名的证书,用户使用的时候会弹出证书不信任提示。正式使用需要在公网申请免费的 Let's Encrypt 证书。
Prosody 安装后有自动生成的默认证书是为 localhost 这个主机名签发的。但是测试的客户端尝试连接的是我的服务 192.168.10.11 这个IP地址。之后就会报错。
安全机制:TLS/SSL 协议有一个重要的安全特性,它会检查服务器证书中的主机名(Common Name 或 Subject Alternative Name)是否与客户端实际连接的主机名一致。如果不一致,就会抛出这个错误,以防止“中间人攻击”。
所以需要使用openssl为服务ip生成专属的证书,到prosody的证书目录下。
sudo openssl req -new -x509 -days 365 -nodes \
-out /etc/prosody/certs/192.168.10.11.crt \
-keyout /etc/prosody/certs/192.168.10.11.key \
-subj "/CN=192.168.10.11"
其中最重要的是CN=192.168.10.11,这就是之前查询的服务器的ip地址。命令执行完成后就会把证书生成在prosody的证书目录下
为了确保prosody能够访问证书,改变所有者为prosody
sudo chown prosody:prosody /etc/prosody/certs/192.168.10.11.crt
sudo chown prosody:prosody /etc/prosody/certs/192.168.10.11.key
证书文件 (.crt): 应该是全局可读的。
sudo chmod 644 /etc/prosody/certs/192.168.10.11.crt
私钥文件 (.key): 必须只能由所有者(即 prosody 用户)读取,其他任何用户都不能访问。
sudo chmod 600 /etc/prosody/certs/192.168.10.11.key
配置Prosody
使用vi编辑器编辑prosody的配置文件。
sudo vim /etc/prosody/prosody.cfg.lua
需要改一些东西:
主机地址就是改成自己的ip地址或者域名
VirtualHost "192.168.10.11"
指定证书和密钥文件的位置是之前生成的证书和密钥位置。
certificate = "/etc/prosody/certs/192.168.10.11.crt"
key = "/etc/prosody/certs/192.168.10.11.key"
允许用户注册账户
allow_registration = true
确保客户端加密连接服务器。如果为了测试可以设置false,但是实际使用不安全。
c2s_require_encryption = true
检查重要的模块启用
modules_enabled = {
"roster";
"saslauth";
"tls";
"dialback";
"disco";
"private";
"vcard";
"version";
"uptime";
"time";
"ping";
"pep";
-- 其他模块...
};
启动服务
sudo systemctl start prosody
重启服务
sudo systemctl restart prosody
检查服务状态
sudo systemctl status prosody
如果服务状态显示是active(running)状态没有报错就行了。
客户端登陆测试
在网站https://xmpp.org/ 可以找到很多可用的xmpp客户端
客户端登陆的账户,可以使用服务端命令创建账户
sudo prosodyctl register <用户名> <服务器域名> <密码>
由于服务端配置开启了注册允许。也可以使用客户端注册账户。
使用pc端的spark软件进行测试。首先可以点击Account注册用户,之后就登陆就行了
因为是自签名的证书,所以会提示是否信任,选择信任
之后登陆成功之后就能看到主页面
手机端使用yaxim登陆

在登陆界面点击advcance设置,自定义主机为服务器地址

之后可以选择注册或者登陆
在pc端直接输入手机端的账号,名字是fff@192.168.10.11,添加联系人,yaxim手机端会提示通过添加联系人。之后就可以互相发消息了。

主机名验证问题
客户端连接时候发现证书是错误的,不能验证主机名。检查证书发现与自己生成的证书不一样,是一个debian的有效期10年的证书。
prosody自己生成的证书信息就是这个。通过下面的openssl命令可以查看。
sudo openssl x509 -in /etc/prosody/certs/localhost.crt -text -noout
这说明prosody加载了默认的证书。检查配置文件/etc/prosody/prosody.cfg.lua,最后有一句
Include "conf.d/*.cfg.lua"
检查/etc/prosody/conf.d/,发现里面有个配置文件,localhost.cfg.lua,配置文件里面有一句
VirtualHost "localhost"
我直接注释了最后的代码,之后验证的证书是自己生成的了。
但是在某些客户端还是提示ssl证书验证有问题,尝试使用pc端的spark客户端连接服务,但是报错,不能验证主机名,关闭它的主机名验证之后才能登陆。
但是使用安卓端的yaxim、Conversations软件测试都通过了。
我不知道什么问题,可能还是ip地址+自签名的本地证书问题。真正部署使用域名+公网证书就没问题了。
应用
这是自建XMPP服务的测试。正确配置后可以作为公司或者组织的私有通讯系统。