Ejabberd:如何使用 Python 脚本在 XMPP 服务器中注册新用户?

问题描述 投票:0回答:1

我最近用 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 协议。

提前谢谢大家。

xmpp ejabberd ejabberd-api xmpppy ejabberd-auth
1个回答
0
投票

在 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 的示例。我假设您从默认配置开始,这样当其他人找到此线程时,他们可以按照该示例进行操作,而无需了解您之前的配置。

  1. listen
    部分必须包含带有模块 ejabberd_http 和 mod_http_api 的端口,例如:
listen:
  -
    port: 5443
    module: ejabberd_http
    tls: true
    request_handlers:
      /api: mod_http_api
  1. 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
  1. modules
    部分必须包含该模块。也许您已经启用了它,但为了确保这一点,请检查:
modules:
  ...
  mod_http_api: {}
  1. 在我的示例配置中,API 查询必须包含 ejabberd 中某些具有管理员权限的帐户的身份验证详细信息,因此让我们向名为 tim@localhost 的帐户授予管理员权限:
acl:
  admin: [user: tim]
  loopback:
    ip:
      - 127.0.0.0/8
      - ::1/128
  1. 是时候启动ejabberd了,我们来注册一下admin帐号:
$ ejabberdctl register tim localhost somepass
User tim@localhost successfully registered
  1. 现在准备一个Python脚本来注册账户,例如:
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)
  1. 最后执行脚本,检查账号是否注册,密码是否设置正确:
$ python3 register.py
<Response [200]>

$ ejabberdctl registered_users localhost
tim
username2

$ ejabberdctl check_password username2 localhost somepassword
$ echo $?
0
© www.soinside.com 2019 - 2024. All rights reserved.