搭建私有即时通讯服务--使用Prosody搭建XMPP服务器并且实现XMPP客户端注册使用测试

⌚Time: 2025-09-05 19:45:00

👨‍💻Author: Jack Ge

使用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服务的测试。正确配置后可以作为公司或者组织的私有通讯系统。