Ejabberd

From SmartCommunity

Jump to: navigation, search

ejabberd is world’s most popular Jabber/XMPP server software. Despite the fact that it is known to be very bulky and hard to manage, it’s used at about 70% of all existing Jabber/XMPP servers.

Contents

ODBC authentication method

TODO

LDAP authentication method

TODO

External authentication method

External authentifation script is supposed to do theses actions, in an infinite loop:

   * read from stdin: AABBBBBBBBB.....
        o A: 2 bytes of length data (a short in network byte order)
        o B: a string of length found in A that contains operation in plain text operation are as follows:
              + auth:User:Server:Password (check if a username/password pair is correct)
              + isuser:User:Server (check if it’s a valid user)
              + setpass:User:Server:Password (set user’s password)
              + tryregister:User:Server:Password (try to register an account)
              + removeuser:User:Server (remove this account)
              + removeuser3:User:Server:Password (remove this account if the password is correct) 
  * write to stdout: AABB
        o A: the number 2 (coded as a short, which is bytes length of following result)
        o B: the result code (coded as a short), should be 1 for success/valid, or 0 for failure/invalid

Example (Python)

#!/usr/bin/python
import sys
from struct import *
def from_ejabberd():
  input_length = sys.stdin.read(2)
  (size,) = unpack('>h', input_length)
  return sys.stdin.read(size).split(':')
def to_ejabberd(bool):
  answer = 0
  if bool:
      answer = 1
  token = pack('>hh', 2, answer)
  sys.stdout.write(token)
  sys.stdout.flush()
def auth(username, server, password):
  return True
def isuser(username, server):
  return True
def setpass(username, server, password):
  return True
while True:
  data = from_ejabberd()
  success = False
  if data[0] == "auth":
      success = auth(data[1], data[2], data[3])
  elif data[0] == "isuser":
      success = isuser(data[1], data[2])
  elif data[0] == "setpass":
      success = setpass(data[1], data[2], data[3])
  to_ejabberd(success)

ejabberd tricks

These tips are useful to adjust running server settings from ejabberd console (ejabberdctl debug).
Please don't try unless you know what you are doing. Most of the tips are just a notices and require viewing source code before use.

how do I get information about module?

try

module:module_info().

e.g.

(ejabberd@myhost)> ejabberd_logger:module_info().
[{exports,[{warning_msg,4},
           {debug_msg,4},
           {module_info,0},
           {module_info,1},
           {critical_msg,4},
           {get,0},
           {error_msg,4},
           {info_msg,4}]},
 {imports,[]},
 {attributes,[{vsn,[209817685696126463583081811167696374369]},
              {author,['mickael.remond@process-one.net']}]},
 {compile,[{options,[]},
           {version,"4.8"},
           {time,{2012,3,17,11,51,15}},
           {source,"/opt/ejabberd/var/lib/ejabberd"}]}]


who is using my nickname?

mnesia:dirty_select(muc_registered, [{#muc_registered{us_host = '$1', nick = "WST", _ = '_'},[],['$1']}]).

release my nickname!

mnesia:transaction(fun() -> mnesia:delete({muc_registered, {{"nany","jsmart.web.id"},"conference.jsmart.web.id"}}) end).

where's muc_register record?

rd(muc_registered, {us_host, nick}).

who is online?

(ejabberd)> rp(ejabberd_sm:get_vh_session_list("my-vhost.org")).

how do I read/write config on-the-fly?

%% Global options are probably those shared in the cluster.
(ejabberd)> ejabberd_config:get_global_option(language).
=> "en"
(ejabberd)> ejabberd_config:get_global_option({shaper, fast, global}).
=> {maxrate,204800}
(ejabberd)> ejabberd_config:get_global_option({access, muc_admin, global}).
=> [{allow,admin},{allow,muc_admin}]
%% Local options are probably for the current node only:
(ejabberd)> ejabberd_config:get_local_option(max_fsm_queue).
=> 500
(ejabberd)> ejabberd_config:get_local_option({odbc_server, "my-vhost.org"}).
=> {mysql,"mysql.my-servers.org","ejabberd_database",
    "ejabberd_username","ejabberd_secret_password"}
(ejabberd)> ejabberd_config:get_local_option({s2s_default_policy, "my-vhost.org"}).
=> allow
%% Let's change the setting
(ejabberd)> ejabberd_config:add_local_option({s2s_default_policy, "my-vhost.org"}, deny).
(ejabberd)> ejabberd_config:add_local_option({{s2s_host, "friendly-host.org"}, "my-vhost.org"}, allow).
(ejabberd)> ejabberd_config:add_global_option({shaper, filter, global}, {maxrate, 102400}).
(ejabberd)> ejabberd_config:add_global_option({access, c2s_shaper, global}, [{none,admin},{filter,filter_bot},{normal,all}]).

how do I invoke GC?

I summon thee almighty GC hallowed be thy name
accept this sacrifice and collect our memory
amen

© Author Unknown
Note that manual GC is not recommended unless it is required measure. Consult erlang manual

  • first, look the most consuming processes:
etop
(ejabberd)> etop:config(sort, memory).
(ejabberd)> etop:config(lines, 50).
  • then, in ejabberd console:
(ejabberd)> erlang:garbage_collect(c:pid(0, 12810, 20)).

note that 1st argument of c:pid is now 0, because we'r in the same node now

  • for all processes:
(ejabberd)> lists:foreach(fun erlang:garbage_collect/1, processes()).

how do I reload modules?

Erlang modules, not ejabberd modules.

%% Try until true (code:purge, in contrast, terminates all processes using it).
(ejabberd)> code:soft_purge(mod_muc).
%% Now delete the purged module:
(ejabberd)> code:delete(mod_muc).
%% Load the new version:
(ejabberd)> code:load_file(mod_muc).

or you can use builting ejabberd_update module for this:

%% Check the list of the modules to update:
(ejabberd)> ejabberd_update:update_info().
%% Update immediately:
(ejabberd)> ejabberd_update:update().

how do I rotate logs?

Before you proceed, ensure that there are no "old" log files, e.g. ejabberd-old.log or erlang-old.log. If you find them, remove or rename, otherwise reopen-log will break your logfiles.
When ready, use the shell command line:

ejabberdctl reopen-log

how do I get user's IP/conn.type/etc?

%% First get the list of connected resources:
(ejabberd)> ejabberd_sm:user_resources("user", "my-vhost.org").
=> ["Psi"]
%% Now you can retrieve info about any resource:
(ejabberd)> ejabberd_sm:get_user_info("user", "my-vhost.org", "Psi").
=> [{node,ejabberd@myhost},
    {conn,c2s_compressed_tls},
    {ip,{{192,168,1,10},40963}}]

how do I change loglevel?

(ejabberd)> ejabberd_loglevel:get().
=> {3,warning,"Warning"}
(ejabberd)> ejabberd_loglevel:set(warning).

Supported levels are:

  • no_log 0
  • critical 1
  • error 2
  • warning 3
  • info 4
  • debug 5

both atom or integer representation is allowed

how do I change affiliation in a room?

	rd(muc_room_affiliation, {name_host, jid, affiliation, reason}).
    gen_storage:write(
      Host,
				      #muc_room_affiliation{name_host = {Name, Host},
							    jid = exmpp_jid:make(Username, Server, Resource),
							    affiliation = Affiliation,
							    reason = Reason})

INCOMPLETE! TODO!

how do I start/stop a module?

%% modules are always local (even though you can configure them globally).
%% Start mod_logxml on my-vhost.org with empty options set []:
(ejabberd)> gen_mod:start_module("my-vhost.org", mod_logxml, []).
                    stop_module

how do I change acl / become an admin?

%% of my-vhost.org vhost:
(ejabberd)> acl:add("my-vhost.org", admin, {user, "my_jid", "jabber.org"}).
%% globally:
(ejabberd)> acl:add(global, admin, {user, "my_jid", "jabber.org"}).
%% test:
(ejabberd)> acl:match_rule("target-vhost.org", configure, jlib:make_jid("my_jid", "jabber.org", "Resource")).
=> allow

how do I update socket settings on-the-fly?

First you should delete listener from ejabberd Listeners set (e.g. with webui). Then the record will hang around in the listen_sockets ets. We should find it (the numbers after 5222 are just IPv6):

(ejabberd)> [{Addr, Port}] = ets:lookup(listen_sockets, {5222, {10753,1272,256,17476,0,0,0,1}, tcp}).
=> [{{5222,{10753,1272,256,17476,0,0,0,1},tcp},#Port<0.3578>}]

Then delete it:

(ejabberd)> ets:delete(listen_sockets, Addr).
=> true

Now close the socket:

(ejabberd)> gen_tcp:close(Port). 
=> ok

Now you can start the new listener and it will create a new socket, with updated settings.

Alert.png This article is marked as unfinished. You may contribute by writing it or wait for it’s author to do it.