Xep-363 and xep-359 support

Hi,
I’m using Freedombox on a 386 laptop. Ejabberd was installed. İt works as expected with Android clients but on iOS client file sharing doesn’t work. İt warns xep-363 not supported on server side.
How can I add xep-363 and xep-359 support to my server?
Thanks in advance.

Do you perhaps mean XEP-357 (Push Notifications), not 359?

There is an open issue to enable XEP-0363 and XEP-0357:

They are supported in Ejabberd through mod_http_upload and mod_push. These would need to be enabled in the Ejabberd configuration. It would be helpful for someone to try this and report back their findings.

Hi,
You can see warning screenshot on attached image.

Hi,
I’m edited ejabberd.yml file as follow;

  • port: 5443
    ip: “::”
    module: ejabberd_http
    request_handlers:
    “/api”: mod_http_api
    “/bosh”: mod_bosh
    “/upload”: mod_http_upload
    “/ws”: ejabberd_http_ws

    captcha: true

    register: true

    tls: false
    protocol_options: ‘TLS_OPTIONS’
    web_admin: true

uncomment of this line -> “/upload”: mod_http_upload

ejabberd servis not restart. Related logs attached below.
I dont send files from iOS client devices. Android clients work as expected.
Thanks in advance.


Feb 22 12:24:58 freedombox sudo[2001]: pam_unix(sudo:session): session closed for user root
Feb 22 12:25:06 freedombox /usr/bin/plinth[436]: # ejabberd mam status
Feb 22 12:25:06 freedombox sudo[2135]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/ejabberd mam status
Feb 22 12:25:06 freedombox sudo[2135]: pam_unix(sudo:session): session opened for user root by catav(uid=0)
Feb 22 12:25:07 freedombox sudo[2135]: pam_unix(sudo:session): session closed for user root
Feb 22 12:25:07 freedombox /usr/bin/plinth[436]: Error executing command - [‘sudo’, ‘-n’, ‘/usr/share/plinth/actions/ejabberd’, ‘mam’, ‘status’], , Traceback (most recent call last):
File “/usr/share/plinth/actions/ejabberd”, line 327, in
main()
File “/usr/share/plinth/actions/ejabberd”, line 323, in main
subcommand_method(arguments)
File “/usr/share/plinth/actions/ejabberd”, line 258, in subcommand_mam
conf = ruamel.yaml.round_trip_load(file_handle, preserve_quotes=True)
File “/usr/lib/python3/dist-packages/ruamel/yaml/main.py”, line 685, in round_trip_load
return load(stream, RoundTripLoader, version, preserve_quotes=preserve_quotes)
File “/usr/lib/python3/dist-packages/ruamel/yaml/main.py”, line 636, in load
return loader._constructor.get_single_data() # type: ignore
File “/usr/lib/python3/dist-packages/ruamel/yaml/constructor.py”, line 102, in get_single_data
node = self.composer.get_single_node()
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 75, in get_single_node
document = self.compose_document()
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 96, in compose_document
node = self.compose_node(None, None)
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 132, in compose_node
node = self.compose_mapping_node(anchor)
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 194, in compose_mapping_node
item_value = self.compose_node(node, item_key)
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 130, in compose_node
node = self.compose_sequence_node(anchor)
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 163, in compose_sequence_node
node.value.append(self.compose_node(node, index))
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 132, in compose_node
node = self.compose_mapping_node(anchor)
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 194, in compose_mapping_node
item_value = self.compose_node(node, item_key)
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 132, in compose_node
node = self.compose_mapping_node(anchor)
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 194, in compose_mapping_node
item_value = self.compose_node(node, item_key)
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 106, in compose_node
if self.parser.check_event(AliasEvent):
File “/usr/lib/python3/dist-packages/ruamel/yaml/parser.py”, line 144, in check_event
self.current_event = self.state()
File “/usr/lib/python3/dist-packages/ruamel/yaml/parser.py”, line 577, in parse_block_mapping_value
if self.scanner.check_token(ValueToken):
File “/usr/lib/python3/dist-packages/ruamel/yaml/scanner.py”, line 1620, in check_token
self._gather_comments()
File “/usr/lib/python3/dist-packages/ruamel/yaml/scanner.py”, line 1662, in _gather_comments
self.fetch_more_tokens()
File “/usr/lib/python3/dist-packages/ruamel/yaml/scanner.py”, line 273, in fetch_more_tokens
return self.fetch_value()
File “/usr/lib/python3/dist-packages/ruamel/yaml/scanner.py”, line 626, in fetch_value
self.reader.get_mark())
ruamel.yaml.scanner.ScannerError: mapping values are not allowed here
in “/etc/ejabberd/ejabberd.yml”, line 74, column 16
Feb 22 12:25:07 freedombox /usr/bin/plinth[436]: Internal Server Error: /plinth/apps/ejabberd/
Traceback (most recent call last):
File “/usr/lib/python3/dist-packages/django/core/handlers/exception.py”, line 41, in inner
response = get_response(request)
File “/usr/lib/python3/dist-packages/django/core/handlers/base.py”, line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File “/usr/lib/python3/dist-packages/django/core/handlers/base.py”, line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File “/usr/lib/python3/dist-packages/django/views/generic/base.py”, line 68, in view
return self.dispatch(request, *args, **kwargs)
File “/usr/lib/python3/dist-packages/django/views/generic/base.py”, line 88, in dispatch
return handler(request, *args, **kwargs)
File “/usr/lib/python3/dist-packages/django/views/generic/edit.py”, line 174, in get
return self.render_to_response(self.get_context_data())
File “/usr/lib/python3/dist-packages/plinth/modules/ejabberd/views.py”, line 49, in get_context_data
context = super().get_context_data(*args, **kwargs)
File “/usr/lib/python3/dist-packages/plinth/views.py”, line 188, in get_context_data
context = super().get_context_data(*args, **kwargs)
File “/usr/lib/python3/dist-packages/django/views/generic/edit.py”, line 93, in get_context_data
kwargs[‘form’] = self.get_form()
File “/usr/lib/python3/dist-packages/django/views/generic/edit.py”, line 45, in get_form
return form_class(**self.get_form_kwargs())
File “/usr/lib/python3/dist-packages/django/views/generic/edit.py”, line 52, in get_form_kwargs
‘initial’: self.get_initial(),
File “/usr/lib/python3/dist-packages/plinth/modules/ejabberd/views.py”, line 44, in get_initial
initdict.update({‘MAM_enabled’: self.is_MAM_enabled()})
File “/usr/lib/python3/dist-packages/plinth/modules/ejabberd/views.py”, line 88, in is_MAM_enabled
output = actions.superuser_run(‘ejabberd’, [‘mam’, ‘status’])
File “/usr/lib/python3/dist-packages/plinth/actions.py”, line 120, in superuser_run
log_error=log_error)
File “/usr/lib/python3/dist-packages/plinth/actions.py”, line 215, in _run
raise ActionError(action, output, error)
plinth.errors.ActionError: (‘ejabberd’, ‘’, ‘Traceback (most recent call last):\n File “/usr/share/plinth/actions/ejabberd”, line 327, in \n main()\n File “/usr/share/plinth/actions/ejabberd”, line 323, in main\n subcommand_method(arguments)\n File “/usr/share/plinth/actions/ejabberd”, line 258, in subcommand_mam\n conf = ruamel.yaml.round_trip_load(file_handle, preserve_quotes=True)\n File “/usr/lib/python3/dist-packages/ruamel/yaml/main.py”, line 685, in round_trip_load\n return load(stream, RoundTripLoader, version, preserve_quotes=preserve_quotes)\n File “/usr/lib/python3/dist-packages/ruamel/yaml/main.py”, line 636, in load\n return loader._constructor.get_single_data() # type: ignore\n File “/usr/lib/python3/dist-packages/ruamel/yaml/constructor.py”, line 102, in get_single_data\n node = self.composer.get_single_node()\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 75, in get_single_node\n document = self.compose_document()\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 96, in compose_document\n node = self.compose_node(None, None)\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 132, in compose_node\n node = self.compose_mapping_node(anchor)\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 194, in compose_mapping_node\n item_value = self.compose_node(node, item_key)\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 130, in compose_node\n node = self.compose_sequence_node(anchor)\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 163, in compose_sequence_node\n node.value.append(self.compose_node(node, index))\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 132, in compose_node\n node = self.compose_mapping_node(anchor)\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 194, in compose_mapping_node\n item_value = self.compose_node(node, item_key)\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 132, in compose_node\n node = self.compose_mapping_node(anchor)\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 194, in compose_mapping_node\n item_value = self.compose_node(node, item_key)\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 106, in compose_node\n if self.parser.check_event(AliasEvent):\n File “/usr/lib/python3/dist-packages/ruamel/yaml/parser.py”, line 144, in check_event\n self.current_event = self.state()\n File “/usr/lib/python3/dist-packages/ruamel/yaml/parser.py”, line 577, in parse_block_mapping_value\n if self.scanner.check_token(ValueToken):\n File “/usr/lib/python3/dist-packages/ruamel/yaml/scanner.py”, line 1620, in check_token\n self._gather_comments()\n File “/usr/lib/python3/dist-packages/ruamel/yaml/scanner.py”, line 1662, in _gather_comments\n self.fetch_more_tokens()\n File “/usr/lib/python3/dist-packages/ruamel/yaml/scanner.py”, line 273, in fetch_more_tokens\n return self.fetch_value()\n File “/usr/lib/python3/dist-packages/ruamel/yaml/scanner.py”, line 626, in fetch_value\n self.reader.get_mark())\nruamel.yaml.scanner.ScannerError: mapping values are not allowed here\n in “/etc/ejabberd/ejabberd.yml”, line 74, column 16\n’)
Feb 22 12:25:18 freedombox /usr/bin/plinth[436]: # help get-logs
Feb 22 12:25:18 freedombox sudo[2138]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/help get-logs
Feb 22 12:25:18 freedombox sudo[2138]: pam_unix(sudo:session): session opened for user root by catav(uid=0)

  1. You must also uncomment the lines
mod_http_upload:
    put_url: "https://@HOST@:5443/upload"
  1. You have to add the 5443 port to the service xmpp-server in the firewallD of freedombox
    sudo firewall-cmd --permanent --service=xmpp-server --add-port=5443/tcp
  2. Of course you must open that port also in your routers NAT
  3. I still get an error Connection closed by peer in my xmpp clients. According to /var/log/ejabberd.log this is due to the lack of matching certificates for <mydomain>.net and the needed subdomains pubsub, echo and so on. By default, ejabberd seems to be configured with a selfsigned cert. I’ll try to find a way to solve this with letsencrypt.

OK, in reference to the german instruction to configure an ejabbered instance at https://www.kuketz-blog.de/ejabberd-installation-und-betrieb-eines-xmpp-servers/ I managed at least the subdomain topic:

  1. I added the subdomains upload pubsub echo proxy and conference to my DNS-config of my domain at my hoster. Don’t know if that’s actually needed.

  2. Stopped my apache2 because otherwise certbot won’t be able to connect to port 80 and so can’t get any updated cert.

  3. Expand your letsencrypt cert by
    sudo certbot certonly -d mydomain.net -d conference.mydomain.net -d upload.mydomain.net -d pubsub.mydomain.net -d proxy.mydomain.net -d echo.mydomain.net -d conference.mydomain.net --standalone
    Don’t forget to restart apache2 after that of course!

  4. As you don’t want to change privs of your certs in /etc/letsencrypt and you shouldn’t be loading your ejabberd as root because of security, we have to copy our certs into an ejabberd-controlled directory. That means that we have to repeat this after every renewal of the letsencrypt certs :disappointed:

sudo mkdir /etc/ejabberd/certs
sudo cp /etc/letsencrypt/live/mydomain.net/fullchain.pem /etc/ejabberd/certs/mydomain.net.pem
sudo cp /etc/letsencrypt/live/mydomain.net/privkey.pem /etc/ejabberd/certs/mydomain.net.key
sudo chown ejabberd:ejabberd /etc/ejabberd/certs/
sudo chown ejabberd:ejabberd /etc/ejabberd/certs/*
sudo chmod 600 /etc/ejabberd/certs/*
sudo openssl dhparam -out /etc/ejabberd/dh4096.pem 4096
  1. In /etc/ejabberd/ejabbered.yml we edit
hosts:
    - "mydomain.net"
  1. and remove domains not needed like e.g. hostname, hostname.local or maybe your tor onion adress.
    Uncomment the old self-certified cert and put in your new copied cert files.
certfiles:
  ## - "/etc/ejabberd/ejabberd.pem"
  ## - "/etc/letsencrypt/live/*/*.pem"
  - "/etc/ejabberd/certs/mydomain.net.pem"
  - "/etc/ejabberd/certs/mydomain.net.key"
  1. You might also activate the Diffie-Hellman-Key for some TLS-CIphers
define_macro:
  'TLS_CIPHERS': "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECD\
HE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-S\
HA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SH\
A384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"
  'TLS_OPTIONS':
  - "no_sslv3"
  - "no_tlsv1"
  - "no_tlsv1_1"
  - "cipher_server_preference"
  - "no_compression"
    ## 'DH_FILE': "/path/to/dhparams.pem"
  'DH_FILE': "/etc/ejabberd/dh4096.pem"
  1. and uncomment
c2s_dhfile: 'DH_FILE'                                                           
s2s_dhfile: 'DH_FILE'    

That should suffice to remove error messages about missing certs form your /var/log/ejabberd/error.log

Unfortunately I still receive the same error in my clients and file transmission doesn’t work. There’s no error message in the ejabberd-logs regarding this :confused:
So I’ll have to keep on looking.

Found the failure!
I had to force tls in the listen-section of ejabberd.yml

listen:
- port: 5222
  ip: "::"
  module: ejabberd_c2s
  max_stanza_size: 262144
  shaper: c2s_shaper
  access: c2s
  starttls_required: true ## <--- Here ...
  protocol_options: 'TLS_OPTIONS'
- port: 5223
  ip: "::"
  module: ejabberd_c2s
  max_stanza_size: 262144
  shaper: c2s_shaper
  access: c2s
  tls: true ## <--- ... here ...
  protocol_options: 'TLS_OPTIONS'
[...]
- port: 5443
  ip: "::"
  module: ejabberd_http
  request_handlers:
    "/api": mod_http_api
    "/bosh": mod_bosh
    "/upload": mod_http_upload
    "/ws": ejabberd_http_ws
    ## captcha: true
    ## register: true
  tls: true ## <--- ... and THIS! makes uploads work finally.
  ciphers: 'TLS_CIPHERS'
  protocol_options: 'TLS_OPTIONS'
  web_admin: true

Now file uploads work like a charm :purple_heart:

Hi,
Idid all of them and my problem not related ssl certificate. When I uncomment http_upload related lines, ejabberd server doesn’t start.

This is the error log output:

– Logs begin at Tue 2020-03-03 19:59:35 UTC, end at Wed 2020-03-04 12:20:01 UTC. –
Mar 04 01:00:31 freedombox sudo[3007]: pam_unix(sudo:session): session closed for user root
Mar 04 02:00:30 freedombox /usr/bin/plinth[421]: # storage usage-info
Mar 04 02:00:30 freedombox sudo[3192]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/storage usage-info
Mar 04 02:00:30 freedombox sudo[3192]: pam_unix(sudo:session): session opened for user root by (uid=0)
Mar 04 02:00:31 freedombox sudo[3192]: pam_unix(sudo:session): session closed for user root
Mar 04 03:00:30 freedombox /usr/bin/plinth[421]: # storage usage-info
Mar 04 03:00:30 freedombox sudo[3367]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/storage usage-info
Mar 04 03:00:30 freedombox sudo[3367]: pam_unix(sudo:session): session opened for user root by (uid=0)
Mar 04 03:00:31 freedombox sudo[3367]: pam_unix(sudo:session): session closed for user root
Mar 04 04:00:30 freedombox /usr/bin/plinth[421]: # storage usage-info
Mar 04 04:00:30 freedombox sudo[3650]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/storage usage-info
Mar 04 04:00:30 freedombox sudo[3650]: pam_unix(sudo:session): session opened for user root by (uid=0)
Mar 04 04:00:31 freedombox sudo[3650]: pam_unix(sudo:session): session closed for user root
Mar 04 05:00:31 freedombox /usr/bin/plinth[421]: # storage usage-info
Mar 04 05:00:31 freedombox sudo[4018]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/storage usage-info
Mar 04 05:00:31 freedombox sudo[4018]: pam_unix(sudo:session): session opened for user root by (uid=0)
Mar 04 05:00:31 freedombox sudo[4018]: pam_unix(sudo:session): session closed for user root
Mar 04 06:00:31 freedombox /usr/bin/plinth[421]: # storage usage-info
Mar 04 06:00:31 freedombox sudo[4427]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/storage usage-info
Mar 04 06:00:31 freedombox sudo[4427]: pam_unix(sudo:session): session opened for user root by (uid=0)
Mar 04 06:00:31 freedombox sudo[4427]: pam_unix(sudo:session): session closed for user root
Mar 04 07:00:31 freedombox /usr/bin/plinth[421]: # storage usage-info
Mar 04 07:00:31 freedombox sudo[4906]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/storage usage-info
Mar 04 07:00:31 freedombox sudo[4906]: pam_unix(sudo:session): session opened for user root by (uid=0)
Mar 04 07:00:31 freedombox sudo[4906]: pam_unix(sudo:session): session closed for user root
Mar 04 08:00:31 freedombox /usr/bin/plinth[421]: # storage usage-info
Mar 04 08:00:31 freedombox sudo[5177]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/storage usage-info
Mar 04 08:00:31 freedombox sudo[5177]: pam_unix(sudo:session): session opened for user root by (uid=0)
Mar 04 08:00:31 freedombox sudo[5177]: pam_unix(sudo:session): session closed for user root
Mar 04 09:00:31 freedombox /usr/bin/plinth[421]: # storage usage-info
Mar 04 09:00:31 freedombox sudo[5366]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/storage usage-info
Mar 04 09:00:31 freedombox sudo[5366]: pam_unix(sudo:session): session opened for user root by (uid=0)
Mar 04 09:00:31 freedombox sudo[5366]: pam_unix(sudo:session): session closed for user root
Mar 04 10:00:31 freedombox /usr/bin/plinth[421]: # storage usage-info
Mar 04 10:00:31 freedombox sudo[5546]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/storage usage-info
Mar 04 10:00:31 freedombox sudo[5546]: pam_unix(sudo:session): session opened for user root by (uid=0)
Mar 04 10:00:32 freedombox sudo[5546]: pam_unix(sudo:session): session closed for user root
Mar 04 10:58:39 freedombox /usr/bin/plinth[421]: AXES: Successful login by {user: ‘user’, ip: ‘46.106.73.228’, user-agent: ‘Mozilla/5.0 (Android 10; Mobile; rv:73.0) Gecko/73.0 Firefox/73.0’, path: ‘/accounts/login/’}.
Mar 04 10:58:39 freedombox /usr/bin/plinth[421]: # auth-pubtkt generate-ticket --uid user --private-key-file /etc/apache2/auth-pubtkt-keys/privkey.pem --tokens admin
Mar 04 10:58:39 freedombox sudo[5755]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/auth-pubtkt generate-ticket --uid user --private-key-file /etc/apache2/auth-pubtkt-keys/privkey.pem --tokens admin
Mar 04 10:58:39 freedombox sudo[5755]: pam_unix(sudo:session): session opened for user root by (uid=0)
Mar 04 10:58:41 freedombox sudo[5755]: pam_unix(sudo:session): session closed for user root
Mar 04 10:58:41 freedombox /usr/bin/plinth[421]: # users get-user-groups user
Mar 04 10:58:41 freedombox sudo[5759]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/users get-user-groups user
Mar 04 10:58:41 freedombox sudo[5759]: pam_unix(sudo:session): session opened for user root by (uid=0)
Mar 04 10:58:42 freedombox ldapsearch[5801]: DIGEST-MD5 common mech free
Mar 04 10:58:42 freedombox ldapsearch[5807]: DIGEST-MD5 common mech free
Mar 04 10:58:42 freedombox ldapsearch[5817]: DIGEST-MD5 common mech free
Mar 04 10:58:42 freedombox ldapsearch[5826]: DIGEST-MD5 common mech free
Mar 04 10:58:42 freedombox ldapsearch[5842]: DIGEST-MD5 common mech free
Mar 04 10:58:42 freedombox sudo[5759]: pam_unix(sudo:session): session closed for user root
Mar 04 11:00:31 freedombox /usr/bin/plinth[421]: # storage usage-info
Mar 04 11:00:31 freedombox sudo[5860]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/storage usage-info
Mar 04 11:00:31 freedombox sudo[5860]: pam_unix(sudo:session): session opened for user root by (uid=0)
Mar 04 11:00:32 freedombox sudo[5860]: pam_unix(sudo:session): session closed for user root
Mar 04 12:00:31 freedombox /usr/bin/plinth[421]: # storage usage-info
Mar 04 12:00:31 freedombox sudo[6054]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/storage usage-info
Mar 04 12:00:31 freedombox sudo[6054]: pam_unix(sudo:session): session opened for user root by (uid=0)
Mar 04 12:00:32 freedombox sudo[6054]: pam_unix(sudo:session): session closed for user root
Mar 04 12:14:28 freedombox /usr/bin/plinth[421]: AXES: Successful login by {user: ‘user’, ip: ‘46.106.73.228’, user-agent: ‘Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36’, path: ‘/accounts/login/’}.
Mar 04 12:14:28 freedombox /usr/bin/plinth[421]: # auth-pubtkt generate-ticket --uid user --private-key-file /etc/apache2/auth-pubtkt-keys/privkey.pem --tokens admin
Mar 04 12:14:28 freedombox sudo[6140]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/auth-pubtkt generate-ticket --uid user --private-key-file /etc/apache2/auth-pubtkt-keys/privkey.pem --tokens admin
Mar 04 12:14:28 freedombox sudo[6140]: pam_unix(sudo:session): session opened for user root by (uid=0)
Mar 04 12:14:29 freedombox sudo[6140]: pam_unix(sudo:session): session closed for user root
Mar 04 12:14:31 freedombox /usr/bin/plinth[421]: # users get-user-groups user
Mar 04 12:14:31 freedombox sudo[6144]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/users get-user-groups user
Mar 04 12:14:31 freedombox sudo[6144]: pam_unix(sudo:session): session opened for user root by (uid=0)
Mar 04 12:14:31 freedombox ldapsearch[6186]: DIGEST-MD5 common mech free
Mar 04 12:14:31 freedombox ldapsearch[6192]: DIGEST-MD5 common mech free
Mar 04 12:14:31 freedombox ldapsearch[6201]: DIGEST-MD5 common mech free
Mar 04 12:14:31 freedombox ldapsearch[6211]: DIGEST-MD5 common mech free
Mar 04 12:14:31 freedombox ldapsearch[6228]: DIGEST-MD5 common mech free
Mar 04 12:14:31 freedombox sudo[6144]: pam_unix(sudo:session): session closed for user root
Mar 04 12:19:46 freedombox /usr/bin/plinth[421]: # users get-user-groups user
Mar 04 12:19:46 freedombox sudo[6318]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/users get-user-groups user
Mar 04 12:19:46 freedombox sudo[6318]: pam_unix(sudo:session): session opened for user root by user(uid=0)
Mar 04 12:19:47 freedombox ldapsearch[6361]: DIGEST-MD5 common mech free
Mar 04 12:19:47 freedombox ldapsearch[6366]: DIGEST-MD5 common mech free
Mar 04 12:19:47 freedombox ldapsearch[6376]: DIGEST-MD5 common mech free
Mar 04 12:19:47 freedombox ldapsearch[6385]: DIGEST-MD5 common mech free
Mar 04 12:19:47 freedombox ldapsearch[6402]: DIGEST-MD5 common mech free
Mar 04 12:19:47 freedombox sudo[6318]: pam_unix(sudo:session): session closed for user root
Mar 04 12:19:50 freedombox /usr/bin/plinth[421]: # users get-user-groups user
Mar 04 12:19:50 freedombox sudo[6409]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/users get-user-groups user
Mar 04 12:19:50 freedombox sudo[6409]: pam_unix(sudo:session): session opened for user root by user(uid=0)
Mar 04 12:19:50 freedombox ldapsearch[6450]: DIGEST-MD5 common mech free
Mar 04 12:19:50 freedombox ldapsearch[6457]: DIGEST-MD5 common mech free
Mar 04 12:19:50 freedombox ldapsearch[6467]: DIGEST-MD5 common mech free
Mar 04 12:19:50 freedombox ldapsearch[6476]: DIGEST-MD5 common mech free
Mar 04 12:19:50 freedombox ldapsearch[6492]: DIGEST-MD5 common mech free
Mar 04 12:19:50 freedombox sudo[6409]: pam_unix(sudo:session): session closed for user root
Mar 04 12:19:54 freedombox /usr/bin/plinth[421]: # ejabberd mam status
Mar 04 12:19:54 freedombox sudo[6506]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/ejabberd mam status
Mar 04 12:19:54 freedombox sudo[6506]: pam_unix(sudo:session): session opened for user root by user(uid=0)
Mar 04 12:19:55 freedombox sudo[6506]: pam_unix(sudo:session): session closed for user root
Mar 04 12:19:55 freedombox /usr/bin/plinth[421]: Error executing command - [‘sudo’, ‘-n’, ‘/usr/share/plinth/actions/ejabberd’, ‘mam’, ‘status’], , Traceback (most recent call last):
File “/usr/share/plinth/actions/ejabberd”, line 312, in
main()
File “/usr/share/plinth/actions/ejabberd”, line 308, in main
subcommand_method(arguments)
File “/usr/share/plinth/actions/ejabberd”, line 243, in subcommand_mam
conf = ruamel.yaml.round_trip_load(file_handle, preserve_quotes=True)
File “/usr/lib/python3/dist-packages/ruamel/yaml/main.py”, line 685, in round_trip_load
return load(stream, RoundTripLoader, version, preserve_quotes=preserve_quotes)
File “/usr/lib/python3/dist-packages/ruamel/yaml/main.py”, line 636, in load
return loader._constructor.get_single_data() # type: ignore
File “/usr/lib/python3/dist-packages/ruamel/yaml/constructor.py”, line 102, in get_single_data
node = self.composer.get_single_node()
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 75, in get_single_node
document = self.compose_document()
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 96, in compose_document
node = self.compose_node(None, None)
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 132, in compose_node
node = self.compose_mapping_node(anchor)
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 194, in compose_mapping_node
item_value = self.compose_node(node, item_key)
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 132, in compose_node
node = self.compose_mapping_node(anchor)
File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 187, in compose_mapping_node
while not self.parser.check_event(MappingEndEvent):
File “/usr/lib/python3/dist-packages/ruamel/yaml/parser.py”, line 144, in check_event
self.current_event = self.state()
File “/usr/lib/python3/dist-packages/ruamel/yaml/parser.py”, line 561, in parse_block_mapping_key
token.start_mark)
ruamel.yaml.parser.ParserError: while parsing a block mapping
in “/etc/ejabberd/ejabberd.yml”, line 172, column 3
expected , but found ‘’
in “/etc/ejabberd/ejabberd.yml”, line 188, column 4
Mar 04 12:19:55 freedombox /usr/bin/plinth[421]: Internal Server Error: /plinth/apps/ejabberd/
Traceback (most recent call last):
File “/usr/lib/python3/dist-packages/django/core/handlers/exception.py”, line 41, in inner
response = get_response(request)
File “/usr/lib/python3/dist-packages/django/core/handlers/base.py”, line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File “/usr/lib/python3/dist-packages/django/core/handlers/base.py”, line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File “/usr/lib/python3/dist-packages/django/views/generic/base.py”, line 68, in view
return self.dispatch(request, *args, **kwargs)
File “/usr/lib/python3/dist-packages/django/views/generic/base.py”, line 88, in dispatch
return handler(request, *args, **kwargs)
File “/usr/lib/python3/dist-packages/django/views/generic/edit.py”, line 174, in get
return self.render_to_response(self.get_context_data())
File “/usr/lib/python3/dist-packages/plinth/modules/ejabberd/views.py”, line 30, in get_context_data
context = super().get_context_data(*args, **kwargs)
File “/usr/lib/python3/dist-packages/plinth/views.py”, line 198, in get_context_data
context = super().get_context_data(*args, **kwargs)
File “/usr/lib/python3/dist-packages/django/views/generic/edit.py”, line 93, in get_context_data
kwargs[‘form’] = self.get_form()
File “/usr/lib/python3/dist-packages/django/views/generic/edit.py”, line 45, in get_form
return form_class(**self.get_form_kwargs())
File “/usr/lib/python3/dist-packages/django/views/generic/edit.py”, line 52, in get_form_kwargs
‘initial’: self.get_initial(),
File “/usr/lib/python3/dist-packages/plinth/modules/ejabberd/views.py”, line 25, in get_initial
initdict.update({‘MAM_enabled’: self.is_MAM_enabled()})
File “/usr/lib/python3/dist-packages/plinth/modules/ejabberd/views.py”, line 68, in is_MAM_enabled
output = actions.superuser_run(‘ejabberd’, [‘mam’, ‘status’])
File “/usr/lib/python3/dist-packages/plinth/actions.py”, line 105, in superuser_run
log_error=log_error)
File “/usr/lib/python3/dist-packages/plinth/actions.py”, line 200, in _run
raise ActionError(action, output, error)
plinth.errors.ActionError: (‘ejabberd’, ‘’, ‘Traceback (most recent call last):\n File “/usr/share/plinth/actions/ejabberd”, line 312, in \n main()\n File “/usr/share/plinth/actions/ejabberd”, line 308, in main\n subcommand_method(arguments)\n File “/usr/share/plinth/actions/ejabberd”, line 243, in subcommand_mam\n conf = ruamel.yaml.round_trip_load(file_handle, preserve_quotes=True)\n File “/usr/lib/python3/dist-packages/ruamel/yaml/main.py”, line 685, in round_trip_load\n return load(stream, RoundTripLoader, version, preserve_quotes=preserve_quotes)\n File “/usr/lib/python3/dist-packages/ruamel/yaml/main.py”, line 636, in load\n return loader._constructor.get_single_data() # type: ignore\n File “/usr/lib/python3/dist-packages/ruamel/yaml/constructor.py”, line 102, in get_single_data\n node = self.composer.get_single_node()\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 75, in get_single_node\n document = self.compose_document()\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 96, in compose_document\n node = self.compose_node(None, None)\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 132, in compose_node\n node = self.compose_mapping_node(anchor)\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 194, in compose_mapping_node\n item_value = self.compose_node(node, item_key)\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 132, in compose_node\n node = self.compose_mapping_node(anchor)\n File “/usr/lib/python3/dist-packages/ruamel/yaml/composer.py”, line 187, in compose_mapping_node\n while not self.parser.check_event(MappingEndEvent):\n File “/usr/lib/python3/dist-packages/ruamel/yaml/parser.py”, line 144, in check_event\n self.current_event = self.state()\n File “/usr/lib/python3/dist-packages/ruamel/yaml/parser.py”, line 561, in parse_block_mapping_key\n token.start_mark)\nruamel.yaml.parser.ParserError: while parsing a block mapping\n in “/etc/ejabberd/ejabberd.yml”, line 172, column 3\nexpected , but found ‘’\n in “/etc/ejabberd/ejabberd.yml”, line 188, column 4\n’)
Mar 04 12:20:01 freedombox /usr/bin/plinth[421]: # help get-logs
Mar 04 12:20:01 freedombox sudo[6509]: plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/help get-logs
Mar 04 12:20:01 freedombox sudo[6509]: pam_unix(sudo:session): session opened for user root by user(uid=0)

:slight_smile: That’s a common problem with yaml files …
Open the ejabberd.yml in your editor, jump to line 188. There’s probably sth wrong with indention or there’s a ’ too much. Try reformating the block between 172 and 188.

If you don’t find it yourself, post a snippet from lines 170 to 190 of your ejabberd.yml here so I can take a look at it.

BTW: I edited my post above. Now upload is working!

Hi,
ejabberd.yml file’s section You asked as follow;

modules:
  mod_adhoc: {}
  mod_admin_extra: {}
  mod_announce:
    access: announce
  mod_avatar: {}
  mod_blocking: {}
  mod_bosh: {}
  mod_caps: {}
  mod_carboncopy: {}
  mod_client_state: {}
  mod_configure: {}
  ## mod_delegation: {}   # for xep0356
  mod_disco: {}
  mod_echo: {}
  mod_fail2ban: {}
  mod_http_api: {}
  ## mod_http_upload:
  ## docroot: /ejabberd/upload  
  ## put_url: "https://@HOST@:5443/upload"
  mod_last: {}
  mod_mam:
  ##   ## Mnesia is limited to 2GB, better to use an SQL backend
  ##   ## For small servers SQLite is a good fit and is very easy
  ##   ## to configure. Uncomment this when you have SQL configured:
  ##   ## db_type: sql
     assume_mam_usage: true
     default: always
  mod_muc:

I hope this is solve my iOS client upload problem. Thanks for your attention.

Uncomment the mod_mam module:

mod_last: {}
  ## mod_mam:
  ##   ## Mnesia is limited to 2GB, better to use an SQL backend
  ##   ## For small servers SQLite is a good fit and is very easy
  ##   ## to configure. Uncomment this when you have SQL configured:
  ##   ## db_type: sql
  ##   assume_mam_usage: true
  ##   default: always
  mod_muc:

In my file there’s another mod_mam section:

  mod_mam:                                                                      
    db_type: mnesia                                                             
    default: always                                                             
    request_activates_archiving: true                                           
    assume_mam_usage: true                                                      
    cache_size: 1000                                                            
    cache_life_time: 3600

Maybe this doubling is the cause?
Try to restart ejabberd after commenting out.

Does it work now? It has definitely to do with the mod_mam.

:confounded:
Unfortunately you can either have a working upload OR a working jsxc webclient …
Which of both depends on your choice to set
tls = true (upload works) or false (jsxc works). The login screen informs that it cannot connect to bosh server and throws error code 520.
I don’t know much about bosh, but I understand that in the past it worked without ssl on port 5280. Maybe bosh isn’t able to use tls at all? …

Hi,
Unfortunately I cant solve. Whole yml file is as follow;

## loglevel: Verbosity of log files generated by ejabberd
## 0: No ejabberd log at all (not recommended)
## 1: Critical
## 2: Error
## 3: Warning
## 4: Info
## 5: Debug
loglevel: 4

## rotation: Disable ejabberd's internal log rotation, as the Debian package
## uses logrotate(8).
log_rotate_count: 0
log_rotate_date: ""

## hosts: Domains served by ejabberd.
## You can define one or several, for example:
## hosts:
##   - "example.net"
##   - "example.com"
##   - "example.org"
hosts:
- "xxxx.yyy"

certfiles:
- "/etc/ejabberd/ejabberd.pem"
  ## - "/etc/letsencrypt/live/*/*.pem"

## TLS configuration
define_macro:
  'TLS_CIPHERS': "HIGH:!aNULL:!eNULL:!3DES:@STRENGTH"
  'TLS_OPTIONS':
  - "no_sslv3"
  - "no_tlsv1"
  - "no_tlsv1_1"
  - "cipher_server_preference"
  - "no_compression"
    ## 'DH_FILE': "/path/to/dhparams.pem"
    ## generated with: openssl dhparam -out dhparams.pem 2048

c2s_ciphers: 'TLS_CIPHERS'
s2s_ciphers: 'TLS_CIPHERS'
c2s_protocol_options: 'TLS_OPTIONS'
s2s_protocol_options: 'TLS_OPTIONS'
## c2s_dhfile: 'DH_FILE'
## s2s_dhfile: 'DH_FILE'

listen:
- port: 5222
  ip: "::"
  module: ejabberd_c2s
  max_stanza_size: 262144
  shaper: c2s_shaper
  access: c2s
  starttls_required: true
  protocol_options: 'TLS_OPTIONS'
- port: 5223
  ip: "::"
  module: ejabberd_c2s
  max_stanza_size: 262144
  shaper: c2s_shaper
  access: c2s
  tls: false
  protocol_options: 'TLS_OPTIONS'
- port: 5269
  ip: "::"
  module: ejabberd_s2s_in
  max_stanza_size: 524288
- port: 5443
  ip: "::"
  module: ejabberd_http
  request_handlers:
    "/api": mod_http_api
    "/bosh": mod_bosh
    "/upload": mod_http_upload
    "/ws": ejabberd_http_ws
    ## captcha: true
    ## register: true
  tls: true
  protocol_options: 'TLS_OPTIONS'
  web_admin: true

## Disabling digest-md5 SASL authentication. digest-md5 requires plain-text
## password storage (see auth_password_format option).
disable_sasl_mechanisms:
- "digest-md5"
- "X-OAUTH2"

s2s_use_starttls: required

## Store the plain passwords or hashed for SCRAM:
auth_password_format: scram

## Full path to a script that generates the image.
## captcha_cmd: "/usr/share/ejabberd/captcha.sh"

acl:
  admin:
    user:
    - ""

  local:
    user_regexp: ""
  loopback:
    ip:
    - "127.0.0.0/8"
    - "::1/128"
    - "::FFFF:127.0.0.1/128"

access_rules:
  local:
  - allow: local
  c2s:
  - deny: blocked
  - allow
  announce:
  - allow: admin
  configure:
  - allow: admin
  muc_create:
  - allow: local
  pubsub_createnode:
  - allow: local
  register:
  - allow
  trusted_network:
  - allow: loopback

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"

shaper:
  normal: 1000
  fast: 50000

shaper_rules:
  max_user_sessions: 10
  max_user_offline_messages:
  - 5000: admin
  - 100
  c2s_shaper:
  - none: admin
  - normal
  s2s_shaper: fast

modules:
  mod_adhoc: {}
  mod_admin_extra: {}
  mod_announce:
    access: announce
  mod_avatar: {}
  mod_blocking: {}
  mod_bosh: {}
  mod_caps: {}
  mod_carboncopy: {}
  mod_client_state: {}
  mod_configure: {}
  ## mod_delegation: {}   # for xep0356
  mod_disco: {}
  mod_echo: {}
  mod_fail2ban: {}
  mod_http_api: {}
   mod_http_upload:
   docroot: /ejabberd/upload  
   put_url: "https://@HOST@:5443/upload"
  mod_last: {}
##  mod_mam:
  ##   ## Mnesia is limited to 2GB, better to use an SQL backend
  ##   ## For small servers SQLite is a good fit and is very easy
  ##   ## to configure. Uncomment this when you have SQL configured:
  ##   ## db_type: sql
##     assume_mam_usage: true
##     default: always
  mod_muc:
    access:
    - allow
    access_admin:
    - allow: admin
    access_create: muc_create
    access_persistent: muc_create
    default_room_options:
      mam: true
  mod_muc_admin: {}
  mod_offline:
    access_max_user_messages: max_user_offline_messages
  mod_ping: {}
  mod_pres_counter:
    count: 5
    interval: 60
  mod_privacy: {}
  mod_private: {}
  ## mod_proxy65: {}
  mod_pubsub:
    access_createnode: pubsub_createnode
    plugins:
    - "flat"
    - "pep"
    force_node_config:
      "eu.siacs.conversations.axolotl.*":
        access_model: open
      ## Avoid buggy clients to make their bookmarks public
      "storage:bookmarks":
        access_model: whitelist
  mod_push: {}
  mod_push_keepalive: {}
  ## mod_register:
  ##   ## Only accept registration requests from the "trusted"
  ##   ## network (see access_rules section above).
  ##   ## Think twice before enabling registration from any
  ##   ## address. See the Jabber SPAM Manifesto for details:
  ##   ## https://github.com/ge0rg/jabber-spam-fighting-manifesto
  ##   ip_access: trusted_network
  mod_roster:
    versioning: true
  mod_s2s_dialback: {}
  mod_shared_roster: {}
  mod_sic: {}
  mod_stream_mgmt:
    resend_on_timeout: if_offline
  mod_vcard:
    search: false
  mod_vcard_xupdate: {}
  mod_version: {}
  mod_mam:
    db_type: mnesia
    default: always
    request_activates_archiving: true
    assume_mam_usage: true
    cache_size: 1000
    cache_life_time: 3600
auth_method: ldap
ldap_servers:
- "localhost"
ldap_base: "ou=users,dc=thisbox"
s2s_certfile: "/etc/ejabberd/letsencrypt/xxx.yyy/ejabberd.pem"

### Local Variables:
### mode: yaml
### End:
### vim: set filetype=yaml tabstop=8

There is no obvious failure in your file, so I can’t say where’s the problem by this.

Proposal:

  1. Open 2 shells on your machine.
  2. On the first do
    sudo tail -f /var/log/ejabberd.log
  3. On the second do
    sudo systemctl restart ejabberd
  4. Switch to the first one again and watch the error output of ejabberd while starting - this might take a while!
  5. It should end with the message that ejabberd coud not start. Read this log output from bottom to top. If there’s a message that ejabberd couldn’t process something in the ejabberd.yml it should also report a line number where it had failed.
  6. Switch to the second shell and open the ejabberd.yml again. Jump to the line the log reported. Check the line and maybe the block beyond if there might be a char too much or if there’s a space missing between <key>: <value> pair. Check if indention of the lines is actually correct.
  7. If you altered anything in the file: Start at 3. again
  8. If you find nothing to alter in the .yml file copy the area around the line of the error message and post it hier in [code]-block. And I will have a look.

By the way: Which editor do you use for editing the .yml file? nano, emacs, vim or any other?

Just to mention:
The upload problem is definitely a ssl related I think. iOS client might be very strict in regards to self certified certificates and won’t accept the connection for the upload I’m afraid.

After you made your ejabberd starting again you should definitely compare my snippets here with your config file and adjust especially the certs to be your valid letsencrypt files and should turn on tls-option for port 5223.

Also the client might be restricted to certain ciphers with need the dhparams.pem to work so you might also follow my advice from above regarding this (step 7. and 8. of my “tutorial”)

Good luck and fingers crossed! :slight_smile:

Hi,
I’m tried your suggestions but failed. Error log is as follow;

Mar 27 10:41:50 freedombox /usr/bin/plinth[416]: Error executing command - ['sudo', '-n', '/usr/share/plinth/actions/ejabberd', 'mam', 'status'], , Traceback (most recent call last):
                                                   File "/usr/share/plinth/actions/ejabberd", line 312, in <module>
                                                     main()
                                                   File "/usr/share/plinth/actions/ejabberd", line 308, in main
                                                     subcommand_method(arguments)
                                                   File "/usr/share/plinth/actions/ejabberd", line 243, in subcommand_mam
                                                     conf = ruamel.yaml.round_trip_load(file_handle, preserve_quotes=True)
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/main.py", line 685, in round_trip_load
                                                     return load(stream, RoundTripLoader, version, preserve_quotes=preserve_quotes)
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/main.py", line 636, in load
                                                     return loader._constructor.get_single_data()  # type: ignore
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/constructor.py", line 102, in get_single_data
                                                     node = self.composer.get_single_node()
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 75, in get_single_node
                                                     document = self.compose_document()
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 96, in compose_document
                                                     node = self.compose_node(None, None)
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 132, in compose_node
                                                     node = self.compose_mapping_node(anchor)
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 194, in compose_mapping_node
                                                     item_value = self.compose_node(node, item_key)
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 132, in compose_node
                                                     node = self.compose_mapping_node(anchor)
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 187, in compose_mapping_node
                                                     while not self.parser.check_event(MappingEndEvent):
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/parser.py", line 144, in check_event
                                                     self.current_event = self.state()
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/parser.py", line 561, in parse_block_mapping_key
                                                     token.start_mark)
                                                 ruamel.yaml.parser.ParserError: while parsing a block mapping
                                                   in "/etc/ejabberd/ejabberd.yml", line 172, column 3
                                                 expected <block end>, but found '<block mapping start>'
                                                   in "/etc/ejabberd/ejabberd.yml", line 188, column 4
Mar 27 10:41:50 freedombox /usr/bin/plinth[416]: Internal Server Error: /plinth/apps/ejabberd/
                                                 Traceback (most recent call last):
                                                   File "/usr/lib/python3/dist-packages/django/core/handlers/exception.py", line 41, in inner
                                                     response = get_response(request)
                                                   File "/usr/lib/python3/dist-packages/django/core/handlers/base.py", line 187, in _get_response
                                                     response = self.process_exception_by_middleware(e, request)
                                                   File "/usr/lib/python3/dist-packages/django/core/handlers/base.py", line 185, in _get_response
                                                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
                                                   File "/usr/lib/python3/dist-packages/django/views/generic/base.py", line 68, in view
                                                     return self.dispatch(request, *args, **kwargs)
                                                   File "/usr/lib/python3/dist-packages/django/views/generic/base.py", line 88, in dispatch
                                                     return handler(request, *args, **kwargs)
                                                   File "/usr/lib/python3/dist-packages/django/views/generic/edit.py", line 174, in get
                                                     return self.render_to_response(self.get_context_data())
                                                   File "/usr/lib/python3/dist-packages/plinth/modules/ejabberd/views.py", line 30, in get_context_data
                                                     context = super().get_context_data(*args, **kwargs)
                                                   File "/usr/lib/python3/dist-packages/plinth/views.py", line 193, in get_context_data
                                                     context = super().get_context_data(*args, **kwargs)
                                                   File "/usr/lib/python3/dist-packages/django/views/generic/edit.py", line 93, in get_context_data
                                                     kwargs['form'] = self.get_form()
                                                   File "/usr/lib/python3/dist-packages/django/views/generic/edit.py", line 45, in get_form
                                                     return form_class(**self.get_form_kwargs())
                                                   File "/usr/lib/python3/dist-packages/django/views/generic/edit.py", line 52, in get_form_kwargs
                                                     'initial': self.get_initial(),
                                                   File "/usr/lib/python3/dist-packages/plinth/modules/ejabberd/views.py", line 25, in get_initial
                                                     initdict.update({'MAM_enabled': self.is_MAM_enabled()})
                                                   File "/usr/lib/python3/dist-packages/plinth/modules/ejabberd/views.py", line 68, in is_MAM_enabled
                                                     output = actions.superuser_run('ejabberd', ['mam', 'status'])
                                                   File "/usr/lib/python3/dist-packages/plinth/actions.py", line 105, in superuser_run
                                                     log_error=log_error)
                                                   File "/usr/lib/python3/dist-packages/plinth/actions.py", line 200, in _run
                                                     raise ActionError(action, output, error)
                                                 plinth.errors.ActionError: ('ejabberd', '', 'Traceback (most recent call last):\n  File "/usr/share/plinth/actions/ejabberd", line 312, in <module>\n    main()\n  File "/usr/share/plinth/actions/ejabberd", line 308, in main\n    subcommand_method(arguments)\n  File "/usr/share/plinth/actions/ejabberd", line 243, in subcommand_mam\n    conf = ruamel.yaml.round_trip_load(file_handle, preserve_quotes=True)\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/main.py", line 685, in round_trip_load\n    return load(stream, RoundTripLoader, version, preserve_quotes=preserve_quotes)\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/main.py", line 636, in load\n    return loader._constructor.get_single_data()  # type: ignore\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/constructor.py", line 102, in get_single_data\n    node = self.composer.get_single_node()\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 75, in get_single_node\n    document = self.compose_document()\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 96, in compose_document\n    node = self.compose_node(None, None)\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 132, in compose_node\n    node = self.compose_mapping_node(anchor)\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 194, in compose_mapping_node\n    item_value = self.compose_node(node, item_key)\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 132, in compose_node\n    node = self.compose_mapping_node(anchor)\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 187, in compose_mapping_node\n    while not self.parser.check_event(MappingEndEvent):\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/parser.py", line 144, in check_event\n    self.current_event = self.state()\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/parser.py", line 561, in parse_block_mapping_key\n    token.start_mark)\nruamel.yaml.parser.ParserError: while parsing a block mapping\n  in "/etc/ejabberd/ejabberd.yml", line 172, column 3\nexpected <block end>, but found \'<block mapping start>\'\n  in "/etc/ejabberd/ejabberd.yml", line 188, column 4\n')
Mar 27 10:41:53 freedombox /usr/bin/plinth[416]: # help get-logs
Mar 27 10:41:53 freedombox sudo[4248]:   plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/help get-logs

There are warnings about lines 188, 172 in .yml file. I did not see problems, if any.
The log file contains a few conf file warnings also.

Can You able to share files from or to iOS client?

Btw, I use nano as editor.

OK, I copied your files now into my editor.
After checking your ejabberd.conf again the online possible mistake I can find at those lines is an indention error in the mod_http_api (line 187):

The block indention is only 1 char while other blocks in your file indent with 2 chars. This could explain why the parser doesn’t identifies line 188 as part of the block.

Solution:

  1. add a space before the lines like this
mod_http_api: {}
    mod_http_upload:
    docroot: /ejabberd/upload  
    put_url: "https://@HOST@:5443/upload"
  1. sudo systemctl restart ejabberd again.
    Hopefully ejabberd will start as it should now.

I cannot tell you about macos clients unfortunately. I have none to check here.

Hi,
Following lines are still problematic;
line 172 column 3 and,
line 188 column 5.

I mentioned in OP, my problem is related iOS clients. Android clients work as expected, without http_upload setting.
IOS client warns me;


It needs http file upload (XEP-0363), why I’m trying to add XEP-0363 support. IOS clients send and receive plain text messages but not images and files.
When I try to uncomment related lines in yml file, following error occurs and ejabberd service not restart.
I’ll try to ask salsa.debian.org as a new issue.

Mar 27 14:09:31 freedombox /usr/bin/plinth[416]: Error executing command - ['sudo', '-n', '/usr/share/plinth/actions/ejabberd', 'mam', 'status'], , Traceback (most recent call last):
                                                   File "/usr/share/plinth/actions/ejabberd", line 312, in <module>
                                                     main()
                                                   File "/usr/share/plinth/actions/ejabberd", line 308, in main
                                                     subcommand_method(arguments)
                                                   File "/usr/share/plinth/actions/ejabberd", line 243, in subcommand_mam
                                                     conf = ruamel.yaml.round_trip_load(file_handle, preserve_quotes=True)
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/main.py", line 685, in round_trip_load
                                                     return load(stream, RoundTripLoader, version, preserve_quotes=preserve_quotes)
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/main.py", line 636, in load
                                                     return loader._constructor.get_single_data()  # type: ignore
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/constructor.py", line 102, in get_single_data
                                                     node = self.composer.get_single_node()
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 75, in get_single_node
                                                     document = self.compose_document()
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 96, in compose_document
                                                     node = self.compose_node(None, None)
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 132, in compose_node
                                                     node = self.compose_mapping_node(anchor)
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 194, in compose_mapping_node
                                                     item_value = self.compose_node(node, item_key)
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 132, in compose_node
                                                     node = self.compose_mapping_node(anchor)
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 187, in compose_mapping_node
                                                     while not self.parser.check_event(MappingEndEvent):
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/parser.py", line 144, in check_event
                                                     self.current_event = self.state()
                                                   File "/usr/lib/python3/dist-packages/ruamel/yaml/parser.py", line 561, in parse_block_mapping_key
                                                     token.start_mark)
                                                 ruamel.yaml.parser.ParserError: while parsing a block mapping
                                                   in "/etc/ejabberd/ejabberd.yml", line 172, column 3
                                                 expected <block end>, but found '<block mapping start>'
                                                   in "/etc/ejabberd/ejabberd.yml", line 188, column 5
Mar 27 14:09:32 freedombox /usr/bin/plinth[416]: Internal Server Error: /plinth/apps/ejabberd/
                                                 Traceback (most recent call last):
                                                   File "/usr/lib/python3/dist-packages/django/core/handlers/exception.py", line 41, in inner
                                                     response = get_response(request)
                                                   File "/usr/lib/python3/dist-packages/django/core/handlers/base.py", line 187, in _get_response
                                                     response = self.process_exception_by_middleware(e, request)
                                                   File "/usr/lib/python3/dist-packages/django/core/handlers/base.py", line 185, in _get_response
                                                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
                                                   File "/usr/lib/python3/dist-packages/django/views/generic/base.py", line 68, in view
                                                     return self.dispatch(request, *args, **kwargs)
                                                   File "/usr/lib/python3/dist-packages/django/views/generic/base.py", line 88, in dispatch
                                                     return handler(request, *args, **kwargs)
                                                   File "/usr/lib/python3/dist-packages/django/views/generic/edit.py", line 174, in get
                                                     return self.render_to_response(self.get_context_data())
                                                   File "/usr/lib/python3/dist-packages/plinth/modules/ejabberd/views.py", line 30, in get_context_data
                                                     context = super().get_context_data(*args, **kwargs)
                                                   File "/usr/lib/python3/dist-packages/plinth/views.py", line 193, in get_context_data
                                                     context = super().get_context_data(*args, **kwargs)
                                                   File "/usr/lib/python3/dist-packages/django/views/generic/edit.py", line 93, in get_context_data
                                                     kwargs['form'] = self.get_form()
                                                   File "/usr/lib/python3/dist-packages/django/views/generic/edit.py", line 45, in get_form
                                                     return form_class(**self.get_form_kwargs())
                                                   File "/usr/lib/python3/dist-packages/django/views/generic/edit.py", line 52, in get_form_kwargs
                                                     'initial': self.get_initial(),
                                                   File "/usr/lib/python3/dist-packages/plinth/modules/ejabberd/views.py", line 25, in get_initial
                                                     initdict.update({'MAM_enabled': self.is_MAM_enabled()})
                                                   File "/usr/lib/python3/dist-packages/plinth/modules/ejabberd/views.py", line 68, in is_MAM_enabled
                                                     output = actions.superuser_run('ejabberd', ['mam', 'status'])
                                                   File "/usr/lib/python3/dist-packages/plinth/actions.py", line 105, in superuser_run
                                                     log_error=log_error)
                                                   File "/usr/lib/python3/dist-packages/plinth/actions.py", line 200, in _run
                                                     raise ActionError(action, output, error)
                                                 plinth.errors.ActionError: ('ejabberd', '', 'Traceback (most recent call last):\n  File "/usr/share/plinth/actions/ejabberd", line 312, in <module>\n    main()\n  File "/usr/share/plinth/actions/ejabberd", line 308, in main\n    subcommand_method(arguments)\n  File "/usr/share/plinth/actions/ejabberd", line 243, in subcommand_mam\n    conf = ruamel.yaml.round_trip_load(file_handle, preserve_quotes=True)\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/main.py", line 685, in round_trip_load\n    return load(stream, RoundTripLoader, version, preserve_quotes=preserve_quotes)\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/main.py", line 636, in load\n    return loader._constructor.get_single_data()  # type: ignore\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/constructor.py", line 102, in get_single_data\n    node = self.composer.get_single_node()\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 75, in get_single_node\n    document = self.compose_document()\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 96, in compose_document\n    node = self.compose_node(None, None)\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 132, in compose_node\n    node = self.compose_mapping_node(anchor)\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 194, in compose_mapping_node\n    item_value = self.compose_node(node, item_key)\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 132, in compose_node\n    node = self.compose_mapping_node(anchor)\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/composer.py", line 187, in compose_mapping_node\n    while not self.parser.check_event(MappingEndEvent):\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/parser.py", line 144, in check_event\n    self.current_event = self.state()\n  File "/usr/lib/python3/dist-packages/ruamel/yaml/parser.py", line 561, in parse_block_mapping_key\n    token.start_mark)\nruamel.yaml.parser.ParserError: while parsing a block mapping\n  in "/etc/ejabberd/ejabberd.yml", line 172, column 3\nexpected <block end>, but found \'<block mapping start>\'\n  in "/etc/ejabberd/ejabberd.yml", line 188, column 5\n')
Mar 27 14:09:34 freedombox /usr/bin/plinth[416]: # help get-logs
Mar 27 14:09:34 freedombox sudo[18561]:   plinth : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/share/plinth/actions/help get-logs
Mar 27 14:09:34 freedombox sudo[18561]: pam_unix(sudo:session): session opened for user root by (uid=0)

Android clients send and receive both plain txt messages, images & files.

1 Like

Sorry, of course, I yet forgot that :man_facepalming:

I asked a friend to install https://monal.im on her iOS iPad and to log in with her account on my freedombox.

  1. So we are both on <myserver.net> with our accounts. Me at my site, she abroad.
  2. I send a picture to her. Works (no surprise, I know, as Android clients can connect to ejabberd yet).
  3. She sends me another picture. I receive it immediately. So she can connect to my server despite having an iOS client obviously.

Maybe it’s not a bug in ejabberd but either due to some specifics of certain iOS clients or it is a matter of the server config …

OK, I now tested your config on my machine. And got it to work.

  1. The bug in the .yml was that mod_http_upload was indented under mod_http_api and so interpreted as a sublock of the latter.
  2. After correcting this the only failure messages or warnings concern the certs.
  3. Adjusting host, certfiles and commenting out s2s_certfile which is warned as deprecated allows me to …
  4. … start ejabberd and send at least images between two Linux clients.

You can download this working config from https://ismus.net/~homer77/ejabberd.yml if you like and check if you want to adjust it to your needs.

Hope that solves your problem :crossed_fingers: