docs.ejabberd.im

Basic Configuration


XMPP Domains

Host Names

ejabberd supports managing several independent XMPP domains on a single ejabberd instance, using a feature called virtual hosting.

The option hosts defines a list containing one or more domains that ejabberd will serve.

Of course, the hosts list can contain just one domain if you do not want to host multiple XMPP domains on the same instance.

Examples:

  • Serving one domain:

    hosts: [example.org]
    
  • Serving three domains:

    hosts:
      - example.net
      - example.com
      - jabber.somesite.org
    

Virtual Hosting

When managing several XMPP domains in a single instance, those domains are truly independent. It means they can even have different configuration parameters.

Options can be defined separately for every virtual host using the host_config option.

Examples:

  • Domain example.net is using the internal authentication method while domain example.com is using the LDAP server running on the domain localhost to perform authentication:

    host_config:
      example.net:
        auth_method: internal
      example.com:
        auth_method: ldap
        ldap_servers:
          - localhost
        ldap_uids:
          - uid
        ldap_rootdn: "dc=localdomain"
        ldap_password: ""
    
  • Domain example.net is using SQL to perform authentication while domain example.com is using the LDAP servers running on the domains localhost and otherhost:

    host_config:
      example.net:
        auth_method: sql
        sql_type: odbc
        sql_server: "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"
      example.com:
        auth_method: ldap
        ldap_servers:
          - localhost
          - otherhost
        ldap_uids:
          - uid
        ldap_rootdn: "dc=example,dc=com"
        ldap_password: ""
    

To define specific ejabberd modules in a virtual host, you can define the global modules option with the common modules, and later add specific modules to certain virtual hosts. To accomplish that, instead of defining each option in host_config use append_host_config with the same syntax.

In this example three virtual hosts have some similar modules, but there are also other different modules for some specific virtual hosts:

## This ejabberd server has three vhosts:
hosts:
  - one.example.org
  - two.example.org
  - three.example.org

## Configuration of modules that are common to all vhosts
modules:
  mod_roster:    {}
  mod_configure: {}
  mod_disco:     {}
  mod_private:   {}
  mod_time:      {}
  mod_last:      {}
  mod_version:   {}

append_host_config:
  ## Add some modules to vhost one:
  one.example.org:
    modules:
      mod_muc:
        host: conference.one.example.org
      mod_ping: {}
  ## Add a module just to vhost two:
  two.example.org:
    modules:
      mod_muc:
        host: conference.two.example.org

Logging

ejabberd configuration can help a lot by having the right amount of logging set up.

There are several toplevel options to configure logging:

  • loglevel: Verbosity of log files generated by ejabberd.
  • hide_sensitive_log_data Privacy option to disable logging of IP address or sensitive data.
  • log_rotate_size
  • log_rotate_count: Setting count to N keeps N rotated logs. Setting count to 0 does not disable rotation, it instead rotates the file and keeps no previous versions around. Setting size to X rotate log when it reaches X bytes.

The values in default configuration file are:

log_rotate_size: 10485760
log_rotate_count: 1

For example:

hide_sensitive_log_data: false

Default Language

The option language defines the default language of server strings that can be seen by XMPP clients. If a XMPP client does not support xml:lang, the specified language is used.

The option syntax is:

language: Language: The default value is en. In order to take effect there must be a translation file Language.msg in ejabberd’s msgs directory.

For example, to set Russian as default language:

language: ru

The page Internationalization and Localization provides more details.

CAPTCHA

Some ejabberd modules can be configured to require a CAPTCHA challenge on certain actions. If the client does not support CAPTCHA Forms (XEP-0158), a web link is provided so the user can fill the challenge in a web browser.

An example script is provided that generates the image using ImageMagick’s Convert program.

Note: we do not provide example scripts to support image generation on Microsoft Windows. Captcha will not work with ejabberd Windows installer.

The configurable options are:

captcha_cmd: Path: Full path to a script that generates the image. The default value disables the feature: undefined

captcha_url: URL: An URL where CAPTCHA requests should be sent. You need to configure request_handlers for ejabberd_http listener as well.

Example configuration:

hosts: [example.org]

captcha_cmd: /lib/ejabberd/priv/bin/captcha.sh
captcha_url: http://example.org:5280/captcha
## captcha_url: https://example.org:443/captcha
## captcha_url: http://example.com/captcha

listen:
  ...
  -
    port: 5280
    module: ejabberd_http
    request_handlers:
      /captcha: ejabberd_captcha
  ...

ACME

ACME is used to automatically obtain SSL certificates for the domains served by ejabberd, which means that certificate requests and renewals are performed to some CA server (aka "ACME server") in a fully automated mode.

Setting up ACME

In ejabberd, ACME is configured using the acme top-level option, check there available options an example configuration.

The automated mode is enabled by default. However, since ACME requires HTTP challenges (i.e. an ACME server will connect to ejabberd server on HTTP port 80 during certificate issuance), some configuration of ejabberd is still required. Namely, an HTTP listener for ejabberd_http listen module should be configured on non-TLS port with so called "ACME well known" request handler:

listen:
  ...
  -
    module: ejabberd_http
    port: 5280
    request_handlers:
      /.well-known/acme-challenge: ejabberd_acme
      ...
  ...

Note that the ACME protocol requires challenges to be sent on port 80. Since this is a privileged port, ejabberd cannot listen on it directly without root privileges. Thus you need some mechanism to forward port 80 to the port defined by the listener (port 5280 in the example above). There are several ways to do this: using NAT, setcap (Linux only), or HTTP front-ends (e.g. sslh, nginx, haproxy and so on). Pick one that fits your installation the best, but DON'T run ejabberd as root.

If you see errors in the logs with ACME server problem reports, it's highly recommended to change ca_url option in the acme top-level option to the URL pointing to some staging ACME environment, fix the problems until you obtain a certificate, and then change the URL back and retry using request-certificate ejabberdctl command (see below). This is needed because ACME servers typically have rate limits, preventing you from requesting certificates too rapidly and you can get stuck for several hours or even days. By default, ejabberd uses Let's Encrypt authority. Thus, the default value of ca_url option is https://acme-v02.api.letsencrypt.org/directory and the staging URL will be https://acme-staging-v02.api.letsencrypt.org/directory:

acme:
  ## Staging environment
  ca_url: https://acme-staging-v02.api.letsencrypt.org/directory
  ## Production environment (the default):
  # ca_url: https://acme-v02.api.letsencrypt.org/directory

The automated mode can be disabled by setting auto option to false in the acme top-level option:

acme:
  auto: false
  ...

In this case automated renewals are still enabled, however, in order to request a new certificate, you need to run request-certificate ejabberdctl command:

$ ejabberdctl request-certificate all

If you only want to request certificates for a subset of the domains, run:

$ ejabberdctl request-certificate domain.tld,pubsub.domain.tld,server.com,conference.server.com,...

You can view the certificates obtained using ACME:

$ ejabberdctl list-certificates
domain.tld /path/to/cert/file1 true
server.com /path/to/cert/file2 false
...

The output is mostly self-explained: every line contains the domain, the corresponding certificate file, and whether this certificate file is used or not. A certificate might not be used for several reasons: mostly because ejabberd detects a better certificate (i.e. not expired, or having a longer lifetime). It's recommended to revoke unused certificates if they are not yet expired (see below).

At any point you can revoke a certificate: pick the certificate file from the listing above and run:

$ ejabberdctl revoke-certificate /path/to/cert/file

If the commands return errors, consult the log files for details.

ACME implementation details

In nutshell, certification requests are performed in two phases. Firstly, ejabberd creates an account at the ACME server. That is an EC private key. Secondly, a certificate is requested. In the case of a revocation, no account is used - only a certificate in question is needed. All information is stored under acme directory inside spool directory of ejabberd (typically /var/lib/ejabberd). An example content of the directory is the following:

$ tree /var/lib/ejabberd
/var/lib/ejabberd
├── acme
│   ├── account.key
│   └── live
│       ├── 251ce180d964e98a2f18b65504df2ab7c55943e2
│       └── 93816a8429ebbaa75574eb3f59d4a806b67d6917
...

Here, account.key is the EC private key used to identify the ACME account. You can inspect its content using openssl command:

$ openssl ec -text -noout -in /var/lib/ejabberd/acme/account.key

Obtained certificates are stored under acme/live directory. You can inspect any of the certificates using openssl command as well:

$ openssl x509 -text -noout -in /var/lib/ejabberd/acme/live/251ce180d964e98a2f18b65504df2ab7c55943e2

In the case of errors, you can delete the whole acme directory - ejabberd will recreate its content on next certification request. However, don't delete it too frequently - usually there is a rate limit on the number of accounts and certificates an ACME server creates. In particular, for Let's Encrypt the limits are described here.

Access Rules

This section describes new ACL syntax introduced in ejabberd 16.06. For old access rule and ACL syntax documentation, please refer to configuration document archive

ACL Definition

Access control in ejabberd is performed via Access Control Lists (ACLs), using the acl option. The declarations of ACLs in the configuration file have the following syntax:

acl: { ACLName: { ACLType: ACLValue } }

ACLType: ACLValue can be one of the following:

all: Matches all JIDs. Example:

    acl:
      world: all

user: Username: Matches the user with the name Username on any of the local virtual host. Example:

    acl:
      admin:
        user: yozhik

user: {Username: Server} | Jid: Matches the user with the JID Username@Server and any resource. Example:

    acl:
      admin:
        - user:
            yozhik@example.org
        - user: peter@example.org

server: Server: Matches any JID from server Server. Example:

    acl:
      exampleorg:
        server: example.org

resource: Resource: Matches any JID with a resource Resource. Example:

    acl:
      mucklres:
        resource: muckl

shared_group: Groupname: Matches any member of a Shared Roster Group with name Groupname in the virtual host. Example:

    acl:
      techgroupmembers:
        shared_group: techteam

shared_group: {Groupname: Server}: Matches any member of a Shared Roster Group with name Groupname in the virtual host Server. Example:

    acl:
      techgroupmembers:
        shared_group:
          techteam: example.org

ip: Network: Matches any IP address from the Network. Example:

    acl:
      loopback:
        ip:
          - 127.0.0.0/8
          - "::1"

user_regexp: Regexp: Matches any local user with a name that matches Regexp on local virtual hosts. Example:

    acl:
      tests:
        user_regexp: "^test[0-9]*$"

user_regexp: {Regexp: Server} | JidRegexp: Matches any user with a name that matches Regexp at server Server. Example:

    acl:
      tests:
        user_regexp:
          - "^test1": example.org
          - "^test2@example.org"

server_regexp: Regexp: Matches any JID from the server that matches Regexp. Example:

    acl:
      icq:
        server_regexp: "^icq\\."

resource_regexp: Regexp: Matches any JID with a resource that matches Regexp. Example:

    acl:
      icq:
        resource_regexp: "^laptop\\."

node_regexp: {UserRegexp: ServerRegexp}: Matches any user with a name that matches UserRegexp at any server that matches ServerRegexp. Example:

    acl:
      yozhik:
        node_regexp:
          "^yozhik$": "^example.(com|org)$"

user_glob: Glob:

user_glob: {Glob: Server}:

server_glob: Glob:

resource_glob: Glob:

node_glob: {UserGlob: ServerGlob}: This is the same as above. However, it uses shell glob patterns instead of regexp. These patterns can have the following special characters:

  • *: matches any string including the null string.

  • ?: matches any single character.

  • [...]: matches any of the enclosed characters. Character ranges are specified by a pair of characters separated by a -. If the first character after [ is a !, any character not enclosed is matched.

The following ACLName are pre-defined:

all: Matches any JID.

none: Matches no JID.

Access Rights

The access_rules option is used to allow or deny access to different services. The syntax is:

access_rules: { AccessName: { - allow|deny: ACLRule|ACLDefinition } }

Each definition may contain arbitrary number of - allow or - deny sections, and each section can contain any number of acl rules (as defined in previous section, it recognizes one additional rule acl: RuleName that matches when acl rule named RuleName matches). If no rule or definition is defined, the rule all is applied.

Definition's - allow and - deny sections are processed in top to bottom order, and first one for which all listed acl rules matches is returned as result of access rule. If no rule matches deny is returned.

To simplify configuration two shortcut version are available: - allow: acl and - allow, example below shows equivalent definitions where short or long version are used:

access_rules:
  a_short: admin
  a_long:
    - acl: admin
  b_short:
    - deny: banned
    - allow
  b_long:
    - deny:
      - acl: banned
    - allow:
      - all

If you define specific Access rights in a virtual host, remember that the globally defined Access rights have precedence over those. This means that, in case of conflict, the Access granted or denied in the global server is used and the Access of a virtual host doesn't have effect.

Example:

  access_rules:
    configure:
      - allow: admin
    something:
      - deny: someone
      - allow
    s2s_banned:
      - deny: problematic_hosts
      - deny:
        - acl: banned_forever
      - deny:
        - ip: 222.111.222.111/32
      - deny:
        - ip: 111.222.111.222/32
      - allow
    xmlrpc_access:
      - allow:
        - user: peter@example.com
      - allow:
        - user: ivone@example.com
      - allow:
        - user: bot@example.com
        - ip: 10.0.0.0/24

The following AccessName are pre-defined:

all: Always returns the value ‘allow’.

none: Always returns the value ‘deny’.

Shaper Rules

An entry allowing to declaring shaper to use for matching user/hosts. The syntax is:

shaper_rules: { ShaperRuleName: { - Number|ShaperName: ACLRule|ACLDefinition } }

Semantic is similar to that described in Access Rights section, only difference is that instead using - allow or - deny, name of shaper or number should be used.

Examples:

shaper_rules:
  connections_limit:
    - 10:
      - user: peter@example.com
    - 100: admin
    - 5
  download_speed:
    - fast: admin
    - slow: anonymous_users
    - normal
  log_days: 30

Limiting Opened Sessions with ACL

The special access max_user_sessions specifies the maximum number of sessions (authenticated connections) per user. If a user tries to open more sessions by using different resources, the first opened session will be disconnected. The error session replaced will be sent to the disconnected session. The value for this option can be either a number, or infinity. The default value is infinity.

The syntax is:

{ max_user_sessions: { - Number: ACLRule|ACLDefinition } }

This example limits the number of sessions per user to 5 for all users, and to 10 for admins:

shaper_rules:
  max_user_sessions:
    - 10: admin
    - 5

Several connections to a remote XMPP server with ACL

The special access max_s2s_connections specifies how many simultaneous S2S connections can be established to a specific remote XMPP server. The default value is 1. There’s also available the access max_s2s_connections_per_node.

The syntax is:

{ max_s2s_connections: { ACLName: MaxNumber } }

Examples:

  • Allow up to 3 connections with each remote server:

    shaper_rules:
      max_s2s_connections: 3
    

Shapers

Shapers enable you to limit connection traffic. The basic syntax is:

shaper: { ShaperName: Rate }

where Rate stands for the maximum allowed incoming rate in bytes per second. When a connection exceeds this limit, ejabberd stops reading from the socket until the average rate is again below the allowed maximum.

This example defines a shaper with name normal that limits traffic speed to 1,000bytes/second, and another shaper with name fast that limits traffic speed to 50,000bytes/second:

shaper:
  normal: 1000
  fast: 50000

You can use the full syntax to set the BurstSize too:

shaper: { ShaperName: { rate: Rate, burst_size: BurstSize}}

With BurstSize you can allow client to send more data, but its amount can be clamped reasonably. Each connection is allowed to send BurstSize of data before processing is delayed, and that amount is replenished by Rate each second, but never more than what BurstSize allows. This allows the client to send quite a bit of data at once, but still have limited amount of data to send on constant basis.

In this example, the normal shaper has Rate set to 1000 and the BurstSize takes that same value. The not_normal shaper has the same Rate that before, and sets a higher BurstSize:

shaper:
  normal: 1000
  not_normal:
    rate: 1000
    burst_size: 20000