Prosody IM 13.0.7 常用 CLI 命令详解
prosodyctl 13.0.7 全量子命令实测详解:status/version/about/check、adduser/passwd/deluser、cert 证书五子命令、社区插件 install/list/remove,以及 shell 管理控制台 user/module/c2s/s2s/muc/config/stats 等全部分区命令的真实回显、在线会话实测与 8 条排障实录。
Prosody IM 13.0.7 常用 CLI 命令详解
目标:逐条实测 Prosody IM 13.0.7 管理命令行工具
prosodyctl的全部子命令——服务状态、用户管理、证书管理、社区插件管理,以及内置管理控制台(shell)各分区命令,每条命令均给出真实执行回显与边界行为。已在 Ubuntu 22.04 + Prosody 13.0.7(安装方法见 《Ubuntu 22.04 安装 Prosody IM 13.0.7 指南》)实测通过,全部命令与回显均为真实执行记录。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64);
- 软件版本:Prosody IM 13.0.7(包版本
13.0.7-1~jammy2),systemd 托管; - 示例 XMPP 域名:
xmpp.example.com,MUC 组件域名:chat.example.com; - 示例管理员:
admin@xmpp.example.com,密码q1w2e3r4; - 关键路径:数据
/var/lib/prosody/、日志/var/log/prosody/、证书/etc/prosody/certs/、模块/usr/lib/prosody/modules/; - 相关文档:《Prosody IM 13.0.7 配置参数详解》(配置文件参数)、《Prosody IM 13.0.7 介绍与选型指南》(架构与选型)。
二、工具概览
2.1 prosodyctl 在管理工具体系中的定位
Prosody 13.0.7 的日常管理有四条通道,prosodyctl 是其中唯一的服务器本地命令行入口:
| 通道 | 形态 | 适用场景 |
|---|---|---|
prosodyctl <子命令> | 本地 CLI,一次性执行 | 用户增删、证书、插件安装、状态检查 |
prosodyctl shell | 本地控制台(可交互、可单次执行) | 会话管理、模块热加载、房间管理、实时诊断 |
systemd(systemctl) | 服务托管层 | 启停服务、开机自启、日志查看 |
| XMPP ad-hoc 命令 | 客户端内管理 | 有管理客户端时的远程管理(需 admin_adhoc 模块) |
💡 说明:
prosodyctl与systemctl分工明确——服务的启停、开机自启由 systemd 托管(systemctl start/stop/restart prosody),而prosodyctl负责服务器内容层面的管理(账号、证书、插件、诊断)。prosodyctl自带的reload只重载配置,服务进程仍由 systemd 管理。
2.2 主命令清单
prosodyctl --help 实测全量输出:
Danger, Will Robinson! Prosody doesn't need to be run as root, so don't do it!
For more information on running Prosody as root, see https://prosody.im/doc/root
prosodyctl - Manage a Prosody server
Usage: /usr/bin/prosodyctl COMMAND [OPTIONS]
Where COMMAND may be one of:
Process management:
reload Reload Prosody's configuration and re-open log files
status Reports the running status of Prosody
shell Interact with a running Prosody
User management:
adduser JID Create the specified user account in Prosody
passwd JID Set the password for the specified user account in Prosody
deluser JID Permanently remove the specified user account from Prosody
Plugin management:
install Installs a prosody/luarocks plugin
remove Removes a module installed in the working directory's plugins folder
list Shows installed rocks
Informative:
check Perform basic checks on your Prosody installation
version [-v] Show current Prosody version, or more
Other:
cert Certificate management commands
about Show information about this Prosody installation
首行 "Danger, Will Robinson!" 是因为以 root 身份执行了 prosodyctl --help:Prosody 提示自身无需 root 运行(服务以 prosody 用户跑)。该提示只是提醒,不影响命令执行;用户管理等写操作需要 root 或 sudo。
主命令与章节对应关系:
| 分组 | 命令 | 详解位置 |
|---|---|---|
| Process | reload / status / shell | 第四章、第六章 |
| User | adduser / passwd / deluser | 第五章 |
| Plugin | install / remove / list | 第八章 |
| Informative | check / version | 第四章 |
| Other | cert / about | 第七章、第四章 |
2.3 管理控制台命令地图
prosodyctl shell 进入交互式管理控制台,也支持把命令直接作为参数一次执行(本文实测均用一次执行形态:prosodyctl shell <命令>)。控制台内 help 列出全部 22 个命令分区(实测):
Commands are divided into multiple sections. For help on a particular section,
type: help SECTION (for example, 'help c2s'). Sections are:
Section | Description
c2s | Commands to manage local client-to-server sessions
config | Reloading the configuration, etc.
cron | View and manage recurring tasks
debug | Commands for debugging the server
dns | Commands to manage and inspect the internal DNS resolver
help | Show this help about available commands
host | Commands to activate, deactivate and list virtual hosts
http | Commands to inspect HTTP services
invite | Create and manage invitations
limits | Commands to inspect rate-limiting state
migrate | Perform data migrations
module | Commands to load/reload/unload modules/plugins
muc | Commands to create, list and manage chat rooms
output | Configure admin console output
port | Commands to manage ports the server is listening on
pubsub | Manage publish/subscribe nodes
role | Role and access management
roster | View and manage user rosters (contact lists)
s2s | Commands to manage sessions between this server and others
server | Uptime, version, shutting down, etc.
stats | Commands to show internal statistics
user | Commands to create and delete users, and change their passwords
watch | Commands for watching live logs from the server
xmpp | Commands for sending XMPP stanzas
各分区详解见第六章;migrate 分区在数据迁移场景使用(本文环境未涉及),output 分区控制台输出格式调整(帮助内容为空)。
三、前置条件
- 已按部署篇完成 Prosody 13.0.7 安装、证书归位并以 systemd 托管(服务
active); - 已创建至少一个管理员账号(本文用
admin@xmpp.example.com); - 控制台命令(
prosodyctl shell)要求配置中启用admin_shell模块(默认配置已含); - 全文示例域名与账号均为本文实验环境的真实取值,套用时替换为读者自己的域名/JID。
四、服务状态与信息类命令
4.1 prosodyctl status:运行状态
日常巡检第一条命令,确认服务进程与 PID:
prosodyctl status
实测回显(服务正常时):
Prosody is running with PID 5663
服务停止时实测:
Prosody is not running
服务因配置错误启动失败时,status 会提示读取系统日志(并给出 systemctl status prosody 建议),此时结合 journalctl -u prosody --no-pager | tail -20 定位。
4.2 prosodyctl version:版本号
prosodyctl version
实测回显:
Prosody 13.0.7
加 -v 输出运行环境全量明细(目录、Lua 环境、依赖库版本),排障时非常有用:
prosodyctl version -v
实测回显(全量):
Prosody 13.0.7
# Prosody directories
Data directory: /var/lib/prosody
Config directory: /etc/prosody
Source directory: /usr/lib/prosody
Plugin directories:
/var/lib/prosody/custom_plugins - not a directory!
/usr/lib/prosody/modules/
# Operating system
Linux 6.8.0-138-generic
# Lua environment
Lua version: Lua 5.4
Lua module search paths:
/usr/lib/prosody/prosody/?.lua
/usr/lib/prosody/?.lua
/usr/local/share/lua/5.4/prosody/?.lua
/usr/local/share/lua/5.4/?.lua
/usr/local/share/lua/5.4/prosody/?/init.lua
/usr/local/share/lua/5.4/?/init.lua
/usr/local/lib/lua/5.4/prosody/?.lua
/usr/local/lib/lua/5.4/prosody/?/init.lua
/usr/share/lua/5.4/prosody/?.lua
/usr/share/lua/5.4/prosody/?/init.lua
/usr/share/lua/5.4/?.lua
/root/.luarocks/share/lua/5.4/?.lua
/root/.luarocks/share/lua/5.4/?/init.lua
/var/lib/prosody/custom_plugins/share/lua/5.4/?.lua
/var/lib/prosody/custom_plugins/share/lua/5.4/?/init.lua
Lua C module search paths:
/usr/lib/prosody/prosody/?.so
/usr/lib/prosody/?.so
/usr/local/lib/lua/5.4/prosody/?.so
/usr/lib/x86_64-linux-gnu/lua/5.4/prosody/?.so
/usr/lib/x86_64-linux-gnu/lua/5.4/?.so
/usr/lib/lua/5.4/prosody/?.so
/usr/lib/lua/5.4/?.so
/usr/local/lib/lua/5.4/loadall.so
/root/.luarocks/lib/lua/5.4/?.so
/var/lib/prosody/custom_plugins/lib/lua/5.4/?.so
LuaRocks: Installed (2.x+)
# Network
Backend: epoll
# Lua module versions
LuaDBI: 0.7
LuaExpat: 1.3.0
LuaFileSystem: 1.8.0
LuaSec: 1.0.2
LuaSocket: 3.0-rc1
luaunbound: 1.0.0
readline: 2.9
# library versions
libcrypto: OpenSSL 3.0.2 15 Mar 2022
libunbound: 1.13.1
要点:Lua version: Lua 5.4 一行可验证部署篇修正解释器的成果;LuaDBI/LuaSec 等依赖版本是 SQL 存储与 TLS 问题排查的依据(详见《Prosody IM 13.0.7 配置参数详解》5.5 节的 LuaDBI 排障实录)。
4.3 prosodyctl about:安装信息
about 输出与 version -v 相同的全量环境信息(目录/Lua/网络后端/依赖版本),可任选其一。实测(节选,与 4.2 输出一致):
prosodyctl about | head -8
Prosody 13.0.7
# Prosody directories
Data directory: /var/lib/prosody
Config directory: /etc/prosody
Source directory: /usr/lib/prosody
Plugin directories:
/var/lib/prosody/custom_plugins - not a directory!
/usr/lib/prosody/modules/
4.4 prosodyctl check:安装体检
对配置、DNS、证书做全面自检,改配置后、加域名后、证书更换后都应执行一遍:
prosodyctl check
实测回显(全量,本文环境含实验域名的 DNS 警告属预期——实验环境无公网 DNS 记录):
Checking config...
Suggestion: If xmpp.example.com is a new host with no real users yet, consider renaming it now to
example.com. You can use SRV records to redirect XMPP clients and servers to xmpp.example.com.
For more information see: https://prosody.im/doc/dns
Some of your hosts may be missing features due to a lack of configuration.
For more details, use the 'prosodyctl check features' command.
Done.
Checking DNS for component chat.example.com...
Host chat.example.com does not seem to resolve to this server (IPv4/IPv6)
Checking DNS for host xmpp.example.com...
HTTP service xmpp.example.com has no A/AAAA record. Create one or change 'http_host' to the correct host.
Host xmpp.example.com does not seem to resolve to this server (IPv4/IPv6)
Checking certificates...
Checking certificate for chat.example.com
No 'certificate' found for chat.example.com
Checking certificate for xmpp.example.com
Certificate: /etc/prosody/certs/xmpp.example.com.crt
For more information about certificates please see https://prosody.im/doc/certificates
Problems found, see above.
逐段解读:Checking config 段含 Lua 语法与配置合法性检查(语法错误会在这一步精确报行号,实测案例见《Prosody IM 13.0.7 配置参数详解》FAQ-1);Checking DNS 段验证各域名能否解析到本机,生产环境应全部通过(实验域名无 DNS 记录故报警);Checking certificates 段确认每个主机都有证书,chat.example.com 的警告在第七章 cert import 实测后可消除。
check 有子命令,最常用的是功能完整度报告:
prosodyctl check features
实测回显(全量):
Feature report
xmpp.example.com
OK Basic functionality
Support for secure connections, authentication and messaging
OK Mobile optimizations
Help mobile clients reduce battery and data usage
OK User profiles
Enable users to publish profile information
OK Blocking
Block communication with chosen entities
OK Push notifications
Receive notifications on platforms that don't support persistent connections
(!) Multi-device messaging and data synchronization
Multiple clients connected to the same account stay in sync
Suggested modules:
- mam: https://prosody.im/doc/modules/mod_mam
(!) Web connections
Allow connections from browser-based web clients
Suggested modules:
- websocket: https://prosody.im/doc/modules/mod_websocket
(!) Audio/video calls and P2P
Assist clients in setting up connections between each other
Suggested modules:
- turn_external: https://prosody.im/doc/modules/mod_turn_external
(!) File sharing
Sharing of files to groups and offline users
Suggested component:
-- Documentation: https://prosody.im/doc/modules/mod_http_file_share
Component "share.xmpp.example.com" "http_file_share"
If you have already configured any of these components, they may not be
linked correctly to xmpp.example.com. For more info see https://prosody.im/doc/components
(!) Group chats
Create group chats and channels
Component "chat.example.com" is missing the following modules: mam
Add the missing modules to your modules_enabled under the Component, like this:
-- Documentation: https://prosody.im/doc/modules/mod_muc
Component "chat.example.com" "muc"
modules_enabled = {
...
"mam"; -- Add this!
}
要点:OK 项是当前配置已具备的能力;(!) 项给出缺失功能与可直接照抄的补齐建议(模块名/组件配置),是扩展功能时的最佳路线图。建议中的配置块中间部分本文以 ... 略去(完整建议在真实输出中为默认模块全集,照抄时以实际回显为准)。
4.5 prosodyctl reload:配置重载
prosodyctl reload
实测回显:
OK: Config reloaded (you may need to reload modules to take effect)
reload 等价于向服务进程发送 SIGHUP(日志可见 startup info Received SIGHUP):热载配置与重开日志文件,不换 PID、不断连接。注意与 systemctl reload prosody 效果相同,二选一即可;模块增删、VirtualHost 变更等结构性修改 reload 无效,必须 systemctl restart prosody(实测对照见《Prosody IM 13.0.7 配置参数详解》3.2 节)。
五、用户管理命令
5.1 prosodyctl adduser:交互式创建账号
adduser 以「JID」为参数,交互式询问两遍密码:
prosodyctl adduser lihua@xmpp.example.com
实测回显(密码经管道输入,交互终端下为隐藏输入):
Enter new password:
Retype new password:
OK: Created lihua@xmpp.example.com with role 'prosody:member'
exit=0
要点:账号默认授予 prosody:member 角色(普通成员);JID 必须写成「用户名@域名」全称,且域名必须是配置中已声明的 VirtualHost。重复创建同名账号的实测:
Error: User exists
exit=1
5.2 prosodyctl passwd / deluser:改密与删除
改密码(同样交互式两遍密码):
prosodyctl passwd lihua@xmpp.example.com
实测回显:
Enter new password:
Retype new password:
OK: User password changed
exit=0
对不存在的账号执行 passwd:
Error: No such user
exit=1
删除账号:
prosodyctl deluser wangwei@xmpp.example.com
实测回显:
OK: User deleted
exit=0
重复删除:
Error: No such user
exit=1
5.3 register:旧式一次性创建(含密码参数)
adduser 的交互形态不便脚本化,13.0 仍保留旧式 register 写法:prosodyctl register <用户名> <域名> <密码>,密码直接作参数:
prosodyctl register wangwei xmpp.example.com q1w2e3r4
实测回显:
usermanager info User account created: wangwei@xmpp.example.com
exit=0
⚠️ 注意:
register形态会把密码留在 shell 历史里,交互终端建议用adduser;脚本化批量开户时注意清理历史或使用HISTCONTROL。
5.4 数据落盘形态
账号创建后以「URL 编码域名」目录存储,验证:
find /var/lib/prosody -path "*accounts*" -name "*.dat"
实测回显:
/var/lib/prosody/xmpp%2eexample%2ecom/accounts/lihua.dat
/var/lib/prosody/xmpp%2eexample%2ecom/accounts/admin.dat
/var/lib/prosody/xmpp%2eexample%2ecom/accounts/wangwei.dat
域名中的 . 被编码为 %2e,每个账号一个 .dat 文件(默认 internal 存储,SCRAM 哈希格式);切换 SQL 后端后的落库形态见《Prosody IM 13.0.7 配置参数详解》5.5 节。
六、管理控制台 shell 详解
6.1 两种用法
prosodyctl shell 有两种用法。交互式:直接执行 prosodyctl shell 进入控制台(横幅如下,Ctrl+D 退出):
____ \ / _
| _ \ _ __ ___ ___ _-_ __| |_ _
| |_) | '__/ _ \/ __|/ _ \ / _` | | | |
|_| |_| \___/|___/\___/ \__,_|\__, |
A study in simplicity |___/
Welcome to the Prosody administration console. For a list of commands, type: help
You may find more help on using this console in our online documentation at
https://prosody.im/doc/console
一次执行式:把命令作为参数直接跟在 shell 后(本文全部采用此形态,便于脚本化):
prosodyctl shell <分区> <命令> [参数...]
💡 说明:控制台命令分区在前、子命令在后(如
user list、c2s show),与--help里的c2s:show冒号写法含义相同;一次执行形态统一用空格分隔。每个分区可用prosodyctl shell help <分区>查看该分区全部命令与参数说明。
6.2 user 分区:账号管理
user 分区是第五章 CLI 用户命令的增强版,全部命令支持非交互参数化。逐条实测:
prosodyctl shell user list xmpp.example.com
lihua@xmpp.example.com
admin@xmpp.example.com
OK: Showing all 2 users
支持模式过滤(第二参数):
prosodyctl shell user list xmpp.example.com zh
zhangsan@xmpp.example.com
OK: Showing 1 of 3 users
创建账号(第三个参数为角色,可省略默认 prosody:member):
prosodyctl shell user create zhangsan@xmpp.example.com q1w2e3r4 prosody:member
OK: Created zhangsan@xmpp.example.com with role 'prosody:member'
查看账号角色:
prosodyctl shell user role admin@xmpp.example.com xmpp.example.com
OK: prosody:operator
查看账号最后活跃时间:
prosodyctl shell user activity lihua@xmpp.example.com
OK: No activity
禁用/启用账号(禁用后拒绝登录、不删数据):
prosodyctl shell user disable zhangsan@xmpp.example.com
prosodyctl shell user enable zhangsan@xmpp.example.com
OK: User disabled
OK: User enabled
改密码与删除(与第五章 CLI 等效,但完全非交互):
prosodyctl shell user password zhangsan@xmpp.example.com q1w2e3r4
prosodyctl shell user delete zhangsan@xmpp.example.com
OK: User password changed
OK: User deleted
排查长期不上线的账号(时长支持 30d/12h 等后缀):
prosodyctl shell user list_inactive xmpp.example.com 30d
OK: 0 accounts inactive since 2026-09-21T11:17:32
💡 技术拓展:Prosody 的账号角色体系——
user create的角色参数与user role的输出对应以下内置角色(prosodyctl shell role list xmpp.example.com实测):prosody:operator prosody:admin prosody:member prosody:registered prosody:guest OK: Showing 5 roles on xmpp.example.com
角色 权限边界 典型用途 prosody:operator服务器级全权(本文 admin 账号即此角色) 服务管理员 prosody:admin域级管理(ad-hoc、广播等) 域管理员 prosody:member普通注册用户( adduser默认)内部成员 prosody:registered自助注册的受限用户 开放注册服务器 prosody:guest最小权限访客 访客账号 本文实际使用默认
prosody:member(普通账号)与prosody:operator(管理账号)两档。
6.3 host 分区:虚拟主机
prosodyctl shell host list
chat.example.com (muc component)
xmpp.example.com
OK: 2 hosts
运行时激活一个新域名(无需改配置文件与重启,立即生效):
prosodyctl shell host activate lab.example.net
prosodyctl shell host list
Result: true
chat.example.com (muc component)
xmpp.example.com
lab.example.net
OK: 3 hosts
停用(会断开该域名上的全部客户端):
prosodyctl shell host deactivate lab.example.net
prosodyctl shell host list
Result: true
chat.example.com (muc component)
xmpp.example.com
OK: 2 hosts
⚠️ 注意:
host activate是运行时激活,不写入配置文件——服务重启后消失。要永久启用域名仍需在配置中添加VirtualHost段。
6.4 module 分区:模块热管理
列出某主机已加载的模块:
prosodyctl shell module list xmpp.example.com
实测回显(全量,45 项):
xmpp.example.com:
account_activity
adhoc
admin_adhoc
admin_shell
auth_internal_hashed
authz_internal
blocklist
bookmarks
bosh
c2s
carbons
cloud_notify
cron
csi
csi_simple
dialback
disco
http
http_altconnect
invites
invites_adhoc
invites_register
iq
limits
message
offline
pep
ping
presence
private
register
register_ibr
register_limits
roster
s2s
saslauth
smacks
storage_internal
time
tls
tokenauth
uptime
user_account_management
vcard4
vcard_legacy
version
Result: nil
MUC 组件主机的模块列表(Component "chat.example.com" "muc" 段):
chat.example.com:
adhoc
admin_shell
authz_internal
dialback
disco
iq
muc
muc_unique
s2s
saslauth
smacks
storage_internal
tls
vcard
Result: nil
查看单个模块详情:
prosodyctl shell module info tls xmpp.example.com
on VirtualHost "xmpp.example.com"
path: /usr/lib/prosody/modules/mod_tls.lua
status: [core] Loaded
Result: true
热加载模块(示例:加载 WebSocket 支持,无需重启):
prosodyctl shell module load websocket xmpp.example.com
Loaded for *
Note: Module will not be loaded after restart unless enabled in configuration
OK: Module loaded onto 1 host
卸载:
prosodyctl shell module unload websocket xmpp.example.com
Unloaded from *
Unloaded from xmpp.example.com
OK: Module unloaded from 2 hosts
加载不存在的模块实测:
prosodyctl shell module load nosuchmod xmpp.example.com
/usr/lib/prosody/modules/share/lua/5.4/mod_nosuchmod/mod_nosuchmod.lua: No such file or directory
Error: Last error: /usr/lib/prosody/modules/share/lua/5.4/mod_nosuchmod/mod_nosuchmod.lua: No such file or directory
⚠️ 注意
module load的提示行:"Module will not be loaded after restart unless enabled in configuration"——热加载只对当前进程有效,永久启用必须在配置modules_enabled中添加并重启(详见《Prosody IM 13.0.7 配置参数详解》5.6 节)。
6.5 c2s 分区:客户端会话管理
c2s(client-to-server)分区管理本地客户端的在线会话。命令输出需要「有会话在线」才有内容,先准备一个在线客户端:任意 XMPP 客户端(Gajim、Pidgin 等)以 admin@xmpp.example.com 登录即可。无图形客户端时,可用以下最小 Python 脚本(标准库实现 STARTTLS + SASL PLAIN + bind,登录后保持在线 60 秒):
#!/usr/bin/env python3
# xmpp_hold.py —— 最小在线会话:登录后保持 60 秒,期间在另一终端执行 c2s show
import socket, ssl, base64, time
HOST, PORT, DOMAIN, USER, PASS = "127.0.0.1", 5222, "xmpp.example.com", "admin", "q1w2e3r4"
STREAM = ("<?xml version='1.0'?><stream:stream to='%s' xmlns='jabber:client' "
"xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>" % DOMAIN)
def rx(s, tag):
data = b""; s.settimeout(5)
try:
while True:
chunk = s.recv(65536)
if not chunk: break
data += chunk
if b"success" in data or b"failure" in data or b"result" in data or b"</stream:features>" in data:
break
except socket.timeout:
pass
print("[%s] %s" % (tag, data.decode(errors="replace")[:200]))
s = socket.create_connection((HOST, PORT), timeout=5)
s.sendall(STREAM.encode()); rx(s, "features")
s.sendall(b"<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"); rx(s, "proceed")
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT); ctx.check_hostname = False; ctx.verify_mode = ssl.CERT_NONE
t = ctx.wrap_socket(s, server_hostname=DOMAIN)
print("[tls]", t.version(), t.cipher()[0])
t.sendall(STREAM.encode()); rx(t, "features2")
tok = base64.b64encode(("\0" + USER + "\0" + PASS).encode()).decode()
t.sendall(("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>%s</auth>" % tok).encode()); rx(t, "auth")
t.sendall(STREAM.encode()); rx(t, "features3")
t.sendall(("<iq type='set' id='b1'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>cli</resource></bind></iq>").encode()); rx(t, "bind")
print("[hold] 在线 60 秒"); time.sleep(60); t.close()
实测(另一终端登录会话在线后)会话数统计:
prosodyctl shell c2s count
OK: Total: 1 clients
列出全部会话:
prosodyctl shell c2s show
Session ID | JID | Role | IPv | Status | Security | SM | CSI State
c2s60b9f00fc2a0 | admin@xmpp.example.com/cli-doc | operator | IPv4 | | TLSv1.3 | no |
OK: 1 c2s sessions shown
逐列解读:Session ID 为会话唯一标识(排障时与日志行 c2s60b9f00fc2a0 对应);JID 含客户端资源名;Security 列显示 TLS 版本;SM 列为流恢复(XEP-0198)协商状态;CSI State 为客户端节能状态。
查看会话加密细节:
prosodyctl shell c2s show_tls admin@xmpp.example.com
JID | Session ID | Security | Encryption
admin@xmpp.example.com/cli-doc | c2s60b9f00fc2a0 | TLSv1.3 | TLS_AES_256_GCM_SHA384
OK: 1 c2s sessions shown
强制断开指定用户的全部会话(踢线):
prosodyctl shell c2s close admin@xmpp.example.com
OK: Total: 1 sessions closed
断开后稍候复查确认:
prosodyctl shell c2s show
Session ID | JID | Role | IPv | Status | Security | SM | CSI State
OK: 0 c2s sessions shown
服务端踢线的客户端侧感知(Python 脚本日志实测):连接收到 TLS EOF(ssl.SSLZeroReturnError: TLS/SSL connection has been closed (EOF)),即服务端优雅关闭流。
c2s closeall 关闭服务器上全部客户端会话(维护窗口前使用)。
6.6 s2s 分区:服务器互联会话
s2s(server-to-server)分区管理与其他 XMPP 服务器的联邦会话。无联邦对端时:
prosodyctl shell s2s show
Session ID | Host | Dir | Remote | IPv | Security | SASL | Dialback
OK: 0 s2s connections shown
实测与公网 XMPP 服务器 jabber.org 建立出站联邦连接(向对端域用户发送 ping 触发 s2s 拨号):
prosodyctl shell xmpp ping admin@xmpp.example.com demo@jabber.org
Session s2sout58c709aa71f0 (xmpp.example.com-->jabber.org) connected (1.6065s)
连接建立后查看 s2s 会话状态:
prosodyctl shell s2s show
Session ID | Host | Dir | Remote | IPv | Security | SASL | Dialback
s2sout58c709aa71f0 | xmpp.example.com | --> | jabber.org | IPv4 | TLSv1.3 | | Initiated
OK: 1 s2s connections shown
要点:Dir 列 --> 表示出站连接;Security 列显示 TLSv1.3 加密;Dialback 列 Initiated 表示域名所有权回拨验证进行中(对端验证通过后进入正常消息交换)。关闭全部联邦连接:
prosodyctl shell s2s closeall xmpp.example.com
OK: Closed 1 s2s session
s2s close <from> <to> 可精确断开某一对域名间的连接;s2s show_tls <域名> 查看联邦连接加密细节。
6.7 muc 分区:聊天室管理
列出 MUC 组件上的房间(初始为空):
prosodyctl shell muc list chat.example.com
OK: 0 rooms
创建房间(房间 JID = 房间名@组件域名):
prosodyctl shell muc create dev-room@chat.example.com
prosodyctl shell muc create meeting-room@chat.example.com
Result: MUC room (dev-room@chat.example.com)
Result: MUC room (meeting-room@chat.example.com)
再次列出:
prosodyctl shell muc list chat.example.com
meeting-room@chat.example.com
dev-room@chat.example.com
OK: 2 rooms
查看房间成员与身份列表(空房间):
prosodyctl shell muc occupants dev-room@chat.example.com
prosodyctl shell muc affiliations dev-room@chat.example.com
OK: 0 out of 0 occupants listed
OK: 0 out of 0 affiliationss listed
(affiliationss 三连 s 为 13.0.7 输出原样。)
⚠️ 注意:
help muc列出的命令只有affiliations/create/list/occupants/room五个,没有房间销毁命令——实测执行不存在的muc destroy会得到:Error: Command not found or necessary module not loaded. Try 'help muc for a list of available commands.而
muc room <房间JID>只返回房间对象引用,不能链式销毁(实测prosodyctl shell muc room meeting-room@chat.example.com destroy仅输出Result: MUC room <meeting-room@chat.example.com>,房间仍在)。删除房间需在 XMPP 客户端内由房间所有者执行销毁操作。
6.8 config 分区:运行时配置查看与修改
config get 查看运行中的配置值(* 表示全局段):
prosodyctl shell config get "*" limits
prosodyctl shell config get xmpp.example.com authentication
OK: {
c2s = {
rate = "10kb/s";
};
s2sin = {
rate = "30kb/s";
};
}
OK: "internal_hashed"
config set 运行时修改(不写入配置文件):
prosodyctl shell config set "*" archive_expires_after 2w
prosodyctl shell config get "*" archive_expires_after
Result: true
OK: "2w"
执行 config reload 后运行时值回落为配置文件中的值(实测闭环):
prosodyctl shell config reload
prosodyctl shell config get "*" archive_expires_after
OK: Config reloaded (you may need to reload modules to take effect)
OK: "1w"
⚠️ 注意三点:
config set是纯运行时修改,重启后失效,要持久化必须改配置文件;config reload等价prosodyctl reload,且如提示所说明——配置重载后部分模块需要单独 reload 才感知新值。
6.9 dns 分区:内部解析器
prosodyctl shell dns lookup xmpp.example.com A
prosodyctl shell dns cache
OK: Status: No Error
OK: Cache:
nil
dns lookup <名称> <类型> 用 Prosody 内置解析器(luaunbound)做 DNS 查询,诊断联邦失败(对端 SRV/A 记录缺失)时使用;dns cache/dns purge 查看与清空解析缓存;dns addnameserver/dns setnameserver 调整解析器使用的上游。
6.10 roster 分区:花名册(联系人列表)
管理员可直接读写用户的花名册,实测让两个账号互为联系人:
prosodyctl shell roster subscribe lihua@xmpp.example.com admin@xmpp.example.com
prosodyctl shell roster subscribe admin@xmpp.example.com lihua@xmpp.example.com
prosodyctl shell roster show lihua@xmpp.example.com
Result: true
Result: true
admin@xmpp.example.com sub=both ask=none
OK: Showing 1 entries
sub=both 表示双方互已订阅。其余命令:roster subscribe_both 一步建立双向订阅、roster unsubscribe/unsubscribe_both 取消订阅、roster clean 清理失效联系人。
6.11 server / port / http / cron 分区
服务运行信息:
prosodyctl shell server uptime
prosodyctl shell server version
prosodyctl shell server memory
OK: This server has been running for 0 days, 1 hour and 4 minutes (since Wed Oct 21 10:13:42 2026)
OK: 13.0.7
Process: 7.52 MiB
Used: 7.16 MiB (4.3 MiB by Lua)
Free: 110 KiB (79.3 KiB returnable)
OK: OK
监听端口总览:
prosodyctl shell port list
c2s: [*]:5222, [::]:5222
http: [127.0.0.1]:5280, [::1]:5280
https: [*]:5281, [::]:5281
s2s: [*]:5269, [::]:5269
OK: 4 services listening on 8 ports
HTTP 端点清单(启用 http/bosh 后):
prosodyctl shell http list
Global HTTP endpoints available on all hosts:
Module | External URL | Internal URL
mod_bosh | https://*:5281/http-bind
HTTP endpoints on xmpp.example.com:
Module | External URL | Internal URL
mod_bosh | https://xmpp.example.com:5281/http-bind
mod_http_altconne… | https://xmpp.example.com:5281/.well-known
HTTP requests to unknown hosts will return 404 Not Found
Result: true
周期任务(mod_cron 注册的内部定时任务):
prosodyctl shell cron tasks
Host | Task | Desc | When | Last run
xmpp.example.com | tokenauth/clear_expired_grants | clear expired grants | daily | 2026-10-21 09:44:54
xmpp.example.com | user_account_management/remove_… | Remove deleted accounts | daily | 2026-10-21 09:44:54
Result: nil
server shutdown <原因> 可从控制台关停服务(原因会广播给在线客户端),日常启停仍建议用 systemd。
6.12 stats 分区:内置统计
stats show 需要先在配置全局段启用统计,否则实测报错:
prosodyctl shell stats show
Error: Statistics disabled. Try `statistics = "internal"` in the global section of the config file and restart.
按提示在 /etc/prosody/prosody.cfg.lua 全局段加入 statistics = "internal" 并 systemctl restart prosody 后重测:
prosodyctl shell stats show
实测回显(节选,全量约百行):
prosody_dns_seconds
prosody_info
version=13.0.7 1
prosody_mod_bosh/active_sessions 0
prosody_mod_bosh/bad_host 0 events/s [avg]
prosody_mod_bosh/bad_sid 0 events/s [avg]
prosody_mod_bosh/inactive_sessions 0
prosody_mod_bosh/new_sid 0 events/s [avg]
prosody_mod_bosh/timeout 0 events/s [avg]
prosody_mod_c2s/connections
prosody_mod_c2s/encrypted
prosody_mod_csi/changes_events
prosody_mod_csi/state_sessions
host=xmpp.example.com csi_state=flushing 0 sessions
host=xmpp.example.com csi_state=active 0 sessions
host=xmpp.example.com csi_state=inactive 0 sessions
prosody_mod_csi_simple/buffer_hold_seconds
host=xmpp.example.com no obs.
prosody_mod_csi_simple/flush_stanza_count
host=xmpp.example.com no obs.
prosody_mod_csi_simple/flushes
prosody_mod_muc/live_room
host=chat.example.com 0
prosody_mod_muc/room_eviction
host=chat.example.com 0 events/s [avg]
prosody_mod_muc/room_hit
host=chat.example.com 0 events/s [avg]
prosody_mod_muc/room_miss
host=chat.example.com 0 events/s [avg]
prosody_mod_s2s/accepted_tcp 0 events/s [avg]
支持按名称过滤:
prosodyctl shell stats show c2s
prosody_mod_c2s/connections
prosody_mod_c2s/encrypted
Result: 2 statistics displayed
统计开启方式与监控对接(statistics_config、OpenMetrics 端点)属调优范畴,配置细节见《Prosody IM 13.0.7 配置参数详解》。
6.13 role / limits / debug / xmpp 分区
角色清单(角色体系见 6.2 拓展说明):
prosodyctl shell role list xmpp.example.com
prosody:operator
prosody:admin
prosody:member
prosody:registered
prosody:guest
OK: Showing 5 roles on xmpp.example.com
role show <host> <role_name> 查看角色包含的权限项;user set_role <jid> <host> <role> 为账号改角色。
每 IP 连接限制状态(未配置限制时):
prosodyctl shell limits connections 127.0.0.1
Error: No per-IP limits are configured
调试分区示例——查看已注册的定时器:
prosodyctl shell debug timers
实测回显(节选前 6 行):
-- net.server.timer
2026-10-21 11:19:14 function @unbound.lua:154()
2026-10-21 11:21:56 function @server_epoll.lua:406()
2026-10-21 11:32:56 function @server_epoll.lua:380()
2026-10-21 12:13:43 function @mod_cron.lua:62()
OK: Next event at 2026-10-21 11:19:14 (in 18.180548s)
debug 分区其余命令:debug async(挂起的异步任务)、debug events <host> <event>(事件处理器注册表)、debug logevents(实时打印事件触发)、debug cert_index <路径>(证书目录索引视图)。watch log 实时跟踪日志流、watch stanzas <目标> 实时监视符合条件的 XML 段——深度排障时使用。
向 XMPP 实体发 ping 并测时延(本地服务器实体):
prosodyctl shell xmpp ping admin@xmpp.example.com xmpp.example.com
OK: pong from xmpp.example.com in 4.91142e-05s
6.14 invite / pubsub / migrate 分区边界
help 列出的三个分区在 13.0.7 默认安装下执行报 Command not found,属「帮助已列出、命令实现未随包提供」的版本边界(排障见 FAQ-6):
prosodyctl shell invite list xmpp.example.com
Error: Command not found. Is the necessary module loaded?
prosodyctl shell pubsub list_nodes pubsub.xmpp.example.com
Error: Command not found. Is the necessary module loaded?
说明:invite 分区命令的提供模块未包含在官方包内(配置中已加载 invites/invites_adhoc/invites_register 三模块仍报错,实测确认);pubsub 分区需先在配置中声明 Component "pubsub.xmpp.example.com" "pubsub" 组件并加载后才可用。migrate 分区用于 internal↔SQL 存储迁移,本文环境未配置 SQL 后端,无实际迁移对象。
七、证书管理命令 cert
7.1 子命令总览
prosodyctl cert --help
实测回显(全量):
Usage: /usr/bin/prosodyctl cert config|request|generate|key|import
Helpers for generating X.509 certificates and keys.
Usage: /usr/bin/prosodyctl cert generate HOSTNAME [HOSTNAME+]
Generates a self-signed certificate for the current hostname(s)
Usage: /usr/bin/prosodyctl cert config HOSTNAME [HOSTNAME+]
Builds a certificate config file covering the supplied hostname(s)
Usage: /usr/bin/prosodyctl cert request HOSTNAME [HOSTNAME+]
Generates a certificate request for the supplied hostname(s)
Usage: /usr/bin/prosodyctl cert import [HOSTNAME+] /path/to/certs [/other/paths/]+
Copies certificates to /var/lib/prosody
Usage: /usr/bin/prosodyctl cert key HOSTNAME <bits>
Generates a RSA key named HOSTNAME.key
Prompts for a key size if none given
💡 技术拓展:XMPP 服务器证书的常见来源对比——
来源 原理 适用场景 自签( cert generate)自己当 CA 签发,客户端需手动信任 内网、测试环境 Let's Encrypt( certbot+cert import)ACME 自动签发受信证书,90 天轮换 有公网域名的生产环境 商业 CA 购买年付证书 无法自动化 ACME 的环境 本文实验采用自签(部署篇)演示
cert generate,并用自签证书模拟外部签发目录演示cert import。
⚠️ 前置条件:cert 全部子命令要求目标主机名已写在配置文件的 VirtualHost/Component 段中,否则一律拒绝(实测见 FAQ-2)。
7.2 cert generate:自签证书
prosodyctl cert generate lab.example.net
实测回显(交互输入直接回车取默认值):
Choose key size (2048): Key written to /var/lib/prosody/lab.example.net.key
Please provide details to include in the certificate config file.
Leave the field empty to use the default value or '.' to exclude the field.
countryName (GB): localityName (The Internet): organizationName (Your Organisation): organizationalUnitName (XMPP Department): commonName (lab.example.net): emailAddress (xmpp@lab.example.net):
Config written to /var/lib/prosody/lab.example.net.cnf
Certificate written to /var/lib/prosody/lab.example.net.crt
exit=0
要点:密钥位数交互询问(默认 2048);证书字段全部有默认值(国家 GB、组织 Your Organisation 等,直接回车即用);产物落在数据目录 /var/lib/prosody/(<域名>.key/.cnf/.crt 三件),而非 /etc/prosody/certs/——certmanager 对两个位置都会索引(/etc/prosody/certs/ 优先),自签证书落数据目录即可被服务加载。
7.3 cert key / config / request
生成指定长度的 RSA 密钥:
prosodyctl cert key lab.example.net 2048
Key written to /var/lib/prosody/lab.example.net.key
exit=0
生成本次 let's encrypt 申请要用的证书配置文件(CSR 申请前的字段问卷,交互式):
prosodyctl cert config lab.example.net
实测回显:
Please provide details to include in the certificate config file.
Leave the field empty to use the default value or '.' to exclude the field.
countryName (GB): localityName (The Internet): organizationName (Your Organisation): organizationalUnitName (XMPP Department): commonName (lab.example.net): emailAddress (xmpp@lab.example.net):
Config written to /var/lib/prosody/lab.example.net.cnf
exit=0
cert request lab.example.net 生成 CSR(证书签发请求,交 CA 签名用)。三者都属于向外部 CA 申请证书的准备步骤;自签场景用 cert generate 一步到位即可。
⚠️ 注意:这三个子命令在目标文件已存在时会交互确认
... exists, do you want to replace it? [y/n]——在无终端的脚本/管道环境执行时,该交互会直接抛出 Lua 错误(实测回显见 FAQ-3)。脚本化使用前先清理旧产物或更换主机名。
7.4 cert import:外部证书归位
cert import 把外部签发的证书拷贝进 /var/lib/prosody/,解决「Let's Encrypt 续期后证书不在 Prosody 目录」的问题。实测:
准备外部证书目录(模拟 certbot 的 live 目录;文件名必须为 <域名>.crt + <域名>.key):
mkdir -p /srv/ext-certs
cp /etc/letsencrypt/live/xmpp.example.com/fullchain.pem /srv/ext-certs/xmpp.example.com.crt # 示意;本文用自签模拟
openssl req -x509 -newkey rsa:2048 -keyout /srv/ext-certs/lab.example.net.key -out /srv/ext-certs/lab.example.net.crt -days 30 -nodes -subj "/CN=lab.example.net"
chmod 755 /srv/ext-certs && chmod 644 /srv/ext-certs/*
导入:
prosodyctl cert import lab.example.net /srv/ext-certs
实测回显:
Imported certificate and key for hosts lab.example.net
exit=0
验证落位与热加载(导入动作会自动触发 SIGHUP 重载证书):
ls -la /var/lib/prosody/ | grep -i lab
-rw-r----- 1 prosody prosody 1131 Oct 21 11:23 lab.example.net.crt
-r-------- 1 prosody prosody 1704 Oct 21 11:23 lab.example.net.key
tail -3 /var/log/prosody/prosody.log
Oct 21 11:23:54 startup info Received SIGHUP
Oct 21 11:23:54 startup info Reloading configuration file
Oct 21 11:23:54 chat.example.com:tls info Certificates reloaded
cert import 可一次传多个目录(cert import <域名> <目录1> <目录2>...),也可省略域名让它扫描全部传入目录并把能匹配配置内主机名的证书全部归位。排障实录(目录权限、文件命名)见 FAQ-4。
八、社区插件管理
8.1 plugin_server:安装前置
prosodyctl install 从 Prosody 社区模块仓库(rocks 格式)安装第三方模块。13.0.7 下未配置 plugin_server 时直接报错:
prosodyctl install mod_privilege
There is no 'plugin_server' option in the configuration file
exit=1
在 /etc/prosody/prosody.cfg.lua 全局段添加官方模块仓库地址后重试:
plugin_server = "https://modules.prosody.im/rocks"
8.2 install / list / remove 实测
安装社区模块 mod_privilege(特权实体,XEP-0356):
prosodyctl install mod_privilege
实测回显(全量):
Installing mod_privilege in /var/lib/prosody/custom_plugins
Installing https://modules.prosody.im/rocks/mod_privilege-28-1.src.rock
No existing manifest. Attempting to rebuild...
mod_privilege 28-1 is now installed in /var/lib/prosody/custom_plugins (license: MIT)
Done.
If you installed a prosody plugin, don't forget to add its name under the 'modules_enabled' section inside your configuration file.
Depending on the module, there might be further configuration steps required.
More info about:
modules_enabled: https://prosody.im/doc/modules_enabled
mod_privilege: https://modules.prosody.im/mod_privilege.html
exit=0
列出已安装插件:
prosodyctl list
Rocks installed for Lua 5.4 in /var/lib/prosody/custom_plugins
--------------------------------------------------------------
mod_privilege
28-1 (installed) - /var/lib/prosody/custom_plugins/lib/luarocks/rocks-5.4
安装后即可热加载(等价内置模块的 module load):
prosodyctl shell module load privilege xmpp.example.com
Loaded for xmpp.example.com
Note: Module will not be loaded after restart unless enabled in configuration
OK: Module loaded onto 1 host
确认已出现在模块列表(节选):
prosodyctl shell module list xmpp.example.com | grep -A1 privilege
privilege
register
卸载:
prosodyctl remove mod_privilege
实测回显:
Removing mod_privilege from /var/lib/prosody/custom_plugins
Checking stability of dependencies in the absence of
mod_privilege 28-1...
Removing mod_privilege 28-1...
Removal successful.
exit=0
要点:插件落盘 /var/lib/prosody/custom_plugins/(luarocks 目录结构),该目录已在默认插件搜索路径中(prosodyctl about 的 Plugin directories 一节可见);remove 会做依赖稳定性检查。注意 install/remove 的参数带 mod_ 前缀(如 mod_privilege),而 module load 的参数不带前缀(如 privilege)。
九、注意事项
- prosodyctl 与 systemctl 分工:服务启停/自启走
systemctl;账号/证书/插件/诊断走prosodyctl。prosodyctl reload与systemctl reload prosody同效,勿叠加。 - 一次性执行优于交互:
prosodyctl shell <命令>的形态可进脚本、可记录;交互控制台适合探索。 - 运行时修改不持久:
config set、module load、host activate都是进程内存态,重启即失;持久化一律回到配置文件。 - JID 全称:用户管理命令一律用「用户名@域名」全称;
register旧式命令才拆「用户名 域名」两个参数。 - 无终端交互命令脚本化要谨慎:
adduser/passwd/cert系列在无 TTY 环境可能因密码输入或 y/n 确认失败,脚本场景改用shell user create/password(参数化)或提前清理旧产物。 - 以非 root 运行提示:
prosodyctl会对 root 执行打警告(Danger, Will Robinson!),属提醒不影响功能;服务进程本身以prosody用户运行。 - 配置检查习惯:任何配置修改后先
prosodyctl check再重启,能在启动失败前发现语法与引用错误。
十、常见问题(FAQ)
FAQ-1:stats show 报 Statistics disabled
现象:prosodyctl shell stats show 报 Error: Statistics disabled. Try statistics = "internal" in the global section of the config file and restart.
定位与解决:内置统计默认关闭。在配置全局段加 statistics = "internal" 后 systemctl restart prosody,重测即出数据(完整实测见 6.12 节)。
FAQ-2:cert 子命令报 The given hostname does not exist in the config
现象:对配置中不存在的域名执行 cert generate/key/config/request/import,实测:
The given hostname does not exist in the config
exit=1
定位:cert 工具先校验主机名是否出现在配置文件(VirtualHost/Component 段)中,运行时 host activate 激活的域名不算(不写配置文件)。
解决:先把域名写进配置(VirtualHost "lab.example.net"),再执行 cert 子命令(实测通过见 7.2 节)。
FAQ-3:cert 交互确认在脚本环境抛 Lua 错误
现象:目标 key/证书文件已存在时,cert key/config/request 会问 ... exists, do you want to replace it? [y/n];在无终端的管道环境实测直接崩溃:
lua: /usr/bin/prosodyctl:631: /usr/share/lua/5.4/prosody/util/human/io.lua:18: attempt to index a nil value (local 'char')
stack traceback:
/usr/share/lua/5.4/prosody/util/human/io.lua:18: in function 'prosody.util.human.io.getchar'
/usr/share/lua/5.4/prosody/util/human/io.lua:52: in function 'prosody.util.human.io.show_yesno'
...
/var/lib/prosody/lab.example.net.key exists, do you want to replace it? [y/n] exit=1
定位:show_yesno 需要从 TTY 读单字符,管道环境下读到 EOF(nil)即抛错。
解决:脚本化场景先删除既有产物(rm /var/lib/prosody/<域名>.*)再执行;或改在交互终端操作。
FAQ-4:cert import 报 No certificate for host ... found :(
现象与定位(两个独立原因,均实测踩中):
- key 文件命名不符:导入目录里 key 命名为
<域名>.pem时报No certificate for host lab.example.net found :(/No certificates imported :(——import 按<域名>.crt+<域名>.key的固定命名匹配。解决:改名mv lab.example.net.pem lab.example.net.key后重试即成功。 - 源目录权限不足:目录放在
/root/ext-certs(700)时,报:
certmanager error Error indexing certificate directory /root/ext-certs: cannot open /root/ext-certs: Permission denied
No certificate for host chat.example.com found :(
No certificate for host xmpp.example.com found :(
No certificates imported :(
exit=1
解决:外部目录放常规路径(如 /srv/ext-certs)并保证 prosody 用户可读(目录 755、文件 644)。
FAQ-5:prosodyctl install 报 There is no 'plugin_server' option
现象与解决见 8.1 节:配置全局段补 plugin_server = "https://modules.prosody.im/rocks" 后安装正常。
FAQ-6:shell 命令报 Command not found. Is the necessary module loaded?
现象:help 分区里列出的命令执行报错,实测 invite 分区(模块 invites/invites_adhoc/invites_register 均已加载仍报错):
Error: Command not found. Is the necessary module loaded?
定位:prosodyctl shell help 的分区表是控制台命令总目录,不等于当前安装可用的命令集——部分分区命令的实现(如 invite 的控制台管理命令)未随 13.0.7 官方包提供。已用 grep -n invite /usr/lib/prosody/modules/mod_admin_shell.lua 实证:命令注册表中确无 invite 条目。
解决:邀请管理改走客户端内的 ad-hoc 命令(invites_adhoc 已加载,支持 ad-hoc 的客户端可用)或社区模块补充;pubsub 分区则需先声明 pubsub 组件。
FAQ-7:客户端发送 SMACKS <r/> 保活被断开
现象:以 Python 标准库自建 c2s 会话(已 bind),向服务器发送流管理保活标签 <r xmlns='urn:xmpp:sm:3'/>,连接随即被服务端关闭,客户端报 ssl.SSLZeroReturnError: TLS/SSL connection has been closed (EOF)。服务端日志(实测照抄):
stanzarouter warn Unhandled c2s stream element or stanza: r; xmlns=urn:xmpp:sm:3: <r xmlns='urn:xmpp:sm:3' xml:lang='en'/>
c2s60b9f072aa50 info Client disconnected: connection closed
定位:SMACKS(XEP-0198)要求客户端先在流协商阶段发送 <enable xmlns='urn:xmpp:sm:3'/> 完成协商;未协商直接发 <r/> 属未处理元素,服务端 warn 后关闭流。
解决:保活改用标准 XMPP ping(<iq type='get'><ping xmlns='urn:xmpp:ping'/></iq>,实测会话稳定保持,见 6.5 节);或按 XEP-0198 先 <enable> 再使用 SM 机制。
FAQ-8:module load 的模块重启后失效
现象:prosodyctl shell module load <模块> 成功,服务重启后模块没了。
定位:module load 的输出已明示——Note: Module will not be loaded after restart unless enabled in configuration。运行时加载只存在于当前进程。
解决:在配置 modules_enabled 列表中加入模块名并 systemctl restart prosody(实测流程见《Prosody IM 13.0.7 配置参数详解》5.6 节)。
十一、参考链接
- 官方 prosodyctl 总文档:https://prosody.im/doc/prosodyctl
- 管理控制台命令:https://prosody.im/doc/console
- 证书管理:https://prosody.im/doc/certificates
- 社区模块仓库:https://modules.prosody.im/
- 模块列表与说明:https://prosody.im/doc/modules
- 本专栏同系列:《Prosody IM 13.0.7 介绍与选型指南》、《Ubuntu 22.04 安装 Prosody IM 13.0.7 指南》、《Prosody IM 13.0.7 配置参数详解》。