XMPP support for GenieACS

Hi @jerry can you explain a bit your change please? Did you only remove that bit of code? Where is it?

Also, any idea why would that work? :slight_smile:

Thanks @jerry, that’s a good catch. Just pushed a fix.

Hi @zaidka , are you sure the fix is correct? I’m building and re-building but still can’t establish communication between ACS and XMPP server.
Maybe there is a typo somewhere ?

Much respect and many thanks

Does this really work with SRV records??

For instance Example 2 in your provided docs link, where- The XMPP domain is example dot net and the server is server dot example dot net.

so JID will be acs@example dot net but ACS should connect XMPP to server dot example dot net using the SRV records.

But I see genieacs connecting to example.net instead of server.example.net. Even the source code says the same, if i am not wrong.

-> connection-request.ts#L269

const [host, username] = XMPP_JID.split("@").reverse();
    xmppClient = await XmppClient.connect({
      host,
      username,
      resource: XMPP_RESOURCE,
      password: XMPP_PASSWORD,
      timeout: 120000,
    });
    xmppClient.on("error", xmppClientOnError);
    xmppClient.on("close", xmppClientOnClose);
    xmppClient.unref();
....
....

-> xmpp-client.ts#L343

 static connect(opts: XmppClientOptions): Promise<XmppClient> {
    return new Promise((resolve, reject) => {
      let socket = new net.Socket();
      socket.on("error", reject);

      socket.connect(opts.port || 5222, opts.host, async () => {
        socket.removeListener("error", reject);
....
....

sorry i had to use server dot net instead of server.net, because it says new users can have only 2 links in a POST :slightly_smiling_face: :slightly_smiling_face:

You’re right that Genie doesn’t make use of SRV records. I mentioned it because some CPEs may look for SRV records.

I haven’t been able to test the xmpp implementation before now. It seems to work with a single CPE. We have yet to test on a larger scale. There is no need to try to explain how I tried to implement this as I have almost no experience with node. I also used an external packaged for XMPP (@xmpp/client).

First issue we got was a tiny bug on line 386 in xmpp-client.ts. We got an invalid tag error so I changed to </stream:stream>.

The second issue I don’t know if is related to ejabberd configuration or GenieACS. The XMPP client loses connection and one or more summon fails until it is up again. I have only tested this with UI, not NBI.

2021-02-04T10:20:24.376Z [ERROR] XMPP exception; pid=11432 exceptionName="Error" exceptionMessage="This socket has been ended by the other party" exceptionStack="Error: This socket has been ended by the other party\n at Socket.writeAfterFIN [as write] (net.js:456:14)\n at xn.send (/opt/genieacs/dist/bin/genieacs-ui:2:74198)\n at /opt/genieacs/dist/bin/genieacs-ui:2:74374\n at new Promise (<anonymous>)\n at xn.sendIqStanza (/opt/genieacs/dist/bin/genieacs-ui:2:74242)\n at /opt/genieacs/dist/bin/genieacs-ui:2:80642\n at runMicrotasks (<anonymous>)\n at processTicksAndRejections (internal/process/task_queues.js:93:5)\n at async qn (/opt/genieacs/dist/bin/genieacs-ui:2:80175)\n at async Gn (/opt/genieacs/dist/bin/genieacs-ui:2:86137)"

In ejabberd log I find this.

2021-02-05 09:46:27.040 [debug] <0.1725.0>@ejabberd_hooks:safe_apply:231 Running hook c2s_closed: mod_stream_mgmt:c2s_closed/2
2021-02-05 09:46:27.040 [debug] <0.1725.0>@ejabberd_hooks:safe_apply:231 Running hook c2s_closed: ejabberd_c2s:process_closed/2
2021-02-05 09:46:27.040 [debug] <0.1725.0>@ejabberd_hooks:safe_apply:231 Running hook c2s_terminated: mod_stream_mgmt:c2s_terminated/2
2021-02-05 09:46:27.040 [debug] <0.1725.0>@ejabberd_hooks:safe_apply:231 Running hook c2s_terminated: mod_pubsub:on_user_offline/2
2021-02-05 09:46:27.040 [info] <0.1725.0> (tcp|<0.1725.0>) Received XML on stream = <<“</stream:stream>”>>
2021-02-05 09:46:27.040 [debug] <0.1725.0>@mod_pubsub:node_action:3841 Node_action <<“pubsub.domain”>> <<“flat”>> get_entity_affiliations [<<“pubsub.domain”>>,{<<“genieacs”>>,<<“domain”>>,<<“acdc106ddcb1b9b9”>>}]
2021-02-05 09:46:27.040 [debug] <0.1725.0>@mod_pubsub:node_call:3818 Node_call <<“flat”>> get_entity_affiliations [<<“pubsub.domain”>>,{<<“genieacs”>>,<<“domain”>>,<<“acdc106ddcb1b9b9”>>}]
2021-02-05 09:46:27.041 [debug] <0.1725.0>@mod_pubsub:node_action:3841 Node_action <<“pubsub.domain”>> <<“pep”>> get_entity_affiliations [<<“pubsub.domain”>>,{<<“genieacs”>>,<<“domain”>>,<<“acdc106ddcb1b9b9”>>}]
2021-02-05 09:46:27.041 [debug] <0.1725.0>@mod_pubsub:node_call:3818 Node_call <<“pep”>> get_entity_affiliations [<<“pubsub.domain”>>,{<<“genieacs”>>,<<“domain”>>,<<“acdc106ddcb1b9b9”>>}]
2021-02-05 09:46:27.041 [debug] <0.1725.0>@ejabberd_hooks:safe_apply:231 Running hook c2s_terminated: ejabberd_c2s:process_terminated/2
2021-02-05 09:46:27.041 [info] <0.1725.0>@ejabberd_c2s:process_terminated:292 (tcp|<0.1725.0>) Closing c2s session for genieacs@domain/acdc106ddcb1b9b9: Stream reset by peer
2021-02-05 09:46:27.042 [debug] <0.1725.0>@ejabberd_hooks:safe_apply:231 Running hook privacy_check_packet: mod_last:privacy_check_packet/4
2021-02-05 09:46:27.042 [debug] <0.1725.0>@ejabberd_hooks:safe_apply:231 Running hook privacy_check_packet: mod_privacy:check_packet/4
2021-02-05 09:46:27.043 [debug] <0.1725.0>@ejabberd_router_multicast:do_route:214 Route multicast:
#presence{id = <<>>,type = unavailable,lang = <<>>,
from = #jid{user = <<“genieacs”>>,
server = <<“domain”>>,
resource = <<“acdc106ddcb1b9b9”>>,
luser = <<“genieacs”>>,
lserver = <<“domain”>>,
lresource = <<“acdc106ddcb1b9b9”>>},
to = #jid{user = <<“genieacs”>>,
server = <<“domain”>>,resource = <<>>,
luser = <<“genieacs”>>,
lserver = <<“domain”>>,
lresource = <<>>},
show = undefined,status = ,priority = undefined,sub_els = ,
meta = #{}}
Domain: domain
Destinations: genieacs@domain
2021-02-05 09:46:27.044 [debug] <0.1725.0>@ejabberd_router:do_route:384 Route:
#presence{id = <<>>,type = unavailable,lang = <<>>,
from = #jid{user = <<“genieacs”>>,
server = <<“domain”>>,
resource = <<“acdc106ddcb1b9b9”>>,
luser = <<“genieacs”>>,
lserver = <<“domain”>>,
lresource = <<“acdc106ddcb1b9b9”>>},
to = #jid{user = <<“genieacs”>>,
server = <<“domain”>>,resource = <<>>,
luser = <<“genieacs”>>,
lserver = <<“domain”>>,
lresource = <<>>},
show = undefined,status = ,priority = undefined,sub_els = ,
meta = #{}}
2021-02-05 09:46:27.045 [debug] <0.1725.0>@ejabberd_local:route:74 Local route:
#presence{id = <<>>,type = unavailable,lang = <<>>,
from = #jid{user = <<“genieacs”>>,
server = <<“domain”>>,
resource = <<“acdc106ddcb1b9b9”>>,
luser = <<“genieacs”>>,
lserver = <<“domain”>>,
lresource = <<“acdc106ddcb1b9b9”>>},
to = #jid{user = <<“genieacs”>>,
server = <<“domain”>>,resource = <<>>,
luser = <<“genieacs”>>,
lserver = <<“domain”>>,
lresource = <<>>},
show = undefined,status = ,priority = undefined,sub_els = ,
meta = #{}}
2021-02-05 09:46:27.045 [debug] <0.1725.0>@ejabberd_hooks:safe_apply:231 Running hook sm_receive_packet: mod_mam:sm_receive_packet/1
2021-02-05 09:46:27.047 [debug] <0.1725.0>@ejabberd_sm:do_route:696 Processing presence to bare JID:
#presence{id = <<>>,type = unavailable,lang = <<>>,
from = #jid{user = <<“genieacs”>>,
server = <<“domain”>>,
resource = <<“acdc106ddcb1b9b9”>>,
luser = <<“genieacs”>>,
lserver = <<“domain”>>,
lresource = <<“acdc106ddcb1b9b9”>>},
to = #jid{user = <<“genieacs”>>,
server = <<“domain”>>,resource = <<>>,
luser = <<“genieacs”>>,
lserver = <<“domain”>>,
lresource = <<>>},
show = undefined,status = ,priority = undefined,sub_els = ,
meta = #{}}
2021-02-05 09:46:27.148 [info] <0.1725.0> (tcp|<0.1725.0>) Send XML on stream = <<“</stream:stream>”>>

Any idea why we get this?

In my experience so far:

  1. GenieACS is started, it does not attempt any communication XMPP server. Confirmed by tcpdump between the 2 servers. There is nothing in the GenieACS debug log.
  2. I connect some CPEs (behind NAT) to GenieACS and they get bootstrapped by GenieACS with XMPP information. They successfully register to XMPP server:
  3. I try to summon or reboot the CPE via the GenieACS GUI and it works. Strangely it works because GenieACS opens a communication to XMPP server and finds the CPE via XMPP.
  4. In this moment I see GenieACS has a presence in the XMPP, but seems unregistered.

My XMPP is prosody, this is what I see in the prosody terminal:
c2s:show()
| xmpp.someurl.net
| acs@xmpp.someurl.net/f1aee6cf1a89ab4f [c2sredacted] unavailable(-) (encrypted)
| cpe@xmpp.someurl.net/83V112-REDACTED-REDACTED [c2sredacted] available(0) (encrypted)
| OK: Total: 2 clients
notice acs seems to be unavailable, I’m sure because it does not register to the XMPP.
Could not figure that out.
But It was a great moment to be able to summon the CPE behind NAT.

I feel like we are very close :slight_smile:

@zaidka, What’s is the change that you pushed here? Does this fix was pushed into xmpp branch?

@zaidka, I have enabled xmpp support in our CPE device which is deployed behind a NATed router. And I have deployed Geneacs server (xmpp branch in git) and ejabberd in a Ubuntu machine.

I followed the steps that you mentioned in your post (XMPP support for GenieACS - #8 by zaidka). With that the CPE successfully establishes a connection to the XMPP server and its coming online on the ACS server.

2021-07-27 14:10:18.599 [info] <0.395.0>@ejabberd_listener:accept:273 (<0.552.0>) Accepted connection [::ffff:27.62.66.95]:21561 -> [::ffff:192.168.10.8]:5222
2021-07-27 14:10:20.083 [info] <0.552.0>@ejabberd_c2s:process_auth_result:268 (tls|<0.552.0>) Accepted c2s SCRAM-SHA-1 authentication for cpe@example.xmpp.com by mnesia backend from ::ffff:27.62.66.95
2021-07-27 14:10:20.366 [info] <0.552.0>@ejabberd_c2s:bind:442 (tls|<0.552.0>) Opened c2s session for cpe@example.xmpp.com/cpe

But when I try to do a reboot of the CPE device from the Genieacs server, some xmpp packet exchanges are happening between ACS and XMPP server and its not forwarding that request to end CPE device. The connection request starts with the STREAM packets exchanged between acs server and xmpp server followed by STARTTLS, Client Hello, Server Hello, client and server certificate exchange and acs server is sending a FIN packet right after Change Cipher Spec, Encrypted Handshake Message.

Also I noticed following logs while booting up the xmpp server

2021-07-27 14:59:27.380 [warning] <0.1735.0>@ejabberd_pkix:log_warnings:393 Invalid certificate in /home/mohanasundarams/ejabberd-21.04/conf/server.pem: at line 53: self-signed certificate
2021-07-27 14:59:28.582 [warning] <0.1735.0>@ejabberd_pkix:check_domain_certfiles:312 No certificate found matching example.xmpp.com
2021-07-27 14:59:28.586 [warning] <0.1735.0>@ejabberd_pkix:check_domain_certfiles:312 No certificate found matching upload.example.xmpp.com
2021-07-27 14:59:28.586 [warning] <0.1735.0>@ejabberd_pkix:check_domain_certfiles:312 No certificate found matching pubsub.example.xmpp.com
2021-07-27 14:59:28.587 [warning] <0.1735.0>@ejabberd_pkix:check_domain_certfiles:312 No certificate found matching conference.example.xmpp.com
2021-07-27 14:59:28.587 [warning] <0.1735.0>@ejabberd_pkix:check_domain_certfiles:312 No certificate found matching proxy.example.xmpp.com
2021-07-27 14:59:28.595 [info] <0.1431.0>@ejabberd_app:start:63 ejabberd 21.04 is started in the node ejabberd@localhost in 25.15s

Do you think I need to replace the server.pem file with a new self signed certificate having CN=*.example.xmpp.com?

I remove this code: if (feature.children.some(©=> c.name === ‘required’)){** and then re-build ,now it works to me.
**else if (feature.name ===‘bind’)(**
** yield* bind(socket,resource);**
** return 0;**

What’s is the change that you pushed here? Does this fix was pushed into xmpp branch?

Hello guys,

I followed the steps that you mentioned in the comment XMPP support for GenieACS - #8 by zaidka.
but actually, I didn’t know if the XMPP server is working or is connected with genieacs.
please if anyone can tell me how can I know if the XMPP server is working or is connected?

@zaidka which simulator we should use or device to test the XMPP server with genieacs?

Unfortunately the simulator doesn’t support XMPP. You’ll have to test against a real CPE.

1 Like

this i dont understand can you explain this please?

Hi @zaidka
Is the merge of the XMPP branch into the master planned any soon? Do you publish a roadmap somewhere?

@zaidka

Does Genie use the reported ConnReqJabberID to initiate the CNR? I have two Access-Points that are behind NAT which only one of them reports the Device.ManagementServer.ConnReqJabberID and the other one does not. Both APs have active connections to Ejabbred.

CNR works for the one that reports the JID. I get Device is offline for the one that does not.

1 Like

I am so close. I have the CPE’s connected to the ejabberd server, xmpp parameters are filled in correctly by CPE for xmpp to work. but genieacs is not attempting to connect to the xmpp server. there are 2 files config.ts and one other that it wants me to recommit?? and a few libraries it wants me to update when building. Otherwise I have been going over this over and over and over… finding many mistakes by me everytime. hope this is enough helpful info in this picture.

Hello,
Can someone help me with the setup of xmpp for geniACS? I managed to build genie from the source and xmpp branch but I’m not able to find the config files. I’m new to all these acs and cpe’s so any help is appreciated.
Also @zaidka Can you tell if the xmpp branch is going to be merged with the master branch. As of now the STUN is working fine but I want to shift to XMPP as it’s more reliable than STUN.
Thanks in advance

XMPP forked a long time ago as is not running 1.2.9 so for now if your devices work with stun stick with it until someone merges XMPP in. I have not gotten the XMPP version running as of yet, as I think I have to create valid wildcard certificate. There was talk of a new version coming out soon, but is private still.

Your image does not show the most important configuration is right below the logo if there is a version # displayed on the webpage. If there is a 1.2.9 you are not running the xmpp version
The XMPP client will make a attempt to the xmpp server when the device comes in with the correct parameters that it is already connected to the xmpp server. It will not connect if the tls does not have a valid certificate.