我最近用 ejabberd 设置了一个 XMPP 服务器。我按照本教程这样做:
DenshiVideo:如何设置 XMPP 服务器(ejabberd)
我可以访问浏览器中的管理界面,可以在其中注册新用户并删除它们。网址是这样的(替换“myserver”):
http://myserver.com:5280/admin/server/myserver.com/users/
我现在想做的是能够从浏览器的管理界面之外注册新用户,也许可以使用 Python 脚本。我正在尝试使用 XMPPpy 库来做到这一点。
这是我尝试过的脚本:
`#!/usr/bin/python3
import xmpp
server = "myserver.com"
admin_username = "[email protected]"
admin_password = "password1234"
new_username = "[email protected]"
new_password = "newuserpassword1234"
def register_user(server, admin_username, admin_password, new_username, new_password):
admin_jid = xmpp.protocol.JID(admin_username)
client = xmpp.Client(server=server, debug=[])
client.connect()
# Authenticate as administrator
client.auth(user=admin_jid.getNode(), password=admin_password)
# Register a new account
iq = xmpp.Iq(to=server, typ='set')
iq.addChild("query", namespace="jabber:iq:register")
iq.getTag("query").addChild("username", payload=[new_username])
iq.getTag("query").addChild("password", payload=[new_password])
result = client.SendAndWaitForResponse(iq)
if result and result.getType() == 'result':
print("User registration successful.")
else:
print(result)
print("User registration failed.")
client.disconnect()
if __name__ == '__main__':
register_user(server, admin_username, admin_password, new_username, new_password)`
但是,ejabberd 服务器返回以下错误:
`<iq xmlns="jabber:client" xml:lang="en" to="[email protected]/18317692873934713179914" from="bryanyep.com" type="error" id="3">
<query xmlns="jabber:iq:register">
<username>dinaboluarte</username>
<password>ROLEX</password>
</query>
<error type="auth">
<forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
<text xml:lang="en" xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
Access denied by service policy
</text>
</error>
</iq>
User registration failed.`
我向 ChatGPT 询问了此事,它告诉我要在 /opt/ejabberd/conf/ejabberd.yml 文件中进行一些更改,但我仔细检查了该文件以及已经存在的更改。这是该文件的“access_rules”部分:
`access_rules:
local:
allow: local
c2s:
deny: blocked
allow: all
announce:
allow: admin
configure:
allow: admin
muc_create:
allow: local
pubsub_createnode:
allow: local
trusted_network:
allow: loopback
register:
allow: all`
我不确定是否需要先设置 API 并执行 POST 请求,或者 API 是否已经存在但我不知道如何访问它。但是,同一文件上有一个“api_permissions”部分:
`api_permissions:
"console commands":
from:
- ejabberd_ctl
who: all
what: "*"
"admin access":
who:
access:
allow:
- acl: loopback
- acl: admin
oauth:
scope: "ejabberd:admin"
access:
allow:
- acl: loopback
- acl: admin
what:
- "*"
- "!stop"
- "!start"
"public commands":
who:
ip: 127.0.0.1/8
what:
- status
- connected_users_number`
为了以防万一,这是同一文件的“监听”部分:
`listen:
-
port: 5222
ip: "::"
module: ejabberd_c2s
max_stanza_size: 262144
shaper: c2s_shaper
access: c2s
starttls_required: true
-
port: 5223
ip: "::"
module: ejabberd_c2s
max_stanza_size: 262144
shaper: c2s_shaper
access: c2s
tls: true
-
port: 5269
ip: "::"
module: ejabberd_s2s_in
max_stanza_size: 524288
shaper: s2s_shaper
-
port: 5443
ip: "::"
module: ejabberd_http
tls: true
request_handlers:
/admin: ejabberd_web_admin
/api: mod_http_api
/bosh: mod_bosh
/captcha: ejabberd_captcha
/upload: mod_http_upload
/ws: ejabberd_http_ws
-
port: 5280
ip: "::"
module: ejabberd_http
request_handlers:
/admin: ejabberd_web_admin
/.well-known/acme-challenge: ejabberd_acme
-
port: 3478
ip: "::"
transport: udp
module: ejabberd_stun
use_turn: true
## The server's public IPv4 address:
# turn_ipv4_address: "203.0.113.3"
## The server's public IPv6 address:
# turn_ipv6_address: "2001:db8::3"
-
port: 1883
ip: "::"
module: mod_mqtt
backlog: 1000`
拜托,如果有人知道如何做到这一点,我将非常感激。对于 n00b 问题感到抱歉,这是我第一次使用 XMPP 协议。
提前谢谢大家。
在 ejabberd 中以编程方式注册帐户有两种方法:
A) 使用XMPP方法:首先配置mod_register以允许任何XMPP客户端注册帐户。或者您可以只允许从 IP 地址 127.0.0.1 进行注册。然后编写一个小型 Python 脚本,其行为类似于常规 XMPP 客户端:它连接到端口 5222 并像任何其他客户端一样注册帐户。
B) 使用 ejabberd 的
register
API 命令:首先使用 ejabberd_http 和 mod_http_api 配置侦听器,并使用选项 api_permissions 授予访问权限。然后编写一个小的 Python 脚本,将 HTTP 查询发送到端口 5443,并将由 mod_http_api 处理。
看看你的问题,你正在混合东西:你的python脚本和access_rules对方法A有用。另一方面,api_permissions仅对方法B有用。最后,监听配置对方法A和方法B有效。
我将提供一个使用方法 B 的示例。我假设您从默认配置开始,这样当其他人找到此线程时,他们可以按照该示例进行操作,而无需了解您之前的配置。
listen
部分必须包含带有模块 ejabberd_http 和 mod_http_api 的端口,例如:listen:
-
port: 5443
module: ejabberd_http
tls: true
request_handlers:
/api: mod_http_api
api_permissions
必须允许您所需的连接,但不允许其余连接。例如,这适用于我的情况:api_permissions:
"console commands":
from:
- ejabberd_ctl
who: all
what: "*"
"admin access":
from:
- mod_http_api
who:
access:
allow:
- acl: loopback
- acl: admin
what:
- register
modules
部分必须包含该模块。也许您已经启用了它,但为了确保这一点,请检查:modules:
...
mod_http_api: {}
acl:
admin: [user: tim]
loopback:
ip:
- 127.0.0.0/8
- ::1/128
$ ejabberdctl register tim localhost somepass
User tim@localhost successfully registered
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
import requests
from requests.auth import HTTPBasicAuth
url = "https://localhost:5443/api/register"
data = {
"user": "username2",
"host": "localhost",
"password": "somepassword"
}
res = requests.post(url, json=data, auth=HTTPBasicAuth("tim@localhost", "somepass"), verify=False)
print(res)
$ python3 register.py
<Response [200]>
$ ejabberdctl registered_users localhost
tim
username2
$ ejabberdctl check_password username2 localhost somepassword
$ echo $?
0